Skip to content

feat: per-identity signing format and SSH key#2

Merged
jmarette merged 3 commits into
masterfrom
feat/per-identity-signing-ssh
Jun 14, 2026
Merged

feat: per-identity signing format and SSH key#2
jmarette merged 3 commits into
masterfrom
feat/per-identity-signing-ssh

Conversation

@jmarette

Copy link
Copy Markdown
Owner

Lets each identity carry its signing format and SSH transport, so they follow
the directory like user.name/user.email already do. Closes the two
"future work" items: GPG/SSH signing helpers and per-identity SSH keys.

New flags (create / edit)

  • --format <openpgp|ssh|x509>gpg.format (SSH commit signing needs git ≥ 2.34)
  • --ssh-key <path> → shorthand for core.sshCommand = ssh -i '<path>' -o IdentitiesOnly=yes,
    so the named key is used and an agent key can't shadow it. The path is
    shell-quoted (git runs core.sshCommand through a shell).
  • --ssh-command <cmd> → stores core.sshCommand verbatim (mutually exclusive
    with --ssh-key)
  • on edit: --no-format / --no-ssh remove them

The two values are exposed in show / list --json as user.format and
user.ssh_command.

Safety

Both new fields go through validate_* (control characters rejected) and
quote_cfg_value at render time, so neither can inject a gitconfig section —
same guarantee as --signing-key. Hand-added keys in a fragment are still
preserved by edit.

doctor

doctor now flags an identity whose gpg.format isn't one of openpgp/ssh/x509
(a hand-edited fragment git would only reject at signing time), and warns when
gpg.format = ssh but the installed git is older than 2.34.

Tests

cargo test green (55 unit + 54 integration). New coverage: fragment rendering
of the [gpg]/[core] sections, shell-quoting of the key path, format
validation, flag exclusivity, control-char rejection, edit set/remove, and
the doctor format check. clippy -D warnings and fmt --check clean.
Verified end-to-end in a throwaway HOME that git resolves gpg.format and
core.sshCommand through the conditional include from inside a routed repo.

🤖 Generated with Claude Code

jmarette added 3 commits June 14, 2026 02:30
Identities can now carry their signing format and SSH transport, so they
follow the directory like name and email do. create/edit gain:

- --format <openpgp|ssh|x509> (gpg.format; SSH signing needs git >= 2.34)
- --ssh-key <path>, shorthand for
  core.sshCommand = ssh -i '<path>' -o IdentitiesOnly=yes (the named key is
  used; an agent key cannot shadow it)
- --ssh-command <cmd>, stored verbatim (mutually exclusive with --ssh-key)
- edit --no-format / --no-ssh to remove them

Both values are validated against control characters and escaped at render
time, so neither can inject a gitconfig section, and they are surfaced in
show/list --json as user.format and user.ssh_command.
Add a "Signing and SSH keys" section to the README, note the new fragment
keys in the layout, and record the feature under CHANGELOG [Unreleased].
Drop the now-implemented items from the Future work line.
doctor now inspects each identity's gpg.format: it warns when the value is
not one of openpgp/ssh/x509 (a hand-edited fragment that git would only
reject at signing time), and when gpg.format=ssh but the installed git is
older than 2.34, which cannot sign with SSH.
@jmarette jmarette merged commit ec70dee into master Jun 14, 2026
9 checks passed
@jmarette jmarette deleted the feat/per-identity-signing-ssh branch June 14, 2026 00:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant