Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions pkg/commands/git_commands/bisect.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,27 @@ func (self *BisectCommands) GetInfoForGitDir(gitDir string) *BisectInfo {
info.statusMap[hash] = status
}

currentContent, err := os.ReadFile(filepath.Join(gitDir, "BISECT_EXPECTED_REV"))
// Only set current when BISECT_EXPECTED_REV exists, which indicates that git has
// started the narrowing process (both good and bad commits have been marked).
// We use HEAD instead of BISECT_EXPECTED_REV because we want to show where HEAD
// actually is, not where git bisect expects you to be. This way, if the user manually
// checks out a different commit during bisect, the UI will correctly show that commit
// as "current" instead of the bisect-expected commit.
bisectExpectedRevPath := filepath.Join(gitDir, "BISECT_EXPECTED_REV")
exists, err = self.os.FileExists(bisectExpectedRevPath)
if err != nil {
self.Log.Infof("error getting git bisect info: %s", err.Error())
return info
}
currentHash := strings.TrimSpace(string(currentContent))
info.current = currentHash
if exists {
cmdArgs := NewGitCmd("rev-parse").Arg("HEAD").ToArgv()
output, err := self.cmd.New(cmdArgs).DontLog().RunWithOutput()
if err != nil {
self.Log.Infof("error getting git bisect info: %s", err.Error())
return info
}
info.current = strings.TrimSpace(output)
}

return info
}
Expand Down
78 changes: 78 additions & 0 deletions pkg/integration/tests/bisect/checkout.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package bisect

import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)

var Checkout = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Start a git bisect and checkout a different commit within the bisect range",
ExtraCmdArgs: []string{},
Skip: false,
SetupRepo: func(shell *Shell) {
shell.
CreateNCommits(10)
},
SetupConfig: func(cfg *config.AppConfig) {
cfg.GetUserConfig().Git.Log.ShowGraph = "never"
},
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"))
}).
// Verify we're at the bisect-selected commit (commit 05)
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"),
).
// Navigate to a different commit and checkout
NavigateToLine(Contains("commit 07")).
PressPrimaryAction()

// Confirm the checkout menu and select detached head checkout
t.ExpectPopup().Menu().
Title(Contains("Checkout branch or commit")).
Select(MatchesRegexp("Checkout commit .* as detached head")).
Confirm()

// After checkout, focus switches to branches panel - just verify it's focused
t.Views().Branches().
IsFocused()

// Switch back to commits panel and verify the current marker moved
t.Views().Commits().
Focus().
Lines(
Contains("CI commit 10").Contains("<-- bad"),
Contains("CI commit 09").DoesNotContain("<--"),
Contains("CI commit 08").DoesNotContain("<--"),
// The current marker should now be on commit 07 (where HEAD is),
// not on commit 05 (where bisect expected us to be)
Contains("CI commit 07").Contains("<-- current"),
Contains("CI commit 06").DoesNotContain("<--"),
Contains("CI commit 05").DoesNotContain("<--"),
Contains("CI commit 04").DoesNotContain("<--"),
Contains("CI commit 03").DoesNotContain("<--"),
Contains("CI commit 02").DoesNotContain("<--"),
Contains("CI commit 01").Contains("<-- good"),
)
},
})
1 change: 1 addition & 0 deletions pkg/integration/tests/test_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import (

var tests = []*components.IntegrationTest{
bisect.Basic,
bisect.Checkout,
bisect.ChooseTerms,
bisect.FromOtherBranch,
bisect.Skip,
Expand Down