Skip to content

Commit e2f12f9

Browse files
authored
git: Don't use rev-list's --no-commit-header (#363)
This flag was introduced in Git 2.33, which is newer than the default on many systems. We don't absolutely need this flag -- just manually skip the header.
1 parent fa5b342 commit e2f12f9

File tree

4 files changed

+142
-4
lines changed

4 files changed

+142
-4
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
kind: Fixed
2+
body: Support use with older Git versions by dropping use of a v2.33-only flag.
3+
time: 2024-08-27T22:13:31.124136-07:00

internal/git/commit.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,8 @@ func (r *Repository) Commit(ctx context.Context, req CommitRequest) error {
158158

159159
// CommitSubject returns the subject of a commit.
160160
func (r *Repository) CommitSubject(ctx context.Context, commitish string) (string, error) {
161-
out, err := r.gitCmd(ctx, "rev-list",
162-
"--no-commit-header", "-n1", "--format=%s", commitish, "--",
161+
out, err := r.gitCmd(ctx,
162+
"show", "--no-patch", "--format=%s", commitish,
163163
).OutputString(r.exec)
164164
if err != nil {
165165
return "", fmt.Errorf("git log: %w", err)
@@ -189,7 +189,6 @@ func (m CommitMessage) String() string {
189189
// That is, all commits reachable from start but not from stop.
190190
func (r *Repository) CommitMessageRange(ctx context.Context, start, stop string) ([]CommitMessage, error) {
191191
cmd := r.gitCmd(ctx, "rev-list",
192-
"--no-commit-header",
193192
"--format=%B%x00", // null-byte separated
194193
start, "--not", stop, "--",
195194
)
@@ -211,6 +210,14 @@ func (r *Repository) CommitMessageRange(ctx context.Context, start, stop string)
211210
if len(raw) == 0 {
212211
continue
213212
}
213+
214+
// --format with rev-list writes in the form:
215+
//
216+
// commit <hash>\n
217+
// <format string>
218+
//
219+
// We need to drop the first line.
220+
_, raw, _ = strings.Cut(raw, "\n")
214221
subject, body, _ := strings.Cut(raw, "\n")
215222
bodies = append(bodies, CommitMessage{
216223
Subject: strings.TrimSpace(subject),

internal/git/integration_test.go

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package git_test
2+
3+
import (
4+
"context"
5+
"testing"
6+
"time"
7+
8+
"github.com/stretchr/testify/assert"
9+
"github.com/stretchr/testify/require"
10+
"go.abhg.dev/gs/internal/git"
11+
"go.abhg.dev/gs/internal/git/gittest"
12+
"go.abhg.dev/gs/internal/logtest"
13+
"go.abhg.dev/gs/internal/text"
14+
)
15+
16+
func TestIntegrationCommitListing(t *testing.T) {
17+
t.Parallel()
18+
19+
fixture, err := gittest.LoadFixtureScript([]byte(text.Dedent(`
20+
as 'Test <[email protected]>'
21+
22+
at '2024-08-27T21:48:32Z'
23+
git init
24+
git config core.editor 'mockedit'
25+
26+
git add init.txt
27+
git commit -m 'Initial commit'
28+
29+
at '2024-08-27T21:52:12Z'
30+
git add feature1.txt
31+
env MOCKEDIT_GIVE=$WORK/input/feature1-commit.txt
32+
git commit
33+
34+
at '2024-08-27T22:10:11Z'
35+
git add feature2.txt
36+
env MOCKEDIT_GIVE=$WORK/input/feature2-commit.txt
37+
git commit
38+
39+
-- init.txt --
40+
-- feature1.txt --
41+
feature 1
42+
-- feature2.txt --
43+
feature 2
44+
-- input/feature1-commit.txt --
45+
Add feature1
46+
47+
This is the first feature.
48+
-- input/feature2-commit.txt --
49+
Add feature2
50+
51+
This is the second feature.
52+
`)))
53+
require.NoError(t, err)
54+
55+
ctx := context.Background()
56+
repo, err := git.Open(ctx, fixture.Dir(), git.OpenOptions{
57+
Log: logtest.New(t),
58+
})
59+
require.NoError(t, err)
60+
61+
t.Run("ListCommitsDetails", func(t *testing.T) {
62+
commits, err := repo.ListCommitsDetails(ctx, git.CommitRangeFrom("HEAD").Limit(2))
63+
require.NoError(t, err)
64+
65+
// Normalize to UTC
66+
for i := range commits {
67+
commits[i].AuthorDate = commits[i].AuthorDate.UTC()
68+
}
69+
70+
assert.Equal(t, []git.CommitDetail{
71+
{
72+
Hash: "9045e63b1d4d4e6e2db3fa03d4eb98a6ed653f3a",
73+
ShortHash: "9045e63",
74+
Subject: "Add feature2",
75+
AuthorDate: time.Date(2024, 8, 27, 22, 10, 11, 0, time.UTC),
76+
},
77+
{
78+
Hash: "acca66548dc31594dc3bc669c804e98eda1edc3d",
79+
ShortHash: "acca665",
80+
Subject: "Add feature1",
81+
AuthorDate: time.Date(2024, 8, 27, 21, 52, 12, 0, time.UTC),
82+
},
83+
}, commits)
84+
})
85+
86+
t.Run("CommitSubject", func(t *testing.T) {
87+
subject, err := repo.CommitSubject(ctx, "HEAD")
88+
require.NoError(t, err)
89+
assert.Equal(t, "Add feature2", subject)
90+
91+
subject, err = repo.CommitSubject(ctx, "HEAD^")
92+
require.NoError(t, err)
93+
assert.Equal(t, "Add feature1", subject)
94+
})
95+
96+
t.Run("CommitMessageRange", func(t *testing.T) {
97+
msgs, err := repo.CommitMessageRange(ctx, "HEAD", "HEAD~2")
98+
require.NoError(t, err)
99+
100+
assert.Equal(t, []git.CommitMessage{
101+
{
102+
Subject: "Add feature2",
103+
Body: "This is the second feature.",
104+
},
105+
{
106+
Subject: "Add feature1",
107+
Body: "This is the first feature.",
108+
},
109+
}, msgs)
110+
})
111+
}

internal/git/rev_list.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ func (r *Repository) listCommitsFormat(ctx context.Context, commits CommitRange,
9494
args := make([]string, 0, len(commits)+3)
9595
args = append(args, "rev-list")
9696
if format != "" {
97-
args = append(args, "--format="+format, "--no-commit-header")
97+
args = append(args, "--format="+format)
9898
}
9999
args = append(args, []string(commits)...)
100100

@@ -112,6 +112,23 @@ func (r *Repository) listCommitsFormat(ctx context.Context, commits CommitRange,
112112
var lines []string
113113
scanner := bufio.NewScanner(out)
114114
for scanner.Scan() {
115+
line := scanner.Text()
116+
117+
// With --format, rev-list output is in the form:
118+
//
119+
// commit <hash>
120+
// <formatted message>
121+
//
122+
// We'll need to ignore the first line.
123+
//
124+
// This is a bit of a hack, but the --no-commit-header flag
125+
// that suppresses this line is only available in git 2.33+.
126+
if format != "" && strings.HasPrefix(line, "commit ") {
127+
if !scanner.Scan() {
128+
break
129+
}
130+
}
131+
115132
lines = append(lines, scanner.Text())
116133
}
117134

0 commit comments

Comments
 (0)