All of lore.kernel.org
 help / color / mirror / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: Alban Gruin <alban.gruin@gmail.com>
Cc: git@vger.kernel.org, Stefan Beller <sbeller@google.com>,
	Christian Couder <christian.couder@gmail.com>,
	Pratik Karki <predatoramigo@gmail.com>,
	Johannes Schindelin <Johannes.Schindelin@gmx.de>,
	phillip.wood@dunelm.org.uk, Elijah Newren <newren@gmail.com>
Subject: Re: [GSoC][PATCH v4 2/3] rebase -i: rewrite checkout_onto() in C
Date: Tue, 26 Jun 2018 10:35:00 -0700	[thread overview]
Message-ID: <xmqqsh59lad7.fsf@gitster-ct.c.googlers.com> (raw)
In-Reply-To: <20180625134419.18435-3-alban.gruin@gmail.com> (Alban Gruin's message of "Mon, 25 Jun 2018 15:44:18 +0200")

Alban Gruin <alban.gruin@gmail.com> writes:

> This rewrites checkout_onto() from shell to C. The new version is called
> detach_onto(), given its role.

The name, given its role, may be good, but is the implementtaion
robust enough to fulfill the promise its name gives?

>  	git rebase--helper --check-todo-list || {
>  		ret=$?
> -		checkout_onto
> +		git rebase--helper --detach-onto "$onto_name" "$onto" \
> +		    "$orig_head" ${verbose:+--verbose}

Here, $onto_name is what the end-user gave us (e.g. it is
"master..." in "git rebase --onto=master... base"), while $onto is a
40-hex object name of the commit.  $orig_head is also a 40-hex
object name.

And this call shows how the above shell scriptlet calls into the
detach_onto() thing ...

> +	if (command == DETACH_ONTO && argc == 4)
> +		return !!detach_onto(&opts, argv[1], argv[2], argv[3], verbose);

... which is defined like so:

> +int detach_onto(struct replay_opts *opts,
> +		const char *onto_name, const char *onto,
> +		const char *orig_head, unsigned verbose)
> +{
> +	struct object_id oid;
> +	const char *action = reflog_message(opts, "start", "checkout %s", onto_name);
> +
> +	if (get_oid(orig_head, &oid))
> +		return error(_("%s: not a valid OID"), orig_head);

Which means that this can be more strict to use get_oid_hex() to
catch possible mistakes in the caller.

> +	if (run_git_checkout(opts, onto, verbose, action)) {

And this could be a bit problematic, as we can see below how the
"checkout" thing does not guarantee "detaching" at all ...

> +		apply_autostash(opts);
> +		sequencer_remove_state(opts);
> +		return error(_("could not detach HEAD"));
> +	}
> +
> +	return update_ref(NULL, "ORIG_HEAD", &oid, NULL, 0, UPDATE_REFS_MSG_ON_ERR);
> +}
> +

... which can be seen here ...

> +static int run_git_checkout(struct replay_opts *opts, const char *commit,
> +				int verbose, const char *action)
> +{
> +	struct child_process cmd = CHILD_PROCESS_INIT;
> +
> +	cmd.git_cmd = 1;
> +
> +	argv_array_push(&cmd.args, "checkout");
> +	argv_array_push(&cmd.args, commit);
> +	argv_array_pushf(&cmd.env_array, GIT_REFLOG_ACTION "=%s", action);
> +
> +	if (verbose)
> +		return run_command(&cmd);
> +	else
> +		return run_command_silent_on_success(&cmd);
> +}

This drives the external command "git checkout" with _any_ string
the caller passes in "commit".  If the variable happens to have
'master', for example, it would be "git checkout master" and if you
have a branch with that name, it will not detach but check out the
branch to build on it.  It is a caller's responsibility to give a
suitable "commit" if it wants to use this helper to detach.

So perhaps the caller of this function in detach_onto() should pass
"%s^0" or even do something like

	struct object_id onto_oid;
	char onto_hex[GIT_MAX_HEXSZ + 1];

	if (get_oid(onto, &onto_oid) || oid_to_hex_r(onto_hex, &onto_oid))
		return error(...);
	if (run_git_checkout(opts, onto_hex, verbose, action)) {
		...

to ensure that it keeps the promise its name gives.

I can hear "Oh, but it is a bug in the caller to give anything that
won't result in detaching in 'onto'" but that is not a valid excuse,
given that this _public_ function is called "detach_onto".  Making
sure detachment happens is its responsibility, not its callers'.

Or we could do a cop-out alternative of commenting the function in *.h
file to say "onto must be given as 40-hex", with a code to make sure
the caller really gave us a 40-hex and not a branch name.  That is a
less ideal but probably acceptable alternative.

>  static const char rescheduled_advice[] =
>  N_("Could not execute the todo command\n"
>  "\n"
> diff --git a/sequencer.h b/sequencer.h
> index 35730b13e..9f0ac5e75 100644
> --- a/sequencer.h
> +++ b/sequencer.h
> @@ -100,6 +100,10 @@ int update_head_with_reflog(const struct commit *old_head,
>  void commit_post_rewrite(const struct commit *current_head,
>  			 const struct object_id *new_head);
>  
> +int detach_onto(struct replay_opts *opts,
> +		const char *onto_name, const char *onto,
> +		const char *orig_head, unsigned verbose);
> +
>  #define SUMMARY_INITIAL_COMMIT   (1 << 0)
>  #define SUMMARY_SHOW_AUTHOR_DATE (1 << 1)
>  void print_commit_summary(const char *prefix, const struct object_id *oid,

  reply	other threads:[~2018-06-26 17:35 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-18 13:18 [GSoC][PATCH 0/3] rebase -i: rewrite reflog operations in C Alban Gruin
2018-06-18 13:18 ` [GSoC][PATCH 1/3] sequencer: add a new function to silence a command, except if it fails Alban Gruin
2018-06-18 15:26   ` Phillip Wood
2018-06-18 16:46     ` Alban Gruin
2018-06-18 16:26   ` Christian Couder
2018-06-18 17:05     ` Alban Gruin
2018-06-18 13:18 ` [GSoC][PATCH 2/3] rebase -i: rewrite setup_reflog_action() in C Alban Gruin
2018-06-18 15:34   ` Phillip Wood
2018-06-18 17:04     ` Alban Gruin
2018-06-18 22:01   ` Stefan Beller
2018-06-19  6:51     ` Johannes Schindelin
2018-06-18 13:18 ` [GSoC][PATCH 3/3] rebase -i: rewrite checkout_onto() " Alban Gruin
2018-06-18 16:09   ` Phillip Wood
2018-06-18 17:04     ` Alban Gruin
2018-06-19 15:44 ` [GSoC][PATCH v2 0/3] rebase -i: rewrite reflog operations " Alban Gruin
2018-06-19 15:44   ` [GSoC][PATCH v2 1/3] sequencer: add a new function to silence a command, except if it fails Alban Gruin
2018-06-21  9:37     ` Johannes Schindelin
2018-06-21 11:53       ` Alban Gruin
2018-06-19 15:44   ` [GSoC][PATCH v2 2/3] rebase -i: rewrite setup_reflog_action() in C Alban Gruin
2018-06-21 10:34     ` Johannes Schindelin
2018-06-19 15:44   ` [GSoC][PATCH v2 3/3] rebase -i: rewrite checkout_onto() " Alban Gruin
2018-06-21 10:38     ` Johannes Schindelin
2018-06-19 18:35   ` [GSoC][PATCH v2 0/3] rebase -i: rewrite reflog operations " Stefan Beller
2018-06-21  8:39   ` Johannes Schindelin
2018-06-21 14:17   ` [GSoC][PATCH v3 " Alban Gruin
2018-06-21 14:17     ` [GSoC][PATCH v3 1/3] sequencer: add a new function to silence a command, except if it fails Alban Gruin
2018-06-21 22:03       ` Junio C Hamano
2018-06-22 20:47         ` Alban Gruin
2018-06-21 14:17     ` [GSoC][PATCH v3 2/3] rebase -i: rewrite setup_reflog_action() in C Alban Gruin
2018-06-22 16:27       ` Junio C Hamano
2018-06-22 20:48         ` Alban Gruin
2018-06-25 15:34           ` Junio C Hamano
2018-06-25 18:21             ` Alban Gruin
2018-06-25 21:14               ` Johannes Schindelin
2018-06-26  9:13                 ` Pratik Karki
2018-06-26 17:44               ` Junio C Hamano
2018-06-21 14:17     ` [GSoC][PATCH v3 3/3] rebase -i: rewrite checkout_onto() " Alban Gruin
2018-06-25 13:44     ` [GSoC][PATCH v4 0/3] rebase -i: rewrite reflog operations " Alban Gruin
2018-06-25 13:44       ` [GSoC][PATCH v4 1/3] sequencer: extract a function to silence a command, except if it fails Alban Gruin
2018-06-25 13:44       ` [GSoC][PATCH v4 2/3] rebase -i: rewrite checkout_onto() in C Alban Gruin
2018-06-26 17:35         ` Junio C Hamano [this message]
2018-06-25 13:44       ` [GSoC][PATCH v4 3/3] rebase -i: rewrite setup_reflog_action() " Alban Gruin
2018-06-29 15:14       ` [GSoC][PATCH v5 0/3] rebase -i: rewrite reflog operations " Alban Gruin
2018-06-29 15:14         ` [GSoC][PATCH v5 1/3] sequencer: add a new function to silence a command, except if it fails Alban Gruin
2018-06-29 15:14         ` [GSoC][PATCH v5 2/3] rebase -i: rewrite setup_reflog_action() in C Alban Gruin
2018-06-29 16:50           ` Junio C Hamano
2018-06-29 15:14         ` [GSoC][PATCH v5 3/3] rebase -i: rewrite checkout_onto() " Alban Gruin
2018-06-29 16:55         ` [GSoC][PATCH v5 0/3] rebase -i: rewrite reflog operations " Junio C Hamano
2018-06-29 18:23           ` Junio C Hamano
2018-07-02 10:36             ` Alban Gruin
2018-07-03 18:15               ` Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=xmqqsh59lad7.fsf@gitster-ct.c.googlers.com \
    --to=gitster@pobox.com \
    --cc=Johannes.Schindelin@gmx.de \
    --cc=alban.gruin@gmail.com \
    --cc=christian.couder@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=newren@gmail.com \
    --cc=phillip.wood@dunelm.org.uk \
    --cc=predatoramigo@gmail.com \
    --cc=sbeller@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.