fast-export: --signed-commits is experimental

As the design of signature handling is still being discussed, it is likely that the data stream produced by the code in Git 2.50 would have to be changed in such a way that is not backward compatible. Mark the feature as experimental and discourge its use for now. Also flip the default on the generation side to "strip"; users of existing versions would not have passed --signed-commits=strip and will be broken by this change if the default is made to abort, and will be encouraged by the error message to produce data stream with future breakage guarantees by passing --signed-commits option. As we tone down the default behaviour, we no longer need the FAST_EXPORT_SIGNED_COMMITS_NOABORT environment variable, which was not discoverable enough. Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed May 28, 2025 at 10:29 UTC 0b4c6baa70033a221fdac2211548a9a6f78d3e42
5 files changed +16 -30
Documentation/RelNotes/2.50.0.adoc
+3 -1
@@ -100,7 +100,9 @@ Performance, Internal Implementation, Development Support etc.
100 * "git fsck" becomes more careful when checking the refs.
101
102 * "git fast-export | git fast-import" learns to deal with commit and
103 - tag objects with embedded signatures a bit better.
103 + tag objects with embedded signatures a bit better. This is highly
104 + experimental and the format of the data stream may change in the
105 + future without compatibility guarantees.
106
107 * The code paths to check whether a refname X is available (by seeing
108 if another ref X/Y exists, etc.) have been optimized.
Documentation/git-fast-export.adoc
+5 -7
@@ -46,14 +46,12 @@ resulting tag will have an invalid signature.
46
47 --signed-commits=(verbatim|warn-verbatim|warn-strip|strip|abort)::
48 Specify how to handle signed commits. Behaves exactly as
49 - '--signed-tags', but for commits. Default is 'abort'.
49 + '--signed-tags', but for commits. Default is 'strip', which
50 + is the same as how earlier versions of this command without
51 + this option behaved.
52 +
51 -Earlier versions this command that did not have '--signed-commits'
52 -behaved as if '--signed-commits=strip'. As an escape hatch for users
53 -of tools that call 'git fast-export' but do not yet support
54 -'--signed-commits', you may set the environment variable
55 -'FAST_EXPORT_SIGNED_COMMITS_NOABORT=1' in order to change the default
56 -from 'abort' to 'warn-strip'.
53 +NOTE: This is highly experimental and the format of the data stream may
54 +change in the future without compatibility guarantees.
55
56 --tag-of-filtered-object=(abort|drop|rewrite)::
57 Specify how to handle tags whose tagged object is filtered out.
Documentation/git-fast-import.adoc
+3
@@ -523,6 +523,9 @@ that signs the commit data.
523 Here <alg> specifies which hashing algorithm is used for this
524 signature, either `sha1` or `sha256`.
525
526 +NOTE: This is highly experimental and the format of the data stream may
527 +change in the future without compatibility guarantees.
528 +
529 `encoding`
530 ^^^^^^^^^^
531 The optional `encoding` command indicates the encoding of the commit
builtin/fast-export.c
+1 -6
@@ -39,7 +39,7 @@ enum sign_mode { SIGN_ABORT, SIGN_VERBATIM, SIGN_STRIP, SIGN_WARN_VERBATIM, SIGN
39
40 static int progress;
41 static enum sign_mode signed_tag_mode = SIGN_ABORT;
42 -static enum sign_mode signed_commit_mode = SIGN_ABORT;
42 +static enum sign_mode signed_commit_mode = SIGN_STRIP;
43 static enum tag_of_filtered_mode { TAG_FILTERING_ABORT, DROP, REWRITE } tag_of_filtered_mode = TAG_FILTERING_ABORT;
44 static enum reencode_mode { REENCODE_ABORT, REENCODE_YES, REENCODE_NO } reencode_mode = REENCODE_ABORT;
45 static int fake_missing_tagger;
@@ -1269,7 +1269,6 @@ int cmd_fast_export(int argc,
1269 const char *prefix,
1270 struct repository *repo UNUSED)
1271 {
1272 - const char *env_signed_commits_noabort;
1272 struct rev_info revs;
1273 struct commit *commit;
1274 char *export_filename = NULL,
@@ -1327,10 +1326,6 @@ int cmd_fast_export(int argc,
1326 if (argc == 1)
1327 usage_with_options (fast_export_usage, options);
1328
1330 - env_signed_commits_noabort = getenv("FAST_EXPORT_SIGNED_COMMITS_NOABORT");
1331 - if (env_signed_commits_noabort && *env_signed_commits_noabort)
1332 - signed_commit_mode = SIGN_WARN_STRIP;
1333 -
1329 /* we handle encodings */
1330 git_config(git_default_config, NULL);
1331
t/t9350-fast-export.sh
+4 -16
@@ -299,22 +299,10 @@ test_expect_success GPG 'set up signed commit' '
299
300 '
301
302 -test_expect_success GPG 'signed-commits default' '
303 -
304 - sane_unset FAST_EXPORT_SIGNED_COMMITS_NOABORT &&
305 - test_must_fail git fast-export --reencode=no commit-signing &&
306 -
307 - FAST_EXPORT_SIGNED_COMMITS_NOABORT=1 git fast-export --reencode=no commit-signing >output 2>err &&
308 - ! grep ^gpgsig output &&
309 - grep "^encoding ISO-8859-1" output &&
310 - test -s err &&
311 - sed "s/commit-signing/commit-strip-signing/" output | (
312 - cd new &&
313 - git fast-import &&
314 - STRIPPED=$(git rev-parse --verify refs/heads/commit-strip-signing) &&
315 - test $COMMIT_SIGNING != $STRIPPED
316 - )
317 -
302 +test_expect_success GPG 'signed-commits default is same as strip' '
303 + git fast-export --reencode=no commit-signing >out1 2>err &&
304 + git fast-export --reencode=no --signed-commits=strip commit-signing >out2 &&
305 + test_cmp out1 out2
306 '
307
308 test_expect_success GPG 'signed-commits=abort' '