mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-05-12 12:55:47 +02:00
When checking out a remote branch by name, ask the user how
The choices are to create a new local branch that tracks the remote, or a detached head.
This commit is contained in:
parent
0360b82aab
commit
e42cbf95ae
4 changed files with 94 additions and 0 deletions
|
@ -28,6 +28,17 @@ func (self *BranchCommands) New(name string, base string) error {
|
||||||
return self.cmd.New(cmdArgs).Run()
|
return self.cmd.New(cmdArgs).Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateWithUpstream creates a new branch with a given upstream, but without
|
||||||
|
// checking it out
|
||||||
|
func (self *BranchCommands) CreateWithUpstream(name string, upstream string) error {
|
||||||
|
cmdArgs := NewGitCmd("branch").
|
||||||
|
Arg("--track").
|
||||||
|
Arg(name, upstream).
|
||||||
|
ToArgv()
|
||||||
|
|
||||||
|
return self.cmd.New(cmdArgs).Run()
|
||||||
|
}
|
||||||
|
|
||||||
// CurrentBranchInfo get the current branch information.
|
// CurrentBranchInfo get the current branch information.
|
||||||
func (self *BranchCommands) CurrentBranchInfo() (BranchInfo, error) {
|
func (self *BranchCommands) CurrentBranchInfo() (BranchInfo, error) {
|
||||||
branchName, err := self.cmd.New(
|
branchName, err := self.cmd.New(
|
||||||
|
|
|
@ -436,6 +436,10 @@ func (self *BranchesController) checkoutByName() error {
|
||||||
FindSuggestionsFunc: self.c.Helpers().Suggestions.GetRefsSuggestionsFunc(),
|
FindSuggestionsFunc: self.c.Helpers().Suggestions.GetRefsSuggestionsFunc(),
|
||||||
HandleConfirm: func(response string) error {
|
HandleConfirm: func(response string) error {
|
||||||
self.c.LogAction("Checkout branch")
|
self.c.LogAction("Checkout branch")
|
||||||
|
_, branchName, found := self.c.Helpers().Refs.ParseRemoteBranchName(response)
|
||||||
|
if found {
|
||||||
|
return self.c.Helpers().Refs.CheckoutRemoteBranch(response, branchName)
|
||||||
|
}
|
||||||
return self.c.Helpers().Refs.CheckoutRef(response, types.CheckoutRefOptions{
|
return self.c.Helpers().Refs.CheckoutRef(response, types.CheckoutRefOptions{
|
||||||
OnRefNotFound: func(ref string) error {
|
OnRefNotFound: func(ref string) error {
|
||||||
return self.c.Confirm(types.ConfirmOpts{
|
return self.c.Confirm(types.ConfirmOpts{
|
||||||
|
|
|
@ -96,6 +96,57 @@ func (self *RefsHelper) CheckoutRef(ref string, options types.CheckoutRefOptions
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Shows a prompt to choose between creating a new branch or checking out a detached head
|
||||||
|
func (self *RefsHelper) CheckoutRemoteBranch(fullBranchName string, localBranchName string) error {
|
||||||
|
checkout := func(branchName string) error {
|
||||||
|
if err := self.CheckoutRef(branchName, types.CheckoutRefOptions{}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if self.c.CurrentContext() != self.c.Contexts().Branches {
|
||||||
|
return self.c.PushContext(self.c.Contexts().Branches)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a branch with this name already exists locally, just check it out. We
|
||||||
|
// don't bother checking whether it actually tracks this remote branch, since
|
||||||
|
// it's very unlikely that it doesn't.
|
||||||
|
if lo.ContainsBy(self.c.Model().Branches, func(branch *models.Branch) bool {
|
||||||
|
return branch.Name == localBranchName
|
||||||
|
}) {
|
||||||
|
return checkout(localBranchName)
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.c.Menu(types.CreateMenuOptions{
|
||||||
|
Title: utils.ResolvePlaceholderString(self.c.Tr.RemoteBranchCheckoutTitle, map[string]string{
|
||||||
|
"branchName": fullBranchName,
|
||||||
|
}),
|
||||||
|
Items: []*types.MenuItem{
|
||||||
|
{
|
||||||
|
Label: self.c.Tr.CheckoutTypeNewBranch,
|
||||||
|
Tooltip: self.c.Tr.CheckoutTypeNewBranchTooltip,
|
||||||
|
OnPress: func() error {
|
||||||
|
// First create the local branch with the upstream set, and
|
||||||
|
// then check it out. We could do that in one step using
|
||||||
|
// "git checkout -b", but we want to benefit from all the
|
||||||
|
// nice features of the CheckoutRef function.
|
||||||
|
if err := self.c.Git().Branch.CreateWithUpstream(localBranchName, fullBranchName); err != nil {
|
||||||
|
return self.c.Error(err)
|
||||||
|
}
|
||||||
|
return checkout(localBranchName)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Label: self.c.Tr.CheckoutTypeDetachedHead,
|
||||||
|
Tooltip: self.c.Tr.CheckoutTypeDetachedHeadTooltip,
|
||||||
|
OnPress: func() error {
|
||||||
|
return checkout(fullBranchName)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (self *RefsHelper) GetCheckedOutRef() *models.Branch {
|
func (self *RefsHelper) GetCheckedOutRef() *models.Branch {
|
||||||
if len(self.c.Model().Branches) == 0 {
|
if len(self.c.Model().Branches) == 0 {
|
||||||
return nil
|
return nil
|
||||||
|
@ -232,3 +283,21 @@ func (self *RefsHelper) NewBranch(from string, fromFormattedName string, suggest
|
||||||
func SanitizedBranchName(input string) string {
|
func SanitizedBranchName(input string) string {
|
||||||
return strings.Replace(input, " ", "-", -1)
|
return strings.Replace(input, " ", "-", -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checks if the given branch name is a remote branch, and returns the name of
|
||||||
|
// the remote and the bare branch name if it is.
|
||||||
|
func (self *RefsHelper) ParseRemoteBranchName(fullBranchName string) (string, string, bool) {
|
||||||
|
remoteName, branchName, found := strings.Cut(fullBranchName, "/")
|
||||||
|
if !found {
|
||||||
|
return "", "", false
|
||||||
|
}
|
||||||
|
|
||||||
|
// See if the part before the first slash is actually one of our remotes
|
||||||
|
if !lo.ContainsBy(self.c.Model().Remotes, func(remote *models.Remote) bool {
|
||||||
|
return remote.Name == remoteName
|
||||||
|
}) {
|
||||||
|
return "", "", false
|
||||||
|
}
|
||||||
|
|
||||||
|
return remoteName, branchName, true
|
||||||
|
}
|
||||||
|
|
|
@ -113,6 +113,11 @@ type TranslationSet struct {
|
||||||
ForceCheckoutTooltip string
|
ForceCheckoutTooltip string
|
||||||
CheckoutByName string
|
CheckoutByName string
|
||||||
CheckoutByNameTooltip string
|
CheckoutByNameTooltip string
|
||||||
|
RemoteBranchCheckoutTitle string
|
||||||
|
CheckoutTypeNewBranch string
|
||||||
|
CheckoutTypeNewBranchTooltip string
|
||||||
|
CheckoutTypeDetachedHead string
|
||||||
|
CheckoutTypeDetachedHeadTooltip string
|
||||||
NewBranch string
|
NewBranch string
|
||||||
NewBranchFromStashTooltip string
|
NewBranchFromStashTooltip string
|
||||||
NoBranchesThisRepo string
|
NoBranchesThisRepo string
|
||||||
|
@ -1065,6 +1070,11 @@ func EnglishTranslationSet() TranslationSet {
|
||||||
ForceCheckoutTooltip: "Force checkout selected branch. This will discard all local changes in your working directory before checking out the selected branch.",
|
ForceCheckoutTooltip: "Force checkout selected branch. This will discard all local changes in your working directory before checking out the selected branch.",
|
||||||
CheckoutByName: "Checkout by name",
|
CheckoutByName: "Checkout by name",
|
||||||
CheckoutByNameTooltip: "Checkout by name. In the input box you can enter '-' to switch to the last branch.",
|
CheckoutByNameTooltip: "Checkout by name. In the input box you can enter '-' to switch to the last branch.",
|
||||||
|
RemoteBranchCheckoutTitle: "Checkout {{.branchName}}",
|
||||||
|
CheckoutTypeNewBranch: "New local branch",
|
||||||
|
CheckoutTypeNewBranchTooltip: "Checkout the remote branch as a local branch, tracking the remote branch.",
|
||||||
|
CheckoutTypeDetachedHead: "Detached head",
|
||||||
|
CheckoutTypeDetachedHeadTooltip: "Checkout the remote branch as a detached head, which can be useful if you just want to test the branch but not work on it yourself. You can still create a local branch from it later.",
|
||||||
NewBranch: "New branch",
|
NewBranch: "New branch",
|
||||||
NewBranchFromStashTooltip: "Create a new branch from the selected stash entry. This works by git checking out the commit that the stash entry was created from, creating a new branch from that commit, then applying the stash entry to the new branch as an additional commit.",
|
NewBranchFromStashTooltip: "Create a new branch from the selected stash entry. This works by git checking out the commit that the stash entry was created from, creating a new branch from that commit, then applying the stash entry to the new branch as an additional commit.",
|
||||||
NoBranchesThisRepo: "No branches for this repo",
|
NoBranchesThisRepo: "No branches for this repo",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue