Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/check-required-label.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Check Required Labels

on:
pull_request:
types: [opened, labeled, unlabeled]
types: [opened, labeled, unlabeled, synchronize]

jobs:
check-required-label:
Expand Down
4 changes: 1 addition & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,9 @@ test: unit-test integration-test-all
generate:
go generate ./...

# If you execute `gofumpt -l -w .`, it will format all Go files in the current directory, including `test/_results/*` files.
# We pass only Git-tracked Go files to gofumpt because we don't want to format the test results or get errors from it.
.PHONY: format
format:
git ls-files '*.go' ':!vendor' | xargs gofumpt -l -w
gofumpt -l -w .

.PHONY: lint
lint:
Expand Down
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ module github.com/jesseduffield/lazygit

go 1.25.0

// This is necessary to ignore test files when executing gofumpt.
ignore ./test

require (
dario.cat/mergo v1.0.1
github.com/adrg/xdg v0.4.0
Expand Down
45 changes: 35 additions & 10 deletions pkg/commands/git_commands/branch.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,26 +250,51 @@ func (self *BranchCommands) Rename(oldName string, newName string) error {
return self.cmd.New(cmdArgs).Run()
}

type MergeOpts struct {
FastForwardOnly bool
Squash bool
}
type MergeVariant int

const (
MERGE_VARIANT_REGULAR MergeVariant = iota
MERGE_VARIANT_FAST_FORWARD
MERGE_VARIANT_NON_FAST_FORWARD
MERGE_VARIANT_SQUASH
)

func (self *BranchCommands) Merge(branchName string, variant MergeVariant) error {
extraArgs := func() []string {
switch variant {
case MERGE_VARIANT_REGULAR:
return []string{}
case MERGE_VARIANT_FAST_FORWARD:
return []string{"--ff"}
case MERGE_VARIANT_NON_FAST_FORWARD:
return []string{"--no-ff"}
case MERGE_VARIANT_SQUASH:
return []string{"--squash", "--ff"}
}

panic("shouldn't get here")
}()

func (self *BranchCommands) Merge(branchName string, opts MergeOpts) error {
if opts.Squash && opts.FastForwardOnly {
panic("Squash and FastForwardOnly can't both be true")
}
cmdArgs := NewGitCmd("merge").
Arg("--no-edit").
Arg(strings.Fields(self.UserConfig().Git.Merging.Args)...).
ArgIf(opts.FastForwardOnly, "--ff-only").
ArgIf(opts.Squash, "--squash", "--ff").
Arg(extraArgs...).
Arg(branchName).
ToArgv()

return self.cmd.New(cmdArgs).Run()
}

// Returns whether refName can be fast-forward merged into the current branch
func (self *BranchCommands) CanDoFastForwardMerge(refName string) bool {
cmdArgs := NewGitCmd("merge-base").
Arg("--is-ancestor").
Arg("HEAD", refName).
ToArgv()
err := self.cmd.New(cmdArgs).DontLog().Run()
return err == nil
}

// Only choose between non-empty, non-identical commands
func (self *BranchCommands) allBranchesLogCandidates() []string {
return lo.Uniq(lo.WithoutEmpty(self.UserConfig().Git.AllBranchesLogCmds))
Expand Down
30 changes: 22 additions & 8 deletions pkg/commands/git_commands/branch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,14 @@ func TestBranchMerge(t *testing.T) {
scenarios := []struct {
testName string
userConfig *config.UserConfig
opts MergeOpts
variant MergeVariant
branchName string
expected []string
}{
{
testName: "basic",
userConfig: &config.UserConfig{},
opts: MergeOpts{},
variant: MERGE_VARIANT_REGULAR,
branchName: "mybranch",
expected: []string{"merge", "--no-edit", "mybranch"},
},
Expand All @@ -142,7 +142,7 @@ func TestBranchMerge(t *testing.T) {
},
},
},
opts: MergeOpts{},
variant: MERGE_VARIANT_REGULAR,
branchName: "mybranch",
expected: []string{"merge", "--no-edit", "--merging-args", "mybranch"},
},
Expand All @@ -155,16 +155,30 @@ func TestBranchMerge(t *testing.T) {
},
},
},
opts: MergeOpts{},
variant: MERGE_VARIANT_REGULAR,
branchName: "mybranch",
expected: []string{"merge", "--no-edit", "--arg1", "--arg2", "mybranch"},
},
{
testName: "fast forward only",
testName: "fast-forward merge",
userConfig: &config.UserConfig{},
opts: MergeOpts{FastForwardOnly: true},
variant: MERGE_VARIANT_FAST_FORWARD,
branchName: "mybranch",
expected: []string{"merge", "--no-edit", "--ff-only", "mybranch"},
expected: []string{"merge", "--no-edit", "--ff", "mybranch"},
},
{
testName: "non-fast-forward merge",
userConfig: &config.UserConfig{},
variant: MERGE_VARIANT_NON_FAST_FORWARD,
branchName: "mybranch",
expected: []string{"merge", "--no-edit", "--no-ff", "mybranch"},
},
{
testName: "squash merge",
userConfig: &config.UserConfig{},
variant: MERGE_VARIANT_SQUASH,
branchName: "mybranch",
expected: []string{"merge", "--no-edit", "--squash", "--ff", "mybranch"},
},
}

Expand All @@ -174,7 +188,7 @@ func TestBranchMerge(t *testing.T) {
ExpectGitArgs(s.expected, "", nil)
instance := buildBranchCommands(commonDeps{runner: runner, userConfig: s.userConfig})

assert.NoError(t, instance.Merge(s.branchName, s.opts))
assert.NoError(t, instance.Merge(s.branchName, s.variant))
runner.CheckForMissingCalls()
})
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/commands/git_commands/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ func (self *ConfigCommands) GetRebaseUpdateRefs() bool {
return self.gitConfig.GetBool("rebase.updateRefs")
}

func (self *ConfigCommands) GetMergeFF() string {
return self.gitConfig.Get("merge.ff")
}

func (self *ConfigCommands) DropConfigCache() {
self.gitConfig.DropCache()
}
32 changes: 16 additions & 16 deletions pkg/commands/oscommands/copy.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,16 @@ import (
// destination file exists, all it's contents will be replaced by the contents
// of the source file. The file mode will be copied from the source and
// the copied data is synced/flushed to stable storage.
func CopyFile(src, dst string) (err error) {
func CopyFile(src, dst string) error {
in, err := os.Open(src)
if err != nil {
return //nolint: nakedret
return err
}
defer in.Close()

out, err := os.Create(dst)
if err != nil {
return //nolint: nakedret
return err
}
defer func() {
if e := out.Close(); e != nil {
Expand All @@ -54,30 +54,30 @@ func CopyFile(src, dst string) (err error) {

_, err = io.Copy(out, in)
if err != nil {
return //nolint: nakedret
return err
}

err = out.Sync()
if err != nil {
return //nolint: nakedret
return err
}

si, err := os.Stat(src)
if err != nil {
return //nolint: nakedret
return err
}
err = os.Chmod(dst, si.Mode())
if err != nil {
return //nolint: nakedret
return err
}

return //nolint: nakedret
return err
}

// CopyDir recursively copies a directory tree, attempting to preserve permissions.
// Source directory must exist. If destination already exists we'll clobber it.
// Symlinks are ignored and skipped.
func CopyDir(src string, dst string) (err error) {
func CopyDir(src string, dst string) error {
src = filepath.Clean(src)
dst = filepath.Clean(dst)

Expand All @@ -91,7 +91,7 @@ func CopyDir(src string, dst string) (err error) {

_, err = os.Stat(dst)
if err != nil && !os.IsNotExist(err) {
return //nolint: nakedret
return err
}
if err == nil {
// it exists so let's remove it
Expand All @@ -102,12 +102,12 @@ func CopyDir(src string, dst string) (err error) {

err = os.MkdirAll(dst, si.Mode())
if err != nil {
return //nolint: nakedret
return err
}

entries, err := os.ReadDir(src)
if err != nil {
return //nolint: nakedret
return err
}

for _, entry := range entries {
Expand All @@ -117,13 +117,13 @@ func CopyDir(src string, dst string) (err error) {
if entry.IsDir() {
err = CopyDir(srcPath, dstPath)
if err != nil {
return //nolint: nakedret
return err
}
} else {
var info os.FileInfo
info, err = entry.Info()
if err != nil {
return //nolint: nakedret
return err
}

// Skip symlinks.
Expand All @@ -133,10 +133,10 @@ func CopyDir(src string, dst string) (err error) {

err = CopyFile(srcPath, dstPath)
if err != nil {
return //nolint: nakedret
return err
}
}
}

return //nolint: nakedret
return err
}
Loading