git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jonathan Nieder <jrnieder@gmail.com>
To: Ramkumar Ramachandra <artagnon@gmail.com>
Cc: Git List <git@vger.kernel.org>,
	Junio C Hamano <gitster@pobox.com>,
	Christian Couder <chriscool@tuxfamily.org>,
	Daniel Barkalow <barkalow@iabervon.org>,
	Jeff King <peff@peff.net>
Subject: Re: [PATCH 3/5] revert: Allow mixed pick and revert instructions
Date: Wed, 10 Aug 2011 10:15:27 -0500	[thread overview]
Message-ID: <20110810151527.GC31315@elie.gateway.2wire.net> (raw)
In-Reply-To: <1312970151-18906-4-git-send-email-artagnon@gmail.com>

Ramkumar Ramachandra wrote:

> Change the way the instruction parser works, allowing arbitrary
> (action, operand) pairs to be parsed.  So now, you can do:
>
>   pick fdc0b12 picked
>   revert 965fed4 anotherpick
>
> For cherry-pick and revert, this means that a 'git cherry-pick
> --continue' can continue an ongoing revert operation and viceversa.

Nice. :)

> This patch lays the foundation for extending the parser to support
> more actions.

And why would I want to do that?  I think there's a missing "so git
rebase -i can reuse this machinery some day" at the end of the
sentence.

> --- a/builtin/revert.c
> +++ b/builtin/revert.c
> @@ -639,89 +639,84 @@ static void read_and_refresh_cache(struct replay_opts *opts)
>   *     assert(commit_list_count(list) == 2);
>   *     return list;
>   */
> -struct commit_list **commit_list_append(struct commit *commit,
> -					struct commit_list **next)
> +struct replay_insn_list **replay_insn_list_append(enum replay_action action,
> +						struct commit *operand,
> +						struct replay_insn_list **next)
>  {
> -	struct commit_list *new = xmalloc(sizeof(struct commit_list));
> +	struct replay_insn_list *new = xmalloc(sizeof(struct replay_insn_list));

Tip: we can save the readers some reading and prepare for future
renaming of the structure (not that that's something to fear) using
the idiom

	struct replay_insn_list *new = xmalloc(sizeof(*new));

[...]
> -static int format_todo(struct strbuf *buf, struct commit_list *todo_list,
> -		struct replay_opts *opts)
> +static int format_todo(struct strbuf *buf, struct replay_insn_list *todo_list)
>  {
> -	struct commit_list *cur = NULL;
> +	struct replay_insn_list *cur = NULL;
>  	struct commit_message msg = { NULL, NULL, NULL, NULL, NULL };
>  	const char *sha1_abbrev = NULL;
> -	const char *action_str = opts->action == REPLAY_REVERT ? "revert" : "pick";
> +	const char *action_str;

Might be clearer with narrower scope:

	struct replay_insn_list *cur;

	for (cur = todo_list; cur; cur = cur->next) {
		struct commit_message msg = COMMIT_MESSAGE_INIT;
		const char *sha1_abbrev, *action_str;

		sha1_abbrev = ...;
		action_str = ...;
		if (get_message(cur->operand, &msg))
			return error(...);
		strbuf_addf(buf, "%s %s %s\n", ...);
	}
	return 0;

By the way, shouldn't there a free_message() call to balance out the
get_message()?

[...]
> -static struct commit *parse_insn_line(char *start, struct replay_opts *opts)
> +static int parse_insn_line(char *start, enum replay_action *action,
> +			struct commit **operand)

Hm, why not

 static int parse_insn_line(const char *start, struct replay_insn_list *item);

>  {
>  	unsigned char commit_sha1[20];
>  	char sha1_abbrev[40];
> -	enum replay_action action;
> -	int insn_len = 0;
> +	int keyword_len;

What is this renaming about?  Maybe "action_len" would work to clarify
that this is about the length of the action string at the start, not
the entire line.

By the way, what are the semantics of that variable?  It doesn't seem
to be used, so couldn't we just eliminate it?

>  	char *p, *q;
>  
>  	if (!prefixcmp(start, "pick ")) {
> -		action = REPLAY_PICK;
> -		insn_len = strlen("pick");
> -		p = start + insn_len + 1;
> +		*action = REPLAY_PICK;
> +		keyword_len = strlen("pick");
> +		p = start + keyword_len + 1;

In such a scenario, this would say

	if (!prefixcmp(start, "pick ")) {
		item->action = REPLAY_PICK;
		p += strlen("pick ");
	}

[...]
>  	} else
> -		return NULL;
> +		return -1;

Unrelated to this patch: maybe

 	return error("unrecognized action in sequencer file: %s", start);

to be easier to debug.

>  	q = strchr(p, ' ');
>  	if (!q)
> -		return NULL;
> +		return -1;

So we reject "pick a87c8989"?  That's a shame.

>  	q++;
>  
>  	strlcpy(sha1_abbrev, p, q - p);

memcpy would be clearer.  Can't this overflow the sha1_abbrev buffer?

[...]
>  	if (get_sha1(sha1_abbrev, commit_sha1) < 0)
> -		return NULL;
> +		return -1;

get_sha1 doesn't print a message, so maybe:

	return error("malformed object name in sequencer file: %s",
							sha1_abbrev);

> +
> +	*operand = lookup_commit_reference(commit_sha1);
> +	if (!*operand)
> +		return -1;

Perhaps something like

	return error("operand %s in sequencer file is not a commit",
							sha1_abbrev);

[...]
> @@ -797,18 +791,18 @@ static void read_populate_opts(struct replay_opts **opts_ptr)
>  		die(_("Malformed options sheet: %s"), opts_file);
>  }
>  
> -static void walk_revs_populate_todo(struct commit_list **todo_list,
> +static void walk_revs_populate_todo(struct replay_insn_list **todo_list,
>  				struct replay_opts *opts)
>  {
>  	struct rev_info revs;
> -	struct commit *commit;
> +	struct commit *operand;

Can avoid some churn by keeping the old name here.

> -	struct commit_list **next;
> +	struct replay_insn_list **next;
>  
>  	prepare_revs(&revs, opts);
>  
>  	next = todo_list;
> -	while ((commit = get_revision(&revs)))
> -		next = commit_list_append(commit, next);
> +	while ((operand = get_revision(&revs)))
> +		next = replay_insn_list_append(opts->action, operand, next);
[...]
> @@ -901,8 +896,9 @@ static int pick_commits(struct commit_list *todo_list, struct replay_opts *opts)
>  	read_and_refresh_cache(opts);
>  
>  	for (cur = todo_list; cur; cur = cur->next) {
> -		save_todo(cur, opts);
> -		res = do_pick_commit(cur->item, opts);
> +		save_todo(cur);
> +		opts->action = cur->action;
> +		res = do_pick_commit(cur->operand, opts);

If do_pick_commit took an "action" operand, this would be less
scary. :)

[...]
> --- a/t/t3510-cherry-pick-sequence.sh
> +++ b/t/t3510-cherry-pick-sequence.sh
> @@ -211,4 +211,62 @@ test_expect_success 'malformed instruction sheet 2' '
>  	test_must_fail git cherry-pick --continue
>  '
>  
> +test_expect_success 'revert --continue continues after cherry-pick' '

I haven't looked at the tests yet.  FWIW, with whatever changes above
seem suitable,
Acked-by: Jonathan Nieder <jrnieder@gmail.com>

Thanks.

  reply	other threads:[~2011-08-10 15:15 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-08-10  9:55 [RFC PATCH 0/5] Some preliminary work based on sequencer-stable Ramkumar Ramachandra
2011-08-10  9:55 ` [PATCH 1/5] revert: Don't remove the sequencer state on error Ramkumar Ramachandra
2011-08-10  9:55 ` [PATCH 2/5] sequencer.h: Move data structures Ramkumar Ramachandra
2011-08-10  9:55 ` [PATCH 3/5] revert: Allow mixed pick and revert instructions Ramkumar Ramachandra
2011-08-10 15:15   ` Jonathan Nieder [this message]
2011-08-11  6:52     ` Ramkumar Ramachandra
2011-08-11  9:50     ` Ramkumar Ramachandra
2011-08-11 10:08       ` Jonathan Nieder
2011-08-10  9:55 ` [PATCH 4/5] sequencer: Expose code that handles files in .git/sequencer Ramkumar Ramachandra
2011-08-10 15:21   ` Jonathan Nieder
2011-08-10 15:34     ` Ramkumar Ramachandra
2011-08-10 15:53       ` Jonathan Nieder
2011-08-11  6:16         ` Ramkumar Ramachandra
2011-08-11  6:22           ` Jonathan Nieder
2011-08-11  6:27             ` Ramkumar Ramachandra
2011-08-10  9:55 ` [PATCH 5/5] sequencer: Remove sequencer state after final commit Ramkumar Ramachandra

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=20110810151527.GC31315@elie.gateway.2wire.net \
    --to=jrnieder@gmail.com \
    --cc=artagnon@gmail.com \
    --cc=barkalow@iabervon.org \
    --cc=chriscool@tuxfamily.org \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=peff@peff.net \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).