mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-11-13 08:13:32 -04:00
Make "go to bottom" stop at the bad, current and good commits of a bisect
During a bisect, the commits panel shows the commits known to be bad at the top, the known good ones at the bottom, and the ones that the bisect hasn't ruled out yet between them. Pressing '>' now stops at the bottommost bad commit, then at the commit to test, and then at the topmost good commit. It doesn't stop at each commit marked good. The commits between two of them are all good, and they don't form a section of their own. During a bisect, it also doesn't stop at the beginnings of the other sections, such as the beginning of a branch. The commits panel doesn't color the commits by whether they are merged while bisecting, so these would look like arbitrary commits. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
462a168d87
commit
280c67ff98
@@ -2,6 +2,7 @@ package context
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/generics/set"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/samber/lo"
|
||||
"github.com/stefanhaller/git-todo-parser/todo"
|
||||
@@ -18,9 +19,21 @@ import (
|
||||
// - each branch of a stack, given by branchesBelow. Among the todos of a
|
||||
// rebase, update-ref todos separate the branches.
|
||||
// - the commits that aren't merged into a main branch yet
|
||||
//
|
||||
// During a bisect, it stops at the bottommost commit marked bad, at the commit
|
||||
// to test, and at the topmost commit marked good instead. The commits list
|
||||
// doesn't color the commits by whether they are merged during a bisect, so the
|
||||
// beginnings of the sections would look like arbitrary commits.
|
||||
func indexForGotoBottomInCommits(
|
||||
commits []*models.Commit, selectedIdx int, branchesBelow []*models.Branch,
|
||||
commits []*models.Commit,
|
||||
selectedIdx int,
|
||||
branchesBelow []*models.Branch,
|
||||
bisectInfo *git_commands.BisectInfo,
|
||||
) int {
|
||||
if bisectInfo.Started() {
|
||||
return closestStopBelow(bisectStops(commits, bisectInfo), selectedIdx, len(commits)-1)
|
||||
}
|
||||
|
||||
stops := []int{}
|
||||
|
||||
if headIdx := models.HeadCommitIdx(commits); headIdx > 0 {
|
||||
@@ -51,6 +64,30 @@ func indexForGotoBottomInCommits(
|
||||
return closestStopBelow(stops, selectedIdx, len(commits)-1)
|
||||
}
|
||||
|
||||
func bisectStops(commits []*models.Commit, bisectInfo *git_commands.BisectInfo) []int {
|
||||
hasStatus := func(status git_commands.BisectStatus) func(*models.Commit) bool {
|
||||
return func(commit *models.Commit) bool {
|
||||
commitStatus, ok := bisectInfo.Status(commit.Hash())
|
||||
return ok && commitStatus == status
|
||||
}
|
||||
}
|
||||
isCommitToTest := func(commit *models.Commit) bool {
|
||||
return bisectInfo.HasCommitToTest() && commit.Hash() == bisectInfo.GetCurrentHash()
|
||||
}
|
||||
|
||||
stops := []int{}
|
||||
if _, idx, found := lo.FindLastIndexOf(commits, hasStatus(git_commands.BisectStatusNew)); found {
|
||||
stops = append(stops, idx)
|
||||
}
|
||||
if _, idx, found := lo.FindIndexOf(commits, isCommitToTest); found {
|
||||
stops = append(stops, idx)
|
||||
}
|
||||
if _, idx, found := lo.FindIndexOf(commits, hasStatus(git_commands.BisectStatusOld)); found {
|
||||
stops = append(stops, idx)
|
||||
}
|
||||
return stops
|
||||
}
|
||||
|
||||
// Returns the smallest of the given stops that is greater than the selected
|
||||
// index, or the last index if there is none
|
||||
func closestStopBelow(stops []int, selectedIdx int, lastIdx int) int {
|
||||
|
||||
@@ -3,6 +3,7 @@ package context
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
"github.com/stefanhaller/git-todo-parser/todo"
|
||||
@@ -185,7 +186,8 @@ func TestIndexForGotoBottomInCommits(t *testing.T) {
|
||||
|
||||
for _, s := range scenarios {
|
||||
t.Run(s.testName, func(t *testing.T) {
|
||||
assert.Equal(t, s.expected, indexForGotoBottomInCommits(s.commits, s.selectedIdx, s.branchesBelow))
|
||||
assert.Equal(t, s.expected, indexForGotoBottomInCommits(
|
||||
s.commits, s.selectedIdx, s.branchesBelow, git_commands.NewNullBisectInfo()))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -525,5 +525,5 @@ func (self *LocalCommitsContext) IndexForGotoBottom() int {
|
||||
commits := self.GetCommits()
|
||||
branchesBelow := branchstack.BranchesBelow(
|
||||
commits, c.Model().Branches, c.Model().CheckedOutBranch, c.UserConfig().Git.MainBranches)
|
||||
return indexForGotoBottomInCommits(commits, self.GetSelectedLineIdx(), branchesBelow)
|
||||
return indexForGotoBottomInCommits(commits, self.GetSelectedLineIdx(), branchesBelow, c.Model().BisectInfo)
|
||||
}
|
||||
|
||||
@@ -276,5 +276,6 @@ func (self *SubCommitsContext) IndexForGotoBottom() int {
|
||||
branchesBelow = branchstack.BranchesBelow(
|
||||
commits, self.c.Model().Branches, self.GetRef().RefName(), self.c.UserConfig().Git.MainBranches)
|
||||
}
|
||||
return indexForGotoBottomInCommits(commits, self.GetSelectedLineIdx(), branchesBelow)
|
||||
return indexForGotoBottomInCommits(
|
||||
commits, self.GetSelectedLineIdx(), branchesBelow, git_commands.NewNullBisectInfo())
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package bisect
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/lazygit/pkg/config"
|
||||
. "github.com/jesseduffield/lazygit/pkg/integration/components"
|
||||
)
|
||||
|
||||
var GotoBottom = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
Description: "Go to the bottom of the commits list in steps, stopping only at the bad commit, the current commit, and the first good commit",
|
||||
ExtraCmdArgs: []string{},
|
||||
Skip: false,
|
||||
SetupRepo: func(shell *Shell) {
|
||||
shell.
|
||||
CreateNCommits(3).
|
||||
NewBranch("mybranch").
|
||||
CreateNCommitsStartingAt(7, 4).
|
||||
StartBisect("HEAD~1", "HEAD~8")
|
||||
},
|
||||
SetupConfig: func(cfg *config.AppConfig) {
|
||||
cfg.GetUserConfig().Git.Log.ShowGraph = "never"
|
||||
},
|
||||
Run: func(t *TestDriver, keys config.KeybindingConfig) {
|
||||
t.Views().Commits().
|
||||
Focus().
|
||||
Lines(
|
||||
Contains("CI commit-10"),
|
||||
Contains("CI commit-09").Contains("<-- bad"),
|
||||
Contains("CI commit-08"),
|
||||
Contains("CI commit-07"),
|
||||
Contains("CI commit-06"),
|
||||
Contains("CI commit-05").Contains("<-- current").IsSelected(),
|
||||
Contains("CI commit-04"),
|
||||
Contains("CI commit-03"),
|
||||
Contains("CI commit-02").Contains("<-- good"),
|
||||
Contains("CI commit-01"),
|
||||
).
|
||||
Press(keys.Universal.GotoTop).
|
||||
Press(keys.Universal.GotoBottom).
|
||||
SelectedLine(Contains("CI commit-09")).
|
||||
Press(keys.Universal.GotoBottom).
|
||||
SelectedLine(Contains("CI commit-05")).
|
||||
Press(keys.Universal.GotoBottom).
|
||||
SelectedLine(Contains("CI commit-02")).
|
||||
Press(keys.Universal.GotoBottom).
|
||||
SelectedLine(Contains("CI commit-01"))
|
||||
},
|
||||
})
|
||||
@@ -39,6 +39,7 @@ var tests = []*components.IntegrationTest{
|
||||
bisect.CheckOutBranchBeforeBisecting,
|
||||
bisect.ChooseTerms,
|
||||
bisect.FromOtherBranch,
|
||||
bisect.GotoBottom,
|
||||
bisect.MarkCandidatesWhileTestingMergeBase,
|
||||
bisect.OfferResetWhenMergeBaseIsBad,
|
||||
bisect.SelectCurrentCommit,
|
||||
|
||||
Reference in New Issue
Block a user