aboutsummaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
authorJustin Tobler <jltobler@gmail.com>2026-03-12 20:39:38 -0500
committerJunio C Hamano <gitster@pobox.com>2026-03-12 21:28:20 -0700
commitee66c793f84ef1c84ec3fe732bb26394ebefd257 (patch)
treef096ae01321a350041133d3156dd39d9db27ea3a /t
parent86ebf870b909a7f4707aa2601d290bc992d21a53 (diff)
downloadgit-ee66c793f84ef1c84ec3fe732bb26394ebefd257.tar.xz
fast-import: add mode to sign commits with invalid signatures
With git-fast-import(1), handling of signed commits is controlled via the `--signed-commits=<mode>` option. When an invalid signature is encountered, a user may want the option to sign the commit again as opposed to just stripping the signature. To facilitate this, introduce a "sign-if-invalid" mode for the `--signed-commits` option. Optionally, a key ID may be explicitly provided in the form `sign-if-invalid[=<keyid>]` to specify which signing key should be used when signing invalid commit signatures. Note that to properly support interoperability mode when signing commit signatures, the commit buffer must be created in both the repository and compatability object formats to generate the appropriate signatures accordingly. As currently implemented, the commit buffer for the compatability object format is not reconstructed and thus signing commits in interoperability mode is not yet supported. Support may be added in the future. Signed-off-by: Justin Tobler <jltobler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 't')
-rwxr-xr-xt/t9305-fast-import-signatures.sh134
1 files changed, 87 insertions, 47 deletions
diff --git a/t/t9305-fast-import-signatures.sh b/t/t9305-fast-import-signatures.sh
index 022dae02e4..ac4228127a 100755
--- a/t/t9305-fast-import-signatures.sh
+++ b/t/t9305-fast-import-signatures.sh
@@ -103,71 +103,111 @@ test_expect_success GPG 'strip both OpenPGP signatures with --signed-commits=war
test_line_count = 2 out
'
-test_expect_success GPG 'import commit with no signature with --signed-commits=strip-if-invalid' '
- git fast-export main >output &&
- git -C new fast-import --quiet --signed-commits=strip-if-invalid <output >log 2>&1 &&
- test_must_be_empty log
-'
+for mode in strip-if-invalid sign-if-invalid
+do
+ test_expect_success GPG "import commit with no signature with --signed-commits=$mode" '
+ git fast-export main >output &&
+ git -C new fast-import --quiet --signed-commits=$mode <output >log 2>&1 &&
+ test_must_be_empty log
+ '
-test_expect_success GPG 'keep valid OpenPGP signature with --signed-commits=strip-if-invalid' '
- rm -rf new &&
- git init new &&
+ test_expect_success GPG "keep valid OpenPGP signature with --signed-commits=$mode" '
+ rm -rf new &&
+ git init new &&
- git fast-export --signed-commits=verbatim openpgp-signing >output &&
- git -C new fast-import --quiet --signed-commits=strip-if-invalid <output >log 2>&1 &&
- IMPORTED=$(git -C new rev-parse --verify refs/heads/openpgp-signing) &&
- test $OPENPGP_SIGNING = $IMPORTED &&
- git -C new cat-file commit "$IMPORTED" >actual &&
- test_grep -E "^gpgsig(-sha256)? " actual &&
- test_must_be_empty log
-'
+ git fast-export --signed-commits=verbatim openpgp-signing >output &&
+ git -C new fast-import --quiet --signed-commits=$mode <output >log 2>&1 &&
+ IMPORTED=$(git -C new rev-parse --verify refs/heads/openpgp-signing) &&
+ test $OPENPGP_SIGNING = $IMPORTED &&
+ git -C new cat-file commit "$IMPORTED" >actual &&
+ test_grep -E "^gpgsig(-sha256)? " actual &&
+ test_must_be_empty log
+ '
-test_expect_success GPG 'strip signature invalidated by message change with --signed-commits=strip-if-invalid' '
- rm -rf new &&
- git init new &&
+ test_expect_success GPG "handle signature invalidated by message change with --signed-commits=$mode" '
+ rm -rf new &&
+ git init new &&
- git fast-export --signed-commits=verbatim openpgp-signing >output &&
+ git fast-export --signed-commits=verbatim openpgp-signing >output &&
- # Change the commit message, which invalidates the signature.
- # The commit message length should not change though, otherwise the
- # corresponding `data <length>` command would have to be changed too.
- sed "s/OpenPGP signed commit/OpenPGP forged commit/" output >modified &&
+ # Change the commit message, which invalidates the signature.
+ # The commit message length should not change though, otherwise the
+ # corresponding `data <length>` command would have to be changed too.
+ sed "s/OpenPGP signed commit/OpenPGP forged commit/" output >modified &&
- git -C new fast-import --quiet --signed-commits=strip-if-invalid <modified >log 2>&1 &&
+ git -C new fast-import --quiet --signed-commits=$mode <modified >log 2>&1 &&
- IMPORTED=$(git -C new rev-parse --verify refs/heads/openpgp-signing) &&
- test $OPENPGP_SIGNING != $IMPORTED &&
- git -C new cat-file commit "$IMPORTED" >actual &&
- test_grep ! -E "^gpgsig" actual &&
- test_grep "stripping invalid signature" log
-'
+ IMPORTED=$(git -C new rev-parse --verify refs/heads/openpgp-signing) &&
+ test $OPENPGP_SIGNING != $IMPORTED &&
+ git -C new cat-file commit "$IMPORTED" >actual &&
-test_expect_success GPGSM 'keep valid X.509 signature with --signed-commits=strip-if-invalid' '
- rm -rf new &&
- git init new &&
+ if test "$mode" = strip-if-invalid
+ then
+ test_grep "stripping invalid signature" log &&
+ test_grep ! -E "^gpgsig" actual
+ else
+ test_grep "replacing invalid signature" log &&
+ test_grep -E "^gpgsig(-sha256)? " actual &&
+ git -C new verify-commit "$IMPORTED"
+ fi
+ '
- git fast-export --signed-commits=verbatim x509-signing >output &&
- git -C new fast-import --quiet --signed-commits=strip-if-invalid <output >log 2>&1 &&
- IMPORTED=$(git -C new rev-parse --verify refs/heads/x509-signing) &&
- test $X509_SIGNING = $IMPORTED &&
- git -C new cat-file commit "$IMPORTED" >actual &&
- test_grep -E "^gpgsig(-sha256)? " actual &&
- test_must_be_empty log
-'
+ test_expect_success GPGSM "keep valid X.509 signature with --signed-commits=$mode" '
+ rm -rf new &&
+ git init new &&
+
+ git fast-export --signed-commits=verbatim x509-signing >output &&
+ git -C new fast-import --quiet --signed-commits=$mode <output >log 2>&1 &&
+ IMPORTED=$(git -C new rev-parse --verify refs/heads/x509-signing) &&
+ test $X509_SIGNING = $IMPORTED &&
+ git -C new cat-file commit "$IMPORTED" >actual &&
+ test_grep -E "^gpgsig(-sha256)? " actual &&
+ test_must_be_empty log
+ '
+
+ test_expect_success GPGSSH "keep valid SSH signature with --signed-commits=$mode" '
+ rm -rf new &&
+ git init new &&
+
+ test_config -C new gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" &&
-test_expect_success GPGSSH 'keep valid SSH signature with --signed-commits=strip-if-invalid' '
+ git fast-export --signed-commits=verbatim ssh-signing >output &&
+ git -C new fast-import --quiet --signed-commits=$mode <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(-sha256)? " actual &&
+ test_must_be_empty log
+ '
+done
+
+test_expect_success GPGSSH "sign invalid commit with explicit keyid" '
rm -rf new &&
git init new &&
+ git fast-export --signed-commits=verbatim ssh-signing >output &&
+
+ # Change the commit message, which invalidates the signature.
+ # The commit message length should not change though, otherwise the
+ # corresponding `data <length>` command would have to be changed too.
+ sed "s/SSH signed commit/SSH forged commit/" output >modified &&
+
+ # Configure the target repository with an invalid default signing key.
+ test_config -C new user.signingkey "not-a-real-key-id" &&
+ test_config -C new gpg.format ssh &&
test_config -C new gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" &&
+ test_must_fail git -C new fast-import --quiet \
+ --signed-commits=sign-if-invalid <modified >/dev/null 2>&1 &&
+
+ # Import using explicitly provided signing key.
+ git -C new fast-import --quiet \
+ --signed-commits=sign-if-invalid="${GPGSSH_KEY_PRIMARY}" <modified &&
- git fast-export --signed-commits=verbatim ssh-signing >output &&
- git -C new fast-import --quiet --signed-commits=strip-if-invalid <output >log 2>&1 &&
IMPORTED=$(git -C new rev-parse --verify refs/heads/ssh-signing) &&
- test $SSH_SIGNING = $IMPORTED &&
+ test $SSH_SIGNING != $IMPORTED &&
git -C new cat-file commit "$IMPORTED" >actual &&
test_grep -E "^gpgsig(-sha256)? " actual &&
- test_must_be_empty log
+ git -C new verify-commit "$IMPORTED"
'
test_done