git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v3 3/3] fast-export, fast-import: implement signed-commits

From
Junio C Hamano <gitster@pobox.com>
Date
Apr 28, 2021, 04:02 UTC
Message-ID
<xmqqfszbcazc.fsf@gitster.g>
In-Reply-To
<20210423164118.693197-4-lukeshu@lukeshu.com>
Luke Shumaker <lukeshu@lukeshu.com> writes:
> From: Luke Shumaker <lukeshu@datawire.io>
>
> fast-export has an existing --signed-tags= flag that controls how to

Don't call a command line option "a flag", especially when it is not a boolean.

"has an existing" feels redundantly repeticious.
Show 9 quoted lines
> handle tag signatures.  However, there is no equivalent for commit
> signatures; it just silently strips the signature out of the commit
> (analogously to --signed-tags=strip).
>
> While signatures are generally problematic for fast-export/fast-import
> (because hashes are likely to change), if they're going to support tag
> signatures, there's no reason to not also support commit signatures.
>
> So, implement signed-commits.

That's misleading. You are not inventing "git commit --signed" here.

    So implement `--signed-commits=<disposition>` that mirrors the
    `--signed-tags=<disposition>` option.
> +--signed-commits=(verbatim|warn-verbatim|warn-strip|strip|abort)::
> +	Specify how to handle signed commits.  Behaves exactly as
> +	--signed-tags (but for commits), except that the default is
> +	'warn-strip' rather than 'abort'.

Why deliberate inconsistency? I am not sure "historically we did a wrong thing" is a good reason (if we view that silently stripping was a disservice to the users, aborting would be a bugfix).

Show 16 quoted lines
> diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt
> index 458af0a2d6..4955c94305 100644
> --- a/Documentation/git-fast-import.txt
> +++ b/Documentation/git-fast-import.txt
> diff --git a/builtin/fast-export.c b/builtin/fast-export.c
> index d121dd2ee6..2b1101d104 100644
> --- a/builtin/fast-export.c
> +++ b/builtin/fast-export.c
> @@ -30,8 +30,11 @@ static const char *fast_export_usage[] = {
>  	NULL
>  };
>  
> +enum sign_mode { SIGN_ABORT, SIGN_VERBATIM, SIGN_STRIP, SIGN_VERBATIM_WARN, SIGN_STRIP_WARN };
> +
>  static int progress;
> -static enum { SIGNED_TAG_ABORT, VERBATIM, WARN, WARN_STRIP, STRIP } signed_tag_mode = SIGNED_TAG_ABORT;

Giving the enum values consistent prefix "SIGN_" is a great improvement. On the other hand, swapping the word order, e.g. WARN_STRIP to SIGN_STRIP_WARN, is unwarranted.

> +static enum sign_mode signed_tag_mode = SIGN_ABORT;
> +static enum sign_mode signed_commit_mode = SIGN_STRIP_WARN;

I think it is safer to abort for both and sell it as a bugfix ("silently stripping commit signatures was wrong. we should abort the same way by default when encountering a signed tag").

Show 14 quoted lines
> -static int parse_opt_signed_tag_mode(const struct option *opt,
> +static int parse_opt_sign_mode(const struct option *opt,
>  				     const char *arg, int unset)
>  {
> -	if (unset || !strcmp(arg, "abort"))
> -		signed_tag_mode = SIGNED_TAG_ABORT;
> +	enum sign_mode *valptr = opt->value;
> +	if (unset)
> +		return 0;
> +	else if (!strcmp(arg, "abort"))
> +		*valptr = SIGN_ABORT;
>  	else if (!strcmp(arg, "verbatim") || !strcmp(arg, "ignore"))
> -		signed_tag_mode = VERBATIM;
> +		*valptr = SIGN_VERBATIM;

Interesting and not a new issue at all, but "ignore" is a confusing symonym to "verbatim"---I would have expected "ignore", if accepted as a choice, would strip the signature. Not documenting it is probably good, but perhaps we would eventually remove it?

Show 5 quoted lines
> @@ -499,6 +505,60 @@ static void show_filemodify(struct diff_queue_struct *q,
>  	}
>  }
>  
> +static const char *find_signature(const char *begin, const char *end, const char *key)

This is only for in-header signature used in commit objects, and not for the traditional "attached to the end" signature used in tag objects, right?

The name of this function should be designed to answer the above question, but find_signature() that does not say either commit or tag implies it can accept both (which would be a horrible interface, though). If this is only for in-header signature, rename it to make sure that the fact is readable out of its name?

Show 8 quoted lines
> +{
> +	static struct strbuf needle = STRBUF_INIT;
> +	char *bod, *eod, *eol;
> +
> +	strbuf_reset(&needle);
> +	strbuf_addch(&needle, '\n');
> +	strbuf_addstr(&needle, key);
> +	strbuf_addch(&needle, ' ');
strbuf_addf(), perhaps?
Show 9 quoted lines
> +	bod = memmem(begin, end ? end - begin : strlen(begin),
> +		     needle.buf, needle.len);
> +	if (!bod)
> +		return NULL;
> +	bod += needle.len;
> +
> +	/*
> +	 * In the commit object, multi-line header values are stored
> +	 * by prefixing continuation lines begin with a space.  So
"by prefixig continuation lines with a space"
Show 11 quoted lines
> +	 * within the commit object, it looks like
> +	 *
> +	 *     "gpgsig -----BEGIN PGP SIGNATURE-----\n"
> +	 *     " Version: GnuPG v1.4.5 (GNU/Linux)\n"
> +	 *     " \n"
> +	 *     " base64_pem_here\n"
> +	 *     " -----END PGP SIGNATURE-----\n"
> +	 *
> +	 * So we need to look for the first '\n' that *isn't* followed
> +	 * by a ' ' (or the first '\0', if no such '\n' exists).
> +	 */
> +	eod = strchrnul(bod, '\n');
> +	while (eod[0] == '\n' && eod[1] == ' ') {
> +		eod = strchrnul(eod+1, '\n');
> +	}

SP on both sides of '+'; no {} around a block that consists of a single statement.

> +	*eod = '\0';

The begin and end pointers pointed to a piece of memory that is supposed to be read-only, but this pointer points into that region of memory and then updates a byte? The function signature is misleading---if you intend to muck with the string, accept them as mutable pointers.

Better yet, don't butcher the region of memory pointed by the "message" variable the caller uses to keep reading from the remainder of the commit object buffer with this and memmove() below. Perhaps have the caller pass a strbuf to fill in the signature found by this helper as another parameter, and then return a bool "Yes, I found a sig" as its return value?

Show 15 quoted lines
> +
> +	/*
> +	 * We now have the value as it's stored in the commit object.
> +	 * However, we want the raw value; we want to return
> +	 *
> +	 *     "-----BEGIN PGP SIGNATURE-----\n"
> +	 *     "Version: GnuPG v1.4.5 (GNU/Linux)\n"
> +	 *     "\n"
> +	 *     "base64_pem_here\n"
> +	 *     "-----END PGP SIGNATURE-----\n"
> +	 *
> +	 * So now we need to strip out all of those extra spaces.
> +	 */
> +	while ((eol = strstr(bod, "\n ")))
> +		memmove(eol+1, eol+2, strlen(eol+1));

Besides, this is O(n^2), isn't it, as it always starts scanning at bod while there are lines in the signature block to be processed, it needs to skip over the lines that the loop already has processed.

I'd stop here for now, as there should be enough to polish.
Thanks.
Previous: Luke ShumakerNext: Luke Shumaker
Message 15 of 60 in “fast-export, fast-import: implement signed-commits”
  1. 0/3 fast-export, fast-import: implement signed-commitsLuke Shumaker, Apr 22, 2021
  2. 1/3 git-fast-import.txt: add missing LF in the BNFLuke Shumaker, Apr 22, 2021
  3. 2/3 fast-export: rename --signed-tags='warn' to 'warn-verbatim'Luke Shumaker, Apr 22, 2021
  4. Eric SunshineApr 22, 2021
  5. Luke ShumakerApr 22, 2021
  6. Luke ShumakerApr 22, 2021
  7. 3/3 fast-export, fast-import: implement signed-commitsLuke Shumaker, Apr 22, 2021
  8. 0/3 fast-export, fast-import: implement signed-commitsLuke Shumaker, Apr 23, 2021
  9. 1/3 git-fast-import.txt: add missing LF in the BNFLuke Shumaker, Apr 23, 2021
  10. 2/3 fast-export: rename --signed-tags='warn' to 'warn-verbatim'Luke Shumaker, Apr 23, 2021
  11. Junio C HamanoApr 28, 2021
  12. Luke ShumakerApr 29, 2021
  13. Junio C HamanoApr 30, 2021
  14. 3/3 fast-export, fast-import: implement signed-commitsLuke Shumaker, Apr 23, 2021
  15. Junio C HamanoApr 28, 2021
  16. Luke ShumakerApr 29, 2021
  17. Elijah NewrenApr 29, 2021
  18. Junio C HamanoApr 29, 2021
  19. Elijah NewrenApr 30, 2021
  20. Junio C HamanoApr 30, 2021
  21. Luke ShumakerApr 30, 2021
  22. Luke ShumakerApr 30, 2021
  23. Elijah NewrenApr 30, 2021
  24. Luke ShumakerApr 30, 2021
  25. 0/5 fast-export, fast-import: add support for signed-commitsLuke Shumaker, Apr 30, 2021
  26. 1/5 git-fast-import.txt: add missing LF in the BNFLuke Shumaker, Apr 30, 2021
  27. 2/5 fast-export: rename --signed-tags='warn' to 'warn-verbatim'Luke Shumaker, Apr 30, 2021
  28. 3/5 git-fast-export.txt: clarify why 'verbatim' may not be a good ideaLuke Shumaker, Apr 30, 2021
  29. 4/5 fast-export: do not modify memory from get_commit_bufferLuke Shumaker, Apr 30, 2021
  30. Junio C HamanoMay 3, 2021
  31. 5/5 fast-export, fast-import: add support for signed-commitsLuke Shumaker, Apr 30, 2021
  32. Junio C HamanoMay 3, 2021
  33. 0/6 fast-export, fast-import: add support for signed-commitsChristian Couder, Feb 24, 2025
  34. 1/6 git-fast-import.adoc: add missing LF in the BNFChristian Couder, Feb 24, 2025
  35. 2/6 fast-export: fix missing whitespace after switchChristian Couder, Feb 24, 2025
  36. 3/6 fast-export: rename --signed-tags='warn' to 'warn-verbatim'Christian Couder, Feb 24, 2025
  37. 4/6 git-fast-export.txt: clarify why 'verbatim' may not be a good ideaChristian Couder, Feb 24, 2025
  38. Elijah NewrenFeb 24, 2025
  39. Christian CouderMar 10, 2025
  40. 5/6 fast-export: do not modify memory from get_commit_bufferChristian Couder, Feb 24, 2025
  41. 6/6 fast-export, fast-import: add support for signed-commitsChristian Couder, Feb 24, 2025
  42. Elijah NewrenFeb 25, 2025
  43. Junio C HamanoFeb 25, 2025
  44. Christian CouderMar 10, 2025
  45. Junio C HamanoFeb 24, 2025
  46. Elijah NewrenFeb 25, 2025
  47. Patrick SteinhardtFeb 25, 2025
  48. Elijah NewrenFeb 25, 2025
  49. Junio C HamanoFeb 25, 2025
  50. Christian CouderMar 10, 2025
  51. Phillip WoodFeb 25, 2025
  52. Christian CouderMar 10, 2025
  53. 0/6 fast-export, fast-import: add support for signed-commitsChristian Couder, Mar 10, 2025
  54. 1/6 git-fast-import.adoc: add missing LF in the BNFChristian Couder, Mar 10, 2025
  55. 2/6 fast-export: fix missing whitespace after switchChristian Couder, Mar 10, 2025
  56. 3/6 fast-export: rename --signed-tags='warn' to 'warn-verbatim'Christian Couder, Mar 10, 2025
  57. 4/6 git-fast-export.adoc: clarify why 'verbatim' may not be a good ideaChristian Couder, Mar 10, 2025
  58. 5/6 fast-export: do not modify memory from get_commit_bufferChristian Couder, Mar 10, 2025
  59. 6/6 fast-export, fast-import: add support for signed-commitsChristian Couder, Mar 10, 2025
  60. Elijah NewrenMar 10, 2025

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.