diff options
-rw-r--r-- | pkg/gui/controllers/branches_controller.go | 2 | ||||
-rw-r--r-- | pkg/gui/controllers/helpers/suggestions_helper.go | 27 | ||||
-rw-r--r-- | pkg/integration/components/shell.go | 4 | ||||
-rw-r--r-- | pkg/integration/tests/branch/checkout_by_name_remote.go | 66 | ||||
-rw-r--r-- | pkg/integration/tests/test_list.go | 1 |
5 files changed, 97 insertions, 3 deletions
diff --git a/pkg/gui/controllers/branches_controller.go b/pkg/gui/controllers/branches_controller.go index 068238ec7..91918923d 100644 --- a/pkg/gui/controllers/branches_controller.go +++ b/pkg/gui/controllers/branches_controller.go @@ -433,7 +433,7 @@ func (self *BranchesController) forceCheckout() error { func (self *BranchesController) checkoutByName() error { return self.c.Prompt(types.PromptOpts{ Title: self.c.Tr.BranchName + ":", - FindSuggestionsFunc: self.c.Helpers().Suggestions.GetRefsSuggestionsFunc(), + FindSuggestionsFunc: self.c.Helpers().Suggestions.GetCheckoutBranchesSuggestionsFunc(), HandleConfirm: func(response string) error { self.c.LogAction("Checkout branch") return self.c.Helpers().Refs.CheckoutRef(response, types.CheckoutRefOptions{ diff --git a/pkg/gui/controllers/helpers/suggestions_helper.go b/pkg/gui/controllers/helpers/suggestions_helper.go index 2ae9d2158..5c10dcd5c 100644 --- a/pkg/gui/controllers/helpers/suggestions_helper.go +++ b/pkg/gui/controllers/helpers/suggestions_helper.go @@ -3,6 +3,7 @@ package helpers import ( "fmt" "os" + "strings" "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/commands/models" @@ -25,6 +26,8 @@ import ( // finding suggestions in this file, so that it's easy to see if a function already // exists for fetching a particular model. +var specialRefNames = []string{"HEAD", "FETCH_HEAD", "MERGE_HEAD", "ORIG_HEAD"} + type ISuggestionsHelper interface { GetRemoteSuggestionsFunc() func(string) []*types.Suggestion GetBranchNameSuggestionsFunc() func(string) []*types.Suggestion @@ -168,9 +171,29 @@ func (self *SuggestionsHelper) GetRefsSuggestionsFunc() func(string) []*types.Su remoteBranchNames := self.getRemoteBranchNames("/") localBranchNames := self.getBranchNames() tagNames := self.getTagNames() - additionalRefNames := []string{"HEAD", "FETCH_HEAD", "MERGE_HEAD", "ORIG_HEAD"} - refNames := append(append(append(remoteBranchNames, localBranchNames...), tagNames...), additionalRefNames...) + refNames := append(append(append(remoteBranchNames, localBranchNames...), tagNames...), specialRefNames...) + + return FuzzySearchFunc(refNames) +} + +func (self *SuggestionsHelper) GetCheckoutBranchesSuggestionsFunc() func(string) []*types.Suggestion { + remoteBranchNames := self.getRemoteBranchNames("/") + // We include remote branches with the remote stripped off in the list of suggestions + // so that you can check out the branch as a local branch tracking the remote branch, just + // like you can do in the git CLI. I.e. if you checkout 'origin/blah' it will be + // checked out as as a detached head, but if you checkout 'blah' it will be checked out + // as a local branch tracking 'origin/blah'. + localisedRemoteBranchNames := lo.Map(remoteBranchNames, func(branchName string, _ int) string { + // strip the remote name from the branch name + return branchName[strings.Index(branchName, "/")+1:] + }) + localBranchNames := self.getBranchNames() + tagNames := self.getTagNames() + + refNames := append(append(append(append(remoteBranchNames, localBranchNames...), tagNames...), specialRefNames...), localisedRemoteBranchNames...) + + refNames = lo.Uniq(refNames) return FuzzySearchFunc(refNames) } diff --git a/pkg/integration/components/shell.go b/pkg/integration/components/shell.go index 60c627918..60652b2ad 100644 --- a/pkg/integration/components/shell.go +++ b/pkg/integration/components/shell.go @@ -148,6 +148,10 @@ func (self *Shell) Checkout(name string) *Shell { return self.RunCommand([]string{"git", "checkout", name}) } +func (self *Shell) DeleteBranch(name string) *Shell { + return self.RunCommand([]string{"git", "branch", "-D", name}) +} + func (self *Shell) Merge(name string) *Shell { return self.RunCommand([]string{"git", "merge", "--commit", "--no-ff", name}) } diff --git a/pkg/integration/tests/branch/checkout_by_name_remote.go b/pkg/integration/tests/branch/checkout_by_name_remote.go new file mode 100644 index 000000000..cd9d01db6 --- /dev/null +++ b/pkg/integration/tests/branch/checkout_by_name_remote.go @@ -0,0 +1,66 @@ +package branch + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var CheckoutByNameRemote = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Checkout a remote branch by name, both using the full name and the local name.", + ExtraCmdArgs: []string{}, + Skip: false, + SetupConfig: func(config *config.AppConfig) {}, + SetupRepo: func(shell *Shell) { + shell.EmptyCommit("initial commit") + // create an origin/foo remote branch + shell.CloneIntoRemote("origin") + shell.NewBranch("foo") + shell.PushBranch("origin", "foo") + // delete the local version of the branch because we need to test checking it out from scratch + shell.Checkout("master") + shell.DeleteBranch("foo") + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Branches(). + Focus(). + Lines( + Contains("master").IsSelected(), + ). + // maximising window so that we can see the tracked branch + Press(keys.Universal.NextScreenMode). + Press(keys.Branches.CheckoutBranchByName). + Tap(func() { + t.ExpectPopup().Prompt(). + Title(Equals("Branch name:")). + Type("foo"). + SuggestionLines( + Contains("foo"), + Contains("origin/foo"), + ). + ConfirmFirstSuggestion() + }). + Lines( + Contains("foo"). + // we have not checked out origin/foo... + DoesNotContain("origin/foo"). + // ... but we are tracking it (formatted as '<remote> <branch>') + Contains("origin foo"), + Contains("master"), + ). + Press(keys.Branches.CheckoutBranchByName). + Tap(func() { + t.ExpectPopup().Prompt(). + Title(Equals("Branch name:")). + Type("origin/foo"). + SuggestionLines( + Contains("origin/foo"), + ). + ConfirmFirstSuggestion() + }). + Lines( + Contains("HEAD detached at origin/foo"), + Contains("foo"), + Contains("master"), + ) + }, +}) diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go index 531fce5d9..4fc6fe710 100644 --- a/pkg/integration/tests/test_list.go +++ b/pkg/integration/tests/test_list.go @@ -37,6 +37,7 @@ var tests = []*components.IntegrationTest{ bisect.FromOtherBranch, bisect.Skip, branch.CheckoutByName, + branch.CheckoutByNameRemote, branch.CreateTag, branch.Delete, branch.DeleteRemoteBranchWithCredentialPrompt, |