Re: [PATCH v2 2/2] builtin/history: sign rewritten commits
From: Patrick Steinhardt <hidden>
Date: 2026-09-11 07:58:02
On Fri, Jul 17, 2026 at 02:51:42PM +0000, Souma wrote:
The history commands create replacement commits directly instead of using the sequencer or the commit porcelain. As a result, rewritten commits ignore `commit.gpgSign` and cannot be signed on demand. Read the signing configuration before parsing options so that it establishes the default and later `-S`/`--gpg-sign` or `--no-gpg-sign` options override it. Pass the selected key through direct rewrites and the replay machinery. Sign every newly created commit, including both halves of a split and replayed descendants. Dropping the tip creates no replacement commit, so there is nothing to sign.
Nit: this sentence doesn't really add much value, I think, as it just covers a small edge case. It might even briefly derail the reader as they might wonder whether we ever have to sign with the "drop" subcommand.
As with `rebase --gpg-sign`, the signature records the attestation of the current committer to the rewritten commit while retaining the original author identity; it does not claim authorship of commits written by somebody else. Document the behavior and add GPG-gated coverage for configuration, command-line overrides, last-option-wins precedence, replayed descendants, split commits, an explicit signing key, and the no-new-commit drop case.
This paragraph doesn't add much value and can be dropped entirely.
quoted hunk ↗ jump to hunk
diff --git a/Documentation/git-history.adoc b/Documentation/git-history.adoc index 28b477cd37..8345cced4c 100644 --- a/Documentation/git-history.adoc +++ b/Documentation/git-history.adoc@@ -125,6 +125,14 @@ OPTIONS `--reedit-message`:: Open an editor to modify the target commit's message. +`-S[<key-id>]`:: +`--gpg-sign[=<key-id>]`:: +`--no-gpg-sign`:: + GPG-sign rewritten commits. The _<key-id>_ argument is optional and + defaults to the committer identity; if specified, it must be stuck to + the option without a space. `--no-gpg-sign` is useful to countermand + both `commit.gpgSign` configuration and earlier `--gpg-sign`. + `--empty=(drop|keep|abort)`:: Control what happens when a commit becomes empty as a result of the fixup. This can happen in two situations:
This matches what we have in git-rebase(1). Good.
quoted hunk ↗ jump to hunk
diff --git a/builtin/history.c b/builtin/history.c index d28c1f08bb..97e0d77013 100644 --- a/builtin/history.c +++ b/builtin/history.c@@ -105,12 +105,37 @@ enum commit_tree_flags { COMMIT_TREE_EDIT_MESSAGE = (1 << 0), }; +static int history_config(const char *var, const char *value, + const struct config_context *ctx, void *data) +{ + const char **sign_commit = data; + + if (!strcmp(var, "commit.gpgsign")) { + *sign_commit = git_config_bool(var, value) ? "" : NULL; + return 0; + } + + return git_default_config(var, value, ctx, NULL); +} + +#define OPT_HISTORY_GPG_SIGN(v) { \ + .type = OPTION_STRING, \ + .short_name = 'S', \ + .long_name = "gpg-sign", \ + .value = (v), \ + .argh = N_("key-id"), \ + .help = N_("GPG-sign rewritten commits"), \ + .flags = PARSE_OPT_OPTARG, \ + .defval = (intptr_t)"", \ +}
Style: we don't align the `\` character. Patrick