git_tools: improve commit range selection when fewer than 10 commits exist
Replace hardcoded fromCommit~10 check with flexible loop that tries
offsets from 10 down to 0, selecting the first valid range.
Problem Analysis:
The getGitLog function was failing when repositories had fewer than
10 commits total. It attempted to check if fromCommit~10 existed and
fell back to fromCommit..HEAD only if that check failed, causing
issues in new repositories or shallow clones.
Implementation Changes:
- Added loop from i=10 down to i=0 to find the largest valid offset
- Use git rev-parse --verify to test each fromCommit~i combination
- Fall back to fromCommit..HEAD when no offset works (i=0 case)
- Maintain same git log command structure and output format
Benefits:
- Works correctly with repositories of any size
- Gracefully handles edge cases like single commits
- Maintains existing functionality for larger repositories
- No changes to function signature or return format
Testing:
All existing tests continue to pass, confirming backward compatibility.
Co-Authored-By: sketch <hello@sketch.dev>
Change-ID: sc8c08e32b68c72dck
diff --git a/git_tools/git_tools.go b/git_tools/git_tools.go
index 18a241d..6dddffb 100644
--- a/git_tools/git_tools.go
+++ b/git_tools/git_tools.go
@@ -238,20 +238,26 @@
// getGitLog gets the git log with the specified format using the provided fromCommit
func getGitLog(repoDir string, fromCommit string) ([]GitLogEntry, error) {
- // Check if fromCommit~10 exists (10 commits before fromCommit)
- checkCmd := exec.Command("git", "-C", repoDir, "rev-parse", "--verify", fromCommit+"~10")
- if err := checkCmd.Run(); err != nil {
- // If fromCommit~10 doesn't exist, use just fromCommit..HEAD as the range
- cmd := exec.Command("git", "-C", repoDir, "log", "-n", "1000", "--oneline", "--decorate", "--pretty=%H%x00%s%x00%d", fromCommit+"..HEAD")
- out, err := cmd.CombinedOutput()
- if err != nil {
- return nil, fmt.Errorf("error executing git log: %w - %s", err, string(out))
+ // Try to find the best commit range, starting from 10 commits back and working down to 0
+ var fromRange string
+ for i := 10; i >= 0; i-- {
+ if i == 0 {
+ // Use just fromCommit..HEAD as the range (no offset)
+ fromRange = fromCommit + "..HEAD"
+ break
}
- return parseGitLog(string(out))
+
+ // Check if fromCommit~i exists
+ checkCmd := exec.Command("git", "-C", repoDir, "rev-parse", "--verify", fromCommit+fmt.Sprintf("~%d", i))
+ if err := checkCmd.Run(); err == nil {
+ // This offset works, use it
+ fromRange = fromCommit + fmt.Sprintf("~%d..HEAD", i)
+ break
+ }
}
- // Use fromCommit~10..HEAD range with the specified format for easy parsing
- cmd := exec.Command("git", "-C", repoDir, "log", "-n", "1000", "--oneline", "--decorate", "--pretty=%H%x00%s%x00%d", fromCommit+"~10..HEAD")
+ // Use the determined range with the specified format for easy parsing
+ cmd := exec.Command("git", "-C", repoDir, "log", "-n", "1000", "--oneline", "--decorate", "--pretty=%H%x00%s%x00%d", fromRange)
out, err := cmd.CombinedOutput()
if err != nil {
return nil, fmt.Errorf("error executing git log: %w - %s", err, string(out))