From: Aleen via GitGitGadget <hidden> Date: 2021-11-12 05:00:46
Since that git has supported the --always option for the git-format-patch
command to create a patch with empty commit message, git-am should support
applying and committing with empty patches.
Aleen (2):
doc: git-format-patch: specify the option --always
am: support --always option to am empty commits
Documentation/git-am.txt | 5 +++++
Documentation/git-format-patch.txt | 5 +++++
builtin/am.c | 18 ++++++++++++++++--
t/t4150-am.sh | 25 +++++++++++++++++++++++++
4 files changed, 51 insertions(+), 2 deletions(-)
base-commit: b550198c73edd4cc058832dcf74b41aeec2adba2
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1076%2Faleen42%2Fnext-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1076/aleen42/next-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/1076
--
gitgitgadget
@@ -388,6 +389,10 @@ you can use `--suffix=-patch` to get `0001-description-of-my-change-patch`. --progress:: Show progress reports on stderr as patches are generated.+--always::+ Patch commits with detailed commit messages,+ even if they emit no changes. (see linkgit:git-diff-tree[1])+ CONFIGURATION ------------- You can specify extra mail header lines to be added to each message,
@@ -159,6 +160,10 @@ default. You can use `--no-utf8` to override this. countermand both `commit.gpgSign` configuration variable, and earlier `--gpg-sign`.+--always::+ Apply patches of commits with detailed commit messages,+ even if they emit no changes. (see linkgit:git-format-patch[1])+ --continue:: -r:: --resolved::
@@ -2357,6 +2367,10 @@ int cmd_am(int argc, const char **argv, const char *prefix){OPTION_STRING,'S',"gpg-sign",&state.sign_commit,N_("key-id"),N_("GPG-sign commits"),PARSE_OPT_OPTARG,NULL,(intptr_t)""},+OPT_BOOL(0,"always",&state.always,+N_("always apply patch event if the patch is empty")),+OPT_HIDDEN_BOOL(0,"empty-commit",&state.empty_commit,+N_("(internal use for skipping git-apply to empty commits)")),OPT_HIDDEN_BOOL(0,"rebasing",&state.rebasing,N_("(internal use for git-rebase)")),OPT_END()
@@ -1152,4 +1158,23 @@ test_expect_success 'apply binary blob in partial clone' 'git-Cclientam../patch'+test_expect_success'am a real empty patch with the --always option''+rm-fr.git/rebase-apply&&+gitreset--hard&&+test_must_failgitam--alwaysempty.patch2>actual&&+echoPatchformatdetectionfailed.>expected&&+test_cmpexpectedactual+'++test_expect_success'am a patch with empty commits''+grep"empty commit"empty-commit.patch&&+rm-fr.git/rebase-apply&&+gitreset--hard&&+gitcheckoutempty-commit^&&+gitam--alwaysempty-commit.patch&&+test_path_is_missing.git/rebase-apply&&+gitcat-filecommitHEAD>actual&&+test_i18ngrep"empty commit"actual+'+ test_done
From: René Scharfe <hidden> Date: 2021-11-12 06:17:56
Am 12.11.21 um 05:58 schrieb Aleen via GitGitGadget:
Since that git has supported the --always option for the git-format-patch
command to create a patch with empty commit message, git-am should support
applying and committing with empty patches.
The symmetry is compelling, but "always" is quite generic. I can see
e.g. someone expecting "git am --always" to imply --keep-non-patch.
git commit and cherry-pick have --allow-empty, which is (a bit) more
specific. That seems to me a better option name to copy for a commit-
creating command like git am.
René
From: Aleen via GitGitGadget <hidden> Date: 2021-11-12 06:54:08
Since that git has supported the --always option for the git-format-patch
command to create a patch with empty commit message, git-am should support
applying and committing with empty patches.
Changes since v1:
* test: am: add the case when not passing the --always option
* chore: am: rename the --always option to --allow-empty
Aleen (4):
doc: git-format-patch: specify the option --always
am: support --always option to am empty commits
test: am: add the case when not passing the --always option
chore: am: rename the --always option to --allow-empty
Documentation/git-am.txt | 5 +++++
Documentation/git-format-patch.txt | 5 +++++
builtin/am.c | 18 +++++++++++++--
t/t4150-am.sh | 35 ++++++++++++++++++++++++++++++
4 files changed, 61 insertions(+), 2 deletions(-)
base-commit: b550198c73edd4cc058832dcf74b41aeec2adba2
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1076%2Faleen42%2Fnext-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1076/aleen42/next-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/1076
Range-diff vs v1:
1: 71e6989375c = 1: 71e6989375c doc: git-format-patch: specify the option --always
2: 59b1417da37 = 2: 59b1417da37 am: support --always option to am empty commits
-: ----------- > 3: da024ced668 test: am: add the case when not passing the --always option
-: ----------- > 4: 45e9720f40b chore: am: rename the --always option to --allow-empty
--
gitgitgadget
@@ -388,6 +389,10 @@ you can use `--suffix=-patch` to get `0001-description-of-my-change-patch`. --progress:: Show progress reports on stderr as patches are generated.+--always::+ Patch commits with detailed commit messages,+ even if they emit no changes. (see linkgit:git-diff-tree[1])+ CONFIGURATION ------------- You can specify extra mail header lines to be added to each message,
@@ -159,6 +160,10 @@ default. You can use `--no-utf8` to override this. countermand both `commit.gpgSign` configuration variable, and earlier `--gpg-sign`.+--always::+ Apply patches of commits with detailed commit messages,+ even if they emit no changes. (see linkgit:git-format-patch[1])+ --continue:: -r:: --resolved::
@@ -2357,6 +2367,10 @@ int cmd_am(int argc, const char **argv, const char *prefix){OPTION_STRING,'S',"gpg-sign",&state.sign_commit,N_("key-id"),N_("GPG-sign commits"),PARSE_OPT_OPTARG,NULL,(intptr_t)""},+OPT_BOOL(0,"always",&state.always,+N_("always apply patch event if the patch is empty")),+OPT_HIDDEN_BOOL(0,"empty-commit",&state.empty_commit,+N_("(internal use for skipping git-apply to empty commits)")),OPT_HIDDEN_BOOL(0,"rebasing",&state.rebasing,N_("(internal use for git-rebase)")),OPT_END()
@@ -1152,4 +1158,23 @@ test_expect_success 'apply binary blob in partial clone' 'git-Cclientam../patch'+test_expect_success'am a real empty patch with the --always option''+rm-fr.git/rebase-apply&&+gitreset--hard&&+test_must_failgitam--alwaysempty.patch2>actual&&+echoPatchformatdetectionfailed.>expected&&+test_cmpexpectedactual+'++test_expect_success'am a patch with empty commits''+grep"empty commit"empty-commit.patch&&+rm-fr.git/rebase-apply&&+gitreset--hard&&+gitcheckoutempty-commit^&&+gitam--alwaysempty-commit.patch&&+test_path_is_missing.git/rebase-apply&&+gitcat-filecommitHEAD>actual&&+test_i18ngrep"empty commit"actual+'+ test_done
@@ -1166,7 +1166,17 @@ test_expect_success 'am a real empty patch with the --always option' 'test_cmpexpectedactual'-test_expect_success'am a patch with empty commits''+test_expect_success'am a patch of empty commits without the --always option''+grep"empty commit"empty-commit.patch&&+rm-fr.git/rebase-apply&&+gitreset--hard&&+gitcheckoutempty-commit^&&+test_must_failgitamempty-commit.patch>err&&+test_path_is_dir.git/rebase-apply&&+test_i18ngrep"Patch is empty."err+'++test_expect_success'am a patch of empty commits with the --always option''grep"empty commit"empty-commit.patch&&rm-fr.git/rebase-apply&&gitreset--hard&&
@@ -160,7 +160,7 @@ default. You can use `--no-utf8` to override this. countermand both `commit.gpgSign` configuration variable, and earlier `--gpg-sign`.---always::+--allow-empty:: Apply patches of commits with detailed commit messages, even if they emit no changes. (see linkgit:git-format-patch[1])
@@ -1251,7 +1251,7 @@ static int parse_mail(struct am_state *state, const char *mail)}if(is_empty_or_missing_file(am_path(state,"patch"))){-if(state->always){+if(state->allow_empty){state->empty_commit=1;}else{printf_ln(_("Patch is empty."));
@@ -2367,8 +2367,8 @@ int cmd_am(int argc, const char **argv, const char *prefix){OPTION_STRING,'S',"gpg-sign",&state.sign_commit,N_("key-id"),N_("GPG-sign commits"),PARSE_OPT_OPTARG,NULL,(intptr_t)""},-OPT_BOOL(0,"always",&state.always,-N_("always apply patch event if the patch is empty")),+OPT_BOOL(0,"allow-empty",&state.allow_empty,+N_("allow to apply patches of empty commits")),OPT_HIDDEN_BOOL(0,"empty-commit",&state.empty_commit,N_("(internal use for skipping git-apply to empty commits)")),OPT_HIDDEN_BOOL(0,"rebasing",&state.rebasing,
@@ -1158,15 +1158,15 @@ test_expect_success 'apply binary blob in partial clone' 'git-Cclientam../patch'-test_expect_success'am a real empty patch with the --always option''+test_expect_success'am a real empty patch with the --allow-empty option''rm-fr.git/rebase-apply&&gitreset--hard&&-test_must_failgitam--alwaysempty.patch2>actual&&+test_must_failgitam--allow-emptyempty.patch2>actual&&echoPatchformatdetectionfailed.>expected&&test_cmpexpectedactual'-test_expect_success'am a patch of empty commits without the --always option''+test_expect_success'am a patch of empty commits without the --allow-empty option''grep"empty commit"empty-commit.patch&&rm-fr.git/rebase-apply&&gitreset--hard&&
@@ -1176,12 +1176,12 @@ test_expect_success 'am a patch of empty commits without the --always option' 'test_i18ngrep"Patch is empty."err'-test_expect_success'am a patch of empty commits with the --always option''+test_expect_success'am a patch of empty commits with the --allow-empty option''grep"empty commit"empty-commit.patch&&rm-fr.git/rebase-apply&&gitreset--hard&&gitcheckoutempty-commit^&&-gitam--alwaysempty-commit.patch&&+gitam--allow-emptyempty-commit.patch&&test_path_is_missing.git/rebase-apply&&gitcat-filecommitHEAD>actual&&test_i18ngrep"empty commit"actual
The symmetry is compelling, but "always" is quite generic. I can see
e.g. someone expecting "git am --always" to imply --keep-non-patch.
git commit and cherry-pick have --allow-empty, which is (a bit) more
specific. That seems to me a better option name to copy for a commit-
creating command like git am.
It was designed corresponding to --always option in git-format-patch, which
will be pssed into git-diff-tree. As a commit-creating command, --allow-empty
is apparently a better choice. I will re-submit it, thank you.
@@ -388,6 +389,10 @@ you can use `--suffix=-patch` to get `0001-description-of-my-change-patch`. --progress:: Show progress reports on stderr as patches are generated.+--always::+ Patch commits with detailed commit messages,+ even if they emit no changes. (see linkgit:git-diff-tree[1])
What does the verb "Patch" mean here? It cannot be what the command
"patch" does, i.e. apply a diff to working tree files, as
format-patch does not apply any patch.
Who guarantees that commit messages are detailed? If I write a
commit that does not change anything with a one-liner message, would
this option make that message more detailed? I doubt that it would
be the case.
This option may sit much better near the --ignore-if-in-upstream
option. The primary way the command is told which commits to show
is via its argument (<since> or <revision-range>), and we do not
have many options to affect the selection of commits, but this one
and --ignore-if-in-upstream are such options. Borrowing from the
way the description of that other option is phrased, perhaps
Include patches for commits that do not introduce any change,
which are omitted by default.
Do not refer to 'git-diff-tree'; I do not think the reader who is
learning how to drive format-patch will learn anything new by
reading that page.
I have a feeling that if we were to endorse and promote this option
by documenting (note: it was an accident and a mistake that this
option is understood by underlying revision.c parse machinery, and
not a designed behaviour for format-patch to do anything to empty
commits), we should give users a better synonym to invoke it, but
that can and should be outside of this step.
From: Junio C Hamano <hidden> Date: 2021-11-12 22:23:05
"Aleen via GitGitGadget" [off-list ref] writes:
From: Aleen <redacted>
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.
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.
quoted hunk
@@ -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.
@@ -1152,4 +1158,23 @@ test_expect_success 'apply binary blob in partial clone' 'git-Cclientam../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)?
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?
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"?
@@ -192,6 +192,10 @@ will want to ensure that threading is disabled for `git send-email`. patches being generated, and any patch that matches is ignored.+--always::+ Include patches for commits that do not introduce any change,+ which are omitted by default.+ --cover-from-description=<mode>:: Controls which parts of the cover letter will be automatically populated using the branch's description.
@@ -63,6 +64,14 @@ OPTIONS --quoted-cr=<action>:: This flag will be passed down to 'git mailinfo' (see linkgit:git-mailinfo[1]).+--empty-commit=(die|skip|asis)::+ 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 outputting error.+ When this option is set to 'asis', create an empty commit,+ recording the contents of the e-mail message as its log.+ 'die' is specified by default.+ -m:: --message-id:: Pass the `-m` flag to 'git mailinfo' (see linkgit:git-mailinfo[1]),
@@ -178,6 +185,23 @@ static int am_option_parse_quoted_cr(const struct option *opt,return0;}+staticintam_option_parse_empty_commit(conststructoption*opt,+constchar*arg,intunset)+{+int*opt_value=opt->value;++if(unset||!strcmp(arg,"die"))+*opt_value=DIE_EMPTY_COMMIT;+elseif(!strcmp(arg,"skip"))+*opt_value=SKIP_EMPTY_COMMIT;+elseif(!strcmp(arg,"asis"))+*opt_value=ASIS_EMPTY_COMMIT;+else+returnerror(_("Invalid value for --empty-commit: %s"),arg);++return0;+}+/***Returnspathrelativetotheam_statedirectory.*/
@@ -1248,11 +1272,6 @@ static int parse_mail(struct am_state *state, const char *mail)gotofinish;}-if(is_empty_or_missing_file(am_path(state,"patch"))){-printf_ln(_("Patch is empty."));-die_user_resolve(state);-}-strbuf_addstr(&msg,"\n\n");strbuf_addbuf(&msg,&mi.log_message);strbuf_stripspace(&msg,0);
@@ -1792,6 +1811,20 @@ static void am_run(struct am_state *state, int resume)if(state->interactive&&do_interactive(state))gotonext;+if(is_empty_or_missing_file(am_path(state,"patch"))){+if(state->empty_commit==SKIP_EMPTY_COMMIT)+gotonext;+elseif(state->empty_commit==ASIS_EMPTY_COMMIT){+if(run_applypatch_msg_hook(state))+exit(1);+else+gotocommit;+}elseif(state->empty_commit==DIE_EMPTY_COMMIT){+printf_ln(_("Patch is empty."));+die_user_resolve(state);+}+}+if(run_applypatch_msg_hook(state))exit(1);
@@ -2357,6 +2391,10 @@ int cmd_am(int argc, const char **argv, const char *prefix){OPTION_STRING,'S',"gpg-sign",&state.sign_commit,N_("key-id"),N_("GPG-sign commits"),PARSE_OPT_OPTARG,NULL,(intptr_t)""},+{OPTION_CALLBACK,0,"empty-commit",&state.empty_commit,+"(die|skip|asis)",+N_("specify how to handle empty patches"),+PARSE_OPT_OPTARG,am_option_parse_empty_commit},OPT_HIDDEN_BOOL(0,"rebasing",&state.rebasing,N_("(internal use for git-rebase)")),OPT_END()
@@ -1152,4 +1158,56 @@ test_expect_success 'apply binary blob in partial clone' 'git-Cclientam../patch'+test_expect_success'still output error with --empty-commit when meeting empty files''+test_must_failgitam--empty-commit=skipempty.patch2>actual&&+echoPatchformatdetectionfailed.>expected&&+test_cmpexpectedactual+'++test_expect_success'error when meeting e-mail message that lacks a patch by default''+gitcheckoutempty-commit^&&+test_must_failgitamempty-commit.patch>err&&+test_path_is_dir.git/rebase-apply&&+test_i18ngrep"Patch is empty."err&&+rm-fr.git/rebase-apply&&++test_must_failgitam--empty-commit=dieempty-commit.patch>err&&+test_path_is_dir.git/rebase-apply&&+test_i18ngrep"Patch is empty."err&&+rm-fr.git/rebase-apply&&++test_must_failgitam--empty-commit=diecover-letter.patch>err&&+test_path_is_dir.git/rebase-apply&&+test_i18ngrep"Patch is empty."err&&+rm-fr.git/rebase-apply+'++test_expect_success'skip without error when meeting e-mail message that lacks a patch''+gitam--empty-commit=skipempty-commit.patch>err&&+test_path_is_missing.git/rebase-apply&&+gitrev-parseempty-commit^>expected&&+gitrev-parseHEAD>actual&&+test_cmpexpectedactual&&++gitam--empty-commit=skipcover-letter.patch>err&&+test_path_is_missing.git/rebase-apply&&+gitrev-parseempty-commit^>expected&&+gitrev-parseHEAD>actual&&+test_cmpexpectedactual+'++test_expect_success'record as an empty commit when meeting e-mail message that lacks a patch''+gitam--empty-commit=asisempty-commit.patch&&+test_path_is_missing.git/rebase-apply&&+gitshowempty-commit--format="%B">expected&&+gitshowHEAD--format="%B">actual&&+grep-factualexpected&&++gitam--empty-commit=asiscover-letter.patch&&+test_path_is_missing.git/rebase-apply&&+gitshowempty-commit--format="%B">expected&&+gitshowHEAD--format="%B">actual&&+grep-factualexpected+'+ test_done
Dears Hamano,
Sorry about the late submission, and I have modified it to support the `--empty-commit=(die|skip|asis)` pattern.
+test_expect_success 'record as an empty commit when meeting e-mail message that lacks a patch' '
+ git am --empty-commit=asis empty-commit.patch &&
+ test_path_is_missing .git/rebase-apply &&
+ git show empty-commit --format="%B" >expected &&
+ git show HEAD --format="%B" >actual &&
+ grep -f actual expected &&
+
+ git am --empty-commit=asis cover-letter.patch &&
+ test_path_is_missing .git/rebase-apply &&
+ git show empty-commit --format="%B" >expected &&
+ git show HEAD --format="%B" >actual &&
+ grep -f actual expected
+'
When it comes to the last test case, there are some accidental contents recognized as commit messages inside an empty patch, like:
1. version signatures:
> --
> 2.34.0.rc2.390.gef33ce8c6f
2. information of cover letter:
> *** BLURB HERE ***
>
> A U Thor (1):
> empty commit
I don't think it is necessary to fix it within `mailinfo.c`. Can you give me some suggestions on whether this case should be handled?
Aleen
@@ -192,6 +192,10 @@ will want to ensure that threading is disabled for `git send-email`. patches being generated, and any patch that matches is ignored.+--always::+ Include patches for commits that do not introduce any change,+ which are omitted by default.+ --cover-from-description=<mode>:: Controls which parts of the cover letter will be automatically populated using the branch's description.
@@ -63,6 +64,14 @@ OPTIONS --quoted-cr=<action>:: This flag will be passed down to 'git mailinfo' (see linkgit:git-mailinfo[1]).+--empty-commit=(die|skip|asis)::+ 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 outputting error.+ When this option is set to 'asis', create an empty commit,+ recording the contents of the e-mail message as its log.+ 'die' is specified by default.+ -m:: --message-id:: Pass the `-m` flag to 'git mailinfo' (see linkgit:git-mailinfo[1]),
@@ -178,6 +185,23 @@ static int am_option_parse_quoted_cr(const struct option *opt,return0;}+staticintam_option_parse_empty_commit(conststructoption*opt,+constchar*arg,intunset)+{+int*opt_value=opt->value;++if(unset||!strcmp(arg,"die"))+*opt_value=DIE_EMPTY_COMMIT;+elseif(!strcmp(arg,"skip"))+*opt_value=SKIP_EMPTY_COMMIT;+elseif(!strcmp(arg,"asis"))+*opt_value=ASIS_EMPTY_COMMIT;+else+returnerror(_("Invalid value for --empty-commit: %s"),arg);++return0;+}+/***Returnspathrelativetotheam_statedirectory.*/
@@ -1248,11 +1272,6 @@ static int parse_mail(struct am_state *state, const char *mail)gotofinish;}-if(is_empty_or_missing_file(am_path(state,"patch"))){-printf_ln(_("Patch is empty."));-die_user_resolve(state);-}-strbuf_addstr(&msg,"\n\n");strbuf_addbuf(&msg,&mi.log_message);strbuf_stripspace(&msg,0);
@@ -1792,6 +1811,20 @@ static void am_run(struct am_state *state, int resume)if(state->interactive&&do_interactive(state))gotonext;+if(is_empty_or_missing_file(am_path(state,"patch"))){+if(state->empty_commit==SKIP_EMPTY_COMMIT)+gotonext;+elseif(state->empty_commit==ASIS_EMPTY_COMMIT){+if(run_applypatch_msg_hook(state))+exit(1);+else+gotocommit;+}elseif(state->empty_commit==DIE_EMPTY_COMMIT){+printf_ln(_("Patch is empty."));+die_user_resolve(state);+}+}+if(run_applypatch_msg_hook(state))exit(1);
@@ -2357,6 +2391,10 @@ int cmd_am(int argc, const char **argv, const char *prefix){OPTION_STRING,'S',"gpg-sign",&state.sign_commit,N_("key-id"),N_("GPG-sign commits"),PARSE_OPT_OPTARG,NULL,(intptr_t)""},+{OPTION_CALLBACK,0,"empty-commit",&state.empty_commit,+"(die|skip|asis)",+N_("specify how to handle empty patches"),+PARSE_OPT_OPTARG,am_option_parse_empty_commit},OPT_HIDDEN_BOOL(0,"rebasing",&state.rebasing,N_("(internal use for git-rebase)")),OPT_END()
@@ -1152,4 +1159,70 @@ test_expect_success 'apply binary blob in partial clone' 'git-Cclientam../patch'+test_expect_success'still output error with --empty-commit when meeting empty files''+test_must_failgitam--empty-commit=skipempty.patch2>actual&&+echoPatchformatdetectionfailed.>expected&&+test_cmpexpectedactual+'++test_expect_success'error when meeting e-mail message that lacks a patch by default''+gitcheckoutempty-commit^&&+test_must_failgitamempty-commit.patch>err&&+test_path_is_dir.git/rebase-apply&&+test_i18ngrep"Patch is empty."err&&+rm-fr.git/rebase-apply&&++test_must_failgitam--empty-commit=dieempty-commit.patch>err&&+test_path_is_dir.git/rebase-apply&&+test_i18ngrep"Patch is empty."err&&+rm-fr.git/rebase-apply&&++test_must_failgitam--empty-commit=diecover-letter.patch>err&&+test_path_is_dir.git/rebase-apply&&+test_i18ngrep"Patch is empty."err&&+rm-fr.git/rebase-apply+'++test_expect_success'skip without error when meeting e-mail message that lacks a patch''+gitam--empty-commit=skipempty-commit.patch>err&&+test_path_is_missing.git/rebase-apply&&+gitrev-parseempty-commit^>expected&&+gitrev-parseHEAD>actual&&+test_cmpexpectedactual&&++gitam--empty-commit=skipcover-letter.patch>err&&+test_path_is_missing.git/rebase-apply&&+test_cmp_revempty-commit^HEAD+'++test_expect_success'record as an empty commit when meeting e-mail message that lacks a patch''+gitam--empty-commit=asisempty-commit.patch&&+test_path_is_missing.git/rebase-apply&&+{+gitshowempty-commit--format="%B"&&+echo"--"&&+gitversion|sed-e"s/^git version //"&&+echo+}>expected&&+gitshowHEAD--format="%B">actual&&+test_cmpactualexpected&&++gitam--empty-commit=asiscover-letter.patch&&+test_path_is_missing.git/rebase-apply&&+{+echo"*** SUBJECT HERE ***"&&+echo&&+echo"*** BLURB HERE ***"&&+echo&&+echo"A U Thor (1):"&&+printf" "&&+gitshowempty-commit--format="%B"&&+echo"--"&&+gitversion|sed-e"s/^git version //"&&+echo+}>expected&&+gitshowHEAD--format="%B">actual&&+test_cmpactualexpected+'+ test_done
@@ -63,6 +64,14 @@ OPTIONS --quoted-cr=<action>:: This flag will be passed down to 'git mailinfo' (see linkgit:git-mailinfo[1]).+--empty-commit=(die|skip|asis)::+ 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 outputting error.+ When this option is set to 'asis', create an empty commit,+ recording the contents of the e-mail message as its log.+ 'die' is specified by default.
This feels sufficiently similar to the case of handling empty commits in
'git rebase' that it is worth trying to have a similar user interface.
Otherwise the two commands have two different option names doing more or
less the same thing. 'git rebase' has --empty=[drop,keep,ask] where drop
is the default. If am were to accept --empty=[drop,keep,die] it would
offer a similar user experience.
Best Wishes
Phillip
quoted hunk
-m::
--message-id::
Pass the `-m` flag to 'git mailinfo' (see linkgit:git-mailinfo[1]),
@@ -178,6 +185,23 @@ static int am_option_parse_quoted_cr(const struct option *opt,return0;}+staticintam_option_parse_empty_commit(conststructoption*opt,+constchar*arg,intunset)+{+int*opt_value=opt->value;++if(unset||!strcmp(arg,"die"))+*opt_value=DIE_EMPTY_COMMIT;+elseif(!strcmp(arg,"skip"))+*opt_value=SKIP_EMPTY_COMMIT;+elseif(!strcmp(arg,"asis"))+*opt_value=ASIS_EMPTY_COMMIT;+else+returnerror(_("Invalid value for --empty-commit: %s"),arg);++return0;+}+/***Returnspathrelativetotheam_statedirectory.*/
@@ -1248,11 +1272,6 @@ static int parse_mail(struct am_state *state, const char *mail)gotofinish;}-if(is_empty_or_missing_file(am_path(state,"patch"))){-printf_ln(_("Patch is empty."));-die_user_resolve(state);-}-strbuf_addstr(&msg,"\n\n");strbuf_addbuf(&msg,&mi.log_message);strbuf_stripspace(&msg,0);
@@ -1792,6 +1811,20 @@ static void am_run(struct am_state *state, int resume)if(state->interactive&&do_interactive(state))gotonext;+if(is_empty_or_missing_file(am_path(state,"patch"))){+if(state->empty_commit==SKIP_EMPTY_COMMIT)+gotonext;+elseif(state->empty_commit==ASIS_EMPTY_COMMIT){+if(run_applypatch_msg_hook(state))+exit(1);+else+gotocommit;+}elseif(state->empty_commit==DIE_EMPTY_COMMIT){+printf_ln(_("Patch is empty."));+die_user_resolve(state);+}+}+if(run_applypatch_msg_hook(state))exit(1);
@@ -2357,6 +2391,10 @@ int cmd_am(int argc, const char **argv, const char *prefix){OPTION_STRING,'S',"gpg-sign",&state.sign_commit,N_("key-id"),N_("GPG-sign commits"),PARSE_OPT_OPTARG,NULL,(intptr_t)""},+{OPTION_CALLBACK,0,"empty-commit",&state.empty_commit,+"(die|skip|asis)",+N_("specify how to handle empty patches"),+PARSE_OPT_OPTARG,am_option_parse_empty_commit},OPT_HIDDEN_BOOL(0,"rebasing",&state.rebasing,N_("(internal use for git-rebase)")),OPT_END()
@@ -1152,4 +1159,70 @@ test_expect_success 'apply binary blob in partial clone' 'git-Cclientam../patch'+test_expect_success'still output error with --empty-commit when meeting empty files''+test_must_failgitam--empty-commit=skipempty.patch2>actual&&+echoPatchformatdetectionfailed.>expected&&+test_cmpexpectedactual+'++test_expect_success'error when meeting e-mail message that lacks a patch by default''+gitcheckoutempty-commit^&&+test_must_failgitamempty-commit.patch>err&&+test_path_is_dir.git/rebase-apply&&+test_i18ngrep"Patch is empty."err&&+rm-fr.git/rebase-apply&&++test_must_failgitam--empty-commit=dieempty-commit.patch>err&&+test_path_is_dir.git/rebase-apply&&+test_i18ngrep"Patch is empty."err&&+rm-fr.git/rebase-apply&&++test_must_failgitam--empty-commit=diecover-letter.patch>err&&+test_path_is_dir.git/rebase-apply&&+test_i18ngrep"Patch is empty."err&&+rm-fr.git/rebase-apply+'++test_expect_success'skip without error when meeting e-mail message that lacks a patch''+gitam--empty-commit=skipempty-commit.patch>err&&+test_path_is_missing.git/rebase-apply&&+gitrev-parseempty-commit^>expected&&+gitrev-parseHEAD>actual&&+test_cmpexpectedactual&&++gitam--empty-commit=skipcover-letter.patch>err&&+test_path_is_missing.git/rebase-apply&&+test_cmp_revempty-commit^HEAD+'++test_expect_success'record as an empty commit when meeting e-mail message that lacks a patch''+gitam--empty-commit=asisempty-commit.patch&&+test_path_is_missing.git/rebase-apply&&+{+gitshowempty-commit--format="%B"&&+echo"--"&&+gitversion|sed-e"s/^git version //"&&+echo+}>expected&&+gitshowHEAD--format="%B">actual&&+test_cmpactualexpected&&++gitam--empty-commit=asiscover-letter.patch&&+test_path_is_missing.git/rebase-apply&&+{+echo"*** SUBJECT HERE ***"&&+echo&&+echo"*** BLURB HERE ***"&&+echo&&+echo"A U Thor (1):"&&+printf" "&&+gitshowempty-commit--format="%B"&&+echo"--"&&+gitversion|sed-e"s/^git version //"&&+echo+}>expected&&+gitshowHEAD--format="%B">actual&&+test_cmpactualexpected+'+test_done
+--empty-commit=(die|skip|asis)::
+ 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 outputting error.
+ When this option is set to 'asis', create an empty commit,
+ recording the contents of the e-mail message as its log.
+ 'die' is specified by default.
This feels sufficiently similar to the case of handling empty commits in
'git rebase' that it is worth trying to have a similar user interface.
Otherwise the two commands have two different option names doing more or
less the same thing. 'git rebase' has --empty=[drop,keep,ask] where drop
is the default. If am were to accept --empty=[drop,keep,die] it would
offer a similar user experience.
Best Wishes
Phillip
Dears Phillip,
It seems a good idea. Can Hamano make a decision?
Aleen
From: Junio C Hamano <hidden> Date: 2021-11-17 08:39:14
Phillip Wood [off-list ref] writes:
quoted
+--empty-commit=(die|skip|asis)::
+ 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 outputting error.
+ When this option is set to 'asis', create an empty commit,
+ recording the contents of the e-mail message as its log.
+ 'die' is specified by default.
This feels sufficiently similar to the case of handling empty commits
in 'git rebase' that it is worth trying to have a similar user
interface. Otherwise the two commands have two different option names
doing more or less the same thing. 'git rebase' has
--empty=[drop,keep,ask] where drop is the default. If am were to
accept --empty=[drop,keep,die] it would offer a similar user
experience.
Ah, thanks for noticing. I like the three words you suggest. If we
already have a similar option, we definitely should follow suit, and
I think "--empty" would be a better fit than "--empty-commit" in the
context of talking about the _input_ to "am".
@@ -192,6 +192,10 @@ will want to ensure that threading is disabled for `git send-email`. patches being generated, and any patch that matches is ignored.+--always::+ Include patches for commits that do not introduce any change,+ which are omitted by default.+ --cover-from-description=<mode>:: Controls which parts of the cover letter will be automatically populated using the branch's description.
@@ -63,6 +64,14 @@ OPTIONS --quoted-cr=<action>:: This flag will be passed down to 'git mailinfo' (see linkgit:git-mailinfo[1]).+--empty-commit=(die|drop|keep)::+ The command usually errors out when seeing an input e-mail+ message that lacks a patch. When this option is set to+ 'drop', skip such an e-mail message without outputting error.+ When this option is set to 'keep', create an empty commit,+ recording the contents of the e-mail message as its log.+ 'die' is specified by default.+ -m:: --message-id:: Pass the `-m` flag to 'git mailinfo' (see linkgit:git-mailinfo[1]),
@@ -178,6 +185,23 @@ static int am_option_parse_quoted_cr(const struct option *opt,return0;}+staticintam_option_parse_empty_commit(conststructoption*opt,+constchar*arg,intunset)+{+int*opt_value=opt->value;++if(unset||!strcmp(arg,"die"))+*opt_value=DIE_EMPTY_COMMIT;+elseif(!strcmp(arg,"drop"))+*opt_value=DROP_EMPTY_COMMIT;+elseif(!strcmp(arg,"keep"))+*opt_value=KEEP_EMPTY_COMMIT;+else+returnerror(_("Invalid value for --empty: %s"),arg);++return0;+}+/***Returnspathrelativetotheam_statedirectory.*/
@@ -1248,11 +1272,6 @@ static int parse_mail(struct am_state *state, const char *mail)gotofinish;}-if(is_empty_or_missing_file(am_path(state,"patch"))){-printf_ln(_("Patch is empty."));-die_user_resolve(state);-}-strbuf_addstr(&msg,"\n\n");strbuf_addbuf(&msg,&mi.log_message);strbuf_stripspace(&msg,0);
@@ -1792,6 +1811,20 @@ static void am_run(struct am_state *state, int resume)if(state->interactive&&do_interactive(state))gotonext;+if(is_empty_or_missing_file(am_path(state,"patch"))){+if(state->empty_type==DROP_EMPTY_COMMIT)+gotonext;+elseif(state->empty_type==KEEP_EMPTY_COMMIT){+if(run_applypatch_msg_hook(state))+exit(1);+else+gotocommit;+}elseif(state->empty_type==DIE_EMPTY_COMMIT){+printf_ln(_("Patch is empty."));+die_user_resolve(state);+}+}+if(run_applypatch_msg_hook(state))exit(1);
@@ -2357,6 +2391,10 @@ int cmd_am(int argc, const char **argv, const char *prefix){OPTION_STRING,'S',"gpg-sign",&state.sign_commit,N_("key-id"),N_("GPG-sign commits"),PARSE_OPT_OPTARG,NULL,(intptr_t)""},+{OPTION_CALLBACK,0,"empty",&state.empty_type,+"(die|drop|keep)",+N_("specify how to handle empty patches"),+PARSE_OPT_OPTARG,am_option_parse_empty_commit},OPT_HIDDEN_BOOL(0,"rebasing",&state.rebasing,N_("(internal use for git-rebase)")),OPT_END()
@@ -1152,4 +1159,70 @@ test_expect_success 'apply binary blob in partial clone' 'git-Cclientam../patch'+test_expect_success'still output error with --empty when meeting empty files''+test_must_failgitam--empty=dropempty.patch2>actual&&+echoPatchformatdetectionfailed.>expected&&+test_cmpexpectedactual+'++test_expect_success'error when meeting e-mail message that lacks a patch by default''+gitcheckoutempty-commit^&&+test_must_failgitamempty-commit.patch>err&&+test_path_is_dir.git/rebase-apply&&+test_i18ngrep"Patch is empty."err&&+rm-fr.git/rebase-apply&&++test_must_failgitam--empty=dieempty-commit.patch>err&&+test_path_is_dir.git/rebase-apply&&+test_i18ngrep"Patch is empty."err&&+rm-fr.git/rebase-apply&&++test_must_failgitam--empty=diecover-letter.patch>err&&+test_path_is_dir.git/rebase-apply&&+test_i18ngrep"Patch is empty."err&&+rm-fr.git/rebase-apply+'++test_expect_success'skip without error when meeting e-mail message that lacks a patch''+gitam--empty=dropempty-commit.patch>err&&+test_path_is_missing.git/rebase-apply&&+gitrev-parseempty-commit^>expected&&+gitrev-parseHEAD>actual&&+test_cmpexpectedactual&&++gitam--empty=dropcover-letter.patch>err&&+test_path_is_missing.git/rebase-apply&&+test_cmp_revempty-commit^HEAD+'++test_expect_success'record as an empty commit when meeting e-mail message that lacks a patch''+gitam--empty=keepempty-commit.patch&&+test_path_is_missing.git/rebase-apply&&+{+gitshowempty-commit--format="%B"&&+echo"--"&&+gitversion|sed-e"s/^git version //"&&+echo+}>expected&&+gitshowHEAD--format="%B">actual&&+test_cmpactualexpected&&++gitam--empty=keepcover-letter.patch&&+test_path_is_missing.git/rebase-apply&&+{+echo"*** SUBJECT HERE ***"&&+echo&&+echo"*** BLURB HERE ***"&&+echo&&+echo"A U Thor (1):"&&+printf" "&&+gitshowempty-commit--format="%B"&&+echo"--"&&+gitversion|sed-e"s/^git version //"&&+echo+}>expected&&+gitshowHEAD--format="%B">actual&&+test_cmpactualexpected+'+ test_done
@@ -192,6 +192,10 @@ will want to ensure that threading is disabled for `git send-email`. patches being generated, and any patch that matches is ignored.+--always::+ Include patches for commits that do not introduce any change,+ which are omitted by default.+ --cover-from-description=<mode>:: Controls which parts of the cover letter will be automatically populated using the branch's description.
From: Aleen via GitGitGadget <hidden> Date: 2021-11-18 10:51:10
Since that git has supported the --always option for the git-format-patch
command to create a patch with an empty commit message, git-am should
support applying and committing with empty patches.
----------------------------------------------------------------------------
Changes since v1:
1. add a case when not passing the --always option.
2. rename the --always option to --allow-empty.
----------------------------------------------------------------------------
Changes since v2:
1. rename the --allow-empty option to --empty-commit.
2. introduce three different strategies (die|skip|asis) when trying to
record empty patches as empty commits.
----------------------------------------------------------------------------
Changes since v3:
1. generate the missed file for test cases.
2. grep -f cannot be used under Mac OS.
----------------------------------------------------------------------------
Changes since v4:
1. rename the --empty-commit option to --empty.
2. rename three different strategies (die|skip|asis) to die, drop and keep
correspondingly.
----------------------------------------------------------------------------
Changes since v5:
1. throw an error when passing --empty option without value.
----------------------------------------------------------------------------
Aleen (3):
doc: git-format-patch: describe the option --always
am: support --empty option to handle empty patches
am: throw an error when passing --empty option without value
Documentation/git-am.txt | 9 ++++
Documentation/git-format-patch.txt | 6 ++-
builtin/am.c | 49 ++++++++++++++++--
t/t4150-am.sh | 79 ++++++++++++++++++++++++++++++
4 files changed, 137 insertions(+), 6 deletions(-)
base-commit: b550198c73edd4cc058832dcf74b41aeec2adba2
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1076%2Faleen42%2Fnext-v6
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1076/aleen42/next-v6
Pull-Request: https://github.com/gitgitgadget/git/pull/1076
Range-diff vs v5:
1: 9f1b3dd6d0b = 1: 9f1b3dd6d0b doc: git-format-patch: describe the option --always
2: 96d8573dc80 = 2: 96d8573dc80 am: support --empty option to handle empty patches
-: ----------- > 3: e907a2b2faa am: throw an error when passing --empty option without value
--
gitgitgadget
@@ -63,6 +64,14 @@ OPTIONS --quoted-cr=<action>:: This flag will be passed down to 'git mailinfo' (see linkgit:git-mailinfo[1]).+--empty-commit=(die|drop|keep)::+ The command usually errors out when seeing an input e-mail+ message that lacks a patch. When this option is set to+ 'drop', skip such an e-mail message without outputting error.+ When this option is set to 'keep', create an empty commit,+ recording the contents of the e-mail message as its log.+ 'die' is specified by default.+ -m:: --message-id:: Pass the `-m` flag to 'git mailinfo' (see linkgit:git-mailinfo[1]),
@@ -178,6 +185,23 @@ static int am_option_parse_quoted_cr(const struct option *opt,return0;}+staticintam_option_parse_empty_commit(conststructoption*opt,+constchar*arg,intunset)+{+int*opt_value=opt->value;++if(unset||!strcmp(arg,"die"))+*opt_value=DIE_EMPTY_COMMIT;+elseif(!strcmp(arg,"drop"))+*opt_value=DROP_EMPTY_COMMIT;+elseif(!strcmp(arg,"keep"))+*opt_value=KEEP_EMPTY_COMMIT;+else+returnerror(_("Invalid value for --empty: %s"),arg);++return0;+}+/***Returnspathrelativetotheam_statedirectory.*/
@@ -1248,11 +1272,6 @@ static int parse_mail(struct am_state *state, const char *mail)gotofinish;}-if(is_empty_or_missing_file(am_path(state,"patch"))){-printf_ln(_("Patch is empty."));-die_user_resolve(state);-}-strbuf_addstr(&msg,"\n\n");strbuf_addbuf(&msg,&mi.log_message);strbuf_stripspace(&msg,0);
@@ -1792,6 +1811,20 @@ static void am_run(struct am_state *state, int resume)if(state->interactive&&do_interactive(state))gotonext;+if(is_empty_or_missing_file(am_path(state,"patch"))){+if(state->empty_type==DROP_EMPTY_COMMIT)+gotonext;+elseif(state->empty_type==KEEP_EMPTY_COMMIT){+if(run_applypatch_msg_hook(state))+exit(1);+else+gotocommit;+}elseif(state->empty_type==DIE_EMPTY_COMMIT){+printf_ln(_("Patch is empty."));+die_user_resolve(state);+}+}+if(run_applypatch_msg_hook(state))exit(1);
@@ -2357,6 +2391,10 @@ int cmd_am(int argc, const char **argv, const char *prefix){OPTION_STRING,'S',"gpg-sign",&state.sign_commit,N_("key-id"),N_("GPG-sign commits"),PARSE_OPT_OPTARG,NULL,(intptr_t)""},+{OPTION_CALLBACK,0,"empty",&state.empty_type,+"(die|drop|keep)",+N_("specify how to handle empty patches"),+PARSE_OPT_OPTARG,am_option_parse_empty_commit},OPT_HIDDEN_BOOL(0,"rebasing",&state.rebasing,N_("(internal use for git-rebase)")),OPT_END()
@@ -1152,4 +1159,70 @@ test_expect_success 'apply binary blob in partial clone' 'git-Cclientam../patch'+test_expect_success'still output error with --empty when meeting empty files''+test_must_failgitam--empty=dropempty.patch2>actual&&+echoPatchformatdetectionfailed.>expected&&+test_cmpexpectedactual+'++test_expect_success'error when meeting e-mail message that lacks a patch by default''+gitcheckoutempty-commit^&&+test_must_failgitamempty-commit.patch>err&&+test_path_is_dir.git/rebase-apply&&+test_i18ngrep"Patch is empty."err&&+rm-fr.git/rebase-apply&&++test_must_failgitam--empty=dieempty-commit.patch>err&&+test_path_is_dir.git/rebase-apply&&+test_i18ngrep"Patch is empty."err&&+rm-fr.git/rebase-apply&&++test_must_failgitam--empty=diecover-letter.patch>err&&+test_path_is_dir.git/rebase-apply&&+test_i18ngrep"Patch is empty."err&&+rm-fr.git/rebase-apply+'++test_expect_success'skip without error when meeting e-mail message that lacks a patch''+gitam--empty=dropempty-commit.patch>err&&+test_path_is_missing.git/rebase-apply&&+gitrev-parseempty-commit^>expected&&+gitrev-parseHEAD>actual&&+test_cmpexpectedactual&&++gitam--empty=dropcover-letter.patch>err&&+test_path_is_missing.git/rebase-apply&&+test_cmp_revempty-commit^HEAD+'++test_expect_success'record as an empty commit when meeting e-mail message that lacks a patch''+gitam--empty=keepempty-commit.patch&&+test_path_is_missing.git/rebase-apply&&+{+gitshowempty-commit--format="%B"&&+echo"--"&&+gitversion|sed-e"s/^git version //"&&+echo+}>expected&&+gitshowHEAD--format="%B">actual&&+test_cmpactualexpected&&++gitam--empty=keepcover-letter.patch&&+test_path_is_missing.git/rebase-apply&&+{+echo"*** SUBJECT HERE ***"&&+echo&&+echo"*** BLURB HERE ***"&&+echo&&+echo"A U Thor (1):"&&+printf" "&&+gitshowempty-commit--format="%B"&&+echo"--"&&+gitversion|sed-e"s/^git version //"&&+echo+}>expected&&+gitshowHEAD--format="%B">actual&&+test_cmpactualexpected+'+ test_done
@@ -185,12 +185,14 @@ static int am_option_parse_quoted_cr(const struct option *opt,return0;}-staticintam_option_parse_empty_commit(conststructoption*opt,+staticintam_option_parse_empty(conststructoption*opt,constchar*arg,intunset){int*opt_value=opt->value;-if(unset||!strcmp(arg,"die"))+BUG_ON_OPT_NEG(unset);++if(!strcmp(arg,"die"))*opt_value=DIE_EMPTY_COMMIT;elseif(!strcmp(arg,"drop"))*opt_value=DROP_EMPTY_COMMIT;
@@ -2391,10 +2393,9 @@ int cmd_am(int argc, const char **argv, const char *prefix){OPTION_STRING,'S',"gpg-sign",&state.sign_commit,N_("key-id"),N_("GPG-sign commits"),PARSE_OPT_OPTARG,NULL,(intptr_t)""},-{OPTION_CALLBACK,0,"empty",&state.empty_type,-"(die|drop|keep)",-N_("specify how to handle empty patches"),-PARSE_OPT_OPTARG,am_option_parse_empty_commit},+OPT_CALLBACK_F(0,"empty",&state.empty_type,"{drop,keep,die}",+N_("how to handle empty patches"),+PARSE_OPT_NONEG,am_option_parse_empty),OPT_HIDDEN_BOOL(0,"rebasing",&state.rebasing,N_("(internal use for git-rebase)")),OPT_END()
@@ -1165,8 +1165,14 @@ test_expect_success 'still output error with --empty when meeting empty files' 'test_cmpexpectedactual'-test_expect_success'error when meeting e-mail message that lacks a patch by default''+test_expect_success'invalid when passing no value for the --empty option''gitcheckoutempty-commit^&&+test_must_failgitam--emptyempty-commit.patch2>err&&+echo"error: Invalid value for --empty: empty-commit.patch">expected&&+test_cmpexpectederr+'++test_expect_success'error when meeting e-mail message that lacks a patch by default''test_must_failgitamempty-commit.patch>err&&test_path_is_dir.git/rebase-apply&&test_i18ngrep"Patch is empty."err&&
From: Aleen via GitGitGadget <hidden> Date: 2021-11-19 05:05:11
From: Aleen <redacted>
This commit has described how to use '--always' option in the command
'git-format-patch' to include patches for commits that emit no changes.
Signed-off-by: Aleen <redacted>
---
Documentation/git-format-patch.txt | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
@@ -192,6 +192,10 @@ will want to ensure that threading is disabled for `git send-email`. patches being generated, and any patch that matches is ignored.+--always::+ Include patches for commits that do not introduce any change,+ which are omitted by default.+ --cover-from-description=<mode>:: Controls which parts of the cover letter will be automatically populated using the branch's description.
@@ -63,6 +64,13 @@ OPTIONS --quoted-cr=<action>:: This flag will be passed down to 'git mailinfo' (see linkgit:git-mailinfo[1]).+--empty-commit=(die|drop|keep)::+ By default, or when the option is set to 'die', the command+ errors out on an input e-mail message that lacks a patch. When+ this option is set to 'drop', skip such an e-mail message instead.+ When this option is set to 'keep', create an empty commit,+ recording the contents of the e-mail message as its log.+ -m:: --message-id:: Pass the `-m` flag to 'git mailinfo' (see linkgit:git-mailinfo[1]),
@@ -178,6 +185,25 @@ static int am_option_parse_quoted_cr(const struct option *opt,return0;}+staticintam_option_parse_empty(conststructoption*opt,+constchar*arg,intunset)+{+int*opt_value=opt->value;++BUG_ON_OPT_NEG(unset);++if(!strcmp(arg,"die"))+*opt_value=DIE_EMPTY_COMMIT;+elseif(!strcmp(arg,"drop"))+*opt_value=DROP_EMPTY_COMMIT;+elseif(!strcmp(arg,"keep"))+*opt_value=KEEP_EMPTY_COMMIT;+else+returnerror(_("Invalid value for --empty: %s"),arg);++return0;+}+/***Returnspathrelativetotheam_statedirectory.*/
@@ -1248,11 +1274,6 @@ static int parse_mail(struct am_state *state, const char *mail)gotofinish;}-if(is_empty_or_missing_file(am_path(state,"patch"))){-printf_ln(_("Patch is empty."));-die_user_resolve(state);-}-strbuf_addstr(&msg,"\n\n");strbuf_addbuf(&msg,&mi.log_message);strbuf_stripspace(&msg,0);
@@ -10840,7 +10840,7 @@ msgstr "no es posible escribir el archivo índice"msgid"Dirty index: cannot apply patches (dirty: %s)"msgstr"Índice sucio: no se puede aplicar parches (sucio: %s)"-#: builtin/am.c:1798 builtin/am.c:1865+#: builtin/am.c:1834 builtin/am.c:1902#, c-formatmsgid"Applying: %.*s"msgstr"Aplicando: %.*s"
@@ -1,7 +1,7 @@# SOME DESCRIPTIVE TITLE.# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER# This file is distributed under the same license as the PACKAGE package.-# +## Translators:# Alexander Golubev <fatzer2@gmail.com>, 2020# Dimitriy Ryazantcev <DJm00n@mail.ru>, 2014-2021
@@ -1152,4 +1158,47 @@ test_expect_success 'apply binary blob in partial clone' 'git-Cclientam../patch'+test_expect_success'An empty input file is error regardless of --empty option''+test_must_failgitam--empty=dropempty.patch2>actual&&+echoPatchformatdetectionfailed.>expected&&+test_cmpexpectedactual+'++test_expect_success'invalid when passing the --empty option alone''+gitcheckoutempty-commit^&&+test_must_failgitam--emptyempty-commit.patch2>err&&+echo"error: Invalid value for --empty: empty-commit.patch">expected&&+test_cmpexpectederr+'++test_expect_success'a message without a patch is an error (default)''+test_when_finished"git am --abort || :"&&+test_must_failgitamempty-commit.patch>err&&+grep"Patch is empty"err&&+rm-fr.git/rebase-apply+'++test_expect_success'a message without a patch is an error where an explicit "--empty=die" is given''+test_when_finished"git am --abort || :"&&+test_must_failgitam--empty=dieempty-commit.patch>err&&+grep"Patch is empty."err&&+rm-fr.git/rebase-apply+'++test_expect_success'a message without a patch will be skipped when "--empty=drop" is given''+gitam--empty=dropempty-commit.patch>output&&+gitrev-parseempty-commit^>expected&&+gitrev-parseHEAD>actual&&+test_cmpexpectedactual&&+grep"Skipping: empty commit"output+'++test_expect_success'record as an empty commit when meeting e-mail message that lacks a patch''+gitam--empty=keepempty-commit.patch&&+test_path_is_missing.git/rebase-apply&&+gitshowempty-commit--format="%s">expected&&+gitshowHEAD--format="%s">actual&&+test_cmpactualexpected+'+ test_done
+test_expect_success 'still output error with --empty when meeting empty files' '
+ test_must_fail git am --empty=drop empty.patch 2>actual &&
+ echo Patch format detection failed. >expected &&
+ test_cmp expected actual
+'
Why isn't the echo string quoted?
There's no need to quote the arguments given to echo in cases like
these.
It's not the same, i.e. it'll get N arguments on argv and not on, but it
makes it easier to spot things that do need quoting, rather than
over-quoting everything.
From: Eric Sunshine <hidden> Date: 2021-11-19 12:20:37
On Fri, Nov 19, 2021 at 7:12 AM Ævar Arnfjörð Bjarmason
[off-list ref] wrote:
On Fri, Nov 19 2021, Bagas Sanjaya wrote:
quoted
On 18/11/21 17.50, Aleen via GitGitGadget wrote:
quoted
+test_expect_success 'still output error with --empty when meeting empty files' '
+ test_must_fail git am --empty=drop empty.patch 2>actual &&
+ echo Patch format detection failed. >expected &&
+ test_cmp expected actual
+'
Why isn't the echo string quoted?
There's no need to quote the arguments given to echo in cases like
these.
It's not the same, i.e. it'll get N arguments on argv and not on, but it
makes it easier to spot things that do need quoting, rather than
over-quoting everything.
I recently expressed an opposing opinion in [1], stating effectively
that omitting the quotes like this is "an accident waiting to happen":
... the lack of quotes ... in the `echo ... >expect` statement
gives me a moment's pause since it relies upon the fact that
`echo` will insert exactly one space between the ... arguments
(which happens to match the single space in the [command's output]
). For clarity and that extra bit of robustness, I'd probably have
used a single double-quoted string argument with `echo`.
But, it's a fairly minor objection.
[1]: https://lore.kernel.org/git/CAPig+cQVSUg1aqry_hMydJ=Uo=-VhOog6TUTpG=0on0LUcw8Dg@mail.gmail.com/
From: Aleen via GitGitGadget <hidden> Date: 2021-11-22 06:46:57
From: Aleen <redacted>
This commit has described how to use '--always' option in the command
'git-format-patch' to include patches for commits that emit no changes.
Signed-off-by: Aleen 徐沛文 <redacted>
---
Documentation/git-format-patch.txt | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
@@ -192,6 +192,10 @@ will want to ensure that threading is disabled for `git send-email`. patches being generated, and any patch that matches is ignored.+--always::+ Include patches for commits that do not introduce any change,+ which are omitted by default.+ --cover-from-description=<mode>:: Controls which parts of the cover letter will be automatically populated using the branch's description.
From: Aleen via GitGitGadget <hidden> Date: 2021-11-22 06:47:04
From: Aleen <redacted>
Since that the command 'git-format-patch' can include patches of
commits that emit no changes, the 'git-am' command should also
support an option, named as '--empty', to specify how to handle
those empty patches. In this commit, we have implemented three
valid options ('die', 'drop' and 'keep').
Signed-off-by: Aleen 徐沛文 <redacted>
---
Documentation/git-am.txt | 8 ++++++
builtin/am.c | 55 ++++++++++++++++++++++++++++++++++++----
t/t4150-am.sh | 49 +++++++++++++++++++++++++++++++++++
3 files changed, 107 insertions(+), 5 deletions(-)
@@ -63,6 +64,13 @@ OPTIONS --quoted-cr=<action>:: This flag will be passed down to 'git mailinfo' (see linkgit:git-mailinfo[1]).+--empty=(die|drop|keep)::+ By default, or when the option is set to 'die', the command+ errors out on an input e-mail message that lacks a patch. When+ this option is set to 'drop', skip such an e-mail message instead.+ When this option is set to 'keep', create an empty commit,+ recording the contents of the e-mail message as its log.+ -m:: --message-id:: Pass the `-m` flag to 'git mailinfo' (see linkgit:git-mailinfo[1]),
@@ -178,6 +185,25 @@ static int am_option_parse_quoted_cr(const struct option *opt,return0;}+staticintam_option_parse_empty(conststructoption*opt,+constchar*arg,intunset)+{+int*opt_value=opt->value;++BUG_ON_OPT_NEG(unset);++if(!strcmp(arg,"die"))+*opt_value=DIE_EMPTY_COMMIT;+elseif(!strcmp(arg,"drop"))+*opt_value=DROP_EMPTY_COMMIT;+elseif(!strcmp(arg,"keep"))+*opt_value=KEEP_EMPTY_COMMIT;+else+returnerror(_("Invalid value for --empty: %s"),arg);++return0;+}+/***Returnspathrelativetotheam_statedirectory.*/
@@ -1248,11 +1274,6 @@ static int parse_mail(struct am_state *state, const char *mail)gotofinish;}-if(is_empty_or_missing_file(am_path(state,"patch"))){-printf_ln(_("Patch is empty."));-die_user_resolve(state);-}-strbuf_addstr(&msg,"\n\n");strbuf_addbuf(&msg,&mi.log_message);strbuf_stripspace(&msg,0);
@@ -1152,4 +1158,47 @@ test_expect_success 'apply binary blob in partial clone' 'git-Cclientam../patch'+test_expect_success'an empty input file is error regardless of --empty option''+test_when_finished"git am --abort || :"&&+test_must_failgitam--empty=dropempty.patch2>actual&&+echo"Patch format detection failed.">expected&&+test_cmpexpectedactual+'++test_expect_success'invalid when passing the --empty option alone''+test_when_finished"git am --abort || :"&&+gitcheckoutempty-commit^&&+test_must_failgitam--emptyempty-commit.patch2>err&&+echo"error: Invalid value for --empty: empty-commit.patch">expected&&+test_cmpexpectederr+'++test_expect_success'a message without a patch is an error (default)''+test_when_finished"git am --abort || :"&&+test_must_failgitamempty-commit.patch>err&&+grep"Patch is empty"err+'++test_expect_success'a message without a patch is an error where an explicit "--empty=die" is given''+test_when_finished"git am --abort || :"&&+test_must_failgitam--empty=dieempty-commit.patch>err&&+grep"Patch is empty."err+'++test_expect_success'a message without a patch will be skipped when "--empty=drop" is given''+gitam--empty=dropempty-commit.patch>output&&+gitrev-parseempty-commit^>expected&&+gitrev-parseHEAD>actual&&+test_cmpexpectedactual&&+grep"Skipping: empty commit"output+'++test_expect_success'record as an empty commit when meeting e-mail message that lacks a patch''+gitam--empty=keepempty-commit.patch&&+test_path_is_missing.git/rebase-apply&&+gitshowempty-commit--format="%s">expected&&+gitshowHEAD--format="%s">actual&&+test_cmpactualexpected+'+ test_done
From: Aleen via GitGitGadget <hidden> Date: 2021-11-22 07:02:39
Since that git has supported the --always option for the git-format-patch
command to create a patch with an empty commit message, git-am should
support applying and committing with empty patches.
----------------------------------------------------------------------------
Changes since v1:
1. add a case when not passing the --always option.
2. rename the --always option to --allow-empty.
----------------------------------------------------------------------------
Changes since v2:
1. rename the --allow-empty option to --empty-commit.
2. introduce three different strategies (die|skip|asis) when trying to
record empty patches as empty commits.
----------------------------------------------------------------------------
Changes since v3:
1. generate the missed file for test cases.
2. grep -f cannot be used under Mac OS.
----------------------------------------------------------------------------
Changes since v4:
1. rename the --empty-commit option to --empty.
2. rename three different strategies (die|skip|asis) to die, drop and keep
correspondingly.
----------------------------------------------------------------------------
Changes since v5:
1. throw an error when passing --empty option without value.
----------------------------------------------------------------------------
Changes since v6:
1. add i18n resources.
----------------------------------------------------------------------------
Changes since v7:
1. update code according to the seen branch.
2. fix the wrong document of git-am.
3. sign off commits by a real name.
----------------------------------------------------------------------------
Changes since v8:
1. update the committer's name with my real name to fix DCO of GGG.
Aleen 徐沛文 (2):
doc: git-format-patch: describe the option --always
am: support --empty=<option> to handle empty patches
Documentation/git-am.txt | 8 +++++
Documentation/git-format-patch.txt | 6 +++-
builtin/am.c | 55 +++++++++++++++++++++++++++---
t/t4150-am.sh | 49 ++++++++++++++++++++++++++
4 files changed, 112 insertions(+), 6 deletions(-)
base-commit: ca35af825273b98fc8dc11527488952f5db8eb80
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1076%2Faleen42%2Fnext-v9
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1076/aleen42/next-v9
Pull-Request: https://github.com/gitgitgadget/git/pull/1076
Range-diff vs v8:
1: 5d98a088e14 ! 1: 3b41ca3dec7 doc: git-format-patch: describe the option --always
@@
## Metadata ##
-Author: Aleen [off-list ref]
+Author: Aleen 徐沛文 [off-list ref]
## Commit message ##
doc: git-format-patch: describe the option --always
2: 3ff18e16a7a ! 2: d2ec18b36af am: support --empty=<option> to handle empty patches
@@
## Metadata ##
-Author: Aleen [off-list ref]
+Author: Aleen 徐沛文 [off-list ref]
## Commit message ##
am: support --empty=<option> to handle empty patches
--
gitgitgadget
From: Aleen 徐沛文 via GitGitGadget <hidden> Date: 2021-11-22 07:02:40
From: =?UTF-8?q?Aleen=20=E5=BE=90=E6=B2=9B=E6=96=87?= <redacted>
This commit has described how to use '--always' option in the command
'git-format-patch' to include patches for commits that emit no changes.
Signed-off-by: Aleen 徐沛文 <redacted>
---
Documentation/git-format-patch.txt | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
@@ -192,6 +192,10 @@ will want to ensure that threading is disabled for `git send-email`. patches being generated, and any patch that matches is ignored.+--always::+ Include patches for commits that do not introduce any change,+ which are omitted by default.+ --cover-from-description=<mode>:: Controls which parts of the cover letter will be automatically populated using the branch's description.
From: Aleen 徐沛文 via GitGitGadget <hidden> Date: 2021-11-22 07:02:43
From: =?UTF-8?q?Aleen=20=E5=BE=90=E6=B2=9B=E6=96=87?= <redacted>
Since that the command 'git-format-patch' can include patches of
commits that emit no changes, the 'git-am' command should also
support an option, named as '--empty', to specify how to handle
those empty patches. In this commit, we have implemented three
valid options ('die', 'drop' and 'keep').
Signed-off-by: Aleen 徐沛文 <redacted>
---
Documentation/git-am.txt | 8 ++++++
builtin/am.c | 55 ++++++++++++++++++++++++++++++++++++----
t/t4150-am.sh | 49 +++++++++++++++++++++++++++++++++++
3 files changed, 107 insertions(+), 5 deletions(-)
@@ -63,6 +64,13 @@ OPTIONS --quoted-cr=<action>:: This flag will be passed down to 'git mailinfo' (see linkgit:git-mailinfo[1]).+--empty=(die|drop|keep)::+ By default, or when the option is set to 'die', the command+ errors out on an input e-mail message that lacks a patch. When+ this option is set to 'drop', skip such an e-mail message instead.+ When this option is set to 'keep', create an empty commit,+ recording the contents of the e-mail message as its log.+ -m:: --message-id:: Pass the `-m` flag to 'git mailinfo' (see linkgit:git-mailinfo[1]),
@@ -178,6 +185,25 @@ static int am_option_parse_quoted_cr(const struct option *opt,return0;}+staticintam_option_parse_empty(conststructoption*opt,+constchar*arg,intunset)+{+int*opt_value=opt->value;++BUG_ON_OPT_NEG(unset);++if(!strcmp(arg,"die"))+*opt_value=DIE_EMPTY_COMMIT;+elseif(!strcmp(arg,"drop"))+*opt_value=DROP_EMPTY_COMMIT;+elseif(!strcmp(arg,"keep"))+*opt_value=KEEP_EMPTY_COMMIT;+else+returnerror(_("Invalid value for --empty: %s"),arg);++return0;+}+/***Returnspathrelativetotheam_statedirectory.*/
@@ -1248,11 +1274,6 @@ static int parse_mail(struct am_state *state, const char *mail)gotofinish;}-if(is_empty_or_missing_file(am_path(state,"patch"))){-printf_ln(_("Patch is empty."));-die_user_resolve(state);-}-strbuf_addstr(&msg,"\n\n");strbuf_addbuf(&msg,&mi.log_message);strbuf_stripspace(&msg,0);
@@ -1152,4 +1158,47 @@ test_expect_success 'apply binary blob in partial clone' 'git-Cclientam../patch'+test_expect_success'an empty input file is error regardless of --empty option''+test_when_finished"git am --abort || :"&&+test_must_failgitam--empty=dropempty.patch2>actual&&+echo"Patch format detection failed.">expected&&+test_cmpexpectedactual+'++test_expect_success'invalid when passing the --empty option alone''+test_when_finished"git am --abort || :"&&+gitcheckoutempty-commit^&&+test_must_failgitam--emptyempty-commit.patch2>err&&+echo"error: Invalid value for --empty: empty-commit.patch">expected&&+test_cmpexpectederr+'++test_expect_success'a message without a patch is an error (default)''+test_when_finished"git am --abort || :"&&+test_must_failgitamempty-commit.patch>err&&+grep"Patch is empty"err+'++test_expect_success'a message without a patch is an error where an explicit "--empty=die" is given''+test_when_finished"git am --abort || :"&&+test_must_failgitam--empty=dieempty-commit.patch>err&&+grep"Patch is empty."err+'++test_expect_success'a message without a patch will be skipped when "--empty=drop" is given''+gitam--empty=dropempty-commit.patch>output&&+gitrev-parseempty-commit^>expected&&+gitrev-parseHEAD>actual&&+test_cmpexpectedactual&&+grep"Skipping: empty commit"output+'++test_expect_success'record as an empty commit when meeting e-mail message that lacks a patch''+gitam--empty=keepempty-commit.patch&&+test_path_is_missing.git/rebase-apply&&+gitshowempty-commit--format="%s">expected&&+gitshowHEAD--format="%s">actual&&+test_cmpactualexpected+'+ test_done
Can somebody from GGG land help this user? I _think_ the easiest
workaround (other than not using GGG and sending e-mail in the old
fashioned way) is to commit and sign-off under the real name, and
push under whatever GitHub username to throw a GGG pull request,
which GGG should be able to take, as I have seen users forward other
authors commits just fine.
Sorry for the wrong report, and I have checked that the DCO integrated by GGG has only checked
whether the committer name is the same as the signed name. So I have changed it, and re-submitted
it via version 9.
`--empty-commit=(die|drop|keep)::`
Besides, I have also fixed a missed mistake, which also exists in the `seen` branch.
From: Junio C Hamano <hidden> Date: 2021-11-22 07:06:19
"Aleen via GitGitGadget" [off-list ref] writes:
From: Aleen <redacted>
Since that the command 'git-format-patch' can include patches of
commits that emit no changes, the 'git-am' command should also
support an option, named as '--empty', to specify how to handle
those empty patches. In this commit, we have implemented three
valid options ('die', 'drop' and 'keep').
Signed-off-by: Aleen 徐沛文 <redacted>
Perhaps this line should imitate what Hans Krentel did in
https://lore.kernel.org/git/pull.1143.git.git.1637347813367.gitgitgadget@gmail.com/,
i.e. real name first, and then (nickname) in parentheses.
Also, the in-body "From:" line should match the sign off.
I corrected what has been queued in 'seen' manually when I applied
the previous round.
+--empty=(die|drop|keep)::
This is the only change relative to what is queued (we had
"--empty-commit", which is remnant from an earlier iteration), and
it makes the documentation consistent with what the code does.
Good.
Perhaps this line should imitate what Hans Krentel did in
https://lore.kernel.org/git/pull.1143.git.git.1637347813367.gitgitgadget@gmail.com/,
i.e. real name first, and then (nickname) in parentheses.
Also, the in-body "From:" line should match the sign off.
I corrected what has been queued in 'seen' manually when I applied
the previous round.
quoted
+--empty=(die|drop|keep)::
This is the only change relative to what is queued (we had
"--empty-commit", which is remnant from an earlier iteration), and
it makes the documentation consistent with what the code does.
Good.
It seems there is something wrong when submitting via "徐沛文 (Aleen) [off-list ref]".
From: Aleen via GitGitGadget <hidden> Date: 2021-11-22 07:51:21
From: Aleen <redacted>
This commit has described how to use '--always' option in the command
'git-format-patch' to include patches for commits that emit no changes.
Signed-off-by: 徐沛文 (Aleen) <redacted>
---
Documentation/git-format-patch.txt | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
@@ -192,6 +192,10 @@ will want to ensure that threading is disabled for `git send-email`. patches being generated, and any patch that matches is ignored.+--always::+ Include patches for commits that do not introduce any change,+ which are omitted by default.+ --cover-from-description=<mode>:: Controls which parts of the cover letter will be automatically populated using the branch's description.
From: Aleen via GitGitGadget <hidden> Date: 2021-11-22 07:51:22
Since that git has supported the --always option for the git-format-patch
command to create a patch with an empty commit message, git-am should
support applying and committing with empty patches.
----------------------------------------------------------------------------
Changes since v1:
1. add a case when not passing the --always option.
2. rename the --always option to --allow-empty.
----------------------------------------------------------------------------
Changes since v2:
1. rename the --allow-empty option to --empty-commit.
2. introduce three different strategies (die|skip|asis) when trying to
record empty patches as empty commits.
----------------------------------------------------------------------------
Changes since v3:
1. generate the missed file for test cases.
2. grep -f cannot be used under Mac OS.
----------------------------------------------------------------------------
Changes since v4:
1. rename the --empty-commit option to --empty.
2. rename three different strategies (die|skip|asis) to die, drop and keep
correspondingly.
----------------------------------------------------------------------------
Changes since v5:
1. throw an error when passing --empty option without value.
----------------------------------------------------------------------------
Changes since v6:
1. add i18n resources.
----------------------------------------------------------------------------
Changes since v7:
1. update code according to the seen branch.
2. fix the wrong document of git-am.
3. sign off commits by a real name.
----------------------------------------------------------------------------
Changes since v8:
1. update the committer's name with my real name to fix DCO of GGG.
----------------------------------------------------------------------------
Changes since v9:
1. imitate the signed name format of
https://lore.kernel.org/git/pull.1143.git.git.1637347813367.gitgitgadget@gmail.com
.
cc: René Scharfe l.s.r@web.de cc: Phillip Wood phillip.wood123@gmail.com cc:
Aleen 徐沛文 pwxu@coremail.cn
Aleen (2):
doc: git-format-patch: describe the option --always
am: support --empty=<option> to handle empty patches
Documentation/git-am.txt | 8 +++++
Documentation/git-format-patch.txt | 6 +++-
builtin/am.c | 55 +++++++++++++++++++++++++++---
t/t4150-am.sh | 49 ++++++++++++++++++++++++++
4 files changed, 112 insertions(+), 6 deletions(-)
base-commit: ca35af825273b98fc8dc11527488952f5db8eb80
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1076%2Faleen42%2Fnext-v10
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1076/aleen42/next-v10
Pull-Request: https://github.com/gitgitgadget/git/pull/1076
Range-diff vs v9:
1: 3b41ca3dec7 ! 1: 59bce7131da doc: git-format-patch: describe the option --always
@@
## Metadata ##
-Author: Aleen 徐沛文 [off-list ref]
+Author: Aleen [off-list ref]
## Commit message ##
doc: git-format-patch: describe the option --always
@@ Commit message
This commit has described how to use '--always' option in the command
'git-format-patch' to include patches for commits that emit no changes.
- Signed-off-by: Aleen 徐沛文 [off-list ref]
+ Signed-off-by: 徐沛文 (Aleen) [off-list ref]
## Documentation/git-format-patch.txt ##
@@ Documentation/git-format-patch.txt: SYNOPSIS
2: d2ec18b36af ! 2: 5025ad30ba7 am: support --empty=<option> to handle empty patches
@@
## Metadata ##
-Author: Aleen 徐沛文 [off-list ref]
+Author: Aleen [off-list ref]
## Commit message ##
am: support --empty=<option> to handle empty patches
@@ Commit message
those empty patches. In this commit, we have implemented three
valid options ('die', 'drop' and 'keep').
- Signed-off-by: Aleen 徐沛文 [off-list ref]
+ Signed-off-by: 徐沛文 (Aleen) [off-list ref]
## Documentation/git-am.txt ##
@@ Documentation/git-am.txt: SYNOPSIS
--
gitgitgadget
From: Aleen via GitGitGadget <hidden> Date: 2021-11-22 07:51:25
From: Aleen <redacted>
Since that the command 'git-format-patch' can include patches of
commits that emit no changes, the 'git-am' command should also
support an option, named as '--empty', to specify how to handle
those empty patches. In this commit, we have implemented three
valid options ('die', 'drop' and 'keep').
Signed-off-by: 徐沛文 (Aleen) <redacted>
---
Documentation/git-am.txt | 8 ++++++
builtin/am.c | 55 ++++++++++++++++++++++++++++++++++++----
t/t4150-am.sh | 49 +++++++++++++++++++++++++++++++++++
3 files changed, 107 insertions(+), 5 deletions(-)
@@ -63,6 +64,13 @@ OPTIONS --quoted-cr=<action>:: This flag will be passed down to 'git mailinfo' (see linkgit:git-mailinfo[1]).+--empty=(die|drop|keep)::+ By default, or when the option is set to 'die', the command+ errors out on an input e-mail message that lacks a patch. When+ this option is set to 'drop', skip such an e-mail message instead.+ When this option is set to 'keep', create an empty commit,+ recording the contents of the e-mail message as its log.+ -m:: --message-id:: Pass the `-m` flag to 'git mailinfo' (see linkgit:git-mailinfo[1]),
@@ -178,6 +185,25 @@ static int am_option_parse_quoted_cr(const struct option *opt,return0;}+staticintam_option_parse_empty(conststructoption*opt,+constchar*arg,intunset)+{+int*opt_value=opt->value;++BUG_ON_OPT_NEG(unset);++if(!strcmp(arg,"die"))+*opt_value=DIE_EMPTY_COMMIT;+elseif(!strcmp(arg,"drop"))+*opt_value=DROP_EMPTY_COMMIT;+elseif(!strcmp(arg,"keep"))+*opt_value=KEEP_EMPTY_COMMIT;+else+returnerror(_("Invalid value for --empty: %s"),arg);++return0;+}+/***Returnspathrelativetotheam_statedirectory.*/
@@ -1248,11 +1274,6 @@ static int parse_mail(struct am_state *state, const char *mail)gotofinish;}-if(is_empty_or_missing_file(am_path(state,"patch"))){-printf_ln(_("Patch is empty."));-die_user_resolve(state);-}-strbuf_addstr(&msg,"\n\n");strbuf_addbuf(&msg,&mi.log_message);strbuf_stripspace(&msg,0);
@@ -1152,4 +1158,47 @@ test_expect_success 'apply binary blob in partial clone' 'git-Cclientam../patch'+test_expect_success'an empty input file is error regardless of --empty option''+test_when_finished"git am --abort || :"&&+test_must_failgitam--empty=dropempty.patch2>actual&&+echo"Patch format detection failed.">expected&&+test_cmpexpectedactual+'++test_expect_success'invalid when passing the --empty option alone''+test_when_finished"git am --abort || :"&&+gitcheckoutempty-commit^&&+test_must_failgitam--emptyempty-commit.patch2>err&&+echo"error: Invalid value for --empty: empty-commit.patch">expected&&+test_cmpexpectederr+'++test_expect_success'a message without a patch is an error (default)''+test_when_finished"git am --abort || :"&&+test_must_failgitamempty-commit.patch>err&&+grep"Patch is empty"err+'++test_expect_success'a message without a patch is an error where an explicit "--empty=die" is given''+test_when_finished"git am --abort || :"&&+test_must_failgitam--empty=dieempty-commit.patch>err&&+grep"Patch is empty."err+'++test_expect_success'a message without a patch will be skipped when "--empty=drop" is given''+gitam--empty=dropempty-commit.patch>output&&+gitrev-parseempty-commit^>expected&&+gitrev-parseHEAD>actual&&+test_cmpexpectedactual&&+grep"Skipping: empty commit"output+'++test_expect_success'record as an empty commit when meeting e-mail message that lacks a patch''+gitam--empty=keepempty-commit.patch&&+test_path_is_missing.git/rebase-apply&&+gitshowempty-commit--format="%s">expected&&+gitshowHEAD--format="%s">actual&&+test_cmpactualexpected+'+ test_done
From: Johannes Schindelin <hidden> Date: 2021-11-22 12:00:48
Hi Aleen,
On Mon, 22 Nov 2021, Aleen via GitGitGadget wrote:
From: Aleen <redacted>
FWIW this information comes from your commit, specifically from the
author information recorded when you committed first. To re-set it in
these two patches, run something like this:
git config --global user.name "徐沛文 (Aleen)"
git rebase -x "git commit --amend --no-edit --reset-author" HEAD~2
and then force-push to your branch.
Ciao,
Dscho
Hi Aleen,
On Mon, 22 Nov 2021, Aleen via GitGitGadget wrote:
quoted
From: Aleen <redacted>
FWIW this information comes from your commit, specifically from the
author information recorded when you committed first. To re-set it in
these two patches, run something like this:
git config --global user.name "徐沛文 (Aleen)"
git rebase -x "git commit --amend --no-edit --reset-author" HEAD~2
and then force-push to your branch.
Ciao,
Dscho
From: Johannes Schindelin <hidden> Date: 2021-11-23 12:30:31
Hi Aleen,
On Tue, 23 Nov 2021, Aleen 徐沛文 wrote:
quoted
Hi Aleen,
On Mon, 22 Nov 2021, Aleen via GitGitGadget wrote:
quoted
From: Aleen <redacted>
FWIW this information comes from your commit, specifically from the
author information recorded when you committed first. To re-set it in
these two patches, run something like this:
git config --global user.name "徐沛文 (Aleen)"
git rebase -x "git commit --amend --no-edit --reset-author" HEAD~2
and then force-push to your branch.
Ciao,
Dscho
Whoops. It seems that the `From:` header cannot be parsed by GitGitGadget.
Most likely because the `<` and `>` of the email address are on the next
line, not the same line as the `From:`.
I had a quick look and opened
https://github.com/gitgitgadget/gitgitgadget/pull/777 to fix this.
Ciao,
Dscho
From: Aleen via GitGitGadget <hidden> Date: 2021-11-23 15:27:00
Since that git has supported the --always option for the git-format-patch
command to create a patch with an empty commit message, git-am should
support applying and committing with empty patches.
----------------------------------------------------------------------------
Changes since v1:
1. add a case when not passing the --always option.
2. rename the --always option to --allow-empty.
----------------------------------------------------------------------------
Changes since v2:
1. rename the --allow-empty option to --empty-commit.
2. introduce three different strategies (die|skip|asis) when trying to
record empty patches as empty commits.
----------------------------------------------------------------------------
Changes since v3:
1. generate the missed file for test cases.
2. grep -f cannot be used under Mac OS.
----------------------------------------------------------------------------
Changes since v4:
1. rename the --empty-commit option to --empty.
2. rename three different strategies (die|skip|asis) to die, drop and keep
correspondingly.
----------------------------------------------------------------------------
Changes since v5:
1. throw an error when passing --empty option without value.
----------------------------------------------------------------------------
Changes since v6:
1. add i18n resources.
----------------------------------------------------------------------------
Changes since v7:
1. update code according to the seen branch.
2. fix the wrong document of git-am.
3. sign off commits by a real name.
----------------------------------------------------------------------------
Changes since v8:
1. update the committer's name with my real name to fix DCO of GGG.
----------------------------------------------------------------------------
Changes since v9:
1. imitate the signed name format of
https://lore.kernel.org/git/pull.1143.git.git.1637347813367.gitgitgadget@gmail.com
.
cc: René Scharfe l.s.r@web.de cc: Phillip Wood phillip.wood123@gmail.com cc:
Aleen 徐沛文 pwxu@coremail.cn
cc: Aleen 徐沛文 pwxu@coremail.cn
徐沛文 (Aleen) (2):
doc: git-format-patch: describe the option --always
am: support --empty=<option> to handle empty patches
Documentation/git-am.txt | 8 +++++
Documentation/git-format-patch.txt | 6 +++-
builtin/am.c | 55 +++++++++++++++++++++++++++---
t/t4150-am.sh | 49 ++++++++++++++++++++++++++
4 files changed, 112 insertions(+), 6 deletions(-)
base-commit: f8b28837226f3932b867ca88a4f830bf203d2afe
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1076%2Faleen42%2Fnext-v11
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1076/aleen42/next-v11
Pull-Request: https://github.com/gitgitgadget/git/pull/1076
Range-diff vs v10:
1: 59bce7131da ! 1: 3d7e96ce2b3 doc: git-format-patch: describe the option --always
@@
## Metadata ##
-Author: Aleen [off-list ref]
+Author: 徐沛文 (Aleen) [off-list ref]
## Commit message ##
doc: git-format-patch: describe the option --always
2: 5025ad30ba7 ! 2: 6051ad9440a am: support --empty=<option> to handle empty patches
@@
## Metadata ##
-Author: Aleen [off-list ref]
+Author: 徐沛文 (Aleen) [off-list ref]
## Commit message ##
am: support --empty=<option> to handle empty patches
--
gitgitgadget
From: 徐沛文 (Aleen) via GitGitGadget <hidden> Date: 2021-11-23 15:27:03
From: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
[off-list ref]
This commit has described how to use '--always' option in the command
'git-format-patch' to include patches for commits that emit no changes.
Signed-off-by: 徐沛文 (Aleen) <redacted>
---
Documentation/git-format-patch.txt | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
@@ -192,6 +192,10 @@ will want to ensure that threading is disabled for `git send-email`. patches being generated, and any patch that matches is ignored.+--always::+ Include patches for commits that do not introduce any change,+ which are omitted by default.+ --cover-from-description=<mode>:: Controls which parts of the cover letter will be automatically populated using the branch's description.
From: 徐沛文 (Aleen) via GitGitGadget <hidden> Date: 2021-11-23 15:27:04
From: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
[off-list ref]
Since that the command 'git-format-patch' can include patches of
commits that emit no changes, the 'git-am' command should also
support an option, named as '--empty', to specify how to handle
those empty patches. In this commit, we have implemented three
valid options ('die', 'drop' and 'keep').
Signed-off-by: 徐沛文 (Aleen) <redacted>
---
Documentation/git-am.txt | 8 ++++++
builtin/am.c | 55 ++++++++++++++++++++++++++++++++++++----
t/t4150-am.sh | 49 +++++++++++++++++++++++++++++++++++
3 files changed, 107 insertions(+), 5 deletions(-)
@@ -63,6 +64,13 @@ OPTIONS --quoted-cr=<action>:: This flag will be passed down to 'git mailinfo' (see linkgit:git-mailinfo[1]).+--empty=(die|drop|keep)::+ By default, or when the option is set to 'die', the command+ errors out on an input e-mail message that lacks a patch. When+ this option is set to 'drop', skip such an e-mail message instead.+ When this option is set to 'keep', create an empty commit,+ recording the contents of the e-mail message as its log.+ -m:: --message-id:: Pass the `-m` flag to 'git mailinfo' (see linkgit:git-mailinfo[1]),
@@ -178,6 +185,25 @@ static int am_option_parse_quoted_cr(const struct option *opt,return0;}+staticintam_option_parse_empty(conststructoption*opt,+constchar*arg,intunset)+{+int*opt_value=opt->value;++BUG_ON_OPT_NEG(unset);++if(!strcmp(arg,"die"))+*opt_value=DIE_EMPTY_COMMIT;+elseif(!strcmp(arg,"drop"))+*opt_value=DROP_EMPTY_COMMIT;+elseif(!strcmp(arg,"keep"))+*opt_value=KEEP_EMPTY_COMMIT;+else+returnerror(_("Invalid value for --empty: %s"),arg);++return0;+}+/***Returnspathrelativetotheam_statedirectory.*/
@@ -1248,11 +1274,6 @@ static int parse_mail(struct am_state *state, const char *mail)gotofinish;}-if(is_empty_or_missing_file(am_path(state,"patch"))){-printf_ln(_("Patch is empty."));-die_user_resolve(state);-}-strbuf_addstr(&msg,"\n\n");strbuf_addbuf(&msg,&mi.log_message);strbuf_stripspace(&msg,0);
@@ -1152,4 +1158,47 @@ test_expect_success 'apply binary blob in partial clone' 'git-Cclientam../patch'+test_expect_success'an empty input file is error regardless of --empty option''+test_when_finished"git am --abort || :"&&+test_must_failgitam--empty=dropempty.patch2>actual&&+echo"Patch format detection failed.">expected&&+test_cmpexpectedactual+'++test_expect_success'invalid when passing the --empty option alone''+test_when_finished"git am --abort || :"&&+gitcheckoutempty-commit^&&+test_must_failgitam--emptyempty-commit.patch2>err&&+echo"error: Invalid value for --empty: empty-commit.patch">expected&&+test_cmpexpectederr+'++test_expect_success'a message without a patch is an error (default)''+test_when_finished"git am --abort || :"&&+test_must_failgitamempty-commit.patch>err&&+grep"Patch is empty"err+'++test_expect_success'a message without a patch is an error where an explicit "--empty=die" is given''+test_when_finished"git am --abort || :"&&+test_must_failgitam--empty=dieempty-commit.patch>err&&+grep"Patch is empty."err+'++test_expect_success'a message without a patch will be skipped when "--empty=drop" is given''+gitam--empty=dropempty-commit.patch>output&&+gitrev-parseempty-commit^>expected&&+gitrev-parseHEAD>actual&&+test_cmpexpectedactual&&+grep"Skipping: empty commit"output+'++test_expect_success'record as an empty commit when meeting e-mail message that lacks a patch''+gitam--empty=keepempty-commit.patch&&+test_path_is_missing.git/rebase-apply&&+gitshowempty-commit--format="%s">expected&&+gitshowHEAD--format="%s">actual&&+test_cmpactualexpected+'+ test_done
I triggered the Azure Pipeline to submit this patch series after merging
the PR that fixed parsing of the `From:` line.
It looks a bit funny that this is in two lines, so I downloaded the mail
from https://lore.kernel.org/git/ and fed it to `git am`, which was just
fine with it.
Ciao,
Dscho
On Tue, Nov 23, 2021 at 8:38 AM 徐沛文 (Aleen) via GitGitGadget
[off-list ref] wrote:
quoted hunk
From: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
[off-list ref]
Since that the command 'git-format-patch' can include patches of
commits that emit no changes, the 'git-am' command should also
support an option, named as '--empty', to specify how to handle
those empty patches. In this commit, we have implemented three
valid options ('die', 'drop' and 'keep').
Signed-off-by: 徐沛文 (Aleen) <redacted>
---
Documentation/git-am.txt | 8 ++++++
builtin/am.c | 55 ++++++++++++++++++++++++++++++++++++----
t/t4150-am.sh | 49 +++++++++++++++++++++++++++++++++++
3 files changed, 107 insertions(+), 5 deletions(-)
@@ -63,6 +64,13 @@ OPTIONS --quoted-cr=<action>:: This flag will be passed down to 'git mailinfo' (see linkgit:git-mailinfo[1]).+--empty=(die|drop|keep)::+ By default, or when the option is set to 'die', the command+ errors out on an input e-mail message that lacks a patch. When+ this option is set to 'drop', skip such an e-mail message instead.+ When this option is set to 'keep', create an empty commit,+ recording the contents of the e-mail message as its log.
What does 'errors out' mean? Is the am operation aborted, and the
user return to the pre-am state? Or is the am operation interrupted,
with the user being asked to choose whether to keep or drop the patch?
Or something else (my first thought was "Are you going to leave the
index locked?")? This description is not that clear. To me, the
wording suggests aborted (or worse), but what you actually implemented
was an interrupt-and-ask.
Can I suggest using 'ask' instead of 'die'? I think that will be
clearer, and it matches the term used by git rebase --empty.
Also, the only instructions given to the user when you interrupt
include how to skip the patch, but I don't see anything for how to
keep it. The instructions are:
'''
Patch is empty.
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
'''
I tried it manually, and it turns out "git am --continue" will just
spit out basically the same message again:
'''
Applying: empty commit
No changes - did you forget to use 'git add'?
If there is nothing left to stage, chances are that something else
already introduced the same changes; you might want to skip this patch.
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
'''
And if I try to run `git commit --allow-empty` (which I happen to
remember is the command suggested by `git rebase --empty=ask` when it
stops), then I'm given an empty editor; it is not pre-populated with
the appropriate commit message. Can the portion of the empty patch
corresponding to the commit message be added to .git/COMMIT_EDITMSG to
correct that? Also, can some extra words be printed before
interrupting to explain what to do when you want to keep the empty
commit? Something like:
"""
The current commit being applied is empty. If you wish to commit it
anyway, use:
git commit --allow-empty
"""
quoted hunk
+
-m::
--message-id::
Pass the `-m` flag to 'git mailinfo' (see linkgit:git-mailinfo[1]),
@@ -178,6 +185,25 @@ static int am_option_parse_quoted_cr(const struct option *opt,return0;}+staticintam_option_parse_empty(conststructoption*opt,+constchar*arg,intunset)+{+int*opt_value=opt->value;++BUG_ON_OPT_NEG(unset);++if(!strcmp(arg,"die"))+*opt_value=DIE_EMPTY_COMMIT;+elseif(!strcmp(arg,"drop"))+*opt_value=DROP_EMPTY_COMMIT;+elseif(!strcmp(arg,"keep"))+*opt_value=KEEP_EMPTY_COMMIT;+else+returnerror(_("Invalid value for --empty: %s"),arg);++return0;+}+/***Returnspathrelativetotheam_statedirectory.*/
@@ -1248,11 +1274,6 @@ static int parse_mail(struct am_state *state, const char *mail)gotofinish;}-if(is_empty_or_missing_file(am_path(state,"patch"))){-printf_ln(_("Patch is empty."));-die_user_resolve(state);-}-strbuf_addstr(&msg,"\n\n");strbuf_addbuf(&msg,&mi.log_message);strbuf_stripspace(&msg,0);
@@ -1152,4 +1158,47 @@ test_expect_success 'apply binary blob in partial clone' 'git-Cclientam../patch'+test_expect_success'an empty input file is error regardless of --empty option''+test_when_finished"git am --abort || :"&&+test_must_failgitam--empty=dropempty.patch2>actual&&+echo"Patch format detection failed.">expected&&+test_cmpexpectedactual+'++test_expect_success'invalid when passing the --empty option alone''+test_when_finished"git am --abort || :"&&+gitcheckoutempty-commit^&&+test_must_failgitam--emptyempty-commit.patch2>err&&+echo"error: Invalid value for --empty: empty-commit.patch">expected&&+test_cmpexpectederr+'++test_expect_success'a message without a patch is an error (default)''+test_when_finished"git am --abort || :"&&+test_must_failgitamempty-commit.patch>err&&+grep"Patch is empty"err+'++test_expect_success'a message without a patch is an error where an explicit "--empty=die" is given''+test_when_finished"git am --abort || :"&&+test_must_failgitam--empty=dieempty-commit.patch>err&&+grep"Patch is empty."err+'++test_expect_success'a message without a patch will be skipped when "--empty=drop" is given''+gitam--empty=dropempty-commit.patch>output&&+gitrev-parseempty-commit^>expected&&+gitrev-parseHEAD>actual&&+test_cmpexpectedactual&&+grep"Skipping: empty commit"output+'++test_expect_success'record as an empty commit when meeting e-mail message that lacks a patch''+gitam--empty=keepempty-commit.patch&&+test_path_is_missing.git/rebase-apply&&+gitshowempty-commit--format="%s">expected&&+gitshowHEAD--format="%s">actual&&+test_cmpactualexpected+'+ test_done--
Dears Hamano,
Elijah Newren has given two better suggestions:
1. Use 'ask' rather than 'die'
2. When erroring out 'Patch is empty', print out a tutorial information
to help users using 'git commit --allow-empty' to keep recording as
an empty commit.
Should we continue to implement these features in current PR?
Aleen
quoted
+--empty=(die|drop|keep)::
+ By default, or when the option is set to 'die', the command
+ errors out on an input e-mail message that lacks a patch. When
+ this option is set to 'drop', skip such an e-mail message instead.
+ When this option is set to 'keep', create an empty commit,
+ recording the contents of the e-mail message as its log.
What does 'errors out' mean? Is the am operation aborted, and the
user return to the pre-am state? Or is the am operation interrupted,
with the user being asked to choose whether to keep or drop the patch?
Or something else (my first thought was "Are you going to leave the
index locked?")? This description is not that clear. To me, the
wording suggests aborted (or worse), but what you actually implemented
was an interrupt-and-ask.
Can I suggest using 'ask' instead of 'die'? I think that will be
clearer, and it matches the term used by git rebase --empty.
Also, the only instructions given to the user when you interrupt
include how to skip the patch, but I don't see anything for how to
keep it. The instructions are:
'''
Patch is empty.
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
'''
I tried it manually, and it turns out "git am --continue" will just
spit out basically the same message again:
'''
Applying: empty commit
No changes - did you forget to use 'git add'?
If there is nothing left to stage, chances are that something else
already introduced the same changes; you might want to skip this patch.
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
'''
And if I try to run `git commit --allow-empty` (which I happen to
remember is the command suggested by `git rebase --empty=ask` when it
stops), then I'm given an empty editor; it is not pre-populated with
the appropriate commit message. Can the portion of the empty patch
corresponding to the commit message be added to .git/COMMIT_EDITMSG to
correct that? Also, can some extra words be printed before
interrupting to explain what to do when you want to keep the empty
commit? Something like:
"""
The current commit being applied is empty. If you wish to commit it
anyway, use:
git commit --allow-empty
"""
It is quite complicated to support 'git commit --allow-empty' extracting messages
from an empty patch, because 'git am' has to find somewhere to store the parsed state
for 'git commit' to read. How about directly supporting another interactive option
'--allow-empty' for 'git am' to keep recording?
Dears Hamano,
Elijah Newren has given two better suggestions:
1. Use 'ask' rather than 'die'
2. When erroring out 'Patch is empty', print out a tutorial information
to help users using 'git commit --allow-empty' to keep recording as
an empty commit.
Should we continue to implement these features in current PR?
Aleen
On Mon, Nov 29, 2021 at 2:00 AM Aleen 徐沛文 [off-list ref] wrote:
It is quite complicated to support 'git commit --allow-empty' extracting messages
from an empty patch, because 'git am' has to find somewhere to store the parsed state
for 'git commit' to read.
.git/COMMIT_EDITMSG is such a place that already exists, assuming you
are just extracting a commit message.
How about directly supporting another interactive option
'--allow-empty' for 'git am' to keep recording?
--empty=keep was already part of your patch series; I don't see why
you'd need to add a synonym (--allow-empty) for it.
I think you were trying to ask if you could just leave out the
implementation of --empty=ask (or --empty=die) from your patches.
That's usually fine, but there is a small wrinkle here since it was
your chosen default. You'll have to pick a different default, and
possibly alert users in the documentation that the default may change
in the future if/when the other option is implemented.
quoted
Dears Hamano,
Elijah Newren has given two better suggestions:
1. Use 'ask' rather than 'die'
2. When erroring out 'Patch is empty', print out a tutorial information
to help users using 'git commit --allow-empty' to keep recording as
an empty commit.
Should we continue to implement these features in current PR?
Aleen
From: Aleen via GitGitGadget <hidden> Date: 2021-11-30 05:37:30
Since that git has supported the --always option for the git-format-patch
command to create a patch with an empty commit message, git-am should
support applying and committing with empty patches.
----------------------------------------------------------------------------
Changes since v1:
1. add a case when not passing the --always option.
2. rename the --always option to --allow-empty.
----------------------------------------------------------------------------
Changes since v2:
1. rename the --allow-empty option to --empty-commit.
2. introduce three different strategies (die|skip|asis) when trying to
record empty patches as empty commits.
----------------------------------------------------------------------------
Changes since v3:
1. generate the missed file for test cases.
2. grep -f cannot be used under Mac OS.
----------------------------------------------------------------------------
Changes since v4:
1. rename the --empty-commit option to --empty.
2. rename three different strategies (die|skip|asis) to die, drop and keep
correspondingly.
----------------------------------------------------------------------------
Changes since v5:
1. throw an error when passing --empty option without value.
----------------------------------------------------------------------------
Changes since v6:
1. add i18n resources.
----------------------------------------------------------------------------
Changes since v7:
1. update code according to the seen branch.
2. fix the wrong document of git-am.
3. sign off commits by a real name.
----------------------------------------------------------------------------
Changes since v8:
1. update the committer's name with my real name to fix DCO of GGG.
----------------------------------------------------------------------------
Changes since v9:
1. imitate the signed name format of
https://lore.kernel.org/git/pull.1143.git.git.1637347813367.gitgitgadget@gmail.com
.
----------------------------------------------------------------------------
Changes since v11:
1. introduce an interactive option --allow-empty for git-am to record empty
patches in the middle of an am session.
徐沛文 (Aleen) (3):
doc: git-format-patch: describe the option --always
am: support --empty=<option> to handle empty patches
am: support --allow-empty to record specific empty patches
Documentation/git-am.txt | 14 +++++-
Documentation/git-format-patch.txt | 6 ++-
builtin/am.c | 77 ++++++++++++++++++++++++++----
t/t4150-am.sh | 61 +++++++++++++++++++++++
t/t7512-status-help.sh | 1 +
wt-status.c | 3 ++
6 files changed, 151 insertions(+), 11 deletions(-)
base-commit: abe6bb3905392d5eb6b01fa6e54d7e784e0522aa
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1076%2Faleen42%2Fnext-v12
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1076/aleen42/next-v12
Pull-Request: https://github.com/gitgitgadget/git/pull/1076
Range-diff vs v11:
1: 3d7e96ce2b3 = 1: a524ca6adfa doc: git-format-patch: describe the option --always
2: 6051ad9440a = 2: a3e850bab7d am: support --empty=<option> to handle empty patches
-: ----------- > 3: d44dac09c87 am: support --allow-empty to record specific empty patches
--
gitgitgadget
From: 徐沛文 (Aleen) via GitGitGadget <hidden> Date: 2021-11-30 05:37:31
From: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
[off-list ref]
This commit has described how to use '--always' option in the command
'git-format-patch' to include patches for commits that emit no changes.
Signed-off-by: 徐沛文 (Aleen) <redacted>
---
Documentation/git-format-patch.txt | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
@@ -192,6 +192,10 @@ will want to ensure that threading is disabled for `git send-email`. patches being generated, and any patch that matches is ignored.+--always::+ Include patches for commits that do not introduce any change,+ which are omitted by default.+ --cover-from-description=<mode>:: Controls which parts of the cover letter will be automatically populated using the branch's description.
From: 徐沛文 (Aleen) via GitGitGadget <hidden> Date: 2021-11-30 05:37:35
From: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
[off-list ref]
Since that the command 'git-format-patch' can include patches of
commits that emit no changes, the 'git-am' command should also
support an option, named as '--empty', to specify how to handle
those empty patches. In this commit, we have implemented three
valid options ('die', 'drop' and 'keep').
Signed-off-by: 徐沛文 (Aleen) <redacted>
---
Documentation/git-am.txt | 8 ++++++
builtin/am.c | 55 ++++++++++++++++++++++++++++++++++++----
t/t4150-am.sh | 49 +++++++++++++++++++++++++++++++++++
3 files changed, 107 insertions(+), 5 deletions(-)
@@ -63,6 +64,13 @@ OPTIONS --quoted-cr=<action>:: This flag will be passed down to 'git mailinfo' (see linkgit:git-mailinfo[1]).+--empty=(die|drop|keep)::+ By default, or when the option is set to 'die', the command+ errors out on an input e-mail message that lacks a patch. When+ this option is set to 'drop', skip such an e-mail message instead.+ When this option is set to 'keep', create an empty commit,+ recording the contents of the e-mail message as its log.+ -m:: --message-id:: Pass the `-m` flag to 'git mailinfo' (see linkgit:git-mailinfo[1]),
@@ -178,6 +185,25 @@ static int am_option_parse_quoted_cr(const struct option *opt,return0;}+staticintam_option_parse_empty(conststructoption*opt,+constchar*arg,intunset)+{+int*opt_value=opt->value;++BUG_ON_OPT_NEG(unset);++if(!strcmp(arg,"die"))+*opt_value=DIE_EMPTY_COMMIT;+elseif(!strcmp(arg,"drop"))+*opt_value=DROP_EMPTY_COMMIT;+elseif(!strcmp(arg,"keep"))+*opt_value=KEEP_EMPTY_COMMIT;+else+returnerror(_("Invalid value for --empty: %s"),arg);++return0;+}+/***Returnspathrelativetotheam_statedirectory.*/
@@ -1248,11 +1274,6 @@ static int parse_mail(struct am_state *state, const char *mail)gotofinish;}-if(is_empty_or_missing_file(am_path(state,"patch"))){-printf_ln(_("Patch is empty."));-die_user_resolve(state);-}-strbuf_addstr(&msg,"\n\n");strbuf_addbuf(&msg,&mi.log_message);strbuf_stripspace(&msg,0);
@@ -1152,4 +1158,47 @@ test_expect_success 'apply binary blob in partial clone' 'git-Cclientam../patch'+test_expect_success'an empty input file is error regardless of --empty option''+test_when_finished"git am --abort || :"&&+test_must_failgitam--empty=dropempty.patch2>actual&&+echo"Patch format detection failed.">expected&&+test_cmpexpectedactual+'++test_expect_success'invalid when passing the --empty option alone''+test_when_finished"git am --abort || :"&&+gitcheckoutempty-commit^&&+test_must_failgitam--emptyempty-commit.patch2>err&&+echo"error: Invalid value for --empty: empty-commit.patch">expected&&+test_cmpexpectederr+'++test_expect_success'a message without a patch is an error (default)''+test_when_finished"git am --abort || :"&&+test_must_failgitamempty-commit.patch>err&&+grep"Patch is empty"err+'++test_expect_success'a message without a patch is an error where an explicit "--empty=die" is given''+test_when_finished"git am --abort || :"&&+test_must_failgitam--empty=dieempty-commit.patch>err&&+grep"Patch is empty."err+'++test_expect_success'a message without a patch will be skipped when "--empty=drop" is given''+gitam--empty=dropempty-commit.patch>output&&+gitrev-parseempty-commit^>expected&&+gitrev-parseHEAD>actual&&+test_cmpexpectedactual&&+grep"Skipping: empty commit"output+'++test_expect_success'record as an empty commit when meeting e-mail message that lacks a patch''+gitam--empty=keepempty-commit.patch&&+test_path_is_missing.git/rebase-apply&&+gitshowempty-commit--format="%s">expected&&+gitshowHEAD--format="%s">actual&&+test_cmpactualexpected+'+ test_done
@@ -199,6 +199,10 @@ default. You can use `--no-utf8` to override this. the e-mail message; if `diff`, show the diff portion only. Defaults to `raw`.+--allow-empty::+ Keep recording the empty patch as an empty commit with+ the contents of the e-mail message as its log.+ DISCUSSION ----------
@@ -1825,7 +1825,8 @@ static void am_run(struct am_state *state, int resume)to_keep=1;break;caseDIE_EMPTY_COMMIT:-printf_ln(_("Patch is empty."));+printf_ln(_("Patch is empty.\n"+"If you want to keep recording it, run \"git am --allow-empty\"."));die_user_resolve(state);break;}
@@ -2390,6 +2398,9 @@ int cmd_am(int argc, const char **argv, const char *prefix)N_("show the patch being applied"),PARSE_OPT_CMDMODE|PARSE_OPT_OPTARG|PARSE_OPT_NONEG|PARSE_OPT_LITERAL_ARGHELP,parse_opt_show_current_patch,RESUME_SHOW_PATCH},+OPT_CMDMODE(0,"allow-empty",&resume.mode,+N_("keep recording the empty patch as empty commits"),+RESUME_ALLOW_EMPTY),OPT_BOOL(0,"committer-date-is-author-date",&state.committer_date_is_author_date,N_("lie about committer date")),
@@ -1201,4 +1201,16 @@ test_expect_success 'record as an empty commit when meeting e-mail message thattest_cmpactualexpected'++test_expect_success'record as an empty commit in the middle of an am session''+gitcheckoutempty-commit^&&+test_must_failgitamempty-commit.patch>err&&+grep"Patch is empty."err&&+grep"If you want to keep recording it, run \"git am --allow-empty\"."err&&+gitam--allow-empty&&+gitshowempty-commit--format="%s">expected&&+gitshowHEAD--format="%s">actual&&+test_cmpactualexpected+'+ test_done
@@ -658,6 +658,7 @@ test_expect_success 'status in an am session: empty patch' ' Onbrancham_empty Youareinthemiddleofanamsession. Thecurrentpatchisempty.+(use"git am --allow-empty"tokeeprecordingthisemptypatch)(use"git am --skip"toskipthispatch)(use"git am --abort"torestoretheoriginalbranch)
@@ -1227,6 +1227,9 @@ static void show_am_in_progress(struct wt_status *s,if(!s->state.am_empty_patch)status_printf_ln(s,color,_(" (fix conflicts and then run \"git am --continue\")"));+else+status_printf_ln(s,color,+_(" (use \"git am --allow-empty\" to keep recording this empty patch)"));status_printf_ln(s,color,_(" (use \"git am --skip\" to skip this patch)"));status_printf_ln(s,color,
I have introduced an interactive option `--allow-empty` in a new independent commit,
and it is not the synonym of the `--empty` option because it is only for the case in
a middle am session where users can resolve "died" problems by choosing whether to
record current empty patch. The `--empty` option acts like a strategy option to tell
`git-am` how to handle when meeting any empty patches.
On Mon, Nov 29, 2021 at 2:00 AM Aleen 徐沛文 [off-list ref] wrote:
quoted
It is quite complicated to support 'git commit --allow-empty' extracting messages
from an empty patch, because 'git am' has to find somewhere to store the parsed state
for 'git commit' to read.
.git/COMMIT_EDITMSG is such a place that already exists, assuming you
are just extracting a commit message.
quoted
How about directly supporting another interactive option
'--allow-empty' for 'git am' to keep recording?
--empty=keep was already part of your patch series; I don't see why
you'd need to add a synonym (--allow-empty) for it.
I think you were trying to ask if you could just leave out the
implementation of --empty=ask (or --empty=die) from your patches.
That's usually fine, but there is a small wrinkle here since it was
your chosen default. You'll have to pick a different default, and
possibly alert users in the documentation that the default may change
in the future if/when the other option is implemented.
quoted
quoted
Dears Hamano,
Elijah Newren has given two better suggestions:
1. Use 'ask' rather than 'die'
2. When erroring out 'Patch is empty', print out a tutorial information
to help users using 'git commit --allow-empty' to keep recording as
an empty commit.
Should we continue to implement these features in current PR?
Aleen
From: Aleen via GitGitGadget <hidden> Date: 2021-11-30 09:55:20
Since that git has supported the --always option for the git-format-patch
command to create a patch with an empty commit message, git-am should
support applying and committing with empty patches.
----------------------------------------------------------------------------
Changes since v1:
1. add a case when not passing the --always option.
2. rename the --always option to --allow-empty.
----------------------------------------------------------------------------
Changes since v2:
1. rename the --allow-empty option to --empty-commit.
2. introduce three different strategies (die|skip|asis) when trying to
record empty patches as empty commits.
----------------------------------------------------------------------------
Changes since v3:
1. generate the missed file for test cases.
2. grep -f cannot be used under Mac OS.
----------------------------------------------------------------------------
Changes since v4:
1. rename the --empty-commit option to --empty.
2. rename three different strategies (die|skip|asis) to die, drop and keep
correspondingly.
----------------------------------------------------------------------------
Changes since v5:
1. throw an error when passing --empty option without value.
----------------------------------------------------------------------------
Changes since v6:
1. add i18n resources.
----------------------------------------------------------------------------
Changes since v7:
1. update code according to the seen branch.
2. fix the wrong document of git-am.
3. sign off commits by a real name.
----------------------------------------------------------------------------
Changes since v8:
1. update the committer's name with my real name to fix DCO of GGG.
----------------------------------------------------------------------------
Changes since v9:
1. imitate the signed name format of
https://lore.kernel.org/git/pull.1143.git.git.1637347813367.gitgitgadget@gmail.com
.
----------------------------------------------------------------------------
Changes since v11:
1. introduce an interactive option --allow-empty for git-am to record empty
patches in the middle of an am session.
----------------------------------------------------------------------------
Changes since v12:
1. record the empty patch as an empty commit only when there are no
changes.
2. fix indentation problems.
3. simplify "to keep recording" to "to record".
4. add a test case for skipping empty patches via the --skip option.
徐沛文 (Aleen) (3):
doc: git-format-patch: describe the option --always
am: support --empty=<option> to handle empty patches
am: support --allow-empty to record specific empty patches
Documentation/git-am.txt | 14 ++++-
Documentation/git-format-patch.txt | 6 ++-
builtin/am.c | 82 +++++++++++++++++++++++++-----
t/t4150-am.sh | 73 ++++++++++++++++++++++++++
t/t7512-status-help.sh | 1 +
wt-status.c | 3 ++
6 files changed, 164 insertions(+), 15 deletions(-)
base-commit: abe6bb3905392d5eb6b01fa6e54d7e784e0522aa
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1076%2Faleen42%2Fnext-v13
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1076/aleen42/next-v13
Pull-Request: https://github.com/gitgitgadget/git/pull/1076
Range-diff vs v12:
1: a524ca6adfa = 1: a524ca6adfa doc: git-format-patch: describe the option --always
2: a3e850bab7d = 2: a3e850bab7d am: support --empty=<option> to handle empty patches
3: d44dac09c87 ! 3: 08bd397ae7a am: support --allow-empty to record specific empty patches
@@ Documentation/git-am.txt: default. You can use `--no-utf8` to override this.
Defaults to `raw`.
+--allow-empty::
-+ Keep recording the empty patch as an empty commit with
++ Record the empty patch as an empty commit with
+ the contents of the e-mail message as its log.
+
DISCUSSION
@@ builtin/am.c: static void am_run(struct am_state *state, int resume)
case DIE_EMPTY_COMMIT:
- printf_ln(_("Patch is empty."));
+ printf_ln(_("Patch is empty.\n"
-+ "If you want to keep recording it, run \"git am --allow-empty\"."));
++ "If you want to record it as an empty commit, run \"git am --allow-empty\"."));
die_user_resolve(state);
break;
}
@@ builtin/am.c: next:
* all the hard work, and we do not have to do any patch application. Just
- * trust and commit what the user has in the index and working tree.
+ * trust and commit what the user has in the index and working tree. If `allow_empty`
-+ * is true, commit as an empty commit.
++ * is true, commit as an empty commit when there is no changes.
*/
-static void am_resolve(struct am_state *state)
+static void am_resolve(struct am_state *state, int allow_empty)
{
-+ if (allow_empty) {
-+ goto commit;
-+ }
-+
validate_resume_state(state);
say(state, stdout, _("Applying: %.*s"), linelen(state->msg), state->msg);
-@@ builtin/am.c: static void am_resolve(struct am_state *state)
-
- repo_rerere(the_repository, 0);
-+commit:
- do_commit(state);
+ if (!repo_index_has_changes(the_repository, NULL, NULL)) {
+- printf_ln(_("No changes - did you forget to use 'git add'?\n"
+- "If there is nothing left to stage, chances are that something else\n"
+- "already introduced the same changes; you might want to skip this patch."));
+- die_user_resolve(state);
++ if (allow_empty)
++ printf_ln(_("No changes - record it as an empty commit."));
++ else {
++ printf_ln(_("No changes - did you forget to use 'git add'?\n"
++ "If there is nothing left to stage, chances are that something else\n"
++ "already introduced the same changes; you might want to skip this patch."));
++ die_user_resolve(state);
++ }
+ }
- next:
+ if (unmerged_cache()) {
@@ builtin/am.c: enum resume_type {
RESUME_SKIP,
RESUME_ABORT,
@@ builtin/am.c: int cmd_am(int argc, const char **argv, const char *prefix)
PARSE_OPT_CMDMODE | PARSE_OPT_OPTARG | PARSE_OPT_NONEG | PARSE_OPT_LITERAL_ARGHELP,
parse_opt_show_current_patch, RESUME_SHOW_PATCH },
+ OPT_CMDMODE(0, "allow-empty", &resume.mode,
-+ N_("keep recording the empty patch as empty commits"),
++ N_("record the empty patch as an empty commit"),
+ RESUME_ALLOW_EMPTY),
OPT_BOOL(0, "committer-date-is-author-date",
&state.committer_date_is_author_date,
@@ builtin/am.c: int cmd_am(int argc, const char **argv, const char *prefix)
break;
case RESUME_RESOLVED:
- am_resolve(&state);
-+ am_resolve(&state, 0);
-+ break;
+ case RESUME_ALLOW_EMPTY:
-+ am_resolve(&state, 1);
++ am_resolve(&state, resume.mode == RESUME_ALLOW_EMPTY ? 1 : 0);
break;
case RESUME_SKIP:
am_skip(&state);
@@ t/t4150-am.sh: test_expect_success 'record as an empty commit when meeting e-mai
test_cmp actual expected
'
++test_expect_success 'skip an empty patch in the middle of an am session' '
++ git checkout empty-commit^ &&
++ test_must_fail git am empty-commit.patch >err &&
++ grep "Patch is empty." err &&
++ grep "If you want to record it as an empty commit, run \"git am --allow-empty\"." err &&
++ git am --skip &&
++ test_path_is_missing .git/rebase-apply &&
++ git rev-parse empty-commit^ >expected &&
++ git rev-parse HEAD >actual &&
++ test_cmp expected actual
++'
+
-+test_expect_success 'record as an empty commit in the middle of an am session' '
++test_expect_success 'record an empty patch as an empty commit in the middle of an am session' '
+ git checkout empty-commit^ &&
+ test_must_fail git am empty-commit.patch >err &&
+ grep "Patch is empty." err &&
-+ grep "If you want to keep recording it, run \"git am --allow-empty\"." err &&
++ grep "If you want to record it as an empty commit, run \"git am --allow-empty\"." err &&
+ git am --allow-empty &&
++ test_path_is_missing .git/rebase-apply &&
+ git show empty-commit --format="%s" >expected &&
+ git show HEAD --format="%s" >actual &&
+ test_cmp actual expected
@@ t/t7512-status-help.sh: test_expect_success 'status in an am session: empty patc
On branch am_empty
You are in the middle of an am session.
The current patch is empty.
-+ (use "git am --allow-empty" to keep recording this empty patch)
++ (use "git am --allow-empty" to record this patch as an empty commit)
(use "git am --skip" to skip this patch)
(use "git am --abort" to restore the original branch)
@@ wt-status.c: static void show_am_in_progress(struct wt_status *s,
_(" (fix conflicts and then run \"git am --continue\")"));
+ else
+ status_printf_ln(s, color,
-+ _(" (use \"git am --allow-empty\" to keep recording this empty patch)"));
++ _(" (use \"git am --allow-empty\" to record this patch as an empty commit)"));
status_printf_ln(s, color,
_(" (use \"git am --skip\" to skip this patch)"));
status_printf_ln(s, color,
--
gitgitgadget
From: 徐沛文 (Aleen) via GitGitGadget <hidden> Date: 2021-11-30 09:55:26
From: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
[off-list ref]
This commit has described how to use '--always' option in the command
'git-format-patch' to include patches for commits that emit no changes.
Signed-off-by: 徐沛文 (Aleen) <redacted>
---
Documentation/git-format-patch.txt | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
@@ -192,6 +192,10 @@ will want to ensure that threading is disabled for `git send-email`. patches being generated, and any patch that matches is ignored.+--always::+ Include patches for commits that do not introduce any change,+ which are omitted by default.+ --cover-from-description=<mode>:: Controls which parts of the cover letter will be automatically populated using the branch's description.
From: 徐沛文 (Aleen) via GitGitGadget <hidden> Date: 2021-11-30 09:55:27
From: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
[off-list ref]
Since that the command 'git-format-patch' can include patches of
commits that emit no changes, the 'git-am' command should also
support an option, named as '--empty', to specify how to handle
those empty patches. In this commit, we have implemented three
valid options ('die', 'drop' and 'keep').
Signed-off-by: 徐沛文 (Aleen) <redacted>
---
Documentation/git-am.txt | 8 ++++++
builtin/am.c | 55 ++++++++++++++++++++++++++++++++++++----
t/t4150-am.sh | 49 +++++++++++++++++++++++++++++++++++
3 files changed, 107 insertions(+), 5 deletions(-)
@@ -63,6 +64,13 @@ OPTIONS --quoted-cr=<action>:: This flag will be passed down to 'git mailinfo' (see linkgit:git-mailinfo[1]).+--empty=(die|drop|keep)::+ By default, or when the option is set to 'die', the command+ errors out on an input e-mail message that lacks a patch. When+ this option is set to 'drop', skip such an e-mail message instead.+ When this option is set to 'keep', create an empty commit,+ recording the contents of the e-mail message as its log.+ -m:: --message-id:: Pass the `-m` flag to 'git mailinfo' (see linkgit:git-mailinfo[1]),
@@ -178,6 +185,25 @@ static int am_option_parse_quoted_cr(const struct option *opt,return0;}+staticintam_option_parse_empty(conststructoption*opt,+constchar*arg,intunset)+{+int*opt_value=opt->value;++BUG_ON_OPT_NEG(unset);++if(!strcmp(arg,"die"))+*opt_value=DIE_EMPTY_COMMIT;+elseif(!strcmp(arg,"drop"))+*opt_value=DROP_EMPTY_COMMIT;+elseif(!strcmp(arg,"keep"))+*opt_value=KEEP_EMPTY_COMMIT;+else+returnerror(_("Invalid value for --empty: %s"),arg);++return0;+}+/***Returnspathrelativetotheam_statedirectory.*/
@@ -1248,11 +1274,6 @@ static int parse_mail(struct am_state *state, const char *mail)gotofinish;}-if(is_empty_or_missing_file(am_path(state,"patch"))){-printf_ln(_("Patch is empty."));-die_user_resolve(state);-}-strbuf_addstr(&msg,"\n\n");strbuf_addbuf(&msg,&mi.log_message);strbuf_stripspace(&msg,0);
@@ -1152,4 +1158,47 @@ test_expect_success 'apply binary blob in partial clone' 'git-Cclientam../patch'+test_expect_success'an empty input file is error regardless of --empty option''+test_when_finished"git am --abort || :"&&+test_must_failgitam--empty=dropempty.patch2>actual&&+echo"Patch format detection failed.">expected&&+test_cmpexpectedactual+'++test_expect_success'invalid when passing the --empty option alone''+test_when_finished"git am --abort || :"&&+gitcheckoutempty-commit^&&+test_must_failgitam--emptyempty-commit.patch2>err&&+echo"error: Invalid value for --empty: empty-commit.patch">expected&&+test_cmpexpectederr+'++test_expect_success'a message without a patch is an error (default)''+test_when_finished"git am --abort || :"&&+test_must_failgitamempty-commit.patch>err&&+grep"Patch is empty"err+'++test_expect_success'a message without a patch is an error where an explicit "--empty=die" is given''+test_when_finished"git am --abort || :"&&+test_must_failgitam--empty=dieempty-commit.patch>err&&+grep"Patch is empty."err+'++test_expect_success'a message without a patch will be skipped when "--empty=drop" is given''+gitam--empty=dropempty-commit.patch>output&&+gitrev-parseempty-commit^>expected&&+gitrev-parseHEAD>actual&&+test_cmpexpectedactual&&+grep"Skipping: empty commit"output+'++test_expect_success'record as an empty commit when meeting e-mail message that lacks a patch''+gitam--empty=keepempty-commit.patch&&+test_path_is_missing.git/rebase-apply&&+gitshowempty-commit--format="%s">expected&&+gitshowHEAD--format="%s">actual&&+test_cmpactualexpected+'+ test_done
@@ -199,6 +199,10 @@ default. You can use `--no-utf8` to override this. the e-mail message; if `diff`, show the diff portion only. Defaults to `raw`.+--allow-empty::+ Record the empty patch as an empty commit with+ the contents of the e-mail message as its log.+ DISCUSSION ----------
@@ -1825,7 +1825,8 @@ static void am_run(struct am_state *state, int resume)to_keep=1;break;caseDIE_EMPTY_COMMIT:-printf_ln(_("Patch is empty."));+printf_ln(_("Patch is empty.\n"+"If you want to record it as an empty commit, run \"git am --allow-empty\"."));die_user_resolve(state);break;}
@@ -1898,19 +1899,24 @@ next:/***Resumethecurrentamsessionafterpatchapplicationfailure.Theuserdid*allthehardwork,andwedonothavetodoanypatchapplication.Just-*trustandcommitwhattheuserhasintheindexandworkingtree.+*trustandcommitwhattheuserhasintheindexandworkingtree.If`allow_empty`+*istrue,commitasanemptycommitwhenthereisnochanges.*/-staticvoidam_resolve(structam_state*state)+staticvoidam_resolve(structam_state*state,intallow_empty){validate_resume_state(state);say(state,stdout,_("Applying: %.*s"),linelen(state->msg),state->msg);if(!repo_index_has_changes(the_repository,NULL,NULL)){-printf_ln(_("No changes - did you forget to use 'git add'?\n"-"If there is nothing left to stage, chances are that something else\n"-"already introduced the same changes; you might want to skip this patch."));-die_user_resolve(state);+if(allow_empty)+printf_ln(_("No changes - record it as an empty commit."));+else{+printf_ln(_("No changes - did you forget to use 'git add'?\n"+"If there is nothing left to stage, chances are that something else\n"+"already introduced the same changes; you might want to skip this patch."));+die_user_resolve(state);+}}if(unmerged_cache()){
@@ -2390,6 +2397,9 @@ int cmd_am(int argc, const char **argv, const char *prefix)N_("show the patch being applied"),PARSE_OPT_CMDMODE|PARSE_OPT_OPTARG|PARSE_OPT_NONEG|PARSE_OPT_LITERAL_ARGHELP,parse_opt_show_current_patch,RESUME_SHOW_PATCH},+OPT_CMDMODE(0,"allow-empty",&resume.mode,+N_("record the empty patch as an empty commit"),+RESUME_ALLOW_EMPTY),OPT_BOOL(0,"committer-date-is-author-date",&state.committer_date_is_author_date,N_("lie about committer date")),
@@ -1201,4 +1201,28 @@ test_expect_success 'record as an empty commit when meeting e-mail message thattest_cmpactualexpected'+test_expect_success'skip an empty patch in the middle of an am session''+gitcheckoutempty-commit^&&+test_must_failgitamempty-commit.patch>err&&+grep"Patch is empty."err&&+grep"If you want to record it as an empty commit, run \"git am --allow-empty\"."err&&+gitam--skip&&+test_path_is_missing.git/rebase-apply&&+gitrev-parseempty-commit^>expected&&+gitrev-parseHEAD>actual&&+test_cmpexpectedactual+'++test_expect_success'record an empty patch as an empty commit in the middle of an am session''+gitcheckoutempty-commit^&&+test_must_failgitamempty-commit.patch>err&&+grep"Patch is empty."err&&+grep"If you want to record it as an empty commit, run \"git am --allow-empty\"."err&&+gitam--allow-empty&&+test_path_is_missing.git/rebase-apply&&+gitshowempty-commit--format="%s">expected&&+gitshowHEAD--format="%s">actual&&+test_cmpactualexpected+'+ test_done
@@ -658,6 +658,7 @@ test_expect_success 'status in an am session: empty patch' ' Onbrancham_empty Youareinthemiddleofanamsession. Thecurrentpatchisempty.+(use"git am --allow-empty"torecordthispatchasanemptycommit)(use"git am --skip"toskipthispatch)(use"git am --abort"torestoretheoriginalbranch)
@@ -1227,6 +1227,9 @@ static void show_am_in_progress(struct wt_status *s,if(!s->state.am_empty_patch)status_printf_ln(s,color,_(" (fix conflicts and then run \"git am --continue\")"));+else+status_printf_ln(s,color,+_(" (use \"git am --allow-empty\" to record this patch as an empty commit)"));status_printf_ln(s,color,_(" (use \"git am --skip\" to skip this patch)"));status_printf_ln(s,color,
From: Aleen via GitGitGadget <hidden> Date: 2021-12-01 03:37:47
Since that git has supported the --always option for the git-format-patch
command to create a patch with an empty commit message, git-am should
support applying and committing with empty patches.
----------------------------------------------------------------------------
Changes since v1:
1. add a case when not passing the --always option.
2. rename the --always option to --allow-empty.
----------------------------------------------------------------------------
Changes since v2:
1. rename the --allow-empty option to --empty-commit.
2. introduce three different strategies (die|skip|asis) when trying to
record empty patches as empty commits.
----------------------------------------------------------------------------
Changes since v3:
1. generate the missed file for test cases.
2. grep -f cannot be used under Mac OS.
----------------------------------------------------------------------------
Changes since v4:
1. rename the --empty-commit option to --empty.
2. rename three different strategies (die|skip|asis) to die, drop and keep
correspondingly.
----------------------------------------------------------------------------
Changes since v5:
1. throw an error when passing --empty option without value.
----------------------------------------------------------------------------
Changes since v6:
1. add i18n resources.
----------------------------------------------------------------------------
Changes since v7:
1. update code according to the seen branch.
2. fix the wrong document of git-am.
3. sign off commits by a real name.
----------------------------------------------------------------------------
Changes since v8:
1. update the committer's name with my real name to fix DCO of GGG.
----------------------------------------------------------------------------
Changes since v9:
1. imitate the signed name format of
https://lore.kernel.org/git/pull.1143.git.git.1637347813367.gitgitgadget@gmail.com
.
----------------------------------------------------------------------------
Changes since v11:
1. introduce an interactive option --allow-empty for git-am to record empty
patches in the middle of an am session.
----------------------------------------------------------------------------
Changes since v12:
1. record the empty patch as an empty commit only when there are no
changes.
2. fix indentation problems.
3. simplify "to keep recording" to "to record".
4. add a test case for skipping empty patches via the --skip option.
----------------------------------------------------------------------------
Changes since v13:
1. add an additional description about the 'die' value.
徐沛文 (Aleen) (3):
doc: git-format-patch: describe the option --always
am: support --empty=<option> to handle empty patches
am: support --allow-empty to record specific empty patches
Documentation/git-am.txt | 16 +++++-
Documentation/git-format-patch.txt | 6 ++-
builtin/am.c | 82 +++++++++++++++++++++++++-----
t/t4150-am.sh | 73 ++++++++++++++++++++++++++
t/t7512-status-help.sh | 1 +
wt-status.c | 3 ++
6 files changed, 166 insertions(+), 15 deletions(-)
base-commit: abe6bb3905392d5eb6b01fa6e54d7e784e0522aa
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1076%2Faleen42%2Fnext-v14
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1076/aleen42/next-v14
Pull-Request: https://github.com/gitgitgadget/git/pull/1076
Range-diff vs v13:
1: a524ca6adfa = 1: a524ca6adfa doc: git-format-patch: describe the option --always
2: a3e850bab7d ! 2: b6a04fc12df am: support --empty=<option> to handle empty patches
@@ Documentation/git-am.txt: OPTIONS
+--empty=(die|drop|keep)::
+ By default, or when the option is set to 'die', the command
-+ errors out on an input e-mail message that lacks a patch. When
-+ this option is set to 'drop', skip such an e-mail message instead.
++ errors out on an input e-mail message lacking a patch
++ and stops into the middle of the current am session. When this
++ option is set to 'drop', skip such an e-mail message instead.
+ When this option is set to 'keep', create an empty commit,
+ recording the contents of the e-mail message as its log.
+
3: 08bd397ae7a ! 3: cbd822d4340 am: support --allow-empty to record specific empty patches
@@ Documentation/git-am.txt: default. You can use `--no-utf8` to override this.
Defaults to `raw`.
+--allow-empty::
-+ Record the empty patch as an empty commit with
++ After a patch failure on an input e-mail message lacking a patch,
++ the user can still record the empty patch as an empty commit with
+ the contents of the e-mail message as its log.
+
DISCUSSION
--
gitgitgadget
From: 徐沛文 (Aleen) via GitGitGadget <hidden> Date: 2021-12-01 03:37:51
From: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
[off-list ref]
This commit has described how to use '--always' option in the command
'git-format-patch' to include patches for commits that emit no changes.
Signed-off-by: 徐沛文 (Aleen) <redacted>
---
Documentation/git-format-patch.txt | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
@@ -192,6 +192,10 @@ will want to ensure that threading is disabled for `git send-email`. patches being generated, and any patch that matches is ignored.+--always::+ Include patches for commits that do not introduce any change,+ which are omitted by default.+ --cover-from-description=<mode>:: Controls which parts of the cover letter will be automatically populated using the branch's description.
From: 徐沛文 (Aleen) via GitGitGadget <hidden> Date: 2021-12-01 03:37:56
From: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
[off-list ref]
Since that the command 'git-format-patch' can include patches of
commits that emit no changes, the 'git-am' command should also
support an option, named as '--empty', to specify how to handle
those empty patches. In this commit, we have implemented three
valid options ('die', 'drop' and 'keep').
Signed-off-by: 徐沛文 (Aleen) <redacted>
---
Documentation/git-am.txt | 9 +++++++
builtin/am.c | 55 ++++++++++++++++++++++++++++++++++++----
t/t4150-am.sh | 49 +++++++++++++++++++++++++++++++++++
3 files changed, 108 insertions(+), 5 deletions(-)
@@ -63,6 +64,14 @@ OPTIONS --quoted-cr=<action>:: This flag will be passed down to 'git mailinfo' (see linkgit:git-mailinfo[1]).+--empty=(die|drop|keep)::+ By default, or when the option is set to 'die', the command+ errors out on an input e-mail message lacking a patch+ and stops into the middle of the current am session. When this+ option is set to 'drop', skip such an e-mail message instead.+ When this option is set to 'keep', create an empty commit,+ recording the contents of the e-mail message as its log.+ -m:: --message-id:: Pass the `-m` flag to 'git mailinfo' (see linkgit:git-mailinfo[1]),
@@ -178,6 +185,25 @@ static int am_option_parse_quoted_cr(const struct option *opt,return0;}+staticintam_option_parse_empty(conststructoption*opt,+constchar*arg,intunset)+{+int*opt_value=opt->value;++BUG_ON_OPT_NEG(unset);++if(!strcmp(arg,"die"))+*opt_value=DIE_EMPTY_COMMIT;+elseif(!strcmp(arg,"drop"))+*opt_value=DROP_EMPTY_COMMIT;+elseif(!strcmp(arg,"keep"))+*opt_value=KEEP_EMPTY_COMMIT;+else+returnerror(_("Invalid value for --empty: %s"),arg);++return0;+}+/***Returnspathrelativetotheam_statedirectory.*/
@@ -1248,11 +1274,6 @@ static int parse_mail(struct am_state *state, const char *mail)gotofinish;}-if(is_empty_or_missing_file(am_path(state,"patch"))){-printf_ln(_("Patch is empty."));-die_user_resolve(state);-}-strbuf_addstr(&msg,"\n\n");strbuf_addbuf(&msg,&mi.log_message);strbuf_stripspace(&msg,0);
@@ -1152,4 +1158,47 @@ test_expect_success 'apply binary blob in partial clone' 'git-Cclientam../patch'+test_expect_success'an empty input file is error regardless of --empty option''+test_when_finished"git am --abort || :"&&+test_must_failgitam--empty=dropempty.patch2>actual&&+echo"Patch format detection failed.">expected&&+test_cmpexpectedactual+'++test_expect_success'invalid when passing the --empty option alone''+test_when_finished"git am --abort || :"&&+gitcheckoutempty-commit^&&+test_must_failgitam--emptyempty-commit.patch2>err&&+echo"error: Invalid value for --empty: empty-commit.patch">expected&&+test_cmpexpectederr+'++test_expect_success'a message without a patch is an error (default)''+test_when_finished"git am --abort || :"&&+test_must_failgitamempty-commit.patch>err&&+grep"Patch is empty"err+'++test_expect_success'a message without a patch is an error where an explicit "--empty=die" is given''+test_when_finished"git am --abort || :"&&+test_must_failgitam--empty=dieempty-commit.patch>err&&+grep"Patch is empty."err+'++test_expect_success'a message without a patch will be skipped when "--empty=drop" is given''+gitam--empty=dropempty-commit.patch>output&&+gitrev-parseempty-commit^>expected&&+gitrev-parseHEAD>actual&&+test_cmpexpectedactual&&+grep"Skipping: empty commit"output+'++test_expect_success'record as an empty commit when meeting e-mail message that lacks a patch''+gitam--empty=keepempty-commit.patch&&+test_path_is_missing.git/rebase-apply&&+gitshowempty-commit--format="%s">expected&&+gitshowHEAD--format="%s">actual&&+test_cmpactualexpected+'+ test_done
@@ -200,6 +200,11 @@ default. You can use `--no-utf8` to override this. the e-mail message; if `diff`, show the diff portion only. Defaults to `raw`.+--allow-empty::+ After a patch failure on an input e-mail message lacking a patch,+ the user can still record the empty patch as an empty commit with+ the contents of the e-mail message as its log.+ DISCUSSION ----------
@@ -1825,7 +1825,8 @@ static void am_run(struct am_state *state, int resume)to_keep=1;break;caseDIE_EMPTY_COMMIT:-printf_ln(_("Patch is empty."));+printf_ln(_("Patch is empty.\n"+"If you want to record it as an empty commit, run \"git am --allow-empty\"."));die_user_resolve(state);break;}
@@ -1898,19 +1899,24 @@ next:/***Resumethecurrentamsessionafterpatchapplicationfailure.Theuserdid*allthehardwork,andwedonothavetodoanypatchapplication.Just-*trustandcommitwhattheuserhasintheindexandworkingtree.+*trustandcommitwhattheuserhasintheindexandworkingtree.If`allow_empty`+*istrue,commitasanemptycommitwhenthereisnochanges.*/-staticvoidam_resolve(structam_state*state)+staticvoidam_resolve(structam_state*state,intallow_empty){validate_resume_state(state);say(state,stdout,_("Applying: %.*s"),linelen(state->msg),state->msg);if(!repo_index_has_changes(the_repository,NULL,NULL)){-printf_ln(_("No changes - did you forget to use 'git add'?\n"-"If there is nothing left to stage, chances are that something else\n"-"already introduced the same changes; you might want to skip this patch."));-die_user_resolve(state);+if(allow_empty)+printf_ln(_("No changes - record it as an empty commit."));+else{+printf_ln(_("No changes - did you forget to use 'git add'?\n"+"If there is nothing left to stage, chances are that something else\n"+"already introduced the same changes; you might want to skip this patch."));+die_user_resolve(state);+}}if(unmerged_cache()){
@@ -2390,6 +2397,9 @@ int cmd_am(int argc, const char **argv, const char *prefix)N_("show the patch being applied"),PARSE_OPT_CMDMODE|PARSE_OPT_OPTARG|PARSE_OPT_NONEG|PARSE_OPT_LITERAL_ARGHELP,parse_opt_show_current_patch,RESUME_SHOW_PATCH},+OPT_CMDMODE(0,"allow-empty",&resume.mode,+N_("record the empty patch as an empty commit"),+RESUME_ALLOW_EMPTY),OPT_BOOL(0,"committer-date-is-author-date",&state.committer_date_is_author_date,N_("lie about committer date")),
@@ -1201,4 +1201,28 @@ test_expect_success 'record as an empty commit when meeting e-mail message thattest_cmpactualexpected'+test_expect_success'skip an empty patch in the middle of an am session''+gitcheckoutempty-commit^&&+test_must_failgitamempty-commit.patch>err&&+grep"Patch is empty."err&&+grep"If you want to record it as an empty commit, run \"git am --allow-empty\"."err&&+gitam--skip&&+test_path_is_missing.git/rebase-apply&&+gitrev-parseempty-commit^>expected&&+gitrev-parseHEAD>actual&&+test_cmpexpectedactual+'++test_expect_success'record an empty patch as an empty commit in the middle of an am session''+gitcheckoutempty-commit^&&+test_must_failgitamempty-commit.patch>err&&+grep"Patch is empty."err&&+grep"If you want to record it as an empty commit, run \"git am --allow-empty\"."err&&+gitam--allow-empty&&+test_path_is_missing.git/rebase-apply&&+gitshowempty-commit--format="%s">expected&&+gitshowHEAD--format="%s">actual&&+test_cmpactualexpected+'+ test_done
@@ -658,6 +658,7 @@ test_expect_success 'status in an am session: empty patch' ' Onbrancham_empty Youareinthemiddleofanamsession. Thecurrentpatchisempty.+(use"git am --allow-empty"torecordthispatchasanemptycommit)(use"git am --skip"toskipthispatch)(use"git am --abort"torestoretheoriginalbranch)
@@ -1227,6 +1227,9 @@ static void show_am_in_progress(struct wt_status *s,if(!s->state.am_empty_patch)status_printf_ln(s,color,_(" (fix conflicts and then run \"git am --continue\")"));+else+status_printf_ln(s,color,+_(" (use \"git am --allow-empty\" to record this patch as an empty commit)"));status_printf_ln(s,color,_(" (use \"git am --skip\" to skip this patch)"));status_printf_ln(s,color,
I have to agree with Elijah that "to die" is used differently in Git's
context. This should probably be called "stop" instead. Or "error". But
not "die".
Ciao,
Dscho
P.S.: The enum value should probably have an `_ON_` in it, i.e.
`STOP_ON_EMPTY_COMMIT` or `ERROR_ON_EMPTY_COMMIT`.
From: Aleen via GitGitGadget <hidden> Date: 2021-12-06 09:41:46
Since that git has supported the --always option for the git-format-patch
command to create a patch with an empty commit message, git-am should
support applying and committing with empty patches.
----------------------------------------------------------------------------
Changes since v1:
1. add a case when not passing the --always option.
2. rename the --always option to --allow-empty.
----------------------------------------------------------------------------
Changes since v2:
1. rename the --allow-empty option to --empty-commit.
2. introduce three different strategies (die|skip|asis) when trying to
record empty patches as empty commits.
----------------------------------------------------------------------------
Changes since v3:
1. generate the missed file for test cases.
2. grep -f cannot be used under Mac OS.
----------------------------------------------------------------------------
Changes since v4:
1. rename the --empty-commit option to --empty.
2. rename three different strategies (die|skip|asis) to die, drop and keep
correspondingly.
----------------------------------------------------------------------------
Changes since v5:
1. throw an error when passing --empty option without value.
----------------------------------------------------------------------------
Changes since v6:
1. add i18n resources.
----------------------------------------------------------------------------
Changes since v7:
1. update code according to the seen branch.
2. fix the wrong document of git-am.
3. sign off commits by a real name.
----------------------------------------------------------------------------
Changes since v8:
1. update the committer's name with my real name to fix DCO of GGG.
----------------------------------------------------------------------------
Changes since v9:
1. imitate the signed name format of
https://lore.kernel.org/git/pull.1143.git.git.1637347813367.gitgitgadget@gmail.com
.
----------------------------------------------------------------------------
Changes since v11:
1. introduce an interactive option --allow-empty for git-am to record empty
patches in the middle of an am session.
----------------------------------------------------------------------------
Changes since v12:
1. record the empty patch as an empty commit only when there are no
changes.
2. fix indentation problems.
3. simplify "to keep recording" to "to record".
4. add a test case for skipping empty patches via the --skip option.
----------------------------------------------------------------------------
Changes since v13:
1. add an additional description about the 'die' value.
----------------------------------------------------------------------------
Changes since v14:
1. reimplement the 'die' value and stop the whole session. (Expected a
reroll)
2. the --allow-empty option is a valid resume value only when: (Expected a
reroll)
* index has not changed
* lacking a patch
徐沛文 (Aleen) (3):
doc: git-format-patch: describe the option --always
am: support --empty=<option> to handle empty patches
am: support --allow-empty to record specific empty patches
Documentation/git-am.txt | 16 ++++-
Documentation/git-format-patch.txt | 6 +-
builtin/am.c | 100 ++++++++++++++++++++++++----
t/t4150-am.sh | 103 +++++++++++++++++++++++++++++
t/t7512-status-help.sh | 1 +
wt-status.c | 3 +
6 files changed, 214 insertions(+), 15 deletions(-)
base-commit: abe6bb3905392d5eb6b01fa6e54d7e784e0522aa
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1076%2Faleen42%2Fnext-v15
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1076/aleen42/next-v15
Pull-Request: https://github.com/gitgitgadget/git/pull/1076
Range-diff vs v14:
1: a524ca6adfa = 1: a524ca6adfa doc: git-format-patch: describe the option --always
2: b6a04fc12df ! 2: 8ec8e212672 am: support --empty=<option> to handle empty patches
@@ Documentation/git-am.txt: OPTIONS
This flag will be passed down to 'git mailinfo' (see linkgit:git-mailinfo[1]).
+--empty=(die|drop|keep)::
-+ By default, or when the option is set to 'die', the command
-+ errors out on an input e-mail message lacking a patch
-+ and stops into the middle of the current am session. When this
-+ option is set to 'drop', skip such an e-mail message instead.
++ By default, the command errors out on an input e-mail message
++ lacking a patch and stops into the middle of the current am session.
++ When this option is set to 'die', the whole session dies with error.
++ When this option is set to 'drop', skip such an e-mail message instead.
+ When this option is set to 'keep', create an empty commit,
+ recording the contents of the e-mail message as its log.
+
@@ builtin/am.c: enum show_patch_type {
};
+enum empty_action {
-+ DIE_EMPTY_COMMIT = 0, /* output errors */
++ ERR_EMPTY_COMMIT = 0, /* output errors and stop in the middle of an am session */
++ DIE_EMPTY_COMMIT, /* output errors and stop the whole am session */
+ DROP_EMPTY_COMMIT, /* skip with a notice message, unless "--quiet" has been passed */
+ KEEP_EMPTY_COMMIT /* keep recording as empty commits */
+};
@@ builtin/am.c: static void am_run(struct am_state *state, int resume)
+ to_keep = 1;
+ break;
+ case DIE_EMPTY_COMMIT:
++ am_destroy(state);
++ die(_("Patch is empty."));
++ break;
++ case ERR_EMPTY_COMMIT:
+ printf_ln(_("Patch is empty."));
+ die_user_resolve(state);
+ break;
@@ builtin/am.c: int cmd_am(int argc, const char **argv, const char *prefix)
{ OPTION_STRING, 'S', "gpg-sign", &state.sign_commit, N_("key-id"),
N_("GPG-sign commits"),
PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
-+ OPT_CALLBACK_F(0, "empty", &state.empty_type, "{drop,keep,die}",
++ OPT_CALLBACK_F(ERR_EMPTY_COMMIT, "empty", &state.empty_type, "{die,drop,keep}",
+ N_("how to handle empty patches"),
+ PARSE_OPT_NONEG, am_option_parse_empty),
OPT_HIDDEN_BOOL(0, "rebasing", &state.rebasing,
@@ t/t4150-am.sh: test_expect_success 'apply binary blob in partial clone' '
+ test_cmp expected err
+'
+
-+test_expect_success 'a message without a patch is an error (default)' '
++test_expect_success 'a message without a patch is an error and stop in the middle of an am session (default)' '
+ test_when_finished "git am --abort || :" &&
+ test_must_fail git am empty-commit.patch >err &&
++ test_path_is_dir .git/rebase-apply &&
+ grep "Patch is empty" err
+'
+
-+test_expect_success 'a message without a patch is an error where an explicit "--empty=die" is given' '
-+ test_when_finished "git am --abort || :" &&
-+ test_must_fail git am --empty=die empty-commit.patch >err &&
-+ grep "Patch is empty." err
++test_expect_success 'a message without a patch is an error and exit where an explicit "--empty=die" is given' '
++ test_must_fail git am --empty=die empty-commit.patch 2>err &&
++ test_path_is_missing .git/rebase-apply &&
++ grep "fatal: Patch is empty." err
+'
+
+test_expect_success 'a message without a patch will be skipped when "--empty=drop" is given' '
3: cbd822d4340 ! 3: d669406a312 am: support --allow-empty to record specific empty patches
@@ Commit message
am: support --allow-empty to record specific empty patches
This option helps to record specific empty patches in the middle
- of an am session.
+ of an am session. However, it is a valid resume value only when:
+
+ 1. index has not changed
+ 2. lacking a branch
Signed-off-by: 徐沛文 (Aleen) [off-list ref]
@@ Documentation/git-am.txt: default. You can use `--no-utf8` to override this.
## builtin/am.c ##
@@ builtin/am.c: static void am_run(struct am_state *state, int resume)
- to_keep = 1;
+ die(_("Patch is empty."));
break;
- case DIE_EMPTY_COMMIT:
+ case ERR_EMPTY_COMMIT:
- printf_ln(_("Patch is empty."));
+ printf_ln(_("Patch is empty.\n"
+ "If you want to record it as an empty commit, run \"git am --allow-empty\"."));
@@ builtin/am.c: next:
-static void am_resolve(struct am_state *state)
+static void am_resolve(struct am_state *state, int allow_empty)
{
++ int index_changed;
++
validate_resume_state(state);
say(state, stdout, _("Applying: %.*s"), linelen(state->msg), state->msg);
- if (!repo_index_has_changes(the_repository, NULL, NULL)) {
+- if (!repo_index_has_changes(the_repository, NULL, NULL)) {
- printf_ln(_("No changes - did you forget to use 'git add'?\n"
- "If there is nothing left to stage, chances are that something else\n"
- "already introduced the same changes; you might want to skip this patch."));
-- die_user_resolve(state);
++ /**
++ * "--allow-empty" is a valid resume value only when:
++ * 1. index has not changed
++ * 2. lacking a patch
++ */
++ index_changed = repo_index_has_changes(the_repository, NULL, NULL);
++ if (allow_empty && (index_changed || !is_empty_or_missing_file(am_path(state, "patch")))) {
++ printf_ln(_("Invalid resume value."));
+ die_user_resolve(state);
+ }
+
++ if (!index_changed) {
+ if (allow_empty)
+ printf_ln(_("No changes - record it as an empty commit."));
+ else {
@@ builtin/am.c: next:
+ "already introduced the same changes; you might want to skip this patch."));
+ die_user_resolve(state);
+ }
- }
-
++ }
++
if (unmerged_cache()) {
+ printf_ln(_("You still have unmerged paths in your index.\n"
+ "You should 'git add' each file with resolved conflicts to mark them as such.\n"
@@ builtin/am.c: enum resume_type {
RESUME_SKIP,
RESUME_ABORT,
@@ t/t4150-am.sh: test_expect_success 'record as an empty commit when meeting e-mai
+ git show HEAD --format="%s" >actual &&
+ test_cmp actual expected
+'
++
++test_expect_success 'cannot create empty commits when the index is changed' '
++ git checkout empty-commit^ &&
++ test_must_fail git am empty-commit.patch >err &&
++ : >empty-file &&
++ git add empty-file &&
++ test_must_fail git am --allow-empty >err &&
++ grep "Invalid resume value." err
++'
++
++test_expect_success 'cannot create empty commits when there is a clean index due to merge conflicts' '
++ test_when_finished "git am --abort || :" &&
++ git rev-parse HEAD >expected &&
++ test_must_fail git am seq.patch &&
++ test_must_fail git am --allow-empty >err &&
++ grep "Invalid resume value." err &&
++ git rev-parse HEAD >actual &&
++ test_cmp actual expected
++'
++
++test_expect_success 'cannot create empty commits when there is unmerged index due to merge conflicts' '
++ test_when_finished "git am --abort || :" &&
++ git rev-parse HEAD >expected &&
++ test_must_fail git am -3 seq.patch &&
++ test_must_fail git am --allow-empty >err &&
++ grep "Invalid resume value." err &&
++ git rev-parse HEAD >actual &&
++ test_cmp actual expected
++'
+
test_done
--
gitgitgadget
From: 徐沛文 (Aleen) via GitGitGadget <hidden> Date: 2021-12-06 09:41:47
From: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
[off-list ref]
This commit has described how to use '--always' option in the command
'git-format-patch' to include patches for commits that emit no changes.
Signed-off-by: 徐沛文 (Aleen) <redacted>
---
Documentation/git-format-patch.txt | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
@@ -192,6 +192,10 @@ will want to ensure that threading is disabled for `git send-email`. patches being generated, and any patch that matches is ignored.+--always::+ Include patches for commits that do not introduce any change,+ which are omitted by default.+ --cover-from-description=<mode>:: Controls which parts of the cover letter will be automatically populated using the branch's description.
From: 徐沛文 (Aleen) via GitGitGadget <hidden> Date: 2021-12-06 09:41:49
From: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
[off-list ref]
Since that the command 'git-format-patch' can include patches of
commits that emit no changes, the 'git-am' command should also
support an option, named as '--empty', to specify how to handle
those empty patches. In this commit, we have implemented three
valid options ('die', 'drop' and 'keep').
Signed-off-by: 徐沛文 (Aleen) <redacted>
---
Documentation/git-am.txt | 9 ++++++
builtin/am.c | 60 ++++++++++++++++++++++++++++++++++++----
t/t4150-am.sh | 50 +++++++++++++++++++++++++++++++++
3 files changed, 114 insertions(+), 5 deletions(-)
@@ -63,6 +64,14 @@ OPTIONS --quoted-cr=<action>:: This flag will be passed down to 'git mailinfo' (see linkgit:git-mailinfo[1]).+--empty=(die|drop|keep)::+ By default, the command errors out on an input e-mail message+ lacking a patch and stops into the middle of the current am session.+ When this option is set to 'die', the whole session dies with error.+ When this option is set to 'drop', skip such an e-mail message instead.+ When this option is set to 'keep', create an empty commit,+ recording the contents of the e-mail message as its log.+ -m:: --message-id:: Pass the `-m` flag to 'git mailinfo' (see linkgit:git-mailinfo[1]),
@@ -87,6 +87,13 @@ enum show_patch_type {SHOW_PATCH_DIFF=1,};+enumempty_action{+ERR_EMPTY_COMMIT=0,/* output errors and stop in the middle of an am session */+DIE_EMPTY_COMMIT,/* output errors and stop the whole am session */+DROP_EMPTY_COMMIT,/* skip with a notice message, unless "--quiet" has been passed */+KEEP_EMPTY_COMMIT/* keep recording as empty commits */+};+structam_state{/* state directory path */char*dir;
@@ -178,6 +186,25 @@ static int am_option_parse_quoted_cr(const struct option *opt,return0;}+staticintam_option_parse_empty(conststructoption*opt,+constchar*arg,intunset)+{+int*opt_value=opt->value;++BUG_ON_OPT_NEG(unset);++if(!strcmp(arg,"die"))+*opt_value=DIE_EMPTY_COMMIT;+elseif(!strcmp(arg,"drop"))+*opt_value=DROP_EMPTY_COMMIT;+elseif(!strcmp(arg,"keep"))+*opt_value=KEEP_EMPTY_COMMIT;+else+returnerror(_("Invalid value for --empty: %s"),arg);++return0;+}+/***Returnspathrelativetotheam_statedirectory.*/
@@ -1248,11 +1275,6 @@ static int parse_mail(struct am_state *state, const char *mail)gotofinish;}-if(is_empty_or_missing_file(am_path(state,"patch"))){-printf_ln(_("Patch is empty."));-die_user_resolve(state);-}-strbuf_addstr(&msg,"\n\n");strbuf_addbuf(&msg,&mi.log_message);strbuf_stripspace(&msg,0);
@@ -1152,4 +1158,48 @@ test_expect_success 'apply binary blob in partial clone' 'git-Cclientam../patch'+test_expect_success'an empty input file is error regardless of --empty option''+test_when_finished"git am --abort || :"&&+test_must_failgitam--empty=dropempty.patch2>actual&&+echo"Patch format detection failed.">expected&&+test_cmpexpectedactual+'++test_expect_success'invalid when passing the --empty option alone''+test_when_finished"git am --abort || :"&&+gitcheckoutempty-commit^&&+test_must_failgitam--emptyempty-commit.patch2>err&&+echo"error: Invalid value for --empty: empty-commit.patch">expected&&+test_cmpexpectederr+'++test_expect_success'a message without a patch is an error and stop in the middle of an am session (default)''+test_when_finished"git am --abort || :"&&+test_must_failgitamempty-commit.patch>err&&+test_path_is_dir.git/rebase-apply&&+grep"Patch is empty"err+'++test_expect_success'a message without a patch is an error and exit where an explicit "--empty=die" is given''+test_must_failgitam--empty=dieempty-commit.patch2>err&&+test_path_is_missing.git/rebase-apply&&+grep"fatal: Patch is empty."err+'++test_expect_success'a message without a patch will be skipped when "--empty=drop" is given''+gitam--empty=dropempty-commit.patch>output&&+gitrev-parseempty-commit^>expected&&+gitrev-parseHEAD>actual&&+test_cmpexpectedactual&&+grep"Skipping: empty commit"output+'++test_expect_success'record as an empty commit when meeting e-mail message that lacks a patch''+gitam--empty=keepempty-commit.patch&&+test_path_is_missing.git/rebase-apply&&+gitshowempty-commit--format="%s">expected&&+gitshowHEAD--format="%s">actual&&+test_cmpactualexpected+'+ test_done