Make "go to bottom" in the commits panel stop at the first todo

During a rebase, cherry-pick or revert, the todos are a section of their
own at the top of the commits panel. Pressing '>' now goes to the first
of them, the bottommost one, before it goes on to the beginning of the
branch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Stefan Haller
2026-11-08 12:42:48 +01:00
co-authored by Claude Opus 5.5
parent 7426d7f934
commit 33f52279c4
2 changed files with 39 additions and 0 deletions
@@ -12,10 +12,15 @@ import (
// last section to the bottom of the list.
//
// The sections are:
// - the todos of a rebase, cherry-pick or revert
// - the commits of the branch that aren't merged into a main branch yet
func indexForGotoBottomInCommits(commits []*models.Commit, selectedIdx int) int {
stops := []int{}
if headIdx := models.HeadCommitIdx(commits); headIdx > 0 {
stops = append(stops, headIdx-1)
}
if _, idx, found := lo.FindIndexOf(commits, func(c *models.Commit) bool {
return c.Status == models.StatusMerged
}); found {
@@ -5,6 +5,7 @@ import (
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/utils"
"github.com/stefanhaller/git-todo-parser/todo"
"github.com/stretchr/testify/assert"
)
@@ -13,6 +14,9 @@ func TestIndexForGotoBottomInCommits(t *testing.T) {
commit := func(hash string, status models.CommitStatus) *models.Commit {
return models.NewCommit(hashPool, models.NewCommitOpts{Hash: hash, Status: status})
}
todoCommit := func(hash string, action todo.TodoCommand) *models.Commit {
return models.NewCommit(hashPool, models.NewCommitOpts{Hash: hash, Action: action, Status: models.StatusRebasing})
}
branchCommits := []*models.Commit{
commit("c3", models.StatusUnpushed),
@@ -22,6 +26,14 @@ func TestIndexForGotoBottomInCommits(t *testing.T) {
commit("m1", models.StatusMerged),
}
rebaseCommits := []*models.Commit{
todoCommit("t3", todo.Pick),
todoCommit("t2", todo.Pick),
todoCommit("t1", todo.Edit),
commit("c1", models.StatusUnpushed),
commit("m1", models.StatusMerged),
}
scenarios := []struct {
testName string
selectedIdx int
@@ -77,6 +89,28 @@ func TestIndexForGotoBottomInCommits(t *testing.T) {
},
expected: 4,
},
{
testName: "goes to the first todo of a rebase",
selectedIdx: 0,
commits: rebaseCommits,
expected: 2,
},
{
testName: "goes from the first todo of a rebase to the beginning of the branch",
selectedIdx: 2,
commits: rebaseCommits,
expected: 3,
},
{
testName: "goes to the conflicted commit at the bottom of the todos",
selectedIdx: 0,
commits: []*models.Commit{
todoCommit("t2", todo.Pick),
models.NewCommit(hashPool, models.NewCommitOpts{Hash: "t1", Action: todo.Pick, Status: models.StatusConflicted}),
commit("c1", models.StatusUnpushed),
},
expected: 1,
},
}
for _, s := range scenarios {