git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: "Aleen via GitGitGadget" <gitgitgadget@gmail.com>
Cc: git@vger.kernel.org, "René Scharfe" <l.s.r@web.de>,
	Aleen <aleen42@vip.qq.com>
Subject: Re: [PATCH v2 2/4] am: support --always option to am empty commits
Date: Fri, 12 Nov 2021 14:23:00 -0800	[thread overview]
Message-ID: <xmqq4k8hovy3.fsf@gitster.g> (raw)
In-Reply-To: 59b1417da3754add11e72692ec11c09e486269e4.1636700040.git.gitgitgadget@gmail.com

"Aleen via GitGitGadget" <gitgitgadget@gmail.com> writes:

> From: Aleen <aleen42@vip.qq.com>
> Subject: Re: [PATCH v2 2/4] am: support --always option to am empty commits

As the inventor of "format-patch" and "am", I probably should wish
that "to am" were by now a valid verb, but no, it is not.

More importantly, when an empty patch comes, there can be many
different ways for the "am" command to handle it.  "to am empty
commits" does not say how the patch chooses to so and does not make
a very useful title for this commit.

Right now, we error out, simply because it is an easy mistake to
save a non-patch e-mail to the mailbox when intending to save a
series of patches belonging to a topic, and the user is expected to
say "git am --skip" to skip over it when it happens.  The above
"Subject:" can be read to mean that the new option instead allows
such an empty message to be skipped without stopping and forcing the
user to say "am --skip", which may be a useful thing to do.  Or it
may mean that the new option creates an empty commit, using the
contents of the e-mail as the commit log message.  Does this patch
offer both behaviour?  If so, "to am", even though it does not
convey a bit of information, might be an acceptable compromise.  If
the patch implements only one of the behaviours, then we should say
so.  Either one of these two:

    am: --always option skips empty patches
    am: --always option records empty patches as empty commits

Also, I thought that the previous round saw a conclusion that --always
is a bad name for the option.  If we are making the second round,
let's not start with a bad name and the "fix the mistake" of
starting with a bad name in a later step.  Just start with the final
name from the beginning.

> +--always::
> +	Apply patches of commits with detailed commit messages,
> +	even if they emit no changes. (see linkgit:git-format-patch[1])

Almost the same comment as 1/4 applies to the above description.

    --empty-patch=(skip|asis|die)::
	The command usually errors out when seeing an input e-mail
	message that lacks a patch.  When this option is set to
	'skip', skip such an e-mail message without erroring out.
	When this option is set to 'asis', create an empty commit,
	recording the contents of the e-mail message as its log.
	'die' is the default.


perhaps?  Assuming that 'skip' would make a useful addition to the
mix in the future.

> diff --git a/builtin/am.c b/builtin/am.c
> index 8677ea2348a..d11efc16f92 100644
> --- a/builtin/am.c
> +++ b/builtin/am.c
> @@ -124,6 +124,8 @@ struct am_state {
>  	int ignore_date;
>  	int allow_rerere_autoupdate;
>  	const char *sign_commit;
> +	int always;

OK, so here is where the parse_options() records the command line
option.

> +	int empty_commit;

I do not think this addtion of empty_commit member to this structure
is welcome or necessary.

>  	int rebasing;
>  };

> @@ -1249,8 +1251,12 @@ static int parse_mail(struct am_state *state, const char *mail)
>  	}

>  	if (is_empty_or_missing_file(am_path(state, "patch"))) {
> -		printf_ln(_("Patch is empty."));
> -		die_user_resolve(state);
> +		if (state->always) {
> +			state->empty_commit = 1;
> +		} else {
> +			printf_ln(_("Patch is empty."));
> +			die_user_resolve(state);
> +		}
>  	}

I am only thinking aloud, but I suspect that the whole "if 'patch'
is empty, do something special" code logically belongs to the
caller.  Perhaps we should remove this block altogether and let the
code continue the rest of this function.  And return 0, as this is
not like mail-system-internal-data that we want to pretend did not
even exist, and have the caller check if "patch" file is empty and
act accordingly.

> @@ -1792,6 +1798,9 @@ static void am_run(struct am_state *state, int resume)
>  		if (state->interactive && do_interactive(state))
>  			goto next;
>  
> +		if (state->empty_commit)
> +			goto commit;
> +

This is probably a wrong place to jump from.  You are bypassing
applypatch-msg-hook that may be serving as a gate to catch typos
if you are going to create a commit.

So, perhaps check if "patch" is empty here, using the code you'd
lift from parse_mail(), and if it is empty then:

  - if --empty-commit is set to die (or left default), do the
    printf_ln(_("Patch is empty.")) followed by a call to
    die_user_resolve(state), just like before.

  - if it is set to skip, jump to "next", just like when
    parse_mail() returned 1.

  - otherwise (i.e. you are told to create an empty commit),
    remember the fact that current e-mail has no patch, but continue
    to the next step to run the hook.

>  		if (run_applypatch_msg_hook(state))
>  			exit(1);

And after passing the hook, if your earlier check says that there is
no patch and you are to create an empty commit, jump to "commit"
label from here.

> diff --git a/t/t4150-am.sh b/t/t4150-am.sh
> index 2aaaa0d7ded..5b3617857a8 100755
> --- a/t/t4150-am.sh
> +++ b/t/t4150-am.sh
> @@ -196,6 +196,12 @@ test_expect_success setup '
>  
>  	git format-patch -M --stdout lorem^ >rename-add.patch &&
>  
> +	git checkout -b empty-commit &&
> +	git commit -m "empty commit" --allow-empty &&
> +
> +	git format-patch --stdout empty-commit^ >empty.patch &&
> +	git format-patch --always --stdout empty-commit^ >empty-commit.patch &&
> +
>  	# reset time
>  	sane_unset test_tick &&
>  	test_tick
> @@ -1152,4 +1158,23 @@ test_expect_success 'apply binary blob in partial clone' '
>  	git -C client am ../patch
>  '
>  
> +test_expect_success 'am a real empty patch with the --always option' '
> +	rm -fr .git/rebase-apply &&

What is this one about?  If this is trying to clean up the cruft the
previous step made, it may be better to do the clean-up in the
previous step using test_when_finished.

> +	git reset --hard &&
> +	test_must_fail git am --always empty.patch 2>actual &&
> +	echo Patch format detection failed. >expected &&
> +	test_cmp expected actual
> +'

It is curious that the error message the patch touched said "Patch
is empty." but the test checks for a different message.  Are we
testing the right failure mode?

> +test_expect_success 'am a patch with empty commits' '
> +	grep "empty commit" empty-commit.patch &&

What is this testing?  If it is checking the sanity of test data we
created earlier, shouldn't we do so where we generated the data
(i.e. the "setup" block that we earlier saw)?

> +	rm -fr .git/rebase-apply &&
> +	git reset --hard &&

These are trying to clean up the cruft the previous step (added by
this patch) may have left.  Perhaps these should be done inside
test_when_finished of the previous step?

> +	git checkout empty-commit^ &&
> +	git am --always empty-commit.patch &&
> +	test_path_is_missing .git/rebase-apply &&

We should trust "git am"'s exit status here, I would think, rather
than be so intimate with the internal implementation detail like the
name of the temporary directory the command uses.

> +	git cat-file commit HEAD >actual &&
> +	test_i18ngrep "empty commit" actual

test_i18ngrep -> grep

The input (i.e. the commit that resulted in this empty patch) said.
"empty commit", and we are making sure that string appears, but we
are not making sure that is the only string appears in the log
message.  Is it because we will later enhance the command to
automatically extend the single-liner "empty patch" log message into
a lot more detailed one?  I doubt it ;-)

More importantly, the above checks if (part of) the log message is
recorded, but does not check if the resulting commit is what is
expected, i.e. an empty one.

Perhaps checking with "grep" is way too loose a test.  Shouldn't we
do something like

	git show -1 --format='%B' >actual

and compare it with expected "the log is recorded as-is, and there
is no change between HEAD^ and HEAD"?

> +'
> +
>  test_done

Thanks.

  reply	other threads:[~2021-11-12 22:23 UTC|newest]

Thread overview: 129+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-12  4:58 [PATCH 0/2] am: support --always option to am empty commits Aleen via GitGitGadget
2021-11-12  4:58 ` [PATCH 1/2] doc: git-format-patch: specify the option --always Aleen via GitGitGadget
2021-11-12  4:58 ` [PATCH 2/2] am: support --always option to am empty commits Aleen via GitGitGadget
2021-11-12  6:17 ` [PATCH 0/2] " René Scharfe
2021-11-12  6:42   ` Aleen
2021-11-12  6:47   ` Junio C Hamano
2021-11-12  7:10     ` Aleen 徐沛文
2021-11-12 15:28     ` René Scharfe
2021-11-12 16:08       ` Junio C Hamano
2021-11-12  6:53 ` [PATCH v2 0/4] am: support --allow-empty " Aleen via GitGitGadget
2021-11-12  6:53   ` [PATCH v2 1/4] doc: git-format-patch: specify the option --always Aleen via GitGitGadget
2021-11-12 22:17     ` Junio C Hamano
2021-11-12  6:53   ` [PATCH v2 2/4] am: support --always option to am empty commits Aleen via GitGitGadget
2021-11-12 22:23     ` Junio C Hamano [this message]
2021-11-12  6:53   ` [PATCH v2 3/4] test: am: add the case when not passing the --always option Aleen via GitGitGadget
2021-11-12  6:54   ` [PATCH v2 4/4] chore: am: rename the --always option to --allow-empty Aleen via GitGitGadget
2021-11-15 10:39   ` [PATCH v3 0/2] am: support --empty-commit=(die|skip|asis) option to am empty commits Aleen via GitGitGadget
2021-11-15 10:39     ` [PATCH v3 1/2] doc: git-format-patch: describe the option --always Aleen via GitGitGadget
2021-11-15 10:39     ` [PATCH v3 2/2] am: support --empty-commit option to handle empty patches Aleen via GitGitGadget
2021-11-15 11:13       ` Aleen 徐沛文
2021-11-16  5:18     ` [PATCH v4 0/2] am: support --empty-commit=(die|skip|asis) option to am empty commits Aleen via GitGitGadget
2021-11-16  5:18       ` [PATCH v4 1/2] doc: git-format-patch: describe the option --always Aleen via GitGitGadget
2021-11-16  5:18       ` [PATCH v4 2/2] am: support --empty-commit option to handle empty patches Aleen via GitGitGadget
2021-11-16 10:07         ` Phillip Wood
2021-11-16 10:31           ` Aleen 徐沛文
2021-11-17  8:39           ` Junio C Hamano
2021-11-17  9:33       ` [PATCH v5 0/2] am: support --empty-commit=(die|skip|asis) option to am empty commits Aleen via GitGitGadget
2021-11-17  9:33         ` [PATCH v5 1/2] doc: git-format-patch: describe the option --always Aleen via GitGitGadget
2021-11-17  9:33         ` [PATCH v5 2/2] am: support --empty option to handle empty patches Aleen via GitGitGadget
2021-11-18 10:50         ` [PATCH v6 0/3] am: support --empty=(die|drop|keep) " Aleen via GitGitGadget
2021-11-18 10:50           ` [PATCH v6 1/3] doc: git-format-patch: describe the option --always Aleen via GitGitGadget
2021-11-18 10:50           ` [PATCH v6 2/3] am: support --empty option to handle empty patches Aleen via GitGitGadget
2021-11-19  0:56             ` Junio C Hamano
2021-11-19 10:33             ` Bagas Sanjaya
2021-11-19 12:10               ` Ævar Arnfjörð Bjarmason
2021-11-19 12:20                 ` Eric Sunshine
2021-11-19 16:49                   ` Junio C Hamano
2021-11-19 16:46               ` Junio C Hamano
2021-11-18 10:50           ` [PATCH v6 3/3] am: throw an error when passing --empty option without value Aleen via GitGitGadget
2021-11-19  1:13             ` Junio C Hamano
2021-11-19  2:11               ` Aleen 徐沛文
2021-11-18 23:47           ` [PATCH v6 0/3] am: support --empty=(die|drop|keep) option to handle empty patches Junio C Hamano
2021-11-19  1:45             ` Aleen 徐沛文
2021-11-19  5:46               ` Junio C Hamano
2021-11-19  7:23                 ` Aleen 徐沛文
2021-11-19  7:25                   ` =?gb18030?B?QWxlZW4=?=
2021-11-19 16:54                   ` Junio C Hamano
2021-11-19 17:14                     ` Aleen 徐沛文
2021-11-19 19:25                       ` Junio C Hamano
2021-11-22 11:57                     ` Johannes Schindelin
2021-11-19  4:16             ` Aleen 徐沛文
2021-11-19  5:04           ` [PATCH v7 0/2] " Aleen via GitGitGadget
2021-11-19  5:04             ` [PATCH v7 1/2] doc: git-format-patch: describe the option --always Aleen via GitGitGadget
2021-11-19  5:04             ` [PATCH v7 2/2] am: support --empty=<option> to handle empty patches Aleen via GitGitGadget
2021-11-19 22:50               ` Junio C Hamano
2021-11-19 23:07               ` Junio C Hamano
2021-11-22  6:46             ` [PATCH v8 0/2] am: support --empty=(die|drop|keep) option " Aleen via GitGitGadget
2021-11-22  6:46               ` [PATCH v8 1/2] doc: git-format-patch: describe the option --always Aleen via GitGitGadget
2021-11-22  6:46               ` [PATCH v8 2/2] am: support --empty=<option> to handle empty patches Aleen via GitGitGadget
2021-11-22  7:06                 ` Junio C Hamano
2021-11-22  7:19                   ` Aleen 徐沛文
2021-11-22  7:02               ` [PATCH v9 0/2] am: support --empty=(die|drop|keep) option " Aleen via GitGitGadget
2021-11-22  7:02                 ` [PATCH v9 1/2] doc: git-format-patch: describe the option --always Aleen 徐沛文 via GitGitGadget
2021-11-22  7:02                 ` [PATCH v9 2/2] am: support --empty=<option> to handle empty patches Aleen 徐沛文 via GitGitGadget
2021-11-22  7:04                   ` Aleen 徐沛文
2021-11-22  7:51                 ` [PATCH v10 0/2] am: support --empty=(die|drop|keep) option " Aleen via GitGitGadget
2021-11-22  7:51                   ` [PATCH v10 1/2] doc: git-format-patch: describe the option --always Aleen via GitGitGadget
2021-11-22 12:00                     ` Johannes Schindelin
2021-11-23  1:25                       ` Aleen 徐沛文
2021-11-23 12:30                         ` Johannes Schindelin
2021-11-22  7:51                   ` [PATCH v10 2/2] am: support --empty=<option> to handle empty patches Aleen via GitGitGadget
2021-11-23 15:26                   ` [PATCH v11 0/2] am: support --empty=(die|drop|keep) option " Aleen via GitGitGadget
2021-11-23 15:26                     ` [PATCH v11 1/2] doc: git-format-patch: describe the option --always 徐沛文 (Aleen) via GitGitGadget
2021-11-23 16:12                       ` Johannes Schindelin
2021-11-23 22:02                         ` Junio C Hamano
2021-11-23 15:26                     ` [PATCH v11 2/2] am: support --empty=<option> to handle empty patches 徐沛文 (Aleen) via GitGitGadget
2021-11-26 20:14                       ` Elijah Newren
2021-11-29  9:19                         ` Aleen 徐沛文
2021-11-29 10:00                           ` Aleen 徐沛文
2021-11-29 17:10                             ` Elijah Newren
2021-11-30  5:45                               ` [PATCH v12 3/3] am: support --allow-empty to record specific " Aleen 徐沛文
2021-11-29 18:17                         ` [PATCH v11 2/2] am: support --empty=<option> to handle " Junio C Hamano
2021-11-29 18:57                           ` Elijah Newren
2021-11-30  5:37                     ` [PATCH v12 0/3] am: support --empty=(die|drop|keep) option and --allow-empty option " Aleen via GitGitGadget
2021-11-30  5:37                       ` [PATCH v12 1/3] doc: git-format-patch: describe the option --always 徐沛文 (Aleen) via GitGitGadget
2021-11-30  5:37                       ` [PATCH v12 2/3] am: support --empty=<option> to handle empty patches 徐沛文 (Aleen) via GitGitGadget
2021-11-30  5:37                       ` [PATCH v12 3/3] am: support --allow-empty to record specific " 徐沛文 (Aleen) via GitGitGadget
2021-11-30  7:21                         ` Junio C Hamano
2021-11-30  9:55                       ` [PATCH v13 0/3] am: support --empty=(die|drop|keep) option and --allow-empty option to handle " Aleen via GitGitGadget
2021-11-30  9:55                         ` [PATCH v13 1/3] doc: git-format-patch: describe the option --always 徐沛文 (Aleen) via GitGitGadget
2021-11-30  9:55                         ` [PATCH v13 2/3] am: support --empty=<option> to handle empty patches 徐沛文 (Aleen) via GitGitGadget
2021-11-30  9:55                         ` [PATCH v13 3/3] am: support --allow-empty to record specific " 徐沛文 (Aleen) via GitGitGadget
2021-12-01  3:37                         ` [PATCH v14 0/3] am: support --empty=(die|drop|keep) option and --allow-empty option to handle " Aleen via GitGitGadget
2021-12-01  3:37                           ` [PATCH v14 1/3] doc: git-format-patch: describe the option --always 徐沛文 (Aleen) via GitGitGadget
2021-12-01  3:37                           ` [PATCH v14 2/3] am: support --empty=<option> to handle empty patches 徐沛文 (Aleen) via GitGitGadget
2021-12-03 22:30                             ` Johannes Schindelin
2021-12-01  3:37                           ` [PATCH v14 3/3] am: support --allow-empty to record specific " 徐沛文 (Aleen) via GitGitGadget
2021-12-02  0:58                             ` Junio C Hamano
2021-12-06  1:35                               ` Aleen 徐沛文
2021-12-06  9:41                           ` [PATCH v15 0/3] am: support --empty=(die|drop|keep) option and --allow-empty option to handle " Aleen via GitGitGadget
2021-12-06  9:41                             ` [PATCH v15 1/3] doc: git-format-patch: describe the option --always 徐沛文 (Aleen) via GitGitGadget
2021-12-06  9:41                             ` [PATCH v15 2/3] am: support --empty=<option> to handle empty patches 徐沛文 (Aleen) via GitGitGadget
2021-12-06  9:41                             ` [PATCH v15 3/3] am: support --allow-empty to record specific " 徐沛文 (Aleen) via GitGitGadget
2021-12-07  5:01                             ` [PATCH v16 0/3] am: support --empty=(die|drop|keep) option and --allow-empty option to handle " Aleen via GitGitGadget
2021-12-07  5:01                               ` [PATCH v16 1/3] doc: git-format-patch: describe the option --always 徐沛文 (Aleen) via GitGitGadget
2021-12-07  5:01                               ` [PATCH v16 2/3] am: support --empty=<option> to handle empty patches 徐沛文 (Aleen) via GitGitGadget
2021-12-07  5:01                               ` [PATCH v16 3/3] am: support --allow-empty to record specific " 徐沛文 (Aleen) via GitGitGadget
2021-12-07  8:31                               ` [PATCH v17 0/3] am: support --empty=(die|drop|keep) option and --allow-empty option to handle " Aleen via GitGitGadget
2021-12-07  8:31                                 ` [PATCH v17 1/3] doc: git-format-patch: describe the option --always 徐沛文 (Aleen) via GitGitGadget
2021-12-07  8:31                                 ` [PATCH v17 2/3] am: support --empty=<option> to handle empty patches 徐沛文 (Aleen) via GitGitGadget
2021-12-07 18:12                                   ` Junio C Hamano
2021-12-07  8:31                                 ` [PATCH v17 3/3] am: support --allow-empty to record specific " 徐沛文 (Aleen) via GitGitGadget
2021-12-07 18:23                                   ` Junio C Hamano
2021-12-07 18:24                                 ` [PATCH v17 0/3] am: support --empty=(die|drop|keep) option and --allow-empty option to handle " Junio C Hamano
2021-12-08  5:05                                 ` [PATCH v18 " Aleen via GitGitGadget
2021-12-08  5:05                                   ` [PATCH v18 1/3] doc: git-format-patch: describe the option --always 徐沛文 (Aleen) via GitGitGadget
2021-12-08  5:05                                   ` [PATCH v18 2/3] am: support --empty=<option> to handle empty patches 徐沛文 (Aleen) via GitGitGadget
2021-12-08  5:05                                   ` [PATCH v18 3/3] am: support --allow-empty to record specific " 徐沛文 (Aleen) via GitGitGadget
2021-12-08  6:22                                     ` Junio C Hamano
2021-12-08  6:46                                       ` Aleen 徐沛文
2021-12-08 11:32                                         ` Junio C Hamano
2021-12-09  7:25                                   ` [PATCH v19 0/3] am: support --empty=(die|drop|keep) option and --allow-empty option to handle " Aleen via GitGitGadget
2021-12-09  7:25                                     ` [PATCH v19 1/3] doc: git-format-patch: describe the option --always 徐沛文 (Aleen) via GitGitGadget
2021-12-09  9:28                                       ` Bagas Sanjaya
2021-12-10  1:26                                         ` Aleen 徐沛文
2021-12-10  6:50                                           ` Bagas Sanjaya
2021-12-11  9:22                                             ` Junio C Hamano
2021-12-09  7:25                                     ` [PATCH v19 2/3] am: support --empty=<option> to handle empty patches 徐沛文 (Aleen) via GitGitGadget
2021-12-09  7:25                                     ` [PATCH v19 3/3] am: support --allow-empty to record specific " 徐沛文 (Aleen) via GitGitGadget

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=xmqq4k8hovy3.fsf@gitster.g \
    --to=gitster@pobox.com \
    --cc=aleen42@vip.qq.com \
    --cc=git@vger.kernel.org \
    --cc=gitgitgadget@gmail.com \
    --cc=l.s.r@web.de \
    /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).