]> git.ipfire.org Git - thirdparty/git.git/commitdiff
fast-import: add 'abort-if-invalid' mode to '--signed-commits=<mode>'
authorJustin Tobler <jltobler@gmail.com>
Thu, 26 Mar 2026 19:14:11 +0000 (14:14 -0500)
committerJunio C Hamano <gitster@pobox.com>
Thu, 26 Mar 2026 19:42:57 +0000 (12:42 -0700)
The '--signed-commits=<mode>' option for git-fast-import(1) configures
how signed commits are handled when encountered. In cases where an
invalid commit signature is encountered, a user may wish to abort the
operation entirely. Introduce an 'abort-if-invalid' mode to do so.

Signed-off-by: Justin Tobler <jltobler@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-fast-import.adoc
builtin/fast-export.c
builtin/fast-import.c
gpg-interface.c
gpg-interface.h
t/t9305-fast-import-signatures.sh

index b3f42d46372a40ae81d7d0651f028de9243eb295..288f2b2a7ead7b56bd4ec5d1613edfad02496e49 100644 (file)
@@ -90,6 +90,8 @@ already trusted to run their own code.
   commit signatures and replaces invalid signatures with newly created ones.
   Valid signatures are left unchanged. If `<keyid>` is provided, that key is
   used for signing; otherwise the configured default signing key is used.
+* `abort-if-invalid` will make this program die when encountering a signed
+  commit that is unable to be verified.
 
 Options for Frontends
 ~~~~~~~~~~~~~~~~~~~~~
index a30fb90b6e0e96d2127bfba9a65cf39d37d6a9ba..2eb43a28da748e19758c987c4d9e9a2d4169923b 100644 (file)
@@ -65,7 +65,7 @@ static int parse_opt_sign_mode(const struct option *opt,
                return 0;
 
        if (parse_sign_mode(arg, val, NULL) || (*val == SIGN_STRIP_IF_INVALID) ||
-           (*val == SIGN_SIGN_IF_INVALID))
+           (*val == SIGN_SIGN_IF_INVALID) || (*val == SIGN_ABORT_IF_INVALID))
                return error(_("unknown %s mode: %s"), opt->long_name, arg);
 
        return 0;
index 9fc6c35b742871f5f025006e2a2dcbbfb18fd817..08ea27242d035c6d737529f6002e32c0b4b58f69 100644 (file)
@@ -2892,6 +2892,9 @@ static void handle_signature_if_invalid(struct strbuf *new_data,
        ret = verify_commit_buffer(tmp_buf.buf, tmp_buf.len, &signature_check);
 
        if (ret) {
+               if (mode == SIGN_ABORT_IF_INVALID)
+                       die(_("aborting due to invalid signature"));
+
                warn_invalid_signature(&signature_check, msg->buf, mode);
 
                if (mode == SIGN_SIGN_IF_INVALID) {
@@ -2983,6 +2986,7 @@ static void parse_new_commit(const char *arg)
                case SIGN_VERBATIM:
                case SIGN_STRIP_IF_INVALID:
                case SIGN_SIGN_IF_INVALID:
+               case SIGN_ABORT_IF_INVALID:
                        import_one_signature(&sig_sha1, &sig_sha256, v);
                        break;
 
@@ -3068,7 +3072,8 @@ static void parse_new_commit(const char *arg)
                        encoding);
 
        if ((signed_commit_mode == SIGN_STRIP_IF_INVALID ||
-            signed_commit_mode == SIGN_SIGN_IF_INVALID) &&
+            signed_commit_mode == SIGN_SIGN_IF_INVALID ||
+            signed_commit_mode == SIGN_ABORT_IF_INVALID) &&
            (sig_sha1.hash_algo || sig_sha256.hash_algo))
                handle_signature_if_invalid(&new_data, &sig_sha1, &sig_sha256,
                                            &msg, signed_commit_mode);
@@ -3115,6 +3120,9 @@ static void handle_tag_signature(struct strbuf *msg, const char *name)
        case SIGN_ABORT:
                die(_("encountered signed tag; use "
                      "--signed-tags=<mode> to handle it"));
+       case SIGN_ABORT_IF_INVALID:
+               die(_("'abort-if-invalid' is not a valid mode for "
+                     "git fast-import with --signed-tags=<mode>"));
        case SIGN_STRIP_IF_INVALID:
                die(_("'strip-if-invalid' is not a valid mode for "
                      "git fast-import with --signed-tags=<mode>"));
index d517425034ee6c85e5106c0941a6515231940f0a..dafd5371fa806d2d043d71b71938c23bc527e302 100644 (file)
@@ -1164,6 +1164,8 @@ int parse_sign_mode(const char *arg, enum sign_mode *mode, const char **keyid)
                *mode = SIGN_WARN_STRIP;
        } else if (!strcmp(arg, "strip")) {
                *mode = SIGN_STRIP;
+       } else if (!strcmp(arg, "abort-if-invalid")) {
+               *mode = SIGN_ABORT_IF_INVALID;
        } else if (!strcmp(arg, "strip-if-invalid")) {
                *mode = SIGN_STRIP_IF_INVALID;
        } else if (!strcmp(arg, "sign-if-invalid")) {
index a365586ce1e75548b267f53c65f888c6c879934e..3d95f5ec14bd0c6f93fd330bff875637d2afeb25 100644 (file)
@@ -115,6 +115,7 @@ void print_signature_buffer(const struct signature_check *sigc,
 /* Modes for --signed-tags=<mode> and --signed-commits=<mode> options. */
 enum sign_mode {
        SIGN_ABORT,
+       SIGN_ABORT_IF_INVALID,
        SIGN_WARN_VERBATIM,
        SIGN_VERBATIM,
        SIGN_WARN_STRIP,
index 18707b3f6c8b748e6863e69f6ca014c33cf566bf..5667693afd004ab8ba0eda2921e0e168fc2e10f2 100755 (executable)
@@ -103,7 +103,7 @@ test_expect_success RUST,GPG 'strip both OpenPGP signatures with --signed-commit
        test_line_count = 2 out
 '
 
-for mode in strip-if-invalid sign-if-invalid
+for mode in strip-if-invalid sign-if-invalid abort-if-invalid
 do
        test_expect_success GPG "import commit with no signature with --signed-commits=$mode" '
                git fast-export main >output &&
@@ -135,6 +135,14 @@ do
                # corresponding `data <length>` command would have to be changed too.
                sed "s/OpenPGP signed commit/OpenPGP forged commit/" output >modified &&
 
+               if test "$mode" = abort-if-invalid
+               then
+                       test_must_fail git -C new fast-import --quiet \
+                               --signed-commits=$mode <modified >log 2>&1 &&
+                       test_grep "aborting due to invalid signature" log &&
+                       return 0
+               fi &&
+
                git -C new fast-import --quiet --signed-commits=$mode <modified >log 2>&1 &&
 
                IMPORTED=$(git -C new rev-parse --verify refs/heads/openpgp-signing) &&