Re: [PATCH v2 2/2] fast-import: add '--signed-commits=<mode>' option

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Sorry I forgot to use the
--in-reply-to='20250910080839.2142651-1-christian.couder@xxxxxxxxx'
option when sending this series. It is related to:

https://lore.kernel.org/git/20250910080839.2142651-1-christian.couder@xxxxxxxxx/

On Fri, Sep 12, 2025 at 2:40 PM Christian Couder
<christian.couder@xxxxxxxxx> wrote:
>
> A '--signed-commits=<mode>' option is already available when using
> `git fast-export` to decide what should be done at export time about
> commit signatures. At import time though, there is no option, or
> other way, in `git fast-import` to decide about commit signatures.
>
> To remediate that, let's add a '--signed-commits=<mode>' option to
> `git fast-import` too.
>
> For now the supported <mode>s are the same as those supported by
> `git fast-export`.
>
> Signed-off-by: Christian Couder <chriscool@xxxxxxxxxxxxx>
> ---
>  Documentation/git-fast-import.adoc |   5 ++
>  builtin/fast-import.c              |  41 ++++++++---
>  t/meson.build                      |   1 +
>  t/t9305-fast-import-signatures.sh  | 106 +++++++++++++++++++++++++++++
>  4 files changed, 145 insertions(+), 8 deletions(-)
>  create mode 100755 t/t9305-fast-import-signatures.sh
>
> diff --git a/Documentation/git-fast-import.adoc b/Documentation/git-fast-import.adoc
> index 3144ffcdb6..90f242d058 100644
> --- a/Documentation/git-fast-import.adoc
> +++ b/Documentation/git-fast-import.adoc
> @@ -66,6 +66,11 @@ OPTIONS
>         remote-helpers that use the `import` capability, as they are
>         already trusted to run their own code.
>
> +--signed-commits=(verbatim|warn-verbatim|warn-strip|strip|abort)::
> +       Specify how to handle signed commits.  Behaves in the same way
> +       as the same option in linkgit:git-fast-export[1], except that
> +       default is 'verbatim' (instead of 'abort').
> +
>  Options for Frontends
>  ~~~~~~~~~~~~~~~~~~~~~
>
> diff --git a/builtin/fast-import.c b/builtin/fast-import.c
> index 2c35f9345d..890f05de4d 100644
> --- a/builtin/fast-import.c
> +++ b/builtin/fast-import.c
> @@ -188,6 +188,8 @@ static int global_argc;
>  static const char **global_argv;
>  static const char *global_prefix;
>
> +static enum sign_mode signed_commit_mode = SIGN_VERBATIM;
> +
>  /* Memory pools */
>  static struct mem_pool fi_mem_pool = {
>         .block_alloc = 2*1024*1024 - sizeof(struct mp_block),
> @@ -2817,19 +2819,39 @@ static void parse_new_commit(const char *arg)
>         if (!committer)
>                 die("Expected committer but didn't get one");
>
> -       /* Process signatures (up to 2: one "sha1" and one "sha256") */
>         while (skip_prefix(command_buf.buf, "gpgsig ", &v)) {
>                 struct signature_data sig = { NULL, NULL, STRBUF_INIT };
>
> -               parse_one_signature(&sig, v);
> +               if (signed_commit_mode == SIGN_ABORT)
> +                       die(_("encountered signed commit; use "
> +                             "--signed-commits=<mode> to handle it"));
>
> -               if (!strcmp(sig.hash_algo, "sha1"))
> -                       store_signature(&sig_sha1, &sig, "SHA-1");
> -               else if (!strcmp(sig.hash_algo, "sha256"))
> -                       store_signature(&sig_sha256, &sig, "SHA-256");
> -               else
> -                       BUG("parse_one_signature() returned unknown hash algo");
> +               parse_one_signature(&sig, v);
>
> +               switch (signed_commit_mode) {
> +               case SIGN_ABORT:
> +                       BUG("SIGN_ABORT should be handled before calling parse_one_signature()");
> +                       break;
> +               case SIGN_WARN_VERBATIM:
> +                       warning(_("importing a commit signature verbatim"));
> +                       /* fallthru */
> +               case SIGN_VERBATIM:
> +                       if (!strcmp(sig.hash_algo, "sha1"))
> +                               store_signature(&sig_sha1, &sig, "SHA-1");
> +                       else if (!strcmp(sig.hash_algo, "sha256"))
> +                               store_signature(&sig_sha256, &sig, "SHA-256");
> +                       else
> +                               die(_("parse_one_signature() returned unknown hash algo"));
> +                       break;
> +               case SIGN_WARN_STRIP:
> +                       warning(_("stripping a commit signature"));
> +                       /* fallthru */
> +               case SIGN_STRIP:
> +                       /* Just discard signature data */
> +                       strbuf_release(&sig.data);
> +                       free(sig.hash_algo);
> +                       break;
> +               }
>                 read_next_command();
>         }
>
> @@ -3501,6 +3523,9 @@ static int parse_one_option(const char *option)
>                 option_active_branches(option);
>         } else if (skip_prefix(option, "export-pack-edges=", &option)) {
>                 option_export_pack_edges(option);
> +       } else if (skip_prefix(option, "signed-commits=", &option)) {
> +               if (parse_sign_mode(option, &signed_commit_mode))
> +                       usagef(_("unknown --signed-commits mode '%s'"), option);
>         } else if (!strcmp(option, "quiet")) {
>                 show_stats = 0;
>                 quiet = 1;
> diff --git a/t/meson.build b/t/meson.build
> index 82af229be3..08ad6938e2 100644
> --- a/t/meson.build
> +++ b/t/meson.build
> @@ -1032,6 +1032,7 @@ integration_tests = [
>    't9302-fast-import-unpack-limit.sh',
>    't9303-fast-import-compression.sh',
>    't9304-fast-import-marks.sh',
> +  't9305-fast-import-signatures.sh',
>    't9350-fast-export.sh',
>    't9351-fast-export-anonymize.sh',
>    't9400-git-cvsserver-server.sh',
> diff --git a/t/t9305-fast-import-signatures.sh b/t/t9305-fast-import-signatures.sh
> new file mode 100755
> index 0000000000..c2b4271658
> --- /dev/null
> +++ b/t/t9305-fast-import-signatures.sh
> @@ -0,0 +1,106 @@
> +#!/bin/sh
> +
> +test_description='git fast-import --signed-commits=<mode>'
> +
> +GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
> +
> +. ./test-lib.sh
> +. "$TEST_DIRECTORY/lib-gpg.sh"
> +
> +test_expect_success 'set up unsigned initial commit and import repo' '
> +       test_commit first &&
> +       git init new
> +'
> +
> +test_expect_success GPG 'set up OpenPGP signed commit' '
> +       git checkout -b openpgp-signing main &&
> +       echo "Content for OpenPGP signing." >file-sign &&
> +       git add file-sign &&
> +       git commit -S -m "OpenPGP signed commit" &&
> +       OPENPGP_SIGNING=$(git rev-parse --verify openpgp-signing)
> +'
> +
> +test_expect_success GPG 'import OpenPGP signature with --signed-commits=verbatim' '
> +       git fast-export --signed-commits=verbatim openpgp-signing >output &&
> +       git -C new fast-import --quiet --signed-commits=verbatim <output >log 2>&1 &&
> +       IMPORTED=$(git -C new rev-parse --verify refs/heads/openpgp-signing) &&
> +       test $OPENPGP_SIGNING = $IMPORTED &&
> +       test_must_be_empty log
> +'
> +
> +test_expect_success GPGSM 'set up X.509 signed commit' '
> +       git checkout -b x509-signing main &&
> +       test_config gpg.format x509 &&
> +       test_config user.signingkey $GIT_COMMITTER_EMAIL &&
> +       echo "Content for X.509 signing." >file-sign &&
> +       git add file-sign &&
> +       git commit -S -m "X.509 signed commit" &&
> +       X509_SIGNING=$(git rev-parse HEAD)
> +'
> +
> +test_expect_success GPGSM 'import X.509 signature fails with --signed-commits=abort' '
> +       git fast-export --signed-commits=verbatim x509-signing >output &&
> +       test_must_fail git -C new fast-import --quiet --signed-commits=abort <output
> +'
> +
> +test_expect_success GPGSM 'import X.509 signature with --signed-commits=warn-verbatim' '
> +       git -C new fast-import --quiet --signed-commits=warn-verbatim <output >log 2>&1 &&
> +       IMPORTED=$(git -C new rev-parse --verify refs/heads/x509-signing) &&
> +       test $X509_SIGNING = $IMPORTED &&
> +       test_grep "importing a commit signature" log
> +'
> +
> +test_expect_success GPGSSH 'set up SSH signed commit' '
> +       git checkout -b ssh-signing main &&
> +       test_config gpg.format ssh &&
> +       test_config user.signingkey "${GPGSSH_KEY_PRIMARY}" &&
> +       echo "Content for SSH signing." >file-sign &&
> +       git add file-sign &&
> +       git commit -S -m "SSH signed commit" &&
> +       SSH_SIGNING=$(git rev-parse HEAD)
> +'
> +
> +test_expect_success GPGSSH 'strip SSH signature with --signed-commits=strip' '
> +       git fast-export --signed-commits=verbatim ssh-signing >output &&
> +       git -C new fast-import --quiet --signed-commits=strip <output >log 2>&1 &&
> +       IMPORTED=$(git -C new rev-parse --verify refs/heads/ssh-signing) &&
> +       test $SSH_SIGNING != $IMPORTED &&
> +       git -C new cat-file commit "$IMPORTED" >actual &&
> +       test_grep ! -E "^gpgsig" actual &&
> +       test_must_be_empty log
> +'
> +
> +test_expect_success GPG 'setup a commit with dual OpenPGP signatures on its SHA-1 and SHA-256 formats' '
> +       # Create a signed SHA-256 commit
> +       git init --object-format=sha256 explicit-sha256 &&
> +       git -C explicit-sha256 config extensions.compatObjectFormat sha1 &&
> +       git -C explicit-sha256 checkout -b dual-signed &&
> +       test_commit -C explicit-sha256 A &&
> +       echo B >explicit-sha256/B &&
> +       git -C explicit-sha256 add B &&
> +       test_tick &&
> +       git -C explicit-sha256 commit -S -m "signed" B &&
> +       SHA256_B=$(git -C explicit-sha256 rev-parse dual-signed) &&
> +
> +       # Create the corresponding SHA-1 commit
> +       SHA1_B=$(git -C explicit-sha256 rev-parse --output-object-format=sha1 dual-signed) &&
> +
> +       # Check that the resulting SHA-1 commit has both signatures
> +       git -C explicit-sha256 cat-file -p $SHA1_B >out &&
> +       test_grep -E "^gpgsig " out &&
> +       test_grep -E "^gpgsig-sha256 " out
> +'
> +
> +test_expect_success GPG 'strip both OpenPGP signatures with --signed-commits=warn-strip' '
> +       git -C explicit-sha256 fast-export --signed-commits=verbatim dual-signed >output &&
> +       test_grep -E "^gpgsig sha1 openpgp" output &&
> +       test_grep -E "^gpgsig sha256 openpgp" output &&
> +       git -C new fast-import --quiet --signed-commits=warn-strip <output >log 2>&1 &&
> +       git -C new cat-file commit refs/heads/dual-signed >actual &&
> +       test_grep ! -E "^gpgsig " actual &&
> +       test_grep ! -E "^gpgsig-sha256 " actual &&
> +       test_grep "stripping a commit signature" log >out &&
> +       test_line_count = 2 out
> +'
> +
> +test_done
> --
> 2.51.0.195.gf8f8f06677
>





[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux