From 368633f69cb0d220c16f76ae09b054584e520d41 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Sat, 31 Oct 2026 08:25:45 +0100 Subject: [PATCH] Show the result of a finished bisect instead of the bisect menu Once git has nothing left to test, the bisect menu offers marking or skipping the current commit, although the user has marked it already. If git found the first bad commit without checking out anything to test, the menu acts on the selected commit instead, as if git didn't know both a good and a bad commit yet. At this point, the user wants to see the result and reset the bisect. Show the "Bisect complete" dialog again instead of the menu. It names the first bad commit and asks whether to reset the bisect. This also lets the user see the result again after declining the reset when the bisect finished. If git stopped without finding the first bad commit, because the merge base of the good and the bad commit is bad, show the confirmation for resetting the bisect. Git said why it stopped when it did. Co-Authored-By: Claude Opus 5.5 --- pkg/gui/controllers/bisect_controller.go | 23 ++++++++++++++++++- .../offer_reset_when_merge_base_is_bad.go | 3 --- .../tests/bisect/show_result_again.go | 3 --- .../show_result_when_found_right_away.go | 3 --- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/pkg/gui/controllers/bisect_controller.go b/pkg/gui/controllers/bisect_controller.go index dd0d4dd94..36d43692f 100644 --- a/pkg/gui/controllers/bisect_controller.go +++ b/pkg/gui/controllers/bisect_controller.go @@ -81,12 +81,33 @@ func (self *BisectController) openMenu(ref models.Ref) error { if !info.Started() { return self.openStartBisectMenu(info, ref) } - if info.GetCurrentHash() == "" { + if !info.Bisecting() { return self.openMenuBeforeBisecting(info, ref) } + if !info.HasCommitToTest() { + return self.showBisectResult() + } return self.openMidBisectMenu(info, ref) } +// Git has nothing left for the user to test, so show the result, and offer to +// reset the bisect. +func (self *BisectController) showBisectResult() error { + done, candidateHashes, err := self.c.Git().Bisect.IsDone() + if err != nil { + return err + } + + if !done { + // Git stopped without finding the first bad commit, for example + // because the merge base of the good and the bad commit is bad. Git + // said why when it stopped, so all that's left to do is to reset. + return self.c.Helpers().Bisect.Reset() + } + + return self.showBisectCompleteMessage(candidateHashes) +} + // The menu for when a bisect has started, but git doesn't know both a good and // a bad commit yet. Its entries act on the selected item. func (self *BisectController) openMenuBeforeBisecting(info *git_commands.BisectInfo, ref models.Ref) error { diff --git a/pkg/integration/tests/bisect/offer_reset_when_merge_base_is_bad.go b/pkg/integration/tests/bisect/offer_reset_when_merge_base_is_bad.go index 2c8b9302a..a9758e6e2 100644 --- a/pkg/integration/tests/bisect/offer_reset_when_merge_base_is_bad.go +++ b/pkg/integration/tests/bisect/offer_reset_when_merge_base_is_bad.go @@ -35,10 +35,7 @@ var OfferResetWhenMergeBaseIsBad = NewIntegrationTest(NewIntegrationTestArgs{ ). Press(keys.Commits.ViewBisectOptions). Tap(func() { - /* EXPECTED: t.ExpectPopup().Confirmation().Title(Equals("Reset 'git bisect'")).Content(Equals("Are you sure you want to reset 'git bisect'?")).Cancel() - ACTUAL: */ - t.ExpectPopup().Menu().Title(Equals("Bisect")).TopLines(Contains("Mark current commit")).Cancel() }) }, }) diff --git a/pkg/integration/tests/bisect/show_result_again.go b/pkg/integration/tests/bisect/show_result_again.go index ac2406732..073cf1456 100644 --- a/pkg/integration/tests/bisect/show_result_again.go +++ b/pkg/integration/tests/bisect/show_result_again.go @@ -26,10 +26,7 @@ var ShowResultAgain = NewIntegrationTest(NewIntegrationTestArgs{ SelectedLine(Contains("CI commit-08").Contains("<-- bad")). Press(keys.Commits.ViewBisectOptions). Tap(func() { - /* EXPECTED: t.ExpectPopup().Alert().Title(Equals("Bisect complete")).Content(MatchesRegexp("(?s)commit-08.*Do you want to reset")).Cancel() - ACTUAL: */ - t.ExpectPopup().Menu().Title(Equals("Bisect")).TopLines(Contains("Mark current commit")).Cancel() }) t.Views().Branches(). diff --git a/pkg/integration/tests/bisect/show_result_when_found_right_away.go b/pkg/integration/tests/bisect/show_result_when_found_right_away.go index 98f4fd7a8..ea74ebe04 100644 --- a/pkg/integration/tests/bisect/show_result_when_found_right_away.go +++ b/pkg/integration/tests/bisect/show_result_when_found_right_away.go @@ -29,10 +29,7 @@ var ShowResultWhenFoundRightAway = NewIntegrationTest(NewIntegrationTestArgs{ ). Press(keys.Commits.ViewBisectOptions). Tap(func() { - /* EXPECTED: t.ExpectPopup().Alert().Title(Equals("Bisect complete")).Content(MatchesRegexp("(?s)commit-03.*Do you want to reset")).Cancel() - ACTUAL: */ - t.ExpectPopup().Menu().Title(Equals("Bisect")).TopLines(MatchesRegexp(`b Mark commit [0-9a-f]+ as bad`)).Cancel() }) t.Views().Branches().