diff --git a/pkg/commands/git_commands/git_command_builder.go b/pkg/commands/git_commands/git_command_builder.go index b6fe573641c..a7edc144c61 100644 --- a/pkg/commands/git_commands/git_command_builder.go +++ b/pkg/commands/git_commands/git_command_builder.go @@ -76,6 +76,14 @@ func (self *GitCommandBuilder) Worktree(path string) *GitCommandBuilder { return self } +func (self *GitCommandBuilder) WorktreePathIf(condition bool, path string) *GitCommandBuilder { + if condition { + return self.Worktree(path) + } + + return self +} + // Note, you may prefer to use the Dir method instead of this one func (self *GitCommandBuilder) GitDir(path string) *GitCommandBuilder { // git dir arg comes before the command diff --git a/pkg/commands/git_commands/sync.go b/pkg/commands/git_commands/sync.go index 360d40fe774..ab6942d05ad 100644 --- a/pkg/commands/git_commands/sync.go +++ b/pkg/commands/git_commands/sync.go @@ -88,6 +88,7 @@ type PullOptions struct { BranchName string FastForwardOnly bool WorktreeGitDir string + WorktreePath string } func (self *SyncCommands) Pull(task gocui.Task, opts PullOptions) error { @@ -97,6 +98,7 @@ func (self *SyncCommands) Pull(task gocui.Task, opts PullOptions) error { ArgIf(opts.RemoteName != "", opts.RemoteName). ArgIf(opts.BranchName != "", "refs/heads/"+opts.BranchName). GitDirIf(opts.WorktreeGitDir != "", opts.WorktreeGitDir). + WorktreePathIf(opts.WorktreePath != "", opts.WorktreePath). ToArgv() // setting GIT_SEQUENCE_EDITOR to ':' as a way of skipping it, in case the user diff --git a/pkg/gui/controllers/branches_controller.go b/pkg/gui/controllers/branches_controller.go index a364811d600..9a1530971cd 100644 --- a/pkg/gui/controllers/branches_controller.go +++ b/pkg/gui/controllers/branches_controller.go @@ -629,9 +629,11 @@ func (self *BranchesController) fastForward(branch *models.Branch) error { self.c.LogAction(action) worktreeGitDir := "" + worktreePath := "" // if it is the current worktree path, no need to specify the path if !worktree.IsCurrent { worktreeGitDir = worktree.GitDir + worktreePath = worktree.Path } err := self.c.Git().Sync.Pull( @@ -641,6 +643,7 @@ func (self *BranchesController) fastForward(branch *models.Branch) error { BranchName: branch.UpstreamBranch, FastForwardOnly: true, WorktreeGitDir: worktreeGitDir, + WorktreePath: worktreePath, }, ) _ = self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC}) diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go index 2e33a4f4e5b..2f5063822ba 100644 --- a/pkg/integration/tests/test_list.go +++ b/pkg/integration/tests/test_list.go @@ -380,6 +380,7 @@ var tests = []*components.IntegrationTest{ worktree.DoubleNestedLinkedSubmodule, worktree.ExcludeFileInWorktree, worktree.FastForwardWorktreeBranch, + worktree.FastForwardWorktreeBranchShouldNotPolluteCurrentWorktree, worktree.ForceRemoveWorktree, worktree.RemoveWorktreeFromBranch, worktree.ResetWindowTabs, diff --git a/pkg/integration/tests/worktree/fast_forward_worktree_branch_should_not_pollute_current_worktree.go b/pkg/integration/tests/worktree/fast_forward_worktree_branch_should_not_pollute_current_worktree.go new file mode 100644 index 00000000000..cbe1ed94394 --- /dev/null +++ b/pkg/integration/tests/worktree/fast_forward_worktree_branch_should_not_pollute_current_worktree.go @@ -0,0 +1,59 @@ +package worktree + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var FastForwardWorktreeBranchShouldNotPolluteCurrentWorktree = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Fast-forward a linked worktree branch from another worktree", + ExtraCmdArgs: []string{}, + Skip: false, + SetupConfig: func(config *config.AppConfig) {}, + SetupRepo: func(shell *Shell) { + // both main and linked worktree will have changed to fast-forward + shell.NewBranch("mybranch") + shell.CreateFileAndAdd("README.md", "hello world") + shell.Commit("initial commit") + shell.EmptyCommit("two") + shell.EmptyCommit("three") + shell.NewBranch("newbranch") + + shell.CloneIntoRemote("origin") + shell.SetBranchUpstream("mybranch", "origin/mybranch") + shell.SetBranchUpstream("newbranch", "origin/newbranch") + + // remove the 'three' commit so that we have something to pull from the remote + shell.HardReset("HEAD^") + shell.Checkout("mybranch") + shell.HardReset("HEAD^") + + shell.AddWorktreeCheckout("newbranch", "../linked-worktree") + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Branches(). + Focus(). + Lines( + Contains("mybranch").Contains("↓1").IsSelected(), + Contains("newbranch (worktree)").Contains("↓1"), + ). + Press(keys.Branches.FastForward). + Lines( + Contains("mybranch").Contains("✓").IsSelected(), + Contains("newbranch (worktree)").Contains("↓1"), + ). + NavigateToLine(Contains("newbranch (worktree)")). + Press(keys.Branches.FastForward). + Lines( + Contains("mybranch").Contains("✓"), + Contains("newbranch (worktree)").Contains("✓").IsSelected(), + ). + NavigateToLine(Contains("mybranch")) + + // check the current worktree that it has no lines in the File changes pane + t.Views().Files(). + Focus(). + Press(keys.Files.RefreshFiles). + LineCount(EqualsInt(0)) + }, +})