mirror of
https://github.com/jesseduffield/lazygit.git
synced 2024-12-12 11:15:00 +02:00
Support fastforwarding worktree
This commit is contained in:
parent
a313b16704
commit
b3060065d9
@ -1,6 +1,8 @@
|
|||||||
package git_commands
|
package git_commands
|
||||||
|
|
||||||
import "strings"
|
import (
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
// convenience struct for building git commands. Especially useful when
|
// convenience struct for building git commands. Especially useful when
|
||||||
// including conditional args
|
// including conditional args
|
||||||
@ -66,6 +68,14 @@ func (self *GitCommandBuilder) GitDir(path string) *GitCommandBuilder {
|
|||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *GitCommandBuilder) GitDirIf(condition bool, path string) *GitCommandBuilder {
|
||||||
|
if condition {
|
||||||
|
return self.GitDir(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
|
||||||
func (self *GitCommandBuilder) ToArgv() []string {
|
func (self *GitCommandBuilder) ToArgv() []string {
|
||||||
return append([]string{"git"}, self.args...)
|
return append([]string{"git"}, self.args...)
|
||||||
}
|
}
|
||||||
|
@ -82,6 +82,7 @@ type PullOptions struct {
|
|||||||
RemoteName string
|
RemoteName string
|
||||||
BranchName string
|
BranchName string
|
||||||
FastForwardOnly bool
|
FastForwardOnly bool
|
||||||
|
WorktreeGitDir string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *SyncCommands) Pull(task gocui.Task, opts PullOptions) error {
|
func (self *SyncCommands) Pull(task gocui.Task, opts PullOptions) error {
|
||||||
@ -90,6 +91,7 @@ func (self *SyncCommands) Pull(task gocui.Task, opts PullOptions) error {
|
|||||||
ArgIf(opts.FastForwardOnly, "--ff-only").
|
ArgIf(opts.FastForwardOnly, "--ff-only").
|
||||||
ArgIf(opts.RemoteName != "", opts.RemoteName).
|
ArgIf(opts.RemoteName != "", opts.RemoteName).
|
||||||
ArgIf(opts.BranchName != "", opts.BranchName).
|
ArgIf(opts.BranchName != "", opts.BranchName).
|
||||||
|
GitDirIf(opts.WorktreeGitDir != "", opts.WorktreeGitDir).
|
||||||
ToArgv()
|
ToArgv()
|
||||||
|
|
||||||
// setting GIT_SEQUENCE_EDITOR to ':' as a way of skipping it, in case the user
|
// setting GIT_SEQUENCE_EDITOR to ':' as a way of skipping it, in case the user
|
||||||
@ -97,7 +99,12 @@ func (self *SyncCommands) Pull(task gocui.Task, opts PullOptions) error {
|
|||||||
return self.cmd.New(cmdArgs).AddEnvVars("GIT_SEQUENCE_EDITOR=:").PromptOnCredentialRequest(task).WithMutex(self.syncMutex).Run()
|
return self.cmd.New(cmdArgs).AddEnvVars("GIT_SEQUENCE_EDITOR=:").PromptOnCredentialRequest(task).WithMutex(self.syncMutex).Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *SyncCommands) FastForward(task gocui.Task, branchName string, remoteName string, remoteBranchName string) error {
|
func (self *SyncCommands) FastForward(
|
||||||
|
task gocui.Task,
|
||||||
|
branchName string,
|
||||||
|
remoteName string,
|
||||||
|
remoteBranchName string,
|
||||||
|
) error {
|
||||||
cmdArgs := NewGitCmd("fetch").
|
cmdArgs := NewGitCmd("fetch").
|
||||||
Arg(remoteName).
|
Arg(remoteName).
|
||||||
Arg(remoteBranchName + ":" + branchName).
|
Arg(remoteBranchName + ":" + branchName).
|
||||||
|
@ -3,6 +3,7 @@ package controllers
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/jesseduffield/gocui"
|
"github.com/jesseduffield/gocui"
|
||||||
@ -426,15 +427,23 @@ func (self *BranchesController) fastForward(branch *models.Branch) error {
|
|||||||
)
|
)
|
||||||
|
|
||||||
return self.c.WithLoaderPanel(message, func(task gocui.Task) error {
|
return self.c.WithLoaderPanel(message, func(task gocui.Task) error {
|
||||||
if branch == self.c.Helpers().Refs.GetCheckedOutRef() {
|
worktree, ok := self.worktreeForBranch(branch)
|
||||||
|
if ok {
|
||||||
self.c.LogAction(action)
|
self.c.LogAction(action)
|
||||||
|
|
||||||
|
worktreeGitDir := ""
|
||||||
|
// if it is the current worktree path, no need to specify the path
|
||||||
|
if !git_commands.IsCurrentWorktree(worktree.Path) {
|
||||||
|
worktreeGitDir = worktree.GitDir
|
||||||
|
}
|
||||||
|
|
||||||
err := self.c.Git().Sync.Pull(
|
err := self.c.Git().Sync.Pull(
|
||||||
task,
|
task,
|
||||||
git_commands.PullOptions{
|
git_commands.PullOptions{
|
||||||
RemoteName: branch.UpstreamRemote,
|
RemoteName: branch.UpstreamRemote,
|
||||||
BranchName: branch.UpstreamBranch,
|
BranchName: branch.UpstreamBranch,
|
||||||
FastForwardOnly: true,
|
FastForwardOnly: true,
|
||||||
|
WorktreeGitDir: worktreeGitDir,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -444,7 +453,10 @@ func (self *BranchesController) fastForward(branch *models.Branch) error {
|
|||||||
return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC})
|
return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC})
|
||||||
} else {
|
} else {
|
||||||
self.c.LogAction(action)
|
self.c.LogAction(action)
|
||||||
err := self.c.Git().Sync.FastForward(task, branch.Name, branch.UpstreamRemote, branch.UpstreamBranch)
|
|
||||||
|
err := self.c.Git().Sync.FastForward(
|
||||||
|
task, branch.Name, branch.UpstreamRemote, branch.UpstreamBranch,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = self.c.Error(err)
|
_ = self.c.Error(err)
|
||||||
}
|
}
|
||||||
@ -455,6 +467,20 @@ func (self *BranchesController) fastForward(branch *models.Branch) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *BranchesController) worktreePathForBranch(branch *models.Branch) string {
|
||||||
|
worktreeForRef, ok := self.worktreeForBranch(branch)
|
||||||
|
if ok {
|
||||||
|
return worktreeForRef.Path
|
||||||
|
}
|
||||||
|
|
||||||
|
dir, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
// swallow for now
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return dir
|
||||||
|
}
|
||||||
|
|
||||||
func (self *BranchesController) createTag(branch *models.Branch) error {
|
func (self *BranchesController) createTag(branch *models.Branch) error {
|
||||||
return self.c.Helpers().Tags.OpenCreateTagPrompt(branch.FullRefName(), func() {})
|
return self.c.Helpers().Tags.OpenCreateTagPrompt(branch.FullRefName(), func() {})
|
||||||
}
|
}
|
||||||
|
@ -261,6 +261,13 @@ func (self *Shell) AddWorktree(base string, path string, newBranchName string) *
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add worktree and have it checkout the base branch
|
||||||
|
func (self *Shell) AddWorktreeCheckout(base string, path string) *Shell {
|
||||||
|
return self.RunCommand([]string{
|
||||||
|
"git", "worktree", "add", path, base,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (self *Shell) AddFileInWorktree(worktreePath string) *Shell {
|
func (self *Shell) AddFileInWorktree(worktreePath string) *Shell {
|
||||||
self.CreateFile(filepath.Join(worktreePath, "content"), "content")
|
self.CreateFile(filepath.Join(worktreePath, "content"), "content")
|
||||||
|
|
||||||
|
@ -227,6 +227,7 @@ var tests = []*components.IntegrationTest{
|
|||||||
worktree.Crud,
|
worktree.Crud,
|
||||||
worktree.CustomCommand,
|
worktree.CustomCommand,
|
||||||
worktree.DetachWorktreeFromBranch,
|
worktree.DetachWorktreeFromBranch,
|
||||||
|
worktree.FastForwardWorktreeBranch,
|
||||||
worktree.ForceRemoveWorktree,
|
worktree.ForceRemoveWorktree,
|
||||||
worktree.Rebase,
|
worktree.Rebase,
|
||||||
worktree.RemoveWorktreeFromBranch,
|
worktree.RemoveWorktreeFromBranch,
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
package worktree
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/config"
|
||||||
|
. "github.com/jesseduffield/lazygit/pkg/integration/components"
|
||||||
|
)
|
||||||
|
|
||||||
|
var FastForwardWorktreeBranch = 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-foward
|
||||||
|
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(),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
})
|
Loading…
Reference in New Issue
Block a user