Skip to content

Commit 4a0446f

Browse files
committed
Fix GPG status parsing for hydrated commits
Pass the GPG parsing mode explicitly so rebasing and sequencer commits keep their subject lines when signature status is enabled. Add regression tests for commit loading, TODO hydration, and commit row rendering.
1 parent 5070bed commit 4a0446f

File tree

3 files changed

+118
-6
lines changed

3 files changed

+118
-6
lines changed

pkg/commands/git_commands/commit_loader.go

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,9 @@ func (self *CommitLoader) GetCommits(opts GetCommitsOptions) ([]*models.Commit,
9191
defer wg.Done()
9292

9393
var realCommits []*models.Commit
94+
showGpg := self.UserConfig().Gui.ShowGpgSigningStatus
9495
realCommits, logErr = loadCommits(self.getLogCmd(opts), opts.FilterPath, func(line string) (*models.Commit, bool) {
95-
return self.extractCommitFromLine(opts.HashPool, line, opts.RefToShowDivergenceFrom != ""), false
96+
return self.extractCommitFromLine(opts.HashPool, line, opts.RefToShowDivergenceFrom != "", showGpg), false
9697
})
9798
if logErr == nil {
9899
commits = append(commits, realCommits...)
@@ -189,8 +190,7 @@ func (self *CommitLoader) MergeRebasingCommits(hashPool *utils.StringPool, commi
189190
// then puts them into a commit object
190191
// example input:
191192
// 8ad01fe32fcc20f07bc6693f87aa4977c327f1e1|10 hours ago|Jesse Duffield| (HEAD -> master, tag: v0.15.2)|refresh commits when adding a tag
192-
func (self *CommitLoader) extractCommitFromLine(hashPool *utils.StringPool, line string, showDivergence bool) *models.Commit {
193-
showGpg := self.UserConfig().Gui.ShowGpgSigningStatus
193+
func (self *CommitLoader) extractCommitFromLine(hashPool *utils.StringPool, line string, showDivergence bool, showGpg bool) *models.Commit {
194194
numFields := 8
195195
if showGpg {
196196
numFields = 9
@@ -299,10 +299,16 @@ func (self *CommitLoader) getHydratedTodoCommits(hashPool *utils.StringPool, tod
299299

300300
// note that we're not filtering these as we do non-rebasing commits just because
301301
// I suspect that will cause some damage
302+
showGpg := self.UserConfig().Gui.ShowGpgSigningStatus
303+
format := prettyFormat
304+
if showGpg {
305+
format = prettyFormatWithGpg
306+
}
307+
302308
cmdObj := self.cmd.New(
303309
NewGitCmd("show").
304310
Config("log.showSignature=false").
305-
Arg("--no-patch", "--oneline", "--abbrev=20", prettyFormat).
311+
Arg("--no-patch", "--oneline", "--abbrev=20", format).
306312
Arg(commitHashes...).
307313
ToArgv(),
308314
).DontLog()
@@ -312,7 +318,10 @@ func (self *CommitLoader) getHydratedTodoCommits(hashPool *utils.StringPool, tod
312318
if line == "" || line[0] != '+' {
313319
return false, nil
314320
}
315-
commit := self.extractCommitFromLine(hashPool, line[1:], false)
321+
commit := self.extractCommitFromLine(hashPool, line[1:], false, showGpg)
322+
if commit == nil {
323+
return false, nil
324+
}
316325
fullCommits[commit.Hash()] = commit
317326
return false, nil
318327
})

pkg/commands/git_commands/commit_loader_test.go

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,16 @@ var commitsOutput = strings.ReplaceAll(`+0eea75e8c631fba6b58135697835d58ba4c18db
2727

2828
var singleCommitOutput = strings.ReplaceAll(`+0eea75e8c631fba6b58135697835d58ba4c18dbc|1640826609|Jesse Duffield|jessedduffield@gmail.com|b21997d6b4cbdf84b149|>|HEAD -> better-tests|better typing for rebase mode`, "|", "\x00")
2929

30+
var singleCommitOutputWithGpg = strings.ReplaceAll(`+0eea75e8c631fba6b58135697835d58ba4c18dbc|1640826609|Jesse Duffield|jessedduffield@gmail.com|b21997d6b4cbdf84b149|>|HEAD -> better-tests|G|better typing for rebase mode`, "|", "\x00")
31+
3032
func TestGetCommits(t *testing.T) {
3133
type scenario struct {
3234
testName string
3335
runner *oscommands.FakeCmdObjRunner
3436
expectedCommitOpts []models.NewCommitOpts
3537
expectedError error
3638
logOrder string
39+
showGpg bool
3740
opts GetCommitsOptions
3841
mainBranches []string
3942
}
@@ -61,6 +64,30 @@ func TestGetCommits(t *testing.T) {
6164
expectedCommitOpts: []models.NewCommitOpts{},
6265
expectedError: nil,
6366
},
67+
{
68+
testName: "should return commits with gpg status when enabled",
69+
logOrder: "topo-order",
70+
showGpg: true,
71+
opts: GetCommitsOptions{RefName: "HEAD", RefForPushedStatus: &models.Branch{Name: "mybranch"}, IncludeRebaseCommits: false},
72+
runner: oscommands.NewFakeRunner(t).
73+
ExpectGitArgs([]string{"rev-list", "refs/heads/mybranch", "^mybranch@{u}"}, "0eea75e8c631fba6b58135697835d58ba4c18dbc\n", nil).
74+
ExpectGitArgs([]string{"log", "HEAD", "--topo-order", "--oneline", "--pretty=format:+%H%x00%at%x00%aN%x00%ae%x00%P%x00%m%x00%D%x00%G?%x00%s", "--abbrev=40", "--no-show-signature", "--"}, singleCommitOutputWithGpg, nil),
75+
76+
expectedCommitOpts: []models.NewCommitOpts{{
77+
Hash: "0eea75e8c631fba6b58135697835d58ba4c18dbc",
78+
Name: "better typing for rebase mode",
79+
Status: models.StatusUnpushed,
80+
Action: models.ActionNone,
81+
Tags: nil,
82+
ExtraInfo: "(HEAD -> better-tests)",
83+
AuthorName: "Jesse Duffield",
84+
AuthorEmail: "jessedduffield@gmail.com",
85+
UnixTimestamp: 1640826609,
86+
Parents: []string{"b21997d6b4cbdf84b149"},
87+
GpgStatus: "G",
88+
}},
89+
expectedError: nil,
90+
},
6491
{
6592
testName: "should return commits if they are present",
6693
logOrder: "topo-order",
@@ -300,6 +327,7 @@ func TestGetCommits(t *testing.T) {
300327
t.Run(scenario.testName, func(t *testing.T) {
301328
common := common.NewDummyCommon()
302329
common.UserConfig().Git.Log.Order = scenario.logOrder
330+
common.UserConfig().Gui.ShowGpgSigningStatus = scenario.showGpg
303331
cmd := oscommands.NewDummyCmdObjBuilder(scenario.runner)
304332

305333
builder := &CommitLoader{
@@ -333,6 +361,42 @@ func TestGetCommits(t *testing.T) {
333361
}
334362
}
335363

364+
func TestCommitLoader_getHydratedTodoCommitsWithGpgStatus(t *testing.T) {
365+
common := common.NewDummyCommon()
366+
common.UserConfig().Gui.ShowGpgSigningStatus = true
367+
runner := oscommands.NewFakeRunner(t).
368+
ExpectGitArgs([]string{"-c", "log.showSignature=false", "show", "--no-patch", "--oneline", "--abbrev=20", prettyFormatWithGpg, "0eea75e8c631fba6b58135697835d58ba4c18dbc"}, singleCommitOutputWithGpg, nil)
369+
370+
hashPool := &utils.StringPool{}
371+
loader := &CommitLoader{
372+
Common: common,
373+
cmd: oscommands.NewDummyCmdObjBuilder(runner),
374+
}
375+
376+
todoCommits := []*models.Commit{models.NewCommit(hashPool, models.NewCommitOpts{
377+
Hash: "0eea75e8c631fba6b58135697835d58ba4c18dbc",
378+
Status: models.StatusRebasing,
379+
Action: todo.Pick,
380+
})}
381+
382+
commits, err := loader.getHydratedTodoCommits(hashPool, todoCommits, false)
383+
384+
assert.NoError(t, err)
385+
assert.Equal(t, []*models.Commit{models.NewCommit(hashPool, models.NewCommitOpts{
386+
Hash: "0eea75e8c631fba6b58135697835d58ba4c18dbc",
387+
Name: "better typing for rebase mode",
388+
Status: models.StatusRebasing,
389+
Action: todo.Pick,
390+
ExtraInfo: "(HEAD -> better-tests)",
391+
AuthorName: "Jesse Duffield",
392+
AuthorEmail: "jessedduffield@gmail.com",
393+
UnixTimestamp: 1640826609,
394+
Parents: []string{"b21997d6b4cbdf84b149"},
395+
GpgStatus: "G",
396+
})}, commits)
397+
runner.CheckForMissingCalls()
398+
}
399+
336400
func TestCommitLoader_getConflictedCommitImpl(t *testing.T) {
337401
hashPool := &utils.StringPool{}
338402

@@ -605,6 +669,7 @@ func TestCommitLoader_extractCommitFromLine(t *testing.T) {
605669
testName string
606670
line string
607671
showDivergence bool
672+
showGpg bool
608673
expectedCommit *models.Commit
609674
}{
610675
{
@@ -759,6 +824,24 @@ func TestCommitLoader_extractCommitFromLine(t *testing.T) {
759824
Divergence: models.DivergenceLeft,
760825
}),
761826
},
827+
{
828+
testName: "valid line with gpg status",
829+
line: "hash\x00timestamp\x00author\x00email\x00parents\x00<\x00extraInfo\x00G\x00message",
830+
showDivergence: true,
831+
showGpg: true,
832+
expectedCommit: models.NewCommit(hashPool, models.NewCommitOpts{
833+
Hash: "hash",
834+
Name: "message",
835+
Tags: nil,
836+
ExtraInfo: "(extraInfo)",
837+
UnixTimestamp: 0,
838+
AuthorName: "author",
839+
AuthorEmail: "email",
840+
Parents: []string{"parents"},
841+
Divergence: models.DivergenceLeft,
842+
GpgStatus: "G",
843+
}),
844+
},
762845
{
763846
testName: "empty line",
764847
line: "",
@@ -785,7 +868,7 @@ func TestCommitLoader_extractCommitFromLine(t *testing.T) {
785868

786869
for _, scenario := range scenarios {
787870
t.Run(scenario.testName, func(t *testing.T) {
788-
result := loader.extractCommitFromLine(hashPool, scenario.line, scenario.showDivergence)
871+
result := loader.extractCommitFromLine(hashPool, scenario.line, scenario.showDivergence, scenario.showGpg)
789872
if scenario.expectedCommit == nil {
790873
assert.Nil(t, result)
791874
} else {

pkg/gui/presentation/commits_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
4040
selectedCommitHashPtr *string
4141
startIdx int
4242
endIdx int
43+
showGpg bool
4344
showGraph bool
4445
bisectInfo *git_commands.BisectInfo
4546
expected string
@@ -90,6 +91,24 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
9091
hash2 commit2
9192
`),
9293
},
94+
{
95+
testName: "show gpg status when enabled",
96+
commitOpts: []models.NewCommitOpts{
97+
{Name: "commit1", Hash: "hash1", GpgStatus: "G"},
98+
{Name: "commit2", Hash: "hash2", GpgStatus: "N"},
99+
},
100+
startIdx: 0,
101+
endIdx: 2,
102+
showGpg: true,
103+
showGraph: false,
104+
bisectInfo: git_commands.NewNullBisectInfo(),
105+
cherryPickedCommitHashSet: set.New[string](),
106+
now: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
107+
expected: formatExpected(`
108+
hash1 ✓ commit1
109+
hash2 - commit2
110+
`),
111+
},
93112
{
94113
testName: "show local branch head, except the current branch, main branches, or merged branches",
95114
commitOpts: []models.NewCommitOpts{
@@ -546,6 +565,7 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
546565
if !focusing || s.focus {
547566
t.Run(s.testName, func(t *testing.T) {
548567
hashPool := &utils.StringPool{}
568+
common.UserConfig().Gui.ShowGpgSigningStatus = s.showGpg
549569

550570
commits := lo.Map(s.commitOpts,
551571
func(opts models.NewCommitOpts, _ int) *models.Commit { return models.NewCommit(hashPool, opts) })

0 commit comments

Comments
 (0)