[PATCH v2 0/2] fast-import: start controlling how commit signatures are handled

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

 



Tools like `git-filter-repo` should be able to control how commit
signatures are handled when regenerating repository content after it
has been filtered (see
https://github.com/newren/git-filter-repo/issues/139). For this
purpose, they need a way for `git fast-import` to control how commit
signatures are handled.

This small patch series starts to implement such a way by adding a new
`--signed-commits=<mode>` option to `git fast-import`.

For now this new option behaves in a very similar way as the option
with the same name that already exists in `git fast-export`.
Especially it supports exactly the same <mode>s and the same aliases
for these modes. For example "ignore" is a synonym for "verbatim".

In the future I want to implement new <mode>s like "strip-if-invalid",
"re-sign", "re-sign-if-invalid" that might be a bit more complex for
this option. But for now I prefer to start with the simple modes to
validate the general design of the new option.

In the future I also plan to add a similar `--signed-tags=<mode>` so
that the import of tags can also be controlled. But I prefer to
validate the general design of a single new option first.

In particular, I am interested in feedback about the following:

  - Should we keep "ignore" as a synonym for "verbatim" and "warn" as
    a synonym for "warn-verbatim"? My opinion is that they might be
    confusing, so we might want to remove them for `git fast-import`
    even if we keep them for `git fast-export`. The parsing code might
    be a bit more complex if we do that though, so for now I have kept
    the synonyms.

  - Are we still fine with most <mode>s having a "warn-*" variant
    (like the "warn-strip" variant of "strip" for example)? Or should
    we have a separate `--verbose` or maybe `--signed-commits-verbose`
    option dedicated to switching warnings on/off? I think it's good
    to decide about this before the number of <mode>s increases a lot
    with new <mode>s like "strip-if-invalid", "re-sign",
    "re-sign-if-invalid" and possibly others.

Changes since v1:
=================

Thanks to Junio and Patrick for reviewing V1.

In patch 1/2:

  - the commit message now says that a single option will be added in
    the following commit

  - instead of returning success in the `!parse_sign_mode(arg, val)`
    case, we return error in the `parse_sign_mode(arg, val)` case,

  - a '.' has been added at the end of a code comment.

In patch 2/2:

  - the import_signature() function has been removed and we just call
    parse_one_signature() in all cases except `SIGN_ABORT`, before
    handling the signature according to `signed_commit_mode`,

  - we now mark for translation all new strings that could be
    displayed to users,

  - usagef() is used instead of die() when the mode is unknown,

  - the warning for `warn-verbatim` has been improved,

  - the tests have been improved by using more idiomatic and
    simplified commands

CI tests:
=========

They have all passed. See:

https://github.com/chriscool/git/actions/runs/17672015528

range-diff vs V1:
=================

1:  7c8216a701 ! 1:  87149ae92d gpg-interface: refactor 'enum sign_mode' parsing
    @@ Commit message
         only command with '--signed-tags=<mode>' or '--signed-commits=<mode>'
         options.
     
    -    In a following commit, we are going to add such options to `git
    +    In a following commit, we are going to add a similar option to `git
         fast-import`, which will be simpler, easier and cleaner if we can reuse
         the 'enum sign_mode' defintion and parsing code.
     
    @@ builtin/fast-export.c: static struct hashmap anonymized_seeds;
     -	else if (!strcmp(arg, "strip"))
     -		*val = SIGN_STRIP;
     -	else
    --		return error("Unknown %s mode: %s", opt->long_name, arg);
    --	return 0;
     +
    -+	if (!parse_sign_mode(arg, val))
    -+		return 0;
    ++	if (parse_sign_mode(arg, val))
    + 		return error("Unknown %s mode: %s", opt->long_name, arg);
     +
    -+	return error("Unknown %s mode: %s", opt->long_name, arg);
    + 	return 0;
      }
      
    - static int parse_opt_tag_of_filtered_mode(const struct option *opt,
     
      ## gpg-interface.c ##
     @@ gpg-interface.c: static int sign_buffer_ssh(struct strbuf *buffer, struct strbuf *signature,
    @@ gpg-interface.h: int check_signature(struct signature_check *sigc,
      void print_signature_buffer(const struct signature_check *sigc,
      			    unsigned flags);
      
    -+/* Modes for --signed-tags=<mode> and --signed-commits=<mode> options */
    ++/* Modes for --signed-tags=<mode> and --signed-commits=<mode> options. */
     +enum sign_mode {
     +	SIGN_ABORT,
     +	SIGN_WARN_VERBATIM,
2:  0294f05ae6 ! 2:  e34f015aea fast-import: add '--signed-commits=<mode>' option
    @@ builtin/fast-import.c: static int global_argc;
      /* Memory pools */
      static struct mem_pool fi_mem_pool = {
      	.block_alloc = 2*1024*1024 - sizeof(struct mp_block),
    -@@ builtin/fast-import.c: static void store_signature(struct signature_data *stored_sig,
    - 	}
    - }
    - 
    -+/* Process signatures (up to 2: one "sha1" and one "sha256") */
    -+static void import_signature(struct signature_data *sig_sha1,
    -+			     struct signature_data *sig_sha256,
    -+			     const char *v)
    -+{
    -+	struct signature_data sig = { NULL, NULL, STRBUF_INIT };
    -+
    -+	parse_one_signature(&sig, v);
    -+
    -+	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");
    -+}
    -+
    - static void parse_new_commit(const char *arg)
    - {
    - 	static struct strbuf msg = STRBUF_INIT;
     @@ builtin/fast-import.c: 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 };
    --
    + 		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");
    --
    -+		struct strbuf data = STRBUF_INIT;
    ++		parse_one_signature(&sig, v);
    + 
     +		switch (signed_commit_mode) {
     +		case SIGN_ABORT:
    -+			die("encountered signed commit; use "
    -+			    "--signed-commits=<mode> to handle it");
    ++			BUG("SIGN_ABORT should be handled before calling parse_one_signature()");
    ++			break;
     +		case SIGN_WARN_VERBATIM:
    -+			warning("importing a commit signature");
    ++			warning(_("importing a commit signature verbatim"));
     +			/* fallthru */
     +		case SIGN_VERBATIM:
    -+			import_signature(&sig_sha1, &sig_sha256, v);
    ++			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");
    ++			warning(_("stripping a commit signature"));
     +			/* fallthru */
     +		case SIGN_STRIP:
    -+			/* Read signature data and discard it */
    -+			read_next_command();
    -+			parse_data(&data, 0, NULL);
    -+			strbuf_release(&data);
    ++			/* Just discard signature data */
    ++			strbuf_release(&sig.data);
    ++			free(sig.hash_algo);
     +			break;
     +		}
      		read_next_command();
    @@ builtin/fast-import.c: static int parse_one_option(const char *option)
      		option_export_pack_edges(option);
     +	} else if (skip_prefix(option, "signed-commits=", &option)) {
     +		if (parse_sign_mode(option, &signed_commit_mode))
    -+			die("unknown --signed-commits mode '%s'", option);
    ++			usagef(_("unknown --signed-commits mode '%s'"), option);
      	} else if (!strcmp(option, "quiet")) {
      		show_stats = 0;
      		quiet = 1;
    @@ t/t9305-fast-import-signatures.sh (new)
     +test_description='git fast-import --signed-commits=<mode>'
     +
     +GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
    -+export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
     +
     +. ./test-lib.sh
     +. "$TEST_DIRECTORY/lib-gpg.sh"
     +
     +test_expect_success 'set up unsigned initial commit and import repo' '
     +	test_commit first &&
    -+	mkdir new &&
    -+	git --git-dir=new/.git init
    ++	git init new
     +'
     +
     +test_expect_success GPG 'set up OpenPGP signed commit' '
    @@ t/t9305-fast-import-signatures.sh (new)
     +	SHA1_B=$(git -C explicit-sha256 rev-parse --output-object-format=sha1 dual-signed) &&
     +
     +	# Check that the resulting SHA-1 commit has both signatures
    -+	echo $SHA1_B | git -C explicit-sha256 cat-file --batch >out &&
    ++	git -C explicit-sha256 cat-file -p $SHA1_B >out &&
     +	test_grep -E "^gpgsig " out &&
     +	test_grep -E "^gpgsig-sha256 " out
     +'


Christian Couder (2):
  gpg-interface: refactor 'enum sign_mode' parsing
  fast-import: add '--signed-commits=<mode>' option

 Documentation/git-fast-import.adoc |   5 ++
 builtin/fast-export.c              |  19 ++----
 builtin/fast-import.c              |  41 ++++++++---
 gpg-interface.c                    |  17 +++++
 gpg-interface.h                    |  15 ++++
 t/meson.build                      |   1 +
 t/t9305-fast-import-signatures.sh  | 106 +++++++++++++++++++++++++++++
 7 files changed, 182 insertions(+), 22 deletions(-)
 create mode 100755 t/t9305-fast-import-signatures.sh

-- 
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