summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pkg/gui/controllers/branches_controller.go2
-rw-r--r--pkg/gui/controllers/helpers/suggestions_helper.go27
-rw-r--r--pkg/integration/components/shell.go4
-rw-r--r--pkg/integration/tests/branch/checkout_by_name_remote.go66
-rw-r--r--pkg/integration/tests/test_list.go1
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,