git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Paul Tan <pyokagan@gmail.com>
To: Junio C Hamano <gitster@pobox.com>
Cc: Jeff King <peff@peff.net>,
	Remi Lespinet <remi.lespinet@ensimag.grenoble-inp.fr>,
	Git List <git@vger.kernel.org>,
	Stefan Beller <sbeller@google.com>,
	Johannes Schindelin <johannes.schindelin@gmx.de>
Subject: Re: [PATCH] am: let command-line options override saved options
Date: Fri, 31 Jul 2015 18:58:48 +0800	[thread overview]
Message-ID: <CACRoPnR1df+uEnpFArJtwEBCh+HiQYDYGOyZ7KQEGtrdiaX3GQ@mail.gmail.com> (raw)
In-Reply-To: <xmqqegjsfbtk.fsf@gitster.dls.corp.google.com>

On Wed, Jul 29, 2015 at 1:09 AM, Junio C Hamano <gitster@pobox.com> wrote:
> Paul Tan <pyokagan@gmail.com> writes:
>
>> diff --git a/t/t4153-am-resume-override-opts.sh b/t/t4153-am-resume-override-opts.sh
>> new file mode 100755
>> index 0000000..c49457c
>> --- /dev/null
>> +++ b/t/t4153-am-resume-override-opts.sh
>> @@ -0,0 +1,144 @@
>> +#!/bin/sh
>> +
>> +test_description='git-am command-line options override saved options'
>> +
>> +. ./test-lib.sh
>> +
>> +test_expect_success 'setup' '
>> +     test_commit initial file &&
>> +     test_commit first file &&
>> +
>> +     git checkout -b side initial &&
>> +     test_commit side-first file &&
>> +     test_commit side-second file &&
>> +
>> +     {
>> +             echo "Message-Id: <side-first@example.com>" &&
>> +             git format-patch --stdout -1 side-first | sed -e "1d"
>> +     } >side-first.patch &&
>> +     {
>> +             sed -ne "1,/^\$/p" side-first.patch &&
>
> sed -e "/^\$/q" would work just as well here

OK.

>> +             echo "-- >8 --" &&
>> +             sed -e "1,/^\$/d" side-first.patch
>> +     } >side-first.scissors &&
>> +     {
>> +             echo "Message-Id: <side-second@example.com>" &&
>> +             git format-patch --stdout -1 side-second | sed -e "1d"
>> +     } >side-second.patch &&
>> +     {
>> +             sed -ne "1,/^\$/p" side-second.patch &&
>> +             echo "-- >8 --" &&
>> +             sed -e "1,/^\$/d" side-second.patch
>> +     } >side-second.scissors
>> +'
>
> A helper function that takes the branch name may be a good idea,
> not just to consolidate the implementation but as a place to
> document how these pairs of files are constructed and why.

I think I will introduce a format_patch() function that takes a single
commit-ish so that we can use tag names to name the patches:

# Given a single commit $commit, formats the following patches with
# git-format-patch:
#
# 1. $commit.eml: an email patch with a Message-Id header.
# 2. $commit.scissors: like $commit.eml but contains a scissors line at the
#    start of the commit message body.
format_patch () {
    {
        echo "Message-Id: <$1@example.com>" &&
        git format-patch --stdout -1 "$1" | sed -e '1d'
    } >"$1".eml &&
    {
        sed -e '/^$/q' "$1".eml &&
        echo '-- >8 --' &&
        sed -e '1,/^$/d' "$1".eml
    } >"$1".scissors
}

>> +'
>> +
>> +test_expect_success '--signoff, --no-signoff' '
>> +     rm -fr .git/rebase-apply &&
>> +     git reset --hard &&
>> +     git checkout first &&
>> +     test_must_fail git am --signoff side-first.patch side-second.patch &&
>> +     echo side-first >file &&
>> +     git add file &&
>> +     git am --no-signoff --continue &&
>> +
>> +     # applied side-first will be signed off
>> +     echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >expected &&
>> +     git cat-file commit HEAD^ | grep "Signed-off-by:" >actual &&
>> +     test_cmp expected actual &&
>> +
>> +     # applied side-second will not be signed off
>> +     test $(git cat-file commit HEAD | grep -c "Signed-off-by:") -eq 0
>> +'
>
> Hmm, the command was run with --signoff at the start, first gets
> applied with "am --no-signoff --resolved" so I would expect it does
> not get signed off, but the second one will apply cleanly on top, so
> shouldn't it get signed off?  Or perhaps somehow I misread Peff's
> idea to make these override one-shot in $gmane/274635?

Ah, I was just following the structure of the code, but stepping back
to think about it, I think there are 2 bugs:

1. The signoff is appended during the email-parsing stage. As such,
when we are resuming, --no-signoff will have no effect, because the
signoff has already been appended at that stage.

A solution for this is tricky though, as there are functions of git-am
that probably depend on the present behavior of the appended signoff
being present in the commit message:

* The applypatch-msg hook

* The --interactive prompt, where the user can edit the commit message
(to remove or edit the signoff maybe?)

These functions are called before we attempt to apply the patch, so we
should probably call append_signoff before then. However, this still
means that --no-signoff will have no effect should the patch
application fail and we resume, as the signoff would still have
already been appended...

So I dunno. I think the cleanest solution would be to change the
behavior so the commit message passed to the applypatch-msg hook and
--interactive prompt  do not contain the appended signoff, and instead
only append the signoff just before we commit. That way, both
--signoff and --no-signoff overriding will work. What do you think?

2. Re-reading Peff's message, I see that he expects the command-line
options to affect just the current patch, which makes sense. This
patch would need to be extended to call am_load() after we finish
processing the current patch when resuming. Something like:

diff --git a/builtin/am.c b/builtin/am.c
index 8a0b0e4..228d4b1 100644
--- a/builtin/am.c
+++ b/builtin/am.c
@@ -1779,7 +1779,6 @@ static void am_run(struct am_state *state, int resume)

         if (resume) {
             validate_resume_state(state);
-            resume = 0;
         } else {
             int skip;

@@ -1841,6 +1840,10 @@ static void am_run(struct am_state *state, int resume)

 next:
         am_next(state);
+
+        if (resume)
+            am_load(state);
+        resume = 0;
     }

     if (!is_empty_file(am_path(state, "rewritten"))) {
@@ -1895,6 +1898,7 @@ static void am_resolve(struct am_state *state)

 next:
     am_next(state);
+    am_load(state);
     am_run(state, 0);
 }

@@ -2022,6 +2026,7 @@ static void am_skip(struct am_state *state)
         die(_("failed to clean index"));

     am_next(state);
+    am_load(state);
     am_run(state, 0);
 }

The tests will also need to be modified as well.

>> +test_expect_success '--3way, --no-3way' '
>> +     rm -fr .git/rebase-apply &&
>> +     git reset --hard &&
>> +     git checkout first &&
>> +     test_must_fail git am --3way side-first.patch side-second.patch &&
>> +     test -n "$(git ls-files -u)" &&
>> +     echo will-conflict >file &&
>> +     git add file &&
>> +     test_must_fail git am --no-3way --continue &&
>> +     test -z "$(git ls-files -u)"
>> +'
>> +

... Although if I implement the above change, I can't implement the
test for --3way, as I think the only way to check if --3way/--no-3way
successfully overrides the saved options for the current patch only is
to run "git am --3way", but that does not work in the test runner as
it expects stdin to be a TTY :-/ So I may have to remove this test.
This shouldn't be a problem though, as all the tests in this test
suite all test the same mechanism.

>> +test_expect_success '--no-quiet, --quiet' '
>> +     rm -fr .git/rebase-apply &&
>> +     git reset --hard &&
>> +     git checkout first &&
>> +     test_must_fail git am --no-quiet side-first.patch side-second.patch &&
>> +     test_must_be_empty out &&
>
> Where did this 'out' come from?

It was a leftover from a previous iteration. Will fix.

>
>> +     echo side-first >file &&
>> +     git add file &&
>> +     git am --quiet --continue >out &&
>> +     test_must_be_empty out
>
> I can see this one, though I am not sure if it is sensible to see
> what the command says under --quiet option, especially if you are
> making sure it does not fail, which you already have checked for its
> exit status.

Well, if --quiet fails to override --no-quiet, then there would be
something written to the stdout, no?

But anyway, if we are implementing the above "command-line option
overriding only affects current patch" behavior, then this test would
be checking if --quiet only affects a single patch, which in practice
would be quite silly. Maybe I should flip it around to "--no-quiet
overrides --quiet", but even then it may still be unlikely to come up
with practice... Still, it may be useful to keep this test to check if
the option overriding mechanism is working properly.

Thanks,
Paul

  reply	other threads:[~2015-07-31 10:58 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-07-24 17:48 "git am" and then "git am -3" regression? Junio C Hamano
2015-07-24 18:09 ` Jeff King
2015-07-26  5:03   ` Paul Tan
2015-07-26  5:21     ` Jeff King
2015-07-27  8:09       ` Matthieu Moy
2015-07-27  8:32         ` Jeff King
2015-07-27 14:21     ` Junio C Hamano
2015-07-28 16:43       ` [PATCH] am: let command-line options override saved options Paul Tan
2015-07-28 16:48         ` Junio C Hamano
2015-07-28 17:09         ` Junio C Hamano
2015-07-31 10:58           ` Paul Tan [this message]
2015-07-31 16:04             ` Junio C Hamano
2015-08-01  0:59               ` Paul Tan
2015-08-04 14:05         ` [PATCH v2 0/3] " Paul Tan
2015-08-04 21:12           ` Junio C Hamano
2015-08-04 14:08         ` Paul Tan
2015-08-04 14:08           ` [PATCH v2 1/3] test_terminal: redirect child process' stdin to a pty Paul Tan
2015-08-06 22:15             ` Eric Sunshine
2015-08-12  4:16               ` Paul Tan
2015-08-04 14:08           ` [PATCH v2 2/3] am: let command-line options override saved options Paul Tan
2015-08-04 14:08           ` [PATCH v2 3/3] am: let --signoff override --no-signoff Paul Tan
2015-08-07  9:29             ` Johannes Schindelin
2015-08-12  3:06               ` Paul Tan
2015-08-12  3:07                 ` Paul Tan
2015-08-05 15:41           ` [PATCH v2 0/3] am: let command-line options override saved options Junio C Hamano
2015-08-05 17:51             ` Paul Tan

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

  List information: http://vger.kernel.org/majordomo-info.html

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

  git send-email \
    --in-reply-to=CACRoPnR1df+uEnpFArJtwEBCh+HiQYDYGOyZ7KQEGtrdiaX3GQ@mail.gmail.com \
    --to=pyokagan@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=johannes.schindelin@gmx.de \
    --cc=peff@peff.net \
    --cc=remi.lespinet@ensimag.grenoble-inp.fr \
    --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.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

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 read-only IMAP folder(s) and NNTP newsgroup(s).