Re: [PATCH 3/4] rebase -m: fix serialization of strategy options

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Mar 15, 2023 at 8:51 AM Phillip Wood <phillip.wood123@xxxxxxxxx> wrote:
>
> From: Phillip Wood <phillip.wood@xxxxxxxxxxxxx>
>
> To store the strategy options rebase prepends " --" to each one and
> writes them to a file. To load them it reads the file and passes the
> contents to split_cmdline(). This roughly mimics the behavior of the
> scripted rebase but has a couple of limitations, (1) options containing
> whitespace are not properly preserved (this is true of the scripted
> rebase as well) and (2) options containing '"' or '\' are incorrectly
> parsed and may cause the parser to return an error.
>
> Fix these limitations by quoting each option when they are stored so
> that they can be parsed correctly. Now that "--preserve-merges" no
> longer exist this change also stops prepending "--" to the options when
> they are stored as that was an artifact of the scripted rebase.
>
> These changes are backwards compatible so the files written by an older
> version of git can be still be read. They are also forwards compatible,
> the file can still be parsed by recent versions of git as they treat the
> "--" prefix as optional.

I'm not sure we want to tie ourselves to support completing a rebase
with git version X+1 that was started with git version X.  But, it's
really nice that you're paying attention to that level of detail.  :-)

>
> Signed-off-by: Phillip Wood <phillip.wood@xxxxxxxxxxxxx>
> ---
>  sequencer.c                    | 23 +++++++++++++++++++----
>  t/t3418-rebase-continue.sh     | 34 ++++++++++++++++++++++------------
>  t/t3436-rebase-more-options.sh | 24 ------------------------
>  3 files changed, 41 insertions(+), 40 deletions(-)
>
> diff --git a/sequencer.c b/sequencer.c
> index 83ea1016ae..8890d1f7a1 100644
> --- a/sequencer.c
> +++ b/sequencer.c
> @@ -2930,7 +2930,7 @@ static void parse_strategy_opts(struct replay_opts *opts, char *raw_opts)
>         count = split_cmdline(strategy_opts_string,
>                               (const char ***)&opts->xopts);
>         if (count < 0)
> -               die(_("could not split '%s': %s"), strategy_opts_string,
> +               BUG("could not split '%s': %s", strategy_opts_string,
>                             split_cmdline_strerror(count));
>         opts->xopts_nr = count;
>         for (i = 0; i < opts->xopts_nr; i++) {
> @@ -3054,12 +3054,27 @@ static int read_populate_opts(struct replay_opts *opts)
>
>  static void write_strategy_opts(struct replay_opts *opts)
>  {
> -       int i;
>         struct strbuf buf = STRBUF_INIT;
>
> -       for (i = 0; i < opts->xopts_nr; ++i)
> -               strbuf_addf(&buf, " --%s", opts->xopts[i]);
> +       /*
> +        * Quote strategy options so that they can be read correctly
> +        * by split_cmdline().
> +        */
> +       for (size_t i = 0; i < opts->xopts_nr; i++) {
> +               char *arg = opts->xopts[i];
>
> +               if (i)
> +                       strbuf_addch(&buf, ' ');
> +               strbuf_addch(&buf, '"');
> +               for (size_t j = 0; arg[j]; j++) {
> +                       const char c = arg[j];
> +
> +                       if (c == '"' || c =='\\')
> +                               strbuf_addch(&buf, '\\');
> +                       strbuf_addch(&buf, c);
> +               }
> +               strbuf_addch(&buf, '"');
> +       }

Do we not have a function in quote.[ch] that can handle this?  If not,
should we add this code to a function in that file and call it?

>         write_file(rebase_path_strategy_opts(), "%s\n", buf.buf);
>         strbuf_release(&buf);
>  }
> diff --git a/t/t3418-rebase-continue.sh b/t/t3418-rebase-continue.sh
> index 130e2f9b55..42c3954125 100755
> --- a/t/t3418-rebase-continue.sh
> +++ b/t/t3418-rebase-continue.sh
> @@ -62,29 +62,39 @@ test_expect_success 'rebase --continue remembers merge strategy and options' '
>         rm -fr .git/rebase-* &&
>         git reset --hard commit-new-file-F2-on-topic-branch &&
>         test_commit "commit-new-file-F3-on-topic-branch" F3 32 &&
> -       test_when_finished "rm -fr test-bin funny.was.run" &&
> +       test_when_finished "rm -fr test-bin" &&
>         mkdir test-bin &&
> -       cat >test-bin/git-merge-funny <<-EOF &&
> -       #!$SHELL_PATH
> -       case "\$1" in --opt) ;; *) exit 2 ;; esac
> -       shift &&
> -       >funny.was.run &&
> -       exec git merge-recursive "\$@"
> +
> +       write_script test-bin/git-merge-funny <<-\EOF &&
> +       printf "[%s]\n" $# "$1" "$2" "$3" "$5" >actual
> +       shift 3 &&
> +       exec git merge-recursive "$@"
>         EOF
> -       chmod +x test-bin/git-merge-funny &&
> +
> +       cat >expect <<-\EOF &&
> +       [7]
> +       [--option=arg with space]
> +       [--op"tion\]
> +       [--new
> +       line ]
> +       [--]
> +       EOF
> +
> +       rm -f actual &&
>         (
>                 PATH=./test-bin:$PATH &&
> -               test_must_fail git rebase -s funny -Xopt main topic
> +               test_must_fail git rebase -s funny -X"option=arg with space" \
> +                               -Xop\"tion\\ -X"new${LF}line " main topic
>         ) &&
> -       test -f funny.was.run &&
> -       rm funny.was.run &&
> +       test_cmp expect actual &&
> +       rm actual &&
>         echo "Resolved" >F2 &&
>         git add F2 &&
>         (
>                 PATH=./test-bin:$PATH &&
>                 git rebase --continue
>         ) &&
> -       test -f funny.was.run
> +       test_cmp expect actual
>  '

I appreciate the more stringent test to cover these new special cases.  :-)

>
>  test_expect_success 'rebase -i --continue handles merge strategy and options' '
> diff --git a/t/t3436-rebase-more-options.sh b/t/t3436-rebase-more-options.sh
> index 3adf42f47d..94671d3c46 100755
> --- a/t/t3436-rebase-more-options.sh
> +++ b/t/t3436-rebase-more-options.sh
> @@ -40,30 +40,6 @@ test_expect_success 'setup' '
>         EOF
>  '
>
> -test_expect_success 'bad -X <strategy-option> arguments: unclosed quote' '
> -       test_when_finished "test_might_fail git rebase --abort" &&
> -       cat >expect <<-\EOF &&
> -       fatal: could not split '\''--bad'\'': unclosed quote
> -       EOF
> -       GIT_SEQUENCE_EDITOR="echo break >" \
> -               git rebase -i -X"bad argument\"" side main &&
> -       test_expect_code 128 git rebase --continue >out 2>actual &&
> -       test_must_be_empty out &&
> -       test_cmp expect actual
> -'
> -
> -test_expect_success 'bad -X <strategy-option> arguments: bad escape' '
> -       test_when_finished "test_might_fail git rebase --abort" &&
> -       cat >expect <<-\EOF &&
> -       fatal: could not split '\''--bad'\'': cmdline ends with \
> -       EOF
> -       GIT_SEQUENCE_EDITOR="echo break >" \
> -               git rebase -i -X"bad escape \\" side main &&
> -       test_expect_code 128 git rebase --continue >out 2>actual &&
> -       test_must_be_empty out &&
> -       test_cmp expect actual
> -'
> -
>  test_expect_success '--ignore-whitespace works with apply backend' '
>         test_must_fail git rebase --apply main side &&
>         git rebase --abort &&
> --
> 2.39.2




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux