Add optional GPG signing status display in commits pane

Add a new gui.showGpgSigningStatus config option that, when enabled, shows GPG signature verification status for each commit in the commits view. Uses git's %G? format placeholder to display colored indicators: green check for valid signatures, red X for bad/revoked, yellow tilde for missing keys, and blue dash for unsigned commits.

Disabled by default since GPG verification adds latency to commit loading.

Closes #5363

Made-with: Cursor
This commit is contained in:
Harsh Abasaheb Chavan 2026-03-15 04:46:15 +05:30
parent 2f6d20275a
commit 33cc4b3928
6 changed files with 64 additions and 9 deletions

View file

@ -261,6 +261,11 @@ gui:
# If true, show commit hashes alongside branch names in the branches view.
showBranchCommitHash: false
# If true, show GPG signature verification status for each commit in the
# commits view. This can slow down commit loading as it requires GPG
# verification.
showGpgSigningStatus: false
# Whether to show the divergence from the base branch in the branches view.
# One of: 'none' | 'onlyArrow' | 'arrowAndNumber'
showDivergenceFromBaseBranch: none

View file

@ -190,11 +190,16 @@ func (self *CommitLoader) MergeRebasingCommits(hashPool *utils.StringPool, commi
// example input:
// 8ad01fe32fcc20f07bc6693f87aa4977c327f1e1|10 hours ago|Jesse Duffield| (HEAD -> master, tag: v0.15.2)|refresh commits when adding a tag
func (self *CommitLoader) extractCommitFromLine(hashPool *utils.StringPool, line string, showDivergence bool) *models.Commit {
split := strings.SplitN(line, "\x00", 8)
showGpg := self.UserConfig().Gui.ShowGpgSigningStatus
numFields := 8
if showGpg {
numFields = 9
}
split := strings.SplitN(line, "\x00", numFields)
// Ensure we have the minimum required fields (at least 7 for basic functionality)
if len(split) < 7 {
self.Log.Warnf("Malformed git log line: expected at least 7 fields, got %d. Line: %s", len(split), line)
minFields := 7
if len(split) < minFields {
self.Log.Warnf("Malformed git log line: expected at least %d fields, got %d. Line: %s", minFields, len(split), line)
return nil
}
@ -209,10 +214,18 @@ func (self *CommitLoader) extractCommitFromLine(hashPool *utils.StringPool, line
}
extraInfo := strings.TrimSpace(split[6])
// message (and the \x00 before it) might not be present if extraInfo is extremely long
gpgStatus := ""
messageIdx := 7
if showGpg {
if len(split) > 7 {
gpgStatus = split[7]
}
messageIdx = 8
}
message := ""
if len(split) > 7 {
message = split[7]
if len(split) > messageIdx {
message = split[messageIdx]
}
var tags []string
@ -248,6 +261,7 @@ func (self *CommitLoader) extractCommitFromLine(hashPool *utils.StringPool, line
AuthorEmail: authorEmail,
Parents: parents,
Divergence: divergence,
GpgStatus: gpgStatus,
})
}
@ -586,12 +600,18 @@ func (self *CommitLoader) getLogCmd(opts GetCommitsOptions) *oscommands.CmdObj {
refSpec += "..." + opts.RefToShowDivergenceFrom
}
showGpg := self.UserConfig().Gui.ShowGpgSigningStatus
format := prettyFormat
if showGpg {
format = prettyFormatWithGpg
}
cmdArgs := NewGitCmd("log").
Arg(refSpec).
ArgIf(gitLogOrder != "default", "--"+gitLogOrder).
ArgIf(opts.All, "--all").
Arg("--oneline").
Arg(prettyFormat).
Arg(format).
Arg("--abbrev=40").
ArgIf(opts.FilterAuthor != "", "--author="+opts.FilterAuthor).
ArgIf(opts.Limit, "-300").
@ -606,3 +626,4 @@ func (self *CommitLoader) getLogCmd(opts GetCommitsOptions) *oscommands.CmdObj {
}
const prettyFormat = `--pretty=format:+%H%x00%at%x00%aN%x00%ae%x00%P%x00%m%x00%D%x00%s`
const prettyFormatWithGpg = `--pretty=format:+%H%x00%at%x00%aN%x00%ae%x00%P%x00%m%x00%D%x00%G?%x00%s`

View file

@ -62,6 +62,10 @@ type Commit struct {
Action todo.TodoCommand
ActionFlag string // e.g. "-C" for fixup -C
Divergence Divergence // set to DivergenceNone unless we are showing the divergence view
// GPG signature status: "G" good, "B" bad, "U" unknown validity,
// "X" expired, "Y" expired key, "R" revoked, "E" missing key, "N" none
GpgStatus string
}
type NewCommitOpts struct {
@ -77,6 +81,7 @@ type NewCommitOpts struct {
UnixTimestamp int64
Divergence Divergence
Parents []string
GpgStatus string
}
func NewCommit(hashPool *utils.StringPool, opts NewCommitOpts) *Commit {
@ -93,6 +98,7 @@ func NewCommit(hashPool *utils.StringPool, opts NewCommitOpts) *Commit {
UnixTimestamp: opts.UnixTimestamp,
Divergence: opts.Divergence,
parents: lo.Map(opts.Parents, func(s string, _ int) *string { return hashPool.Add(s) }),
GpgStatus: opts.GpgStatus,
}
}

View file

@ -162,6 +162,8 @@ type GuiConfig struct {
CommitHashLength int `yaml:"commitHashLength" jsonschema:"minimum=0"`
// If true, show commit hashes alongside branch names in the branches view.
ShowBranchCommitHash bool `yaml:"showBranchCommitHash"`
// If true, show GPG signature verification status for each commit in the commits view. This can slow down commit loading as it requires GPG verification.
ShowGpgSigningStatus bool `yaml:"showGpgSigningStatus"`
// Whether to show the divergence from the base branch in the branches view.
// One of: 'none' | 'onlyArrow' | 'arrowAndNumber'
ShowDivergenceFromBaseBranch string `yaml:"showDivergenceFromBaseBranch" jsonschema:"enum=none,enum=onlyArrow,enum=arrowAndNumber"`
@ -804,6 +806,7 @@ func GetDefaultConfig() *UserConfig {
CommitAuthorLongLength: 17,
CommitHashLength: 8,
ShowBranchCommitHash: false,
ShowGpgSigningStatus: false,
ShowDivergenceFromBaseBranch: "none",
CommandLogSize: 8,
SplitDiff: "auto",

View file

@ -393,6 +393,20 @@ func displayCommit(
actionString = actionColorMap(commit.Action, commit.Status).Sprint(actionStr)
}
gpgString := ""
if common.UserConfig().Gui.ShowGpgSigningStatus {
switch commit.GpgStatus {
case "G", "U":
gpgString = style.FgGreen.Sprint("✓")
case "B", "R", "X", "Y":
gpgString = style.FgRed.Sprint("✗")
case "E":
gpgString = style.FgYellow.Sprint("~")
default:
gpgString = style.FgBlue.Sprint("-")
}
}
tagString := ""
if fullDescription {
if commit.ExtraInfo != "" {
@ -439,11 +453,12 @@ func displayCommit(
}
author := authors.AuthorWithLength(commit.AuthorName, authorLength)
cols := make([]string, 0, 7)
cols := make([]string, 0, 8)
cols = append(
cols,
divergenceString,
hashString,
gpgString,
bisectString,
descriptionString,
actionString,

View file

@ -697,6 +697,11 @@
"description": "If true, show commit hashes alongside branch names in the branches view.",
"default": false
},
"showGpgSigningStatus": {
"type": "boolean",
"description": "If true, show GPG signature verification status for each commit in the commits view. This can slow down commit loading as it requires GPG verification.",
"default": false
},
"showDivergenceFromBaseBranch": {
"type": "string",
"enum": [