diff --git a/docs-master/Config.md b/docs-master/Config.md index aa149e9e8ea..e5ee8ec9c5c 100644 --- a/docs-master/Config.md +++ b/docs-master/Config.md @@ -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 diff --git a/pkg/commands/git_commands/commit_loader.go b/pkg/commands/git_commands/commit_loader.go index 8b79bd8cd49..abc3011cf5f 100644 --- a/pkg/commands/git_commands/commit_loader.go +++ b/pkg/commands/git_commands/commit_loader.go @@ -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` diff --git a/pkg/commands/models/commit.go b/pkg/commands/models/commit.go index 137528ee6e9..1f148ea5a22 100644 --- a/pkg/commands/models/commit.go +++ b/pkg/commands/models/commit.go @@ -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, } } diff --git a/pkg/config/user_config.go b/pkg/config/user_config.go index 192d13843d7..66c1a21ea8f 100644 --- a/pkg/config/user_config.go +++ b/pkg/config/user_config.go @@ -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", diff --git a/pkg/gui/presentation/commits.go b/pkg/gui/presentation/commits.go index 67fa62ac82c..bf8c9f3aaff 100644 --- a/pkg/gui/presentation/commits.go +++ b/pkg/gui/presentation/commits.go @@ -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, diff --git a/schema-master/config.json b/schema-master/config.json index 54f9fa9ec4d..b0a04c320ed 100644 --- a/schema-master/config.json +++ b/schema-master/config.json @@ -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": [