diff --git a/pkg/gui/controllers/bisect_controller.go b/pkg/gui/controllers/bisect_controller.go index afa417bb1..7cb36ef26 100644 --- a/pkg/gui/controllers/bisect_controller.go +++ b/pkg/gui/controllers/bisect_controller.go @@ -8,6 +8,8 @@ import ( "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/gui/context" "github.com/jesseduffield/lazygit/pkg/gui/types" + "github.com/jesseduffield/lazygit/pkg/utils" + "github.com/samber/lo" ) type BisectController struct { @@ -65,12 +67,18 @@ func (self *BisectController) openMidBisectMenu(info *git_commands.BisectInfo, c // ref, because we'll be reloading our commits in that case. waitToReselect := selectCurrentAfter && !self.c.Git().Bisect.ReachableFromStart(info) + // If we have a current sha already, then we always want to use that one. If + // not, we're still picking the initial commits before we really start, so + // use the selected commit in that case. + shaToMark := lo.Ternary(info.GetCurrentSha() != "", info.GetCurrentSha(), commit.Sha) + shortShaToMark := utils.ShortSha(shaToMark) + menuItems := []*types.MenuItem{ { - Label: fmt.Sprintf(self.c.Tr.Bisect.Mark, commit.ShortSha(), info.NewTerm()), + Label: fmt.Sprintf(self.c.Tr.Bisect.Mark, shortShaToMark, info.NewTerm()), OnPress: func() error { self.c.LogAction(self.c.Tr.Actions.BisectMark) - if err := self.c.Git().Bisect.Mark(commit.Sha, info.NewTerm()); err != nil { + if err := self.c.Git().Bisect.Mark(shaToMark, info.NewTerm()); err != nil { return self.c.Error(err) } @@ -79,10 +87,10 @@ func (self *BisectController) openMidBisectMenu(info *git_commands.BisectInfo, c Key: 'b', }, { - Label: fmt.Sprintf(self.c.Tr.Bisect.Mark, commit.ShortSha(), info.OldTerm()), + Label: fmt.Sprintf(self.c.Tr.Bisect.Mark, shortShaToMark, info.OldTerm()), OnPress: func() error { self.c.LogAction(self.c.Tr.Actions.BisectMark) - if err := self.c.Git().Bisect.Mark(commit.Sha, info.OldTerm()); err != nil { + if err := self.c.Git().Bisect.Mark(shaToMark, info.OldTerm()); err != nil { return self.c.Error(err) } @@ -91,7 +99,21 @@ func (self *BisectController) openMidBisectMenu(info *git_commands.BisectInfo, c Key: 'g', }, { - Label: fmt.Sprintf(self.c.Tr.Bisect.Skip, commit.ShortSha()), + Label: fmt.Sprintf(self.c.Tr.Bisect.SkipCurrent, shortShaToMark), + OnPress: func() error { + self.c.LogAction(self.c.Tr.Actions.BisectSkip) + if err := self.c.Git().Bisect.Skip(shaToMark); err != nil { + return self.c.Error(err) + } + + return self.afterMark(selectCurrentAfter, waitToReselect) + }, + Key: 's', + }, + } + if info.GetCurrentSha() != "" && info.GetCurrentSha() != commit.Sha { + menuItems = append(menuItems, lo.ToPtr(types.MenuItem{ + Label: fmt.Sprintf(self.c.Tr.Bisect.SkipSelected, commit.ShortSha()), OnPress: func() error { self.c.LogAction(self.c.Tr.Actions.BisectSkip) if err := self.c.Git().Bisect.Skip(commit.Sha); err != nil { @@ -100,16 +122,16 @@ func (self *BisectController) openMidBisectMenu(info *git_commands.BisectInfo, c return self.afterMark(selectCurrentAfter, waitToReselect) }, - Key: 's', - }, - { - Label: self.c.Tr.Bisect.ResetOption, - OnPress: func() error { - return self.c.Helpers().Bisect.Reset() - }, - Key: 'r', - }, + Key: 'S', + })) } + menuItems = append(menuItems, lo.ToPtr(types.MenuItem{ + Label: self.c.Tr.Bisect.ResetOption, + OnPress: func() error { + return self.c.Helpers().Bisect.Reset() + }, + Key: 'r', + })) return self.c.Menu(types.CreateMenuOptions{ Title: self.c.Tr.Bisect.BisectMenuTitle, diff --git a/pkg/i18n/chinese.go b/pkg/i18n/chinese.go index f6171f68e..2a494c97e 100644 --- a/pkg/i18n/chinese.go +++ b/pkg/i18n/chinese.go @@ -544,7 +544,7 @@ func chineseTranslationSet() TranslationSet { Bisect: Bisect{ Mark: "将 %s 标记为 %s", MarkStart: "将 %s 标记为 %s (start bisect)", - Skip: "跳过 %s", + SkipCurrent: "跳过 %s", ResetTitle: "重置 'git bisect'", ResetPrompt: "您确定要重置 'git bisect' 吗?", ResetOption: "重置二分查找", diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index 2d0fb90e8..34f9e66e0 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -557,7 +557,8 @@ type Bisect struct { NewTermPrompt string BisectMenuTitle string Mark string - Skip string + SkipCurrent string + SkipSelected string CompleteTitle string CompletePrompt string CompletePromptIndeterminate string @@ -1347,9 +1348,10 @@ func EnglishTranslationSet() TranslationSet { BisectMark: "Bisect mark", }, Bisect: Bisect{ - Mark: "Mark %s as %s", + Mark: "Mark current commit (%s) as %s", MarkStart: "Mark %s as %s (start bisect)", - Skip: "Skip %s", + SkipCurrent: "Skip current commit (%s)", + SkipSelected: "Skip selected commit (%s)", ResetTitle: "Reset 'git bisect'", ResetPrompt: "Are you sure you want to reset 'git bisect'?", ResetOption: "Reset bisect", diff --git a/pkg/i18n/japanese.go b/pkg/i18n/japanese.go index 6f77aa26d..3cbc6e225 100644 --- a/pkg/i18n/japanese.go +++ b/pkg/i18n/japanese.go @@ -577,7 +577,7 @@ func japaneseTranslationSet() TranslationSet { Bisect: Bisect{ // Mark: "Mark %s as %s", // MarkStart: "Mark %s as %s (start bisect)", - Skip: "%s をスキップする", + SkipCurrent: "%s をスキップする", ResetTitle: "'git bisect' をリセット", ResetPrompt: "'git bisect' をリセットします。よろしいですか?", ResetOption: "Bisectをリセット", diff --git a/pkg/i18n/korean.go b/pkg/i18n/korean.go index 801a83474..f22e6cc47 100644 --- a/pkg/i18n/korean.go +++ b/pkg/i18n/korean.go @@ -576,7 +576,7 @@ func koreanTranslationSet() TranslationSet { Bisect: Bisect{ Mark: "Mark %s as %s", MarkStart: "Mark %s as %s (start bisect)", - Skip: "%s 를 스킵", + SkipCurrent: "%s 를 스킵", ResetTitle: "'git bisect' 를 리셋", ResetPrompt: "정말로 'git bisect' 를 리셋하시겠습니까?", ResetOption: "Bisect를 리셋", diff --git a/pkg/i18n/russian.go b/pkg/i18n/russian.go index fe4785667..ae21430e6 100644 --- a/pkg/i18n/russian.go +++ b/pkg/i18n/russian.go @@ -671,7 +671,7 @@ func RussianTranslationSet() TranslationSet { Bisect: Bisect{ Mark: "Отметить %s как %s", MarkStart: "Отметить %s как %s (начать бинарный поиск)", - Skip: "Пропустить %s", + SkipCurrent: "Пропустить %s", ResetTitle: "Сбросить 'git bisect'", ResetPrompt: "Вы уверены, что хотите сбросить 'git bisect'?", ResetOption: "Сбросить бинарный поиск", diff --git a/pkg/i18n/traditional_chinese.go b/pkg/i18n/traditional_chinese.go index ebdda62bf..3ccac945a 100644 --- a/pkg/i18n/traditional_chinese.go +++ b/pkg/i18n/traditional_chinese.go @@ -698,7 +698,7 @@ func traditionalChineseTranslationSet() TranslationSet { Bisect: Bisect{ Mark: "將 %s 標記為 %s", MarkStart: "將 %s 標記為 %s(開始二分查找)", - Skip: "跳過 %s", + SkipCurrent: "跳過 %s", ResetTitle: "重設 'git bisect'", ResetPrompt: "你確定要重設 'git bisect' 嗎?", ResetOption: "重設二分查找", diff --git a/pkg/integration/tests/bisect/skip.go b/pkg/integration/tests/bisect/skip.go new file mode 100644 index 000000000..998e82361 --- /dev/null +++ b/pkg/integration/tests/bisect/skip.go @@ -0,0 +1,88 @@ +package bisect + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var Skip = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Start a git bisect and skip a few commits (selected or current)", + ExtraCmdArgs: []string{}, + Skip: false, + SetupRepo: func(shell *Shell) { + shell. + CreateNCommits(10) + }, + SetupConfig: func(cfg *config.AppConfig) {}, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Commits(). + Focus(). + SelectedLine(Contains("commit 10")). + Press(keys.Commits.ViewBisectOptions). + Tap(func() { + t.ExpectPopup().Menu().Title(Equals("Bisect")).Select(MatchesRegexp(`Mark .* as bad`)).Confirm() + }). + NavigateToLine(Contains("commit 01")). + Press(keys.Commits.ViewBisectOptions). + Tap(func() { + t.ExpectPopup().Menu().Title(Equals("Bisect")).Select(MatchesRegexp(`Mark .* as good`)).Confirm() + t.Views().Information().Content(Contains("Bisecting")) + }). + Lines( + Contains("CI commit 10").Contains("<-- bad"), + Contains("CI commit 09").DoesNotContain("<--"), + Contains("CI commit 08").DoesNotContain("<--"), + Contains("CI commit 07").DoesNotContain("<--"), + Contains("CI commit 06").DoesNotContain("<--"), + Contains("CI commit 05").Contains("<-- current").IsSelected(), + Contains("CI commit 04").DoesNotContain("<--"), + Contains("CI commit 03").DoesNotContain("<--"), + Contains("CI commit 02").DoesNotContain("<--"), + Contains("CI commit 01").Contains("<-- good"), + ). + Press(keys.Commits.ViewBisectOptions). + Tap(func() { + t.ExpectPopup().Menu().Title(Equals("Bisect")). + // Does not show a "Skip selected commit" entry: + Lines( + Contains("b Mark current commit").Contains("as bad"), + Contains("g Mark current commit").Contains("as good"), + Contains("s Skip current commit"), + Contains("r Reset bisect"), + Contains("Cancel"), + ). + Select(Contains("Skip current commit")).Confirm() + }). + // Skipping the current commit selects the new current commit: + Lines( + Contains("CI commit 10").Contains("<-- bad"), + Contains("CI commit 09").DoesNotContain("<--"), + Contains("CI commit 08").DoesNotContain("<--"), + Contains("CI commit 07").DoesNotContain("<--"), + Contains("CI commit 06").Contains("<-- current").IsSelected(), + Contains("CI commit 05").Contains("<-- skipped"), + Contains("CI commit 04").DoesNotContain("<--"), + Contains("CI commit 03").DoesNotContain("<--"), + Contains("CI commit 02").DoesNotContain("<--"), + Contains("CI commit 01").Contains("<-- good"), + ). + NavigateToLine(Contains("commit 07")). + Press(keys.Commits.ViewBisectOptions). + Tap(func() { + t.ExpectPopup().Menu().Title(Equals("Bisect")). + // Does show a "Skip selected commit" entry: + Lines( + Contains("b Mark current commit").Contains("as bad"), + Contains("g Mark current commit").Contains("as good"), + Contains("s Skip current commit"), + Contains("S Skip selected commit"), + Contains("r Reset bisect"), + Contains("Cancel"), + ). + Select(Contains("Skip selected commit")).Confirm() + }). + // Skipping a selected, non-current commit keeps the selection + // there: + SelectedLine(Contains("CI commit 07").Contains("<-- skipped")) + }, +}) diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go index 17f01995c..88d1883ac 100644 --- a/pkg/integration/tests/test_list.go +++ b/pkg/integration/tests/test_list.go @@ -32,6 +32,7 @@ var tests = []*components.IntegrationTest{ bisect.Basic, bisect.ChooseTerms, bisect.FromOtherBranch, + bisect.Skip, branch.CheckoutByName, branch.CreateTag, branch.Delete,