All of lore.kernel.org
 help / color / mirror / Atom feed
From: Phillip Wood <phillip.wood@talktalk.net>
To: Johannes Schindelin <Johannes.Schindelin@gmx.de>,
	Phillip Wood <phillip.wood@dunelm.org.uk>
Cc: Johannes Schindelin via GitGitGadget <gitgitgadget@gmail.com>,
	git@vger.kernel.org, Junio C Hamano <gitster@pobox.com>
Subject: Re: [PATCH 1/1] rebase: really just passthru the `git am` options
Date: Tue, 13 Nov 2018 19:58:55 +0000	[thread overview]
Message-ID: <1b8461d1-6cb7-6622-94d2-44c27623236d@talktalk.net> (raw)
In-Reply-To: <nycvar.QRO.7.76.6.1811132019440.39@tvgsbejvaqbjf.bet>

Hi Johannes

On 13/11/2018 19:21, Johannes Schindelin wrote:
> Hi Phillip,
> 
> On Tue, 13 Nov 2018, Phillip Wood wrote:
> 
>> Thanks for looking at this. Unfortunately using OPT_PASSTHRU_ARGV seems to
>> break the error reporting
>>
>> Running
>>    bin/wrappers/git rebase --onto @^^^^ @^^ -Cbad
>>
>> Gives
>>    git encountered an error while preparing the patches to replay
>>    these revisions:
>>
>>
>> 67f673aa4a580b9e407b1ca505abf1f50510ec47...7c3e01a708856885e60bf4051586970e65dd326c
>>
>>    As a result, git cannot rebase them.
>>

git 2.19.1 gives

First, rewinding head to replay your work on top of it...
Applying: Ninth batch for 2.20
error: switch `C' expects a numerical value

So it has a clear message as to what the error is, this patch regresses 
that. It would be better if rebase detected the error before starting 
though.

>> If I do
>>
>>    bin/wrappers/git rebase @^^ -Cbad
>>
>> I get no error, it just tells me that it does not need to rebase (which is
>> true)
> 
> Hmm. Isn't this the same behavior as with the scripted version?

Ah you're right the script does not check if the option argument is valid.

> Also: are
> we sure that we want to allow options to come *after* the `<upstream>`
> argument?

Maybe not but the scripted version does. I'm not sure if that is a good 
idea or not.

Best Wishes

Phillip

> Ciao,
> Dscho
> 
>> Best Wishes
>>
>> Phillip
>>
>>
>> On 13/11/2018 12:38, Johannes Schindelin via GitGitGadget wrote:
>>> From: Johannes Schindelin <johannes.schindelin@gmx.de>
>>>
>>> Currently, we parse the options intended for `git am` as if we wanted to
>>> handle them in `git rebase`, and then reconstruct them painstakingly to
>>> define the `git_am_opt` variable.
>>>
>>> However, there is a much better way (that I was unaware of, at the time
>>> when I mentored Pratik to implement these options): OPT_PASSTHRU_ARGV.
>>> It is intended for exactly this use case, where command-line options
>>> want to be parsed into a separate `argv_array`.
>>>
>>> Let's use this feature.
>>>
>>> Incidentally, this also allows us to address a bug discovered by Phillip
>>> Wood, where the built-in rebase failed to understand that the `-C`
>>> option takes an optional argument.
>>>
>>> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
>>> ---
>>>    builtin/rebase.c | 98 +++++++++++++++++-------------------------------
>>>    1 file changed, 35 insertions(+), 63 deletions(-)
>>>
>>> diff --git a/builtin/rebase.c b/builtin/rebase.c
>>> index 0ee06aa363..96ffa80b71 100644
>>> --- a/builtin/rebase.c
>>> +++ b/builtin/rebase.c
>>> @@ -87,7 +87,7 @@ struct rebase_options {
>>>      REBASE_FORCE = 1<<3,
>>>      REBASE_INTERACTIVE_EXPLICIT = 1<<4,
>>>    	} flags;
>>> -	struct strbuf git_am_opt;
>>> +	struct argv_array git_am_opts;
>>>     const char *action;
>>>     int signoff;
>>>     int allow_rerere_autoupdate;
>>> @@ -339,7 +339,7 @@ N_("Resolve all conflicts manually, mark them as
>>> resolved with\n"
>>>    static int run_specific_rebase(struct rebase_options *opts)
>>>    {
>>>    	const char *argv[] = { NULL, NULL };
>>> -	struct strbuf script_snippet = STRBUF_INIT;
>>> +	struct strbuf script_snippet = STRBUF_INIT, buf = STRBUF_INIT;
>>>     int status;
>>>     const char *backend, *backend_func;
>>>    @@ -433,7 +433,9 @@ static int run_specific_rebase(struct rebase_options
>>> *opts)
>>>     	oid_to_hex(&opts->restrict_revision->object.oid) : NULL);
>>>     add_var(&script_snippet, "GIT_QUIET",
>>>    		opts->flags & REBASE_NO_QUIET ? "" : "t");
>>> -	add_var(&script_snippet, "git_am_opt", opts->git_am_opt.buf);
>>> +	sq_quote_argv_pretty(&buf, opts->git_am_opts.argv);
>>> +	add_var(&script_snippet, "git_am_opt", buf.buf);
>>> +	strbuf_release(&buf);
>>>     add_var(&script_snippet, "verbose",
>>>     	opts->flags & REBASE_VERBOSE ? "t" : "");
>>>    	add_var(&script_snippet, "diffstat",
>>> @@ -756,7 +758,7 @@ int cmd_rebase(int argc, const char **argv, const char
>>> *prefix)
>>>     struct rebase_options options = {
>>>      .type = REBASE_UNSPECIFIED,
>>>      .flags = REBASE_NO_QUIET,
>>> -		.git_am_opt = STRBUF_INIT,
>>> +		.git_am_opts = ARGV_ARRAY_INIT,
>>>      .allow_rerere_autoupdate  = -1,
>>>      .allow_empty_message = 1,
>>>      .git_format_patch_opt = STRBUF_INIT,
>>> @@ -777,12 +779,7 @@ int cmd_rebase(int argc, const char **argv, const
>>> char *prefix)
>>>      ACTION_EDIT_TODO,
>>>      ACTION_SHOW_CURRENT_PATCH,
>>>    	} action = NO_ACTION;
>>> -	int committer_date_is_author_date = 0;
>>> -	int ignore_date = 0;
>>> -	int ignore_whitespace = 0;
>>>    	const char *gpg_sign = NULL;
>>> -	int opt_c = -1;
>>> -	struct string_list whitespace = STRING_LIST_INIT_NODUP;
>>>     struct string_list exec = STRING_LIST_INIT_NODUP;
>>>     const char *rebase_merges = NULL;
>>>     int fork_point = -1;
>>> @@ -804,15 +801,20 @@ int cmd_rebase(int argc, const char **argv, const
>>> char *prefix)
>>>      {OPTION_NEGBIT, 'n', "no-stat", &options.flags, NULL,
>>>       N_("do not show diffstat of what changed upstream"),
>>>       PARSE_OPT_NOARG, NULL, REBASE_DIFFSTAT },
>>> -		OPT_BOOL(0, "ignore-whitespace", &ignore_whitespace,
>>> -			 N_("passed to 'git apply'")),
>>>      OPT_BOOL(0, "signoff", &options.signoff,
>>>    			 N_("add a Signed-off-by: line to each commit")),
>>> -		OPT_BOOL(0, "committer-date-is-author-date",
>>> -			 &committer_date_is_author_date,
>>> -			 N_("passed to 'git am'")),
>>> -		OPT_BOOL(0, "ignore-date", &ignore_date,
>>> -			 N_("passed to 'git am'")),
>>> +		OPT_PASSTHRU_ARGV(0, "ignore-whitespace",
>>> &options.git_am_opts,
>>> +				  NULL, N_("passed to 'git am'"),
>>> +				  PARSE_OPT_NOARG),
>>> +		OPT_PASSTHRU_ARGV(0, "committer-date-is-author-date",
>>> +				  &options.git_am_opts, NULL,
>>> +				  N_("passed to 'git am'"),
>>> PARSE_OPT_NOARG),
>>> +		OPT_PASSTHRU_ARGV(0, "ignore-date", &options.git_am_opts,
>>> NULL,
>>> +				  N_("passed to 'git am'"),
>>> PARSE_OPT_NOARG),
>>> +		OPT_PASSTHRU_ARGV('C', NULL, &options.git_am_opts, N_("n"),
>>> +				  N_("passed to 'git apply'"), 0),
>>> +		OPT_PASSTHRU_ARGV(0, "whitespace", &options.git_am_opts,
>>> +				  N_("action"), N_("passed to 'git apply'"),
>>> 0),
>>>      OPT_BIT('f', "force-rebase", &options.flags,
>>>       N_("cherry-pick all commits, even if unchanged"),
>>>       REBASE_FORCE),
>>> @@ -856,10 +858,6 @@ int cmd_rebase(int argc, const char **argv, const
>>> char *prefix)
>>>      { OPTION_STRING, 'S', "gpg-sign", &gpg_sign, N_("key-id"),
>>>       N_("GPG-sign commits"),
>>>       PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
>>> -		OPT_STRING_LIST(0, "whitespace", &whitespace,
>>> -				N_("whitespace"), N_("passed to 'git
>>> apply'")),
>>> -		OPT_SET_INT('C', NULL, &opt_c, N_("passed to 'git apply'"),
>>> -			    REBASE_AM),
>>>      OPT_BOOL(0, "autostash", &options.autostash,
>>>      	 N_("automatically stash/stash pop before and after")),
>>>    		OPT_STRING_LIST('x', "exec", &exec, N_("exec"),
>>> @@ -884,6 +882,7 @@ int cmd_rebase(int argc, const char **argv, const char
>>> *prefix)
>>>      	 N_("rebase all reachable commits up to the root(s)")),
>>>     	OPT_END(),
>>>    	};
>>> +	int i;
>>>    
>>>     /*
>>>    	 * NEEDSWORK: Once the builtin rebase has been tested enough
>>> @@ -1064,22 +1063,17 @@ int cmd_rebase(int argc, const char **argv, const
>>> char *prefix)
>>>     	    state_dir_base, cmd_live_rebase, buf.buf);
>>>     }
>>>    -	if (!(options.flags & REBASE_NO_QUIET))
>>> -		strbuf_addstr(&options.git_am_opt, " -q");
>>> -
>>> -	if (committer_date_is_author_date) {
>>> -		strbuf_addstr(&options.git_am_opt,
>>> -			      " --committer-date-is-author-date");
>>> -		options.flags |= REBASE_FORCE;
>>> +	for (i = 0; i < options.git_am_opts.argc; i++) {
>>> +		const char *option = options.git_am_opts.argv[i];
>>> +		if (!strcmp(option, "--committer-date-is-author-date") ||
>>> +		    !strcmp(option, "--ignore-date") ||
>>> +		    !strcmp(option, "--whitespace=fix") ||
>>> +		    !strcmp(option, "--whitespace=strip"))
>>> +			options.flags |= REBASE_FORCE;
>>>     }
>>>    -	if (ignore_whitespace)
>>> -		strbuf_addstr(&options.git_am_opt, " --ignore-whitespace");
>>> -
>>> -	if (ignore_date) {
>>> -		strbuf_addstr(&options.git_am_opt, " --ignore-date");
>>> -		options.flags |= REBASE_FORCE;
>>> -	}
>>> +	if (!(options.flags & REBASE_NO_QUIET))
>>> +		argv_array_push(&options.git_am_opts, "-q");
>>>    
>>>     if (options.keep_empty)
>>>    		imply_interactive(&options, "--keep-empty");
>>> @@ -1089,23 +1083,6 @@ int cmd_rebase(int argc, const char **argv, const
>>> char *prefix)
>>>     	options.gpg_sign_opt = xstrfmt("-S%s", gpg_sign);
>>>     }
>>>    -	if (opt_c >= 0)
>>> -		strbuf_addf(&options.git_am_opt, " -C%d", opt_c);
>>> -
>>> -	if (whitespace.nr) {
>>> -		int i;
>>> -
>>> -		for (i = 0; i < whitespace.nr; i++) {
>>> -			const char *item = whitespace.items[i].string;
>>> -
>>> -			strbuf_addf(&options.git_am_opt, " --whitespace=%s",
>>> -				    item);
>>> -
>>> -			if ((!strcmp(item, "fix")) || (!strcmp(item,
>>> "strip")))
>>> -				options.flags |= REBASE_FORCE;
>>> -		}
>>> -	}
>>> -
>>>     if (exec.nr) {
>>>      int i;
>>>    @@ -1181,23 +1158,18 @@ int cmd_rebase(int argc, const char **argv,
>>> const char *prefix)
>>>     	break;
>>>     }
>>>    -	if (options.git_am_opt.len) {
>>> -		const char *p;
>>> -
>>> +	if (options.git_am_opts.argc) {
>>>    		/* all am options except -q are compatible only with --am */
>>> -		strbuf_reset(&buf);
>>> -		strbuf_addbuf(&buf, &options.git_am_opt);
>>> -		strbuf_addch(&buf, ' ');
>>> -		while ((p = strstr(buf.buf, " -q ")))
>>> -			strbuf_splice(&buf, p - buf.buf, 4, " ", 1);
>>> -		strbuf_trim(&buf);
>>> +		for (i = options.git_am_opts.argc - 1; i >= 0; i--)
>>> +			if (strcmp(options.git_am_opts.argv[i], "-q"))
>>> +				break;
>>>    -		if (is_interactive(&options) && buf.len)
>>> +		if (is_interactive(&options) && i >= 0)
>>>       die(_("error: cannot combine interactive options "
>>>             "(--interactive, --exec, --rebase-merges, "
>>>             "--preserve-merges, --keep-empty, --root + "
>>>             "--onto) with am options (%s)"), buf.buf);
>>> -		if (options.type == REBASE_MERGE && buf.len)
>>> +		if (options.type == REBASE_MERGE && i >= 0)
>>>       die(_("error: cannot combine merge options (--merge, "
>>>             "--strategy, --strategy-option) with am options "
>>>             "(%s)"), buf.buf);
>>> @@ -1207,7 +1179,7 @@ int cmd_rebase(int argc, const char **argv, const
>>> char *prefix)
>>>      if (options.type == REBASE_PRESERVE_MERGES)
>>>       die("cannot combine '--signoff' with "
>>>    			    "'--preserve-merges'");
>>> -		strbuf_addstr(&options.git_am_opt, " --signoff");
>>> +		argv_array_push(&options.git_am_opts, "--signoff");
>>>     	options.flags |= REBASE_FORCE;
>>>     }
>>>    
>>>
>>
>>


  reply	other threads:[~2018-11-13 19:59 UTC|newest]

Thread overview: 97+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-11-13 12:38 [PATCH 0/1] rebase: understand -C again, refactor Johannes Schindelin via GitGitGadget
2018-11-13 12:38 ` [PATCH 1/1] rebase: really just passthru the `git am` options Johannes Schindelin via GitGitGadget
2018-11-13 13:05   ` Junio C Hamano
2018-11-13 15:05   ` Phillip Wood
2018-11-13 19:21     ` Johannes Schindelin
2018-11-13 19:58       ` Phillip Wood [this message]
2018-11-13 21:50         ` rebase-in-C stability for 2.20 Ævar Arnfjörð Bjarmason
2018-11-14  0:07           ` Stefan Beller
2018-11-14  9:01             ` [PATCH 0/2] rebase.useBuiltin doc & test mode Ævar Arnfjörð Bjarmason
2018-11-14 14:07               ` Johannes Schindelin
2018-11-14  9:01             ` [PATCH 1/2] rebase doc: document rebase.useBuiltin Ævar Arnfjörð Bjarmason
2018-11-14  9:01             ` [PATCH 2/2] tests: add a special setup where rebase.useBuiltin is off Ævar Arnfjörð Bjarmason
2018-11-14  0:36           ` rebase-in-C stability for 2.20 Elijah Newren
2018-11-14  3:39           ` Junio C Hamano
2018-11-24 20:54           ` [ANNOUNCE] Git v2.20.0-rc1 Ævar Arnfjörð Bjarmason
2018-11-25  1:00             ` Junio C Hamano
2018-11-26  6:10               ` [PATCH] rebase: mark the C reimplementation as an experimental opt-in feature (was Re: [ANNOUNCE] Git v2.20.0-rc1) Junio C Hamano
2018-11-28  4:31                 ` Jonathan Nieder
2018-11-28  9:23                   ` Johannes Schindelin
2018-11-28 12:21                     ` Ævar Arnfjörð Bjarmason
2018-11-29  4:58                       ` Junio C Hamano
2018-11-29 14:17                     ` Johannes Schindelin
2018-11-29 14:30                       ` Ian Jackson
2018-11-29 15:39                         ` Johannes Schindelin
2018-11-29 15:50                           ` Ian Jackson
2018-11-29 16:14                             ` Johannes Schindelin
2018-11-29 16:26                               ` Ian Jackson
2018-11-26 22:52             ` [ANNOUNCE] Git v2.20.0-rc1 Johannes Schindelin
2018-11-26 23:47               ` Johannes Schindelin
2018-11-28  4:07                 ` Junio C Hamano
2018-11-28  9:30                   ` Johannes Schindelin
2018-11-14 14:22         ` [PATCH 1/1] rebase: really just passthru the `git am` options Johannes Schindelin
2018-11-14  7:29 ` [PATCH 0/1] rebase: understand -C again, refactor Jeff King
2018-11-14 14:28   ` Johannes Schindelin
2018-11-14 16:25 ` [PATCH v2 0/2] " Johannes Schindelin via GitGitGadget
2018-11-14 16:25   ` [PATCH v2 1/2] rebase: really just passthru the `git am` options Johannes Schindelin via GitGitGadget
2018-11-14 16:25   ` [PATCH v2 2/2] rebase: validate -C<n> and --whitespace=<mode> parameters early Johannes Schindelin via GitGitGadget
2018-11-14 16:37     ` Phillip Wood
2018-11-14 21:24       ` Johannes Schindelin
2018-11-19 12:38     ` Ævar Arnfjörð Bjarmason
2018-11-19 21:37       ` Git Test Coverage Report (v2.20.0-rc0) Ævar Arnfjörð Bjarmason
2018-11-20 10:58       ` [PATCH v2 2/2] rebase: validate -C<n> and --whitespace=<mode> parameters early Johannes Schindelin
2018-11-20 11:42         ` [PATCH] rebase: mark a test as failing with rebase.useBuiltin=false Ævar Arnfjörð Bjarmason
2018-11-20 19:55           ` Johannes Schindelin
2018-11-19  2:54 Git Test Coverage Report (v2.20.0-rc0) Derrick Stolee
2018-11-19 15:40 ` Derrick Stolee
2018-11-19 16:21   ` Jeff King
2018-11-19 18:44     ` Jeff King
2018-11-19 19:00   ` Ben Peart
2018-11-19 21:06     ` Derrick Stolee
2018-11-20 11:34   ` Jeff King
2018-11-20 12:17     ` Derrick Stolee
2018-11-20 12:40       ` Jeff King
2018-11-19 18:33 ` Ævar Arnfjörð Bjarmason
2018-11-19 18:51   ` [PATCH] tests: add a special setup where rebase.useBuiltin is off (Re: Git Test Coverage Report (v2.20.0-rc0)) Jonathan Nieder
2018-11-19 21:03     ` Ævar Arnfjörð Bjarmason
2018-11-19 19:10   ` Git Test Coverage Report (v2.20.0-rc0) Derrick Stolee
2018-11-19 19:39     ` Ævar Arnfjörð Bjarmason
2018-11-19 19:44       ` Derrick Stolee
2018-11-19 21:31   ` Derrick Stolee
2018-11-20 20:43     ` Johannes Schindelin
2018-11-21 15:20 [ANNOUNCE] Git v2.20.0-rc1 Junio C Hamano
2018-11-22 15:58 ` Ævar Arnfjörð Bjarmason
2018-11-22 19:27   ` Eric Sunshine
2018-11-22 21:12     ` [PATCH 0/2] format-patch: pre-2.20 range-diff regression fix Ævar Arnfjörð Bjarmason
2018-11-22 21:12     ` [PATCH 1/2] format-patch: add a more exhaustive --range-diff test Ævar Arnfjörð Bjarmason
2018-11-24  4:14       ` Junio C Hamano
2018-11-24 11:45         ` Ævar Arnfjörð Bjarmason
2018-11-22 21:12     ` [PATCH 2/2] format-patch: don't include --stat with --range-diff output Ævar Arnfjörð Bjarmason
2018-11-24  2:26       ` Junio C Hamano
2018-11-24  4:17         ` Junio C Hamano
2018-11-28 20:18           ` [PATCH 0/2] format-patch: fix root cause of recent regression Ævar Arnfjörð Bjarmason
2018-11-28 20:18           ` [PATCH 1/2] format-patch: add test for --range-diff diff output Ævar Arnfjörð Bjarmason
2018-11-28 20:18           ` [PATCH 2/2] format-patch: allow for independent diff & range-diff options Ævar Arnfjörð Bjarmason
2018-11-29  2:59             ` Junio C Hamano
2018-11-29 10:07             ` Johannes Schindelin
2018-11-29 10:30               ` Ævar Arnfjörð Bjarmason
2018-11-29 12:12                 ` Johannes Schindelin
2018-11-29 14:35                   ` Ævar Arnfjörð Bjarmason
2018-11-29 15:41                     ` Johannes Schindelin
2018-11-29 16:03                       ` Ævar Arnfjörð Bjarmason
2018-11-29 19:03                         ` Johannes Schindelin
2018-11-30  2:30                         ` Junio C Hamano
2018-11-30  4:27                           ` [PATCH] format-patch: do not let its diff-options affect --range-diff (was Re: [PATCH 2/2] format-patch: allow for independent diff & range-diff options) Junio C Hamano
2018-11-30  8:57                             ` Junio C Hamano
2018-11-30  9:24                               ` Ævar Arnfjörð Bjarmason
2018-11-30 12:32                               ` Johannes Schindelin
2018-11-30  9:31                             ` Eric Sunshine
2018-12-03 13:27                               ` Martin Ågren
2018-12-03 20:07                                 ` [PATCH v2] range-diff: always pass at least minimal diff options Martin Ågren
2018-12-03 21:21                                   ` [PATCH v3] " Eric Sunshine
2018-12-04  1:35                                     ` Junio C Hamano
2018-12-04  5:40                                     ` Martin Ågren
2018-11-30  9:58                         ` [PATCH 2/2] format-patch: allow for independent diff & range-diff options Eric Sunshine
2018-11-26  7:35 ` [ANNOUNCE] Git v2.20.0-rc1 Junio C Hamano
2018-11-26 15:41   ` Elijah Newren
2018-11-27  0:40     ` 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=1b8461d1-6cb7-6622-94d2-44c27623236d@talktalk.net \
    --to=phillip.wood@talktalk.net \
    --cc=Johannes.Schindelin@gmx.de \
    --cc=git@vger.kernel.org \
    --cc=gitgitgadget@gmail.com \
    --cc=gitster@pobox.com \
    --cc=phillip.wood@dunelm.org.uk \
    /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.