fast-(import|export): improve on commit signature output format

A recent commit, d9cb0e6ff8 (fast-export, fast-import: add support for
signed-commits, 2025-03-10), added support for signed commits to
fast-export and fast-import.

When a signed commit is processed, fast-export can output either
"gpgsig sha1" or "gpgsig sha256" depending on whether the signed
commit uses the SHA-1 or SHA-256 Git object format.

However, this implementation has a number of limitations:

  - the output format was not properly described in the documentation,
  - the output format is not very informative as it doesn't even say
    if the signature is an OpenPGP, an SSH, or an X509 signature,
  - the implementation doesn't support having both one signature on
    the SHA-1 object and one on the SHA-256 object.

Let's improve on these limitations by improving fast-export and
fast-import so that:

  - all the signatures are exported,
  - at most one signature on the SHA-1 object and one on the SHA-256
    are imported,
  - if there is more than one signature on the SHA-1 object or on
    the SHA-256 object, fast-import emits a warning for each
    additional signature,
  - the output format is "gpgsig <git-hash-algo> <signature-format>",
    where <git-hash-algo> is the Git object format as before, and
    <signature-format> is the signature type ("openpgp", "x509",
    "ssh" or "unknown"),
  - the output is properly documented.

About the output format:

  - <git-hash-algo> allows to know which representation of the commit
    was signed (the SHA-1 or the SHA-256 version) which helps with
    both signature verification and interoperability between repos
    with different hash functions,

  - <signature-format> helps tools that process the fast-export
    stream, so they don't have to parse the ASCII armor to identify
    the signature type.

It could be even better to be able to import more than one signature
on the SHA-1 object and on the SHA-256 object, but other parts of
Git don't handle that well for now, so this is left for future
improvements.

Helped-by: brian m. carlson <sandals@crustytoothpaste.net>
Helped-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Christian Couder
2025-07-09 16:12:53 +02:00
committed by Junio C Hamano
parent cb3b40381e
commit b5b3ddbe5c
7 changed files with 312 additions and 44 deletions

View File

@@ -445,7 +445,7 @@ one).
original-oid?
('author' (SP <name>)? SP LT <email> GT SP <when> LF)?
'committer' (SP <name>)? SP LT <email> GT SP <when> LF
('gpgsig' SP <alg> LF data)?
('gpgsig' SP <algo> SP <format> LF data)?
('encoding' SP <encoding> LF)?
data
('from' SP <commit-ish> LF)?
@@ -518,13 +518,39 @@ their syntax.
^^^^^^^^
The optional `gpgsig` command is used to include a PGP/GPG signature
that signs the commit data.
or other cryptographic signature that signs the commit data.
Here <alg> specifies which hashing algorithm is used for this
signature, either `sha1` or `sha256`.
....
'gpgsig' SP <git-hash-algo> SP <signature-format> LF data
....
NOTE: This is highly experimental and the format of the data stream may
change in the future without compatibility guarantees.
The `gpgsig` command takes two arguments:
* `<git-hash-algo>` specifies which Git object format this signature
applies to, either `sha1` or `sha256`. This allows to know which
representation of the commit was signed (the SHA-1 or the SHA-256
version) which helps with both signature verification and
interoperability between repos with different hash functions.
* `<signature-format>` specifies the type of signature, such as
`openpgp`, `x509`, `ssh`, or `unknown`. This is a convenience for
tools that process the stream, so they don't have to parse the ASCII
armor to identify the signature type.
A commit may have at most one signature for the SHA-1 object format
(stored in the "gpgsig" header) and one for the SHA-256 object format
(stored in the "gpgsig-sha256" header).
See below for a detailed description of the `data` command which
contains the raw signature data.
Signatures are not yet checked in the current implementation
though. (Already setting the `extensions.compatObjectFormat`
configuration option might help with verifying both SHA-1 and SHA-256
object format signatures when it will be implemented.)
NOTE: This is highly experimental and the format of the `gpgsig`
command may change in the future without compatibility guarantees.
`encoding`
^^^^^^^^^^