From 6e74cc026866f7f0ea54e6cd33d8ff86f3ffed7d Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Fri, 22 May 2026 18:33:20 +0200 Subject: [PATCH] Show base branches as bare names in labels MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ShortBranchName previously turned "refs/remotes/origin/main" into "origin/main", leaking the resolved-ref shape into UI labels that the user thinks of as plain "main" — the name they put in their mainBranches config. With the ambiguous-base label now potentially listing several branches ("pick: origin/main, origin/13"), the noise is even more pronounced. Strip the remote name along with the "refs/remotes/" prefix so the short name matches what the user configured. Rename the helper to BaseBranchDisplayName to make the constraint explicit at every call site: dropping the remote is a sensible choice only for base-branch display, not for refs in general. All current callers happen to be base-branch related, so the rename is just a scope-tightening. Existing integration test updated to expect the bare "master" form. --- pkg/gui/controllers/branches_controller.go | 6 ++--- .../controllers/helpers/base_branch_helper.go | 2 +- .../controllers/helpers/branches_helper.go | 26 +++++++++++++++++-- .../helpers/merge_and_rebase_helper.go | 4 +-- pkg/gui/controllers/helpers/refs_helper.go | 6 ++--- ..._commits_to_new_branch_from_base_branch.go | 4 +-- 6 files changed, 35 insertions(+), 13 deletions(-) diff --git a/pkg/gui/controllers/branches_controller.go b/pkg/gui/controllers/branches_controller.go index 193e7acb0..01bd15fc7 100644 --- a/pkg/gui/controllers/branches_controller.go +++ b/pkg/gui/controllers/branches_controller.go @@ -295,14 +295,14 @@ func (self *BranchesController) viewUpstreamOptions(selectedBranch *models.Branc if err != nil { return err } - baseBranchLabel := helpers.ShortBranchName(baseBranch) + baseBranchLabel := helpers.BaseBranchDisplayName(baseBranch) switch { case baseBranch == "": baseBranchLabel = self.c.Tr.CouldNotDetermineBaseBranch disabledReason = &types.DisabledReason{Text: self.c.Tr.CouldNotDetermineBaseBranch} case baseAmbiguous: shortNames := lo.Map(baseCandidates, func(ref string, _ int) string { - return helpers.ShortBranchName(ref) + return helpers.BaseBranchDisplayName(ref) }) baseBranchLabel = utils.ResolvePlaceholderString(self.c.Tr.PickBaseBranchLabel, map[string]string{"candidates": strings.Join(shortNames, ", ")}, @@ -323,7 +323,7 @@ func (self *BranchesController) viewUpstreamOptions(selectedBranch *models.Branc showDivergence := func(base string) error { return self.c.Helpers().SubCommits.ViewSubCommits(helpers.ViewSubCommitsOpts{ Ref: branch, - TitleRef: fmt.Sprintf("%s <-> %s", branch.RefName(), helpers.ShortBranchName(base)), + TitleRef: fmt.Sprintf("%s <-> %s", branch.RefName(), helpers.BaseBranchDisplayName(base)), RefToShowDivergenceFrom: base, Context: self.context(), ShowBranchHeads: false, diff --git a/pkg/gui/controllers/helpers/base_branch_helper.go b/pkg/gui/controllers/helpers/base_branch_helper.go index 2386898a3..8db870e96 100644 --- a/pkg/gui/controllers/helpers/base_branch_helper.go +++ b/pkg/gui/controllers/helpers/base_branch_helper.go @@ -50,7 +50,7 @@ func (self *BaseBranchHelper) ShowPicker( ) error { items := lo.Map(candidates, func(ref string, _ int) *types.MenuItem { return &types.MenuItem{ - Label: ShortBranchName(ref), + Label: BaseBranchDisplayName(ref), OnPress: func() error { return onPicked(ref) }, } }) diff --git a/pkg/gui/controllers/helpers/branches_helper.go b/pkg/gui/controllers/helpers/branches_helper.go index 4283bd29a..6c77e0384 100644 --- a/pkg/gui/controllers/helpers/branches_helper.go +++ b/pkg/gui/controllers/helpers/branches_helper.go @@ -161,8 +161,30 @@ func (self *BranchesHelper) ConfirmLocalAndRemoteDelete(branches []*models.Branc return nil } -func ShortBranchName(fullBranchName string) string { - return strings.TrimPrefix(strings.TrimPrefix(fullBranchName, "refs/heads/"), "refs/remotes/") +// BaseBranchDisplayName returns the user-facing name of a configured main +// branch from its resolved full ref: +// +// refs/heads/main → main +// refs/remotes/origin/main → main +// refs/remotes/origin/feat/x → feat/x +// +// For remote-tracking refs the remote name is dropped along with the prefix: +// the user configured plain "main" in mainBranches and shouldn't have to see +// whether lazygit ultimately resolved it to a local or remote ref. The remote +// is only meaningful internally, so this function is intended specifically for +// base-branch display — don't use it where the local/remote distinction +// matters. +func BaseBranchDisplayName(fullBranchName string) string { + if name, ok := strings.CutPrefix(fullBranchName, "refs/heads/"); ok { + return name + } + if name, ok := strings.CutPrefix(fullBranchName, "refs/remotes/"); ok { + if _, withoutRemote, found := strings.Cut(name, "/"); found { + return withoutRemote + } + return name + } + return fullBranchName } func (self *BranchesHelper) checkedOutByOtherWorktree(branch *models.Branch) bool { diff --git a/pkg/gui/controllers/helpers/merge_and_rebase_helper.go b/pkg/gui/controllers/helpers/merge_and_rebase_helper.go index b20ed2555..34d378163 100644 --- a/pkg/gui/controllers/helpers/merge_and_rebase_helper.go +++ b/pkg/gui/controllers/helpers/merge_and_rebase_helper.go @@ -351,14 +351,14 @@ func (self *MergeAndRebaseHelper) RebaseOntoRef(ref string) error { if err != nil { return err } - baseBranchLabel := ShortBranchName(baseBranch) + baseBranchLabel := BaseBranchDisplayName(baseBranch) switch { case baseBranch == "": baseBranchLabel = self.c.Tr.CouldNotDetermineBaseBranch baseBranchDisabledReason = &types.DisabledReason{Text: self.c.Tr.CouldNotDetermineBaseBranch} case baseAmbiguous: shortNames := lo.Map(baseCandidates, func(ref string, _ int) string { - return ShortBranchName(ref) + return BaseBranchDisplayName(ref) }) baseBranchLabel = utils.ResolvePlaceholderString(self.c.Tr.PickBaseBranchLabel, map[string]string{"candidates": strings.Join(shortNames, ", ")}, diff --git a/pkg/gui/controllers/helpers/refs_helper.go b/pkg/gui/controllers/helpers/refs_helper.go index 8d0d59370..dde4d109f 100644 --- a/pkg/gui/controllers/helpers/refs_helper.go +++ b/pkg/gui/controllers/helpers/refs_helper.go @@ -480,10 +480,10 @@ func (self *RefsHelper) MoveCommitsToNewBranch() error { return nil } - baseBranchLabel := ShortBranchName(baseBranchRef) + baseBranchLabel := BaseBranchDisplayName(baseBranchRef) if baseAmbiguous { shortNames := lo.Map(baseCandidates, func(ref string, _ int) string { - return ShortBranchName(ref) + return BaseBranchDisplayName(ref) }) baseBranchLabel = utils.ResolvePlaceholderString(self.c.Tr.PickBaseBranchLabel, map[string]string{"candidates": strings.Join(shortNames, ", ")}, @@ -503,7 +503,7 @@ func (self *RefsHelper) MoveCommitsToNewBranch() error { Label: fmt.Sprintf(self.c.Tr.MoveCommitsToNewBranchFromBaseItem, baseBranchLabel), OnPress: func() error { moveOff := func(base string) error { - return withNewBranchNamePrompt(ShortBranchName(base), func(newBranchName string) error { + return withNewBranchNamePrompt(BaseBranchDisplayName(base), func(newBranchName string) error { return self.moveCommitsToNewBranchOffOfMainBranch(newBranchName, base) }) } diff --git a/pkg/integration/tests/branch/move_commits_to_new_branch_from_base_branch.go b/pkg/integration/tests/branch/move_commits_to_new_branch_from_base_branch.go index 0b6bd71aa..8c53fa9cc 100644 --- a/pkg/integration/tests/branch/move_commits_to_new_branch_from_base_branch.go +++ b/pkg/integration/tests/branch/move_commits_to_new_branch_from_base_branch.go @@ -37,11 +37,11 @@ var MoveCommitsToNewBranchFromBaseBranch = NewIntegrationTest(NewIntegrationTest t.ExpectPopup().Menu(). Title(Equals("Move commits to new branch")). - Select(Contains("New branch from base branch (origin/master)")). + Select(Contains("New branch from base branch (master)")). Confirm() t.ExpectPopup().Prompt(). - Title(Equals("New branch name (branch is off of 'origin/master')")). + Title(Equals("New branch name (branch is off of 'master')")). Type("new branch"). Confirm()