From 1b7ded6df36afc2a52a60863ec7ab23b79326a24 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Fri, 3 May 2024 19:30:28 +0200 Subject: [PATCH 1/5] Fix typo --- pkg/i18n/english.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index a0f205508da..b2393883350 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -1443,7 +1443,7 @@ func EnglishTranslationSet() TranslationSet { ViewUpstreamResetOptions: "Reset checked-out branch onto {{.upstream}}", ViewUpstreamResetOptionsTooltip: "View options for resetting the checked-out branch onto {{upstream}}. Note: this will not reset the selected branch onto the upstream, it will reset the checked-out branch onto the upstream.", ViewUpstreamRebaseOptions: "Rebase checked-out branch onto {{.upstream}}", - ViewUpstreamRebaseOptionsTooltip: "View options for rebasing the checked-out branch onto {{upstream}}. Note: this will not rebase the selected branch onto the upstream, it will rebased the checked-out branch onto the upstream.", + ViewUpstreamRebaseOptionsTooltip: "View options for rebasing the checked-out branch onto {{upstream}}. Note: this will not rebase the selected branch onto the upstream, it will rebase the checked-out branch onto the upstream.", UpstreamGenericName: "upstream of selected branch", SetUpstreamTitle: "Set upstream branch", SetUpstreamMessage: "Are you sure you want to set the upstream branch of '{{.checkedOut}}' to '{{.selected}}'", From ca6d88080cef1ab768fc088081d1962e110234e8 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Sat, 4 May 2024 16:15:08 +0200 Subject: [PATCH 2/5] Make "Rebase" show up with "..." in the keybindings menu --- pkg/gui/controllers/branches_controller.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/gui/controllers/branches_controller.go b/pkg/gui/controllers/branches_controller.go index b46802320fc..c975d500d50 100644 --- a/pkg/gui/controllers/branches_controller.go +++ b/pkg/gui/controllers/branches_controller.go @@ -107,6 +107,7 @@ func (self *BranchesController) GetKeybindings(opts types.KeybindingsOpts) []*ty ), Description: self.c.Tr.RebaseBranch, Tooltip: self.c.Tr.RebaseBranchTooltip, + OpensMenu: true, DisplayOnScreen: true, }, { From ddf5e24499fb8ca91ca67f8efa887b74bebb5a70 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Fri, 3 May 2024 19:30:31 +0200 Subject: [PATCH 3/5] Always show rebase menu, even when rebasing is not possible Instead, disable the individual entries in the menu. This is necessary because we are going to add another entry to the menu that is independent of the selected branch. --- pkg/gui/controllers/branches_controller.go | 31 ++++++------------- .../helpers/merge_and_rebase_helper.go | 16 +++++++--- 2 files changed, 20 insertions(+), 27 deletions(-) diff --git a/pkg/gui/controllers/branches_controller.go b/pkg/gui/controllers/branches_controller.go index c975d500d50..62eda703ef3 100644 --- a/pkg/gui/controllers/branches_controller.go +++ b/pkg/gui/controllers/branches_controller.go @@ -100,15 +100,13 @@ func (self *BranchesController) GetKeybindings(opts types.KeybindingsOpts) []*ty DisplayOnScreen: true, }, { - Key: opts.GetKey(opts.Config.Branches.RebaseBranch), - Handler: opts.Guards.OutsideFilterMode(self.rebase), - GetDisabledReason: self.require( - self.singleItemSelected(self.notRebasingOntoSelf), - ), - Description: self.c.Tr.RebaseBranch, - Tooltip: self.c.Tr.RebaseBranchTooltip, - OpensMenu: true, - DisplayOnScreen: true, + Key: opts.GetKey(opts.Config.Branches.RebaseBranch), + Handler: opts.Guards.OutsideFilterMode(self.withItem(self.rebase)), + GetDisabledReason: self.require(self.singleItemSelected()), + Description: self.c.Tr.RebaseBranch, + Tooltip: self.c.Tr.RebaseBranchTooltip, + OpensMenu: true, + DisplayOnScreen: true, }, { Key: opts.GetKey(opts.Config.Branches.MergeIntoCurrentBranch), @@ -634,19 +632,8 @@ func (self *BranchesController) merge() error { return self.c.Helpers().MergeAndRebase.MergeRefIntoCheckedOutBranch(selectedBranchName) } -func (self *BranchesController) rebase() error { - selectedBranchName := self.context().GetSelected().Name - return self.c.Helpers().MergeAndRebase.RebaseOntoRef(selectedBranchName) -} - -func (self *BranchesController) notRebasingOntoSelf(branch *models.Branch) *types.DisabledReason { - selectedBranchName := branch.Name - checkedOutBranch := self.c.Helpers().Refs.GetCheckedOutRef().Name - if selectedBranchName == checkedOutBranch { - return &types.DisabledReason{Text: self.c.Tr.CantRebaseOntoSelf} - } - - return nil +func (self *BranchesController) rebase(branch *models.Branch) error { + return self.c.Helpers().MergeAndRebase.RebaseOntoRef(branch.Name) } func (self *BranchesController) fastForward(branch *models.Branch) error { diff --git a/pkg/gui/controllers/helpers/merge_and_rebase_helper.go b/pkg/gui/controllers/helpers/merge_and_rebase_helper.go index 4bffcfa99ee..35903ea64d4 100644 --- a/pkg/gui/controllers/helpers/merge_and_rebase_helper.go +++ b/pkg/gui/controllers/helpers/merge_and_rebase_helper.go @@ -235,10 +235,15 @@ func (self *MergeAndRebaseHelper) PromptToContinueRebase() error { func (self *MergeAndRebaseHelper) RebaseOntoRef(ref string) error { checkedOutBranch := self.refsHelper.GetCheckedOutRef().Name + var disabledReason *types.DisabledReason + if checkedOutBranch == ref { + disabledReason = &types.DisabledReason{Text: self.c.Tr.CantRebaseOntoSelf} + } menuItems := []*types.MenuItem{ { - Label: self.c.Tr.SimpleRebase, - Key: 's', + Label: self.c.Tr.SimpleRebase, + Key: 's', + DisabledReason: disabledReason, OnPress: func() error { self.c.LogAction(self.c.Tr.Actions.RebaseBranch) return self.c.WithWaitingStatus(self.c.Tr.RebasingStatus, func(task gocui.Task) error { @@ -258,9 +263,10 @@ func (self *MergeAndRebaseHelper) RebaseOntoRef(ref string) error { }, }, { - Label: self.c.Tr.InteractiveRebase, - Key: 'i', - Tooltip: self.c.Tr.InteractiveRebaseTooltip, + Label: self.c.Tr.InteractiveRebase, + Key: 'i', + DisabledReason: disabledReason, + Tooltip: self.c.Tr.InteractiveRebaseTooltip, OnPress: func() error { self.c.LogAction(self.c.Tr.Actions.RebaseBranch) baseCommit := self.c.Modes().MarkedBaseCommit.GetHash() From 837f7456ab39027ea77a437c72344e785693f0cd Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Sat, 4 May 2024 16:12:40 +0200 Subject: [PATCH 4/5] Remove target branch from title of rebase menu Put it into the individual menu items instead. Again, this is necessary because we are going to add another entry to the menu that is independent of the selected branch. --- pkg/gui/controllers/helpers/merge_and_rebase_helper.go | 9 ++++++--- pkg/i18n/english.go | 8 ++++---- pkg/i18n/polish.go | 8 ++++---- pkg/i18n/russian.go | 6 +++--- pkg/i18n/traditional_chinese.go | 6 +++--- pkg/integration/tests/branch/rebase.go | 2 +- pkg/integration/tests/branch/rebase_abort_on_conflict.go | 2 +- pkg/integration/tests/branch/rebase_and_drop.go | 2 +- .../tests/branch/rebase_cancel_on_conflict.go | 2 +- pkg/integration/tests/branch/rebase_copied_branch.go | 2 +- .../tests/branch/rebase_does_not_autosquash.go | 2 +- pkg/integration/tests/branch/rebase_from_marked_base.go | 2 +- pkg/integration/tests/branch/rebase_to_upstream.go | 2 +- .../interactive_rebase/advanced_interactive_rebase.go | 2 +- 14 files changed, 29 insertions(+), 26 deletions(-) diff --git a/pkg/gui/controllers/helpers/merge_and_rebase_helper.go b/pkg/gui/controllers/helpers/merge_and_rebase_helper.go index 35903ea64d4..2ec315d62d4 100644 --- a/pkg/gui/controllers/helpers/merge_and_rebase_helper.go +++ b/pkg/gui/controllers/helpers/merge_and_rebase_helper.go @@ -241,7 +241,9 @@ func (self *MergeAndRebaseHelper) RebaseOntoRef(ref string) error { } menuItems := []*types.MenuItem{ { - Label: self.c.Tr.SimpleRebase, + Label: utils.ResolvePlaceholderString(self.c.Tr.SimpleRebase, + map[string]string{"ref": ref}, + ), Key: 's', DisabledReason: disabledReason, OnPress: func() error { @@ -263,7 +265,9 @@ func (self *MergeAndRebaseHelper) RebaseOntoRef(ref string) error { }, }, { - Label: self.c.Tr.InteractiveRebase, + Label: utils.ResolvePlaceholderString(self.c.Tr.InteractiveRebase, + map[string]string{"ref": ref}, + ), Key: 'i', DisabledReason: disabledReason, Tooltip: self.c.Tr.InteractiveRebaseTooltip, @@ -293,7 +297,6 @@ func (self *MergeAndRebaseHelper) RebaseOntoRef(ref string) error { self.c.Tr.RebasingTitle), map[string]string{ "checkedOutBranch": checkedOutBranch, - "ref": ref, }, ) diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index b2393883350..9ca5e5af983 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -1253,10 +1253,10 @@ func EnglishTranslationSet() TranslationSet { KeybindingsMenuSectionLocal: "Local", KeybindingsMenuSectionGlobal: "Global", KeybindingsMenuSectionNavigation: "Navigation", - RebasingTitle: "Rebase '{{.checkedOutBranch}}' onto '{{.ref}}'", - RebasingFromBaseCommitTitle: "Rebase '{{.checkedOutBranch}}' from marked base onto '{{.ref}}'", - SimpleRebase: "Simple rebase", - InteractiveRebase: "Interactive rebase", + RebasingTitle: "Rebase '{{.checkedOutBranch}}'", + RebasingFromBaseCommitTitle: "Rebase '{{.checkedOutBranch}}' from marked base", + SimpleRebase: "Simple rebase onto '{{.ref}}'", + InteractiveRebase: "Interactive rebase onto '{{.ref}}'", InteractiveRebaseTooltip: "Begin an interactive rebase with a break at the start, so you can update the TODO commits before continuing.", MustSelectTodoCommits: "When rebasing, this action only works on a selection of TODO commits.", ConfirmMerge: "Are you sure you want to merge '{{.selectedBranch}}' into '{{.checkedOutBranch}}'?", diff --git a/pkg/i18n/polish.go b/pkg/i18n/polish.go index ae99829aa17..5ca7d7ca69c 100644 --- a/pkg/i18n/polish.go +++ b/pkg/i18n/polish.go @@ -274,10 +274,10 @@ func polishTranslationSet() TranslationSet { KeybindingsMenuSectionLocal: "Lokalne", KeybindingsMenuSectionGlobal: "Globalne", KeybindingsMenuSectionNavigation: "Nawigacja", - RebasingTitle: "Rebase '{{.checkedOutBranch}}' na '{{.ref}}'", - RebasingFromBaseCommitTitle: "Rebase '{{.checkedOutBranch}}' od oznaczonego commita bazowego na '{{.ref}}'", - SimpleRebase: "Prosty rebase", - InteractiveRebase: "Interaktywny rebase", + RebasingTitle: "Rebase '{{.checkedOutBranch}}'", + RebasingFromBaseCommitTitle: "Rebase '{{.checkedOutBranch}}' od oznaczonego commita bazowego", + SimpleRebase: "Prosty rebase na '{{.ref}}'", + InteractiveRebase: "Interaktywny rebase na '{{.ref}}'", InteractiveRebaseTooltip: "Rozpocznij interaktywny rebase z przerwaniem na początku, abyś mógł zaktualizować commity TODO przed kontynuacją.", MustSelectTodoCommits: "Podczas rebase ta akcja działa tylko na zaznaczonych commitach TODO.", ConfirmMerge: "Czy na pewno chcesz scalić '{{.selectedBranch}}' z '{{.checkedOutBranch}}'?", diff --git a/pkg/i18n/russian.go b/pkg/i18n/russian.go index ebcfaacfe5c..d7b7a61d4ef 100644 --- a/pkg/i18n/russian.go +++ b/pkg/i18n/russian.go @@ -226,9 +226,9 @@ func RussianTranslationSet() TranslationSet { ConflictsResolved: "Все конфликты слияния разрешены. Продолжить?", Continue: "Продолжить", Keybindings: "Связки клавиш", - RebasingTitle: "Перебазировать '{{.checkedOutBranch}}' на '{{.ref}}'", - SimpleRebase: "Простая перебазировка", - InteractiveRebase: "Интерактивная перебазировка", + RebasingTitle: "Перебазировать '{{.checkedOutBranch}}'", + SimpleRebase: "Простая перебазировка на '{{.ref}}'", + InteractiveRebase: "Интерактивная перебазировка на '{{.ref}}'", InteractiveRebaseTooltip: "Начать интерактивную перебазировку с перерыва в начале, чтобы можно было обновить TODO коммиты, прежде чем продолжить.", ConfirmMerge: "Вы уверены, что хотите to merge '{{.selectedBranch}}' into '{{.checkedOutBranch}}'?", FwdNoUpstream: "Невозможно перемотать ветку без upstream-ветки", diff --git a/pkg/i18n/traditional_chinese.go b/pkg/i18n/traditional_chinese.go index 2da3d52c04e..1e80344e4a3 100644 --- a/pkg/i18n/traditional_chinese.go +++ b/pkg/i18n/traditional_chinese.go @@ -256,9 +256,9 @@ func traditionalChineseTranslationSet() TranslationSet { ConflictsResolved: "所有合併衝突都已解決。是否繼續?", Continue: "確認", Keybindings: "鍵盤快捷鍵", - RebasingTitle: "將 '{{.checkedOutBranch}}' 變基至 '{{.ref}}'", - SimpleRebase: "簡單變基", - InteractiveRebase: "互動變基", + RebasingTitle: "將 '{{.checkedOutBranch}}'", + SimpleRebase: "簡單變基 變基至 '{{.ref}}'", + InteractiveRebase: "互動變基 變基至 '{{.ref}}'", InteractiveRebaseTooltip: "開始一個互動變基,以中斷開始,這樣你可以在繼續之前更新TODO提交", ConfirmMerge: "是否將 '{{.selectedBranch}}' 合併至 '{{.checkedOutBranch}}' ?", FwdNoUpstream: "無法快進無上游分支", diff --git a/pkg/integration/tests/branch/rebase.go b/pkg/integration/tests/branch/rebase.go index 66a23510782..c7dc028afa4 100644 --- a/pkg/integration/tests/branch/rebase.go +++ b/pkg/integration/tests/branch/rebase.go @@ -31,7 +31,7 @@ var Rebase = NewIntegrationTest(NewIntegrationTestArgs{ Press(keys.Branches.RebaseBranch) t.ExpectPopup().Menu(). - Title(Equals("Rebase 'first-change-branch' onto 'second-change-branch'")). + Title(Equals("Rebase 'first-change-branch'")). Select(Contains("Simple rebase")). Confirm() diff --git a/pkg/integration/tests/branch/rebase_abort_on_conflict.go b/pkg/integration/tests/branch/rebase_abort_on_conflict.go index 4eba7762716..47f59d3d1bc 100644 --- a/pkg/integration/tests/branch/rebase_abort_on_conflict.go +++ b/pkg/integration/tests/branch/rebase_abort_on_conflict.go @@ -31,7 +31,7 @@ var RebaseAbortOnConflict = NewIntegrationTest(NewIntegrationTestArgs{ Press(keys.Branches.RebaseBranch) t.ExpectPopup().Menu(). - Title(Equals("Rebase 'first-change-branch' onto 'second-change-branch'")). + Title(Equals("Rebase 'first-change-branch'")). Select(Contains("Simple rebase")). Confirm() diff --git a/pkg/integration/tests/branch/rebase_and_drop.go b/pkg/integration/tests/branch/rebase_and_drop.go index 4c6712f2369..60ef19e6ad1 100644 --- a/pkg/integration/tests/branch/rebase_and_drop.go +++ b/pkg/integration/tests/branch/rebase_and_drop.go @@ -37,7 +37,7 @@ var RebaseAndDrop = NewIntegrationTest(NewIntegrationTestArgs{ Press(keys.Branches.RebaseBranch) t.ExpectPopup().Menu(). - Title(Equals("Rebase 'first-change-branch' onto 'second-change-branch'")). + Title(Equals("Rebase 'first-change-branch'")). Select(Contains("Simple rebase")). Confirm() diff --git a/pkg/integration/tests/branch/rebase_cancel_on_conflict.go b/pkg/integration/tests/branch/rebase_cancel_on_conflict.go index 23b7661b239..03923c81daf 100644 --- a/pkg/integration/tests/branch/rebase_cancel_on_conflict.go +++ b/pkg/integration/tests/branch/rebase_cancel_on_conflict.go @@ -31,7 +31,7 @@ var RebaseCancelOnConflict = NewIntegrationTest(NewIntegrationTestArgs{ Press(keys.Branches.RebaseBranch) t.ExpectPopup().Menu(). - Title(Equals("Rebase 'first-change-branch' onto 'second-change-branch'")). + Title(Equals("Rebase 'first-change-branch'")). Select(Contains("Simple rebase")). Confirm() diff --git a/pkg/integration/tests/branch/rebase_copied_branch.go b/pkg/integration/tests/branch/rebase_copied_branch.go index faa31093e2f..bc9fcb4a6bb 100644 --- a/pkg/integration/tests/branch/rebase_copied_branch.go +++ b/pkg/integration/tests/branch/rebase_copied_branch.go @@ -42,7 +42,7 @@ var RebaseCopiedBranch = NewIntegrationTest(NewIntegrationTestArgs{ Press(keys.Branches.RebaseBranch). Tap(func() { t.ExpectPopup().Menu(). - Title(Equals("Rebase 'branch2' onto 'master'")). + Title(Equals("Rebase 'branch2'")). Select(Contains("Simple rebase")). Confirm() }) diff --git a/pkg/integration/tests/branch/rebase_does_not_autosquash.go b/pkg/integration/tests/branch/rebase_does_not_autosquash.go index 66ad870c403..523682410de 100644 --- a/pkg/integration/tests/branch/rebase_does_not_autosquash.go +++ b/pkg/integration/tests/branch/rebase_does_not_autosquash.go @@ -40,7 +40,7 @@ var RebaseDoesNotAutosquash = NewIntegrationTest(NewIntegrationTestArgs{ Press(keys.Branches.RebaseBranch) t.ExpectPopup().Menu(). - Title(Equals("Rebase 'my-branch' onto 'master'")). + Title(Equals("Rebase 'my-branch'")). Select(Contains("Simple rebase")). Confirm() diff --git a/pkg/integration/tests/branch/rebase_from_marked_base.go b/pkg/integration/tests/branch/rebase_from_marked_base.go index c2ee307e3e7..c26dce9a396 100644 --- a/pkg/integration/tests/branch/rebase_from_marked_base.go +++ b/pkg/integration/tests/branch/rebase_from_marked_base.go @@ -61,7 +61,7 @@ var RebaseFromMarkedBase = NewIntegrationTest(NewIntegrationTestArgs{ Press(keys.Branches.RebaseBranch) t.ExpectPopup().Menu(). - Title(Equals("Rebase 'active-branch' from marked base onto 'target-branch'")). + Title(Equals("Rebase 'active-branch' from marked base")). Select(Contains("Simple rebase")). Confirm() diff --git a/pkg/integration/tests/branch/rebase_to_upstream.go b/pkg/integration/tests/branch/rebase_to_upstream.go index 2469eb012d4..f8b2d6fd138 100644 --- a/pkg/integration/tests/branch/rebase_to_upstream.go +++ b/pkg/integration/tests/branch/rebase_to_upstream.go @@ -67,7 +67,7 @@ var RebaseToUpstream = NewIntegrationTest(NewIntegrationTestArgs{ Select(Contains("Rebase checked-out branch onto origin/master...")). Confirm() t.ExpectPopup().Menu(). - Title(Equals("Rebase 'target' onto 'origin/master'")). + Title(Equals("Rebase 'target'")). Select(Contains("Simple rebase")). Confirm() }) diff --git a/pkg/integration/tests/interactive_rebase/advanced_interactive_rebase.go b/pkg/integration/tests/interactive_rebase/advanced_interactive_rebase.go index 43ac8eb7f3d..771b2e164ee 100644 --- a/pkg/integration/tests/interactive_rebase/advanced_interactive_rebase.go +++ b/pkg/integration/tests/interactive_rebase/advanced_interactive_rebase.go @@ -39,7 +39,7 @@ var AdvancedInteractiveRebase = NewIntegrationTest(NewIntegrationTestArgs{ Press(keys.Branches.RebaseBranch) t.ExpectPopup().Menu(). - Title(Equals(fmt.Sprintf("Rebase '%s' onto '%s'", TOP_BRANCH, BASE_BRANCH))). + Title(Equals(fmt.Sprintf("Rebase '%s'", TOP_BRANCH))). Select(Contains("Interactive rebase")). Confirm() t.Views().Commits(). From a8921a13cb0acddf8fdac02c62a84cf478b9e2eb Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Sat, 4 May 2024 16:39:06 +0200 Subject: [PATCH 5/5] Add command "Rebase onto base branch" to rebase menu --- .../helpers/merge_and_rebase_helper.go | 44 +++++++++++++-- pkg/i18n/english.go | 4 ++ .../tests/branch/rebase_onto_base_branch.go | 53 +++++++++++++++++++ pkg/integration/tests/test_list.go | 1 + 4 files changed, 98 insertions(+), 4 deletions(-) create mode 100644 pkg/integration/tests/branch/rebase_onto_base_branch.go diff --git a/pkg/gui/controllers/helpers/merge_and_rebase_helper.go b/pkg/gui/controllers/helpers/merge_and_rebase_helper.go index 2ec315d62d4..c2aa1418ae3 100644 --- a/pkg/gui/controllers/helpers/merge_and_rebase_helper.go +++ b/pkg/gui/controllers/helpers/merge_and_rebase_helper.go @@ -234,11 +234,22 @@ func (self *MergeAndRebaseHelper) PromptToContinueRebase() error { } func (self *MergeAndRebaseHelper) RebaseOntoRef(ref string) error { - checkedOutBranch := self.refsHelper.GetCheckedOutRef().Name - var disabledReason *types.DisabledReason - if checkedOutBranch == ref { + checkedOutBranch := self.refsHelper.GetCheckedOutRef() + checkedOutBranchName := self.refsHelper.GetCheckedOutRef().Name + var disabledReason, baseBranchDisabledReason *types.DisabledReason + if checkedOutBranchName == ref { disabledReason = &types.DisabledReason{Text: self.c.Tr.CantRebaseOntoSelf} } + + baseBranch, err := self.c.Git().Loaders.BranchLoader.GetBaseBranch(checkedOutBranch, self.refsHelper.c.Model().MainBranches) + if err != nil { + return err + } + if baseBranch == "" { + baseBranch = self.c.Tr.CouldNotDetermineBaseBranch + baseBranchDisabledReason = &types.DisabledReason{Text: self.c.Tr.CouldNotDetermineBaseBranch} + } + menuItems := []*types.MenuItem{ { Label: utils.ResolvePlaceholderString(self.c.Tr.SimpleRebase, @@ -289,6 +300,31 @@ func (self *MergeAndRebaseHelper) RebaseOntoRef(ref string) error { return self.c.PushContext(self.c.Contexts().LocalCommits) }, }, + { + Label: utils.ResolvePlaceholderString(self.c.Tr.RebaseOntoBaseBranch, + map[string]string{"baseBranch": ShortBranchName(baseBranch)}, + ), + Key: 'b', + DisabledReason: baseBranchDisabledReason, + Tooltip: self.c.Tr.RebaseOntoBaseBranchTooltip, + OnPress: func() error { + self.c.LogAction(self.c.Tr.Actions.RebaseBranch) + return self.c.WithWaitingStatus(self.c.Tr.RebasingStatus, func(task gocui.Task) error { + baseCommit := self.c.Modes().MarkedBaseCommit.GetHash() + var err error + if baseCommit != "" { + err = self.c.Git().Rebase.RebaseBranchFromBaseCommit(baseBranch, baseCommit) + } else { + err = self.c.Git().Rebase.RebaseBranch(baseBranch) + } + err = self.CheckMergeOrRebase(err) + if err == nil { + return self.ResetMarkedBaseCommit() + } + return err + }) + }, + }, } title := utils.ResolvePlaceholderString( @@ -296,7 +332,7 @@ func (self *MergeAndRebaseHelper) RebaseOntoRef(ref string) error { self.c.Tr.RebasingFromBaseCommitTitle, self.c.Tr.RebasingTitle), map[string]string{ - "checkedOutBranch": checkedOutBranch, + "checkedOutBranch": checkedOutBranchName, }, ) diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index 9ca5e5af983..d32aafbf2bc 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -289,7 +289,9 @@ type TranslationSet struct { RebasingFromBaseCommitTitle string SimpleRebase string InteractiveRebase string + RebaseOntoBaseBranch string InteractiveRebaseTooltip string + RebaseOntoBaseBranchTooltip string MustSelectTodoCommits string ConfirmMerge string FwdNoUpstream string @@ -1257,7 +1259,9 @@ func EnglishTranslationSet() TranslationSet { RebasingFromBaseCommitTitle: "Rebase '{{.checkedOutBranch}}' from marked base", SimpleRebase: "Simple rebase onto '{{.ref}}'", InteractiveRebase: "Interactive rebase onto '{{.ref}}'", + RebaseOntoBaseBranch: "Rebase onto base branch ({{.baseBranch}})", InteractiveRebaseTooltip: "Begin an interactive rebase with a break at the start, so you can update the TODO commits before continuing.", + RebaseOntoBaseBranchTooltip: "Rebase the checked out branch onto its base branch (i.e. the closest main branch).", MustSelectTodoCommits: "When rebasing, this action only works on a selection of TODO commits.", ConfirmMerge: "Are you sure you want to merge '{{.selectedBranch}}' into '{{.checkedOutBranch}}'?", FwdNoUpstream: "Cannot fast-forward a branch with no upstream", diff --git a/pkg/integration/tests/branch/rebase_onto_base_branch.go b/pkg/integration/tests/branch/rebase_onto_base_branch.go new file mode 100644 index 00000000000..3944f4fe699 --- /dev/null +++ b/pkg/integration/tests/branch/rebase_onto_base_branch.go @@ -0,0 +1,53 @@ +package branch + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var RebaseOntoBaseBranch = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Rebase the current branch onto its base branch", + ExtraCmdArgs: []string{}, + Skip: false, + SetupConfig: func(config *config.AppConfig) { + config.UserConfig.Gui.ShowDivergenceFromBaseBranch = "arrowAndNumber" + }, + SetupRepo: func(shell *Shell) { + shell. + EmptyCommit("master 1"). + EmptyCommit("master 2"). + EmptyCommit("master 3"). + NewBranchFrom("feature", "master^"). + EmptyCommit("feature 1"). + EmptyCommit("feature 2") + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Commits().Lines( + Contains("feature 2"), + Contains("feature 1"), + Contains("master 2"), + Contains("master 1"), + ) + + t.Views().Branches(). + Focus(). + Lines( + Contains("feature ↓1").IsSelected(), + Contains("master"), + ). + Press(keys.Branches.RebaseBranch) + + t.ExpectPopup().Menu(). + Title(Equals("Rebase 'feature'")). + Select(Contains("Rebase onto base branch (master)")). + Confirm() + + t.Views().Commits().Lines( + Contains("feature 2"), + Contains("feature 1"), + Contains("master 3"), + Contains("master 2"), + Contains("master 1"), + ) + }, +}) diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go index 92aaedd235d..c1e153a2b41 100644 --- a/pkg/integration/tests/test_list.go +++ b/pkg/integration/tests/test_list.go @@ -51,6 +51,7 @@ var tests = []*components.IntegrationTest{ branch.RebaseCopiedBranch, branch.RebaseDoesNotAutosquash, branch.RebaseFromMarkedBase, + branch.RebaseOntoBaseBranch, branch.RebaseToUpstream, branch.Rename, branch.Reset,