Load the commits down to the current bisect commit

The commits view loads the first 300 commits only. If the range to
bisect is longer than about 600 commits, the commit that git wants the
user to test is further down than that, so it isn't shown, and we can't
select it.

While bisecting, count the commits in the log above the current commit,
and load that many more than usual.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Stefan Haller
2026-10-31 11:27:58 +01:00
co-authored by Claude Opus 5.5
parent 990913dd63
commit 08065f0294
3 changed files with 40 additions and 4 deletions
+18
View File
@@ -3,6 +3,7 @@ package git_commands
import (
"os"
"path/filepath"
"strconv"
"strings"
)
@@ -192,3 +193,20 @@ func (self *BisectCommands) ReachableFromStart(bisectInfo *BisectInfo) bool {
return err == nil
}
// Returns the number of commits that are reachable from logRef but not from
// the given commit. In a log of logRef, parents come after their children
// (unless the log uses git's default order and commit dates are skewed), so
// the commit is at most this many commits down from the top.
func (self *BisectCommands) CountCommitsAbove(hash string, logRef string) (int, error) {
cmdArgs := NewGitCmd("rev-list").
Arg("--count", hash+".."+logRef).
ToArgv()
output, err := self.cmd.New(cmdArgs).DontLog().RunWithOutput()
if err != nil {
return 0, err
}
return strconv.Atoi(strings.TrimSpace(output))
}
+22 -1
View File
@@ -854,7 +854,7 @@ func (self *RefreshHelper) determineCheckedOutRef(env refreshEnv) models.Ref {
func (self *RefreshHelper) refreshCommitsWithLimit(captured capturedCommitState, commitSelection types.CommitSelectionBehavior, env refreshEnv) error {
checkedOutRef := self.determineCheckedOutRef(env)
refName, bisectInfo := self.refForLog(env)
limit := lo.Ternary(captured.limitCommits, commitLimit, 0)
limit := self.commitLimitForLog(captured.limitCommits, refName, bisectInfo, env)
commits, err := env.git.Loaders.CommitLoader.GetCommits(
git_commands.GetCommitsOptions{
Limit: limit,
@@ -1777,6 +1777,27 @@ func (self *RefreshHelper) refForLog(env refreshEnv) (string, *git_commands.Bise
return bisectInfo.GetStartHash(), bisectInfo
}
// commitLimitForLog returns the number of commits to load for the commits view,
// or 0 to load all of them.
func (self *RefreshHelper) commitLimitForLog(limitCommits bool, refName string, bisectInfo *git_commands.BisectInfo, env refreshEnv) int {
if !limitCommits {
return 0
}
if hash := bisectCommitToSelect(bisectInfo); hash != "" {
// Load the commit that the user needs to look at, and as many commits
// after it as we load from the top otherwise. This way we can select it
// without having to load all commits.
count, err := env.git.Bisect.CountCommitsAbove(hash, refName)
if err == nil {
return count + commitLimit
}
self.c.Log.Warnf("Failed to count the commits above the bisect commit to select: %v", err)
}
return commitLimit
}
func (self *RefreshHelper) refreshView(context types.Context, env refreshEnv) {
// refreshView is called from the worker goroutine that drives async
// refreshes, so bounce to the UI thread before mutating view content. Guard
@@ -23,9 +23,6 @@ var SelectCurrentCommitInLongRange = NewIntegrationTest(NewIntegrationTestArgs{
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Commits().
Focus().
/* EXPECTED:
SelectedLine(Contains("<-- current"))
ACTUAL: */
SelectedLine(Contains("commit 700"))
},
})