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

Re: [PATCH v6 02/10] replace: add --graft option

From
Junio C Hamano <gitster@pobox.com>
Date
Jul 9, 2014, 14:59 UTC
Message-ID
<xmqqsima7f3r.fsf@gitster.dls.corp.google.com>
In-Reply-To
<20140707063540.3708.51047.chriscool@tuxfamily.org>
Christian Couder <chriscool@tuxfamily.org> writes:
Show 12 quoted lines
> The usage string for this option is:
>
> git replace [-f] --graft <commit> [<parent>...]
>
> First we create a new commit that is the same as <commit>
> except that its parents are [<parents>...]
>
> Then we create a replace ref that replace <commit> with
> the commit we just created.
>
> With this new option, it should be straightforward to
> convert grafts to replace refs.
Sensible.
Show 39 quoted lines
>
> Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
> Signed-off-by: Junio C Hamano <gitster@pobox.com>
> ---
>  builtin/replace.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 73 insertions(+), 1 deletion(-)
>
> diff --git a/builtin/replace.c b/builtin/replace.c
> index 1bb491d..ad47237 100644
> --- a/builtin/replace.c
> +++ b/builtin/replace.c
> @@ -17,6 +17,7 @@
>  static const char * const git_replace_usage[] = {
>  	N_("git replace [-f] <object> <replacement>"),
>  	N_("git replace [-f] --edit <object>"),
> +	N_("git replace [-f] --graft <commit> [<parent>...]"),
>  	N_("git replace -d <object>..."),
>  	N_("git replace [--format=<format>] [-l [<pattern>]]"),
>  	NULL
> @@ -294,6 +295,66 @@ static int edit_and_replace(const char *object_ref, int force)
>  	return replace_object_sha1(object_ref, old, "replacement", new, force);
>  }
>  
> +static void replace_parents(struct strbuf *buf, int argc, const char **argv)
> +{
> +	struct strbuf new_parents = STRBUF_INIT;
> +	const char *parent_start, *parent_end;
> +	int i;
> +
> +	/* find existing parents */
> +	parent_start = buf->buf;
> +	parent_start += 46; /* "tree " + "hex sha1" + "\n" */
> +	parent_end = parent_start;
> +
> +	while (starts_with(parent_end, "parent "))
> +		parent_end += 48; /* "parent " + "hex sha1" + "\n" */
> +
> +	/* prepare new parents */
> +	for (i = 1; i < argc; i++) {

It looks somewhat strange that both replace_parents() and create_graft() take familiar-looking <argc, argv> pair, but one ignores argv[0] and uses the remainder and the other uses argv[0]. Shouldn't this function consume argv[] starting from [0] for consistency? You'd obviously need to update the caller to adjust the arguments it gives to this function.

Show 15 quoted lines
> +static int create_graft(int argc, const char **argv, int force)
> +{
> +	unsigned char old[20], new[20];
> +	const char *old_ref = argv[0];
> +...
> +
> +	replace_parents(&buf, argc, argv);
> +
> +	if (write_sha1_file(buf.buf, buf.len, commit_type, new))
> +		die(_("could not write replacement commit for: '%s'"), old_ref);
> +
> +	strbuf_release(&buf);
> +
> +	if (!hashcmp(old, new))
> +		return error("new commit is the same as the old one: '%s'", sha1_to_hex(old));

Is this really an error? It may be a warning-worthy situation for a user or a script to end up doing a no-op graft, e.g.

	git replace --graft HEAD HEAD^

but I wonder if it is more convenient to signal an error (like this patch does) or just ignore the request and return without adding the replace ref.

Other than these two points, looks good to me.
Thanks.
Previous: Christian CouderNext: Christian Couder
Message 4 of 26 in “Add --graft option to git replace”
  1. 00/10 Add --graft option to git replaceChristian Couder, Jul 7, 2014
  2. 01/10 replace: cleanup redirection style in testsChristian Couder, Jul 7, 2014
  3. 02/10 replace: add --graft optionChristian Couder, Jul 7, 2014
  4. Junio C HamanoJul 9, 2014
  5. Christian CouderJul 10, 2014
  6. Junio C HamanoJul 10, 2014
  7. Junio C HamanoJul 10, 2014
  8. Christian CouderJul 11, 2014
  9. Junio C HamanoJul 11, 2014
  10. Christian CouderJul 11, 2014
  11. Junio C HamanoJul 11, 2014
  12. Jeff KingJul 11, 2014
  13. 03/10 replace: add test for --graftChristian Couder, Jul 7, 2014
  14. Junio C HamanoJul 7, 2014
  15. Christian CouderJul 8, 2014
  16. 04/10 Documentation: replace: add --graft optionChristian Couder, Jul 7, 2014
  17. 05/10 contrib: add convert-grafts-to-replace-refs.shChristian Couder, Jul 7, 2014
  18. 06/10 replace: remove signature when using --graftChristian Couder, Jul 7, 2014
  19. 07/10 replace: add test for --graft with signed commitChristian Couder, Jul 7, 2014
  20. 08/10 commit: add for_each_mergetag()Christian Couder, Jul 7, 2014
  21. Junio C HamanoJul 7, 2014
  22. Christian CouderJul 8, 2014
  23. 09/10 replace: check mergetags when using --graftChristian Couder, Jul 7, 2014
  24. Junio C HamanoJul 7, 2014
  25. Christian CouderJul 8, 2014
  26. 10/10 replace: add test for --graft with a mergetagChristian Couder, Jul 7, 2014

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.