am: support --always option to am empty commits
cover am: support --always option to am empty commits
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
Signature · 1 line
gitgitgadget
PATCH 1/2 doc: git-format-patch: specify the option --always
From: Aleen <[email protected]>
--- Documentation/git-format-patch.txt | 5 +++++ 1 file changed, 5 insertions(+)
Documentation/git-format-patch.txt +5 -0
@@ -30,6 +30,7 @@ SYNOPSIS [--range-diff=<previous> [--creation-factor=<percent>]] [--filename-max-length=<n>] [--progress] + [--always] [<common diff options>] [ <since> | <revision range> ]
@@ -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,
Signature · 1 line
gitgitgadget
PATCH 2/2 am: support --always option to am empty commits
In reply to Aleen via GitGitGadgetFrom: Aleen <[email protected]>
--- Documentation/git-am.txt | 5 +++++ builtin/am.c | 18 ++++++++++++++++-- t/t4150-am.sh | 25 +++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-)
Documentation/git-am.txt +5 -0
@@ -16,6 +16,7 @@ SYNOPSIS [--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet] [--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>] [--quoted-cr=<action>] + [--always] [(<mbox> | <Maildir>)...] 'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)])
@@ -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::
builtin/am.c +16 -2
@@ -124,6 +124,8 @@ struct am_state {int ignore_date;int allow_rerere_autoupdate;const char *sign_commit; +int always; +int empty_commit;int rebasing; };
@@ -1249,8 +1251,12 @@ static int parse_mail(struct am_state *state, const char *mail) }if (is_empty_or_missing_file (am_path (state,"patch" ))) { -printf_ln (_ ("Patch is empty." )); -die_user_resolve (state); +if (state->always) { + state->empty_commit =1 ; + }else { +printf_ln (_ ("Patch is empty." )); +die_user_resolve (state); + } }strbuf_addstr (&msg,"\n\n" );
@@ -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; +if (run_applypatch_msg_hook (state))exit (1 );
@@ -1827,6 +1836,7 @@ static void am_run(struct am_state *state, int resume)die_user_resolve (state); } +commit:do_commit (state); next:
@@ -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 ()
t/t4150-am.sh +25 -0
@@ -196,6 +196,12 @@ test_expect_success setup ' git format-patch -M --stdout lorem^ >rename-add.patch && + git checkout -b empty-commit && + git commit -m "empty commit" --allow-empty && + + git format-patch --stdout empty-commit^ >empty.patch && + git format-patch --always --stdout empty-commit^ >empty-commit.patch && + # reset time sane_unset test_tick && test_tick
@@ -1152,4 +1158,23 @@ test_expect_success 'apply binary blob in partial clone' ' git -C client am ../patch ' +test_expect_success 'am a real empty patch with the --always option' ' + rm -fr .git/rebase-apply && + git reset --hard && + test_must_fail git am --always empty.patch 2>actual && + echo Patch format detection failed. >expected && + test_cmp expected actual +' + +test_expect_success 'am a patch with empty commits' ' + grep "empty commit" empty-commit.patch && + rm -fr .git/rebase-apply && + git reset --hard && + git checkout empty-commit^ && + git am --always empty-commit.patch && + test_path_is_missing .git/rebase-apply && + git cat-file commit HEAD >actual && + test_i18ngrep "empty commit" actual +' + test_done
Signature · 1 line
gitgitgadget
Am 12.11.21 um 05:58 schrieb Aleen via GitGitGadget:
Quoted 3 lines
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é
Quoted 7 lines · René Scharfe
Am 12.11.21 um 05:58 schrieb Aleen via GitGitGadget:
Quoted 3 lines
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.
What symmetry?
Quoted 3 lines
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.
That one I can believe, even though I do not necessarily think it is a good idea to add such an option.
v2 cover am: support --allow-empty option to am empty commits
In reply to Aleen via GitGitGadgetSince 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
Signature · 1 line
gitgitgadget
PATCH v2 1/4 doc: git-format-patch: specify the option --always
From: Aleen <[email protected]>
--- Documentation/git-format-patch.txt | 5 +++++ 1 file changed, 5 insertions(+)
Documentation/git-format-patch.txt +5 -0
@@ -30,6 +30,7 @@ SYNOPSIS [--range-diff=<previous> [--creation-factor=<percent>]] [--filename-max-length=<n>] [--progress] + [--always] [<common diff options>] [ <since> | <revision range> ]
@@ -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,
Signature · 1 line
gitgitgadget
PATCH v2 2/4 am: support --always option to am empty commits
In reply to Aleen via GitGitGadgetFrom: Aleen <[email protected]>
--- Documentation/git-am.txt | 5 +++++ builtin/am.c | 18 ++++++++++++++++-- t/t4150-am.sh | 25 +++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-)
Documentation/git-am.txt +5 -0
@@ -16,6 +16,7 @@ SYNOPSIS [--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet] [--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>] [--quoted-cr=<action>] + [--always] [(<mbox> | <Maildir>)...] 'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)])
@@ -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::
builtin/am.c +16 -2
@@ -124,6 +124,8 @@ struct am_state {int ignore_date;int allow_rerere_autoupdate;const char *sign_commit; +int always; +int empty_commit;int rebasing; };
@@ -1249,8 +1251,12 @@ static int parse_mail(struct am_state *state, const char *mail) }if (is_empty_or_missing_file (am_path (state,"patch" ))) { -printf_ln (_ ("Patch is empty." )); -die_user_resolve (state); +if (state->always) { + state->empty_commit =1 ; + }else { +printf_ln (_ ("Patch is empty." )); +die_user_resolve (state); + } }strbuf_addstr (&msg,"\n\n" );
@@ -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; +if (run_applypatch_msg_hook (state))exit (1 );
@@ -1827,6 +1836,7 @@ static void am_run(struct am_state *state, int resume)die_user_resolve (state); } +commit:do_commit (state); next:
@@ -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 ()
t/t4150-am.sh +25 -0
@@ -196,6 +196,12 @@ test_expect_success setup ' git format-patch -M --stdout lorem^ >rename-add.patch && + git checkout -b empty-commit && + git commit -m "empty commit" --allow-empty && + + git format-patch --stdout empty-commit^ >empty.patch && + git format-patch --always --stdout empty-commit^ >empty-commit.patch && + # reset time sane_unset test_tick && test_tick
@@ -1152,4 +1158,23 @@ test_expect_success 'apply binary blob in partial clone' ' git -C client am ../patch ' +test_expect_success 'am a real empty patch with the --always option' ' + rm -fr .git/rebase-apply && + git reset --hard && + test_must_fail git am --always empty.patch 2>actual && + echo Patch format detection failed. >expected && + test_cmp expected actual +' + +test_expect_success 'am a patch with empty commits' ' + grep "empty commit" empty-commit.patch && + rm -fr .git/rebase-apply && + git reset --hard && + git checkout empty-commit^ && + git am --always empty-commit.patch && + test_path_is_missing .git/rebase-apply && + git cat-file commit HEAD >actual && + test_i18ngrep "empty commit" actual +' + test_done
Signature · 1 line
gitgitgadget
PATCH v2 3/4 test: am: add the case when not passing the --always option
In reply to Aleen via GitGitGadgetFrom: Aleen <[email protected]>
--- t/t4150-am.sh | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
t/t4150-am.sh +11 -1
@@ -1166,7 +1166,17 @@ test_expect_success 'am a real empty patch with the --always option' ' test_cmp expected actual ' -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 && + git reset --hard && + git checkout empty-commit^ && + test_must_fail git am empty-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 && git reset --hard &&
Signature · 1 line
gitgitgadget
PATCH v2 4/4 chore: am: rename the --always option to --allow-empty
In reply to Aleen via GitGitGadgetFrom: Aleen <[email protected]>
--- Documentation/git-am.txt | 4 ++-- builtin/am.c | 8 ++++---- t/t4150-am.sh | 10 +++++----- 3 files changed, 11 insertions(+), 11 deletions(-)
Documentation/git-am.txt +2 -2
@@ -16,7 +16,7 @@ SYNOPSIS [--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet] [--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>] [--quoted-cr=<action>] - [--always] + [--allow-empty] [(<mbox> | <Maildir>)...] 'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)])
@@ -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])
builtin/am.c +4 -4
@@ -124,7 +124,7 @@ struct am_state {int ignore_date;int allow_rerere_autoupdate;const char *sign_commit; -int always; +int allow_empty;int empty_commit;int rebasing; };
@@ -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,
t/t4150-am.sh +5 -5
@@ -1158,15 +1158,15 @@ test_expect_success 'apply binary blob in partial clone' ' git -C client am ../patch ' -test_expect_success 'am a real empty patch with the --always option' ' +test_expect_success 'am a real empty patch with the --allow-empty option' ' rm -fr .git/rebase-apply && git reset --hard && - test_must_fail git am --always empty.patch 2>actual && + test_must_fail git am --allow-empty empty.patch 2>actual && echo Patch format detection failed. >expected && test_cmp expected actual ' -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 && git reset --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 && git reset --hard && git checkout empty-commit^ && - git am --always empty-commit.patch && + git am --allow-empty empty-commit.patch && test_path_is_missing .git/rebase-apply && git cat-file commit HEAD >actual && test_i18ngrep "empty commit" actual
Signature · 1 line
gitgitgadget
Dears René,
Quoted 6 lines
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.
Dears Junio C Hamano:
Quoted 10 lines
Quoted 7 lines · René Scharfe
Am 12.11.21 um 05:58 schrieb Aleen via GitGitGadget:
Quoted 3 lines
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.
Quoted 8 lines
What symmetry?
Quoted 3 lines
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.
That one I can believe, even though I do not necessarily think it is a good idea to add such an option.
In some cases when we need to migrate commits from one branch to another branch, from one repo to another repo, it should be necessary.
Aleen
Am 12.11.21 um 07:47 schrieb Junio C Hamano:
Quoted 11 lines
Quoted 7 lines · René Scharfe
Am 12.11.21 um 05:58 schrieb Aleen via GitGitGadget:
Quoted 3 lines
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.
What symmetry?
To have the same option in both producer and consumer.
René
Quoted 6 lines · René Scharfe
Quoted 4 lines
Quoted 2 lines
The symmetry is compelling, but "always" is quite generic. I can see e.g. someone expecting "git am --always" to imply --keep-non-patch.
What symmetry?
To have the same option in both producer and consumer.
Well, "--always" that stands for "--always-show-header" seeps through to the command line parser from revision.c layer but that is by accident, and is not even documented. We may want to file it as a bug and fix it later.
As you mentioned, allow-empty-commit does sound like a much better name.
Re: [PATCH v2 1/4] doc: git-format-patch: specify the option --always
In reply to Aleen via GitGitGadgetQuoted 2 lines · Aleen via GitGitGadget
From: Aleen <[email protected]>
Subject: Re: [PATCH v2 1/4] doc: git-format-patch: specify the option --always
"specify" -> "describe", perhaps?
Quoted 18 lines
Signed-off-by Aleen <[email protected]>--- Documentation/git-format-patch.txt | 5 +++++ 1 file changed, 5 insertions(+)Documentation/git-format-patch.txt +1
-0@@ -30,6 +30,7 @@ SYNOPSIS [--range-diff=<previous> [--creation-factor=<percent>]] [--filename-max-length=<n>] [--progress] + [--always] [<common diff options>] [ <since> | <revision range> ]
Documentation/git-format-patch.txt you can use `--suffix=-patch` to get `0001-description-of-my-change-patch`. · line 394
Quoted 6 lines
Documentation/git-format-patch.txt +3
-0@@ -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.
Quoted 2 lines · Aleen via GitGitGadget
From: Aleen <[email protected]>
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.
Documentation/git-am.txt default. You can use `--no-utf8` to override this. · line 165
Quoted 3 lines
+--always::
Documentation/git-am.txt +2
-0+ 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.
builtin/am.c struct am_state { · line 127
Quoted 9 lines
builtin/am.c +1
-0@@ -124,6 +124,8 @@ struct am_state {int ignore_date;int allow_rerere_autoupdate;const char *sign_commit; +int always;
OK, so here is where the parse_options() records the command line option.
builtin/am.c struct am_state { · line 128
Quoted 1 line
builtin/am.c +1
-0+int empty_commit;
I do not think this addtion of empty_commit member to this structure is welcome or necessary.
Quoted 6 lines
builtin/am.c +0
-0int rebasing; };@@ -1249,8 +1251,12 @@ static int parse_mail(struct am_state *state, const char *mail) }
builtin/am.c static int parse_mail(struct am_state *state, const char *mail) · line 1260
Quoted 10 lines
builtin/am.c +6
-2if (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.
builtin/am.c static void am_run(struct am_state *state, int resume) · line 1803
Quoted 7 lines
builtin/am.c +3
-0@@ -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.
builtin/am.c static void am_run(struct am_state *state, int resume) · line 1805
Quoted 2 lines
builtin/am.c +0
-0if (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.
Quoted 18 lines
t/t4150-am.sh +6
-0@@ -196,6 +196,12 @@ test_expect_success setup ' git format-patch -M --stdout lorem^ >rename-add.patch && + git checkout -b empty-commit && + git commit -m "empty commit" --allow-empty && + + git format-patch --stdout empty-commit^ >empty.patch && + git format-patch --always --stdout empty-commit^ >empty-commit.patch && + # reset time sane_unset test_tick && test_tick
t/t4150-am.sh test_expect_success 'apply binary blob in partial clone' ' · line 1162
Quoted 5 lines
t/t4150-am.sh +2
-0@@ -1152,4 +1158,23 @@ test_expect_success 'apply binary blob in partial clone' ' git -C client am ../patch ' +test_expect_success 'am a real empty patch with the --always option' ' + rm -fr .git/rebase-apply &&
What is this one about? If this is trying to clean up the cruft the previous step made, it may be better to do the clean-up in the previous step using test_when_finished.
t/t4150-am.sh test_expect_success 'apply binary blob in partial clone' ' · line 1167
Quoted 5 lines
t/t4150-am.sh +5
-0+ 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?
t/t4150-am.sh test_expect_success 'apply binary blob in partial clone' ' · line 1170
Quoted 2 lines
t/t4150-am.sh +2
-0+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)?
t/t4150-am.sh test_expect_success 'apply binary blob in partial clone' ' · line 1171
Quoted 2 lines
t/t4150-am.sh +2
-0+ rm -fr .git/rebase-apply && + git reset --hard &&
These are trying to clean up the cruft the previous step (added by this patch) may have left. Perhaps these should be done inside test_when_finished of the previous step?
t/t4150-am.sh test_expect_success 'apply binary blob in partial clone' ' · line 1175
Quoted 3 lines
t/t4150-am.sh +3
-0+ git checkout empty-commit^ && + git am --always empty-commit.patch && + test_path_is_missing .git/rebase-apply &&
We should trust "git am"'s exit status here, I would think, rather than be so intimate with the internal implementation detail like the name of the temporary directory the command uses.
t/t4150-am.sh test_expect_success 'apply binary blob in partial clone' ' · line 1177
Quoted 2 lines
t/t4150-am.sh +2
-0+ 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"?
t/t4150-am.sh test_expect_success 'apply binary blob in partial clone' ' · line 1180
Quoted 3 lines
t/t4150-am.sh +2
-0+' + test_done
Thanks.
v3 cover am: support --empty-commit=(die|skip|asis) option to am empty commits
In reply to Aleen via GitGitGadgetSince 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.
----------------------------------------------------------------------------
Aleen (2):
doc: git-format-patch: describe the option --always
am: support --empty-commit option to handle empty patches
Documentation/git-am.txt | 9 +++++ Documentation/git-format-patch.txt | 6 +++- builtin/am.c | 48 ++++++++++++++++++++++--- t/t4150-am.sh | 58 ++++++++++++++++++++++++++++++ 4 files changed, 115 insertions(+), 6 deletions(-)
base-commit: b550198c73edd4cc058832dcf74b41aeec2adba2
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1076%2Faleen42%2Fnext-v3
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1076/aleen42/next-v3
Pull-Request: https://github.com/gitgitgadget/git/pull/1076
Range-diff vs v2:
1: 71e6989375c ! 1: 9f1b3dd6d0b doc: git-format-patch: specify the option --always
@@ Metadata
Author: Aleen <[email protected]>
## Commit message ##
- doc: git-format-patch: specify the option --always
+ doc: git-format-patch: describe the option --always
## Documentation/git-format-patch.txt ##
@@ Documentation/git-format-patch.txt: SYNOPSIS
- [--range-diff=<previous> [--creation-factor=<percent>]]
- [--filename-max-length=<n>]
- [--progress]
-+ [--always]
- [<common diff options>]
- [ <since> | <revision range> ]
-
-@@ Documentation/git-format-patch.txt: you can use --suffix=-patch to get 0001-description-of-my-change-patch.
- --progress::
- Show progress reports on stderr as patches are generated.
+ [-n | --numbered | -N | --no-numbered]
+ [--start-number <n>] [--numbered-files]
+ [--in-reply-to=<message id>] [--suffix=.<sfx>]
+- [--ignore-if-in-upstream]
++ [--ignore-if-in-upstream] [--always]
+ [--cover-from-description=<mode>]
+ [--rfc] [--subject-prefix=<subject prefix>]
+ [(--reroll-count|-v) <n>]
+@@ Documentation/git-format-patch.txt: will want to ensure that threading is disabled for git send-email.
+ patches being generated, and any patch that matches is
+ ignored.
+--always::
-+ Patch commits with detailed commit messages,
-+ even if they emit no changes. (see linkgit:git-diff-tree[1])
++ Include patches for commits that do not introduce any change,
++ which are omitted by default.
+
- CONFIGURATION
- -------------
- You can specify extra mail header lines to be added to each message,
+ --cover-from-description=<mode>::
+ Controls which parts of the cover letter will be automatically
+ populated using the branch's description.
2: 59b1417da37 ! 2: ef33ce8c6f9 am: support --always option to am empty commits
@@ Metadata
Author: Aleen <[email protected]>
## Commit message ##
- am: support --always option to am empty commits
+ am: support --empty-commit option to handle empty patches
Signed-off-by: Aleen <[email protected]>
@@ Documentation/git-am.txt: SYNOPSIS
[--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet]
[--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>]
[--quoted-cr=<action>]
-+ [--always]
++ [--empty-commit=(die|skip|asis)]
[(<mbox> | <Maildir>)...]
'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)])
-@@ Documentation/git-am.txt: default. You can use `--no-utf8` to override this.
- countermand both `commit.gpgSign` configuration variable, and
- earlier `--gpg-sign`.
+@@ Documentation/git-am.txt: OPTIONS
+ --quoted-cr=<action>::
+ This flag will be passed down to 'git mailinfo' (see linkgit:git-mailinfo[1]).
-+--always::
-+ Apply patches of commits with detailed commit messages,
-+ even if they emit no changes. (see linkgit:git-format-patch[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.
+
- --continue::
- -r::
- --resolved::
+ -m::
+ --message-id::
+ Pass the `-m` flag to 'git mailinfo' (see linkgit:git-mailinfo[1]),
## builtin/am.c ##
-@@ builtin/am.c: struct am_state {
- int ignore_date;
- int allow_rerere_autoupdate;
- const char *sign_commit;
-+ int always;
-+ int empty_commit;
- int rebasing;
+@@ builtin/am.c: enum show_patch_type {
+ SHOW_PATCH_DIFF = 1,
};
++enum empty_commit_action {
++ DIE_EMPTY_COMMIT = 0, /* output errors */
++ SKIP_EMPTY_COMMIT, /* skip without outputting errors */
++ ASIS_EMPTY_COMMIT /* keep recording as empty commits */
++};
++
+ struct am_state {
+ /* state directory path */
+ char *dir;
+@@ builtin/am.c: struct am_state {
+ int message_id;
+ int scissors; /* enum scissors_type */
+ int quoted_cr; /* enum quoted_cr_action */
++ int empty_commit; /* enum empty_commit_action */
+ struct strvec git_apply_opts;
+ const char *resolvemsg;
+ int committer_date_is_author_date;
+@@ builtin/am.c: static int am_option_parse_quoted_cr(const struct option *opt,
+ return 0;
+ }
+
++static int am_option_parse_empty_commit(const struct option *opt,
++ const char *arg, int unset)
++{
++ int *opt_value = opt->value;
++
++ if (unset || !strcmp(arg, "die"))
++ *opt_value = DIE_EMPTY_COMMIT;
++ else if (!strcmp(arg, "skip"))
++ *opt_value = SKIP_EMPTY_COMMIT;
++ else if (!strcmp(arg, "asis"))
++ *opt_value = ASIS_EMPTY_COMMIT;
++ else
++ return error(_("Invalid value for --empty-commit: %s"), arg);
++
++ return 0;
++}
++
+ /**
+ * Returns path relative to the am_state directory.
+ */
@@ builtin/am.c: static int parse_mail(struct am_state *state, const char *mail)
+ goto finish;
}
- if (is_empty_or_missing_file(am_path(state, "patch"))) {
+- 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);
-+ }
- }
-
+- }
+-
strbuf_addstr(&msg, "\n\n");
+ strbuf_addbuf(&msg, &mi.log_message);
+ strbuf_stripspace(&msg, 0);
@@ builtin/am.c: static void am_run(struct am_state *state, int resume)
if (state->interactive && do_interactive(state))
goto next;
-+ if (state->empty_commit)
-+ goto commit;
++ if (is_empty_or_missing_file(am_path(state, "patch"))) {
++ if (state->empty_commit == SKIP_EMPTY_COMMIT)
++ goto next;
++ else if (state->empty_commit == ASIS_EMPTY_COMMIT) {
++ if (run_applypatch_msg_hook(state))
++ exit(1);
++ else
++ goto commit;
++ } else if (state->empty_commit == DIE_EMPTY_COMMIT) {
++ printf_ln(_("Patch is empty."));
++ die_user_resolve(state);
++ }
++ }
+
if (run_applypatch_msg_hook(state))
exit(1);
@@ 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_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)")),
++ { 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()
@@ t/t4150-am.sh: test_expect_success 'apply binary blob in partial clone' '
git -C client am ../patch
'
-+test_expect_success 'am a real empty patch with the --always option' '
-+ rm -fr .git/rebase-apply &&
-+ git reset --hard &&
-+ test_must_fail git am --always empty.patch 2>actual &&
++test_expect_success 'still output error with --empty-commit when meeting empty files' '
++ test_must_fail git am --empty-commit=skip empty.patch 2>actual &&
+ echo Patch format detection failed. >expected &&
+ test_cmp expected actual
+'
+
-+test_expect_success 'am a patch with empty commits' '
-+ grep "empty commit" empty-commit.patch &&
-+ rm -fr .git/rebase-apply &&
-+ git reset --hard &&
++test_expect_success 'error when meeting e-mail message that lacks a patch by default' '
+ git checkout empty-commit^ &&
-+ git am --always empty-commit.patch &&
++ test_must_fail git am empty-commit.patch >err &&
++ test_path_is_dir .git/rebase-apply &&
++ test_i18ngrep "Patch is empty." err &&
++ rm -fr .git/rebase-apply &&
++
++ test_must_fail git am --empty-commit=die empty-commit.patch >err &&
++ test_path_is_dir .git/rebase-apply &&
++ test_i18ngrep "Patch is empty." err &&
++ rm -fr .git/rebase-apply &&
++
++ test_must_fail git am --empty-commit=die cover-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' '
++ git am --empty-commit=skip empty-commit.patch >err &&
++ test_path_is_missing .git/rebase-apply &&
++ git rev-parse empty-commit^ >expected &&
++ git rev-parse HEAD >actual &&
++ test_cmp expected actual &&
++
++ git am --empty-commit=skip cover-letter.patch >err &&
++ 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 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 cat-file commit HEAD >actual &&
-+ test_i18ngrep "empty commit" actual
++ git show empty-commit --format="%B" >expected &&
++ git show HEAD --format="%B" >actual &&
++ grep -f actual expected
+'
+
test_done
3: da024ced668 < -: ----------- test: am: add the case when not passing the --always option
4: 45e9720f40b < -: ----------- chore: am: rename the --always option to --allow-emptySignature · 1 line
gitgitgadget
PATCH v3 1/2 doc: git-format-patch: describe the option --always
From: Aleen <[email protected]>
--- Documentation/git-format-patch.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
Documentation/git-format-patch.txt +5 -1
@@ -18,7 +18,7 @@ SYNOPSIS [-n | --numbered | -N | --no-numbered] [--start-number <n>] [--numbered-files] [--in-reply-to=<message id>] [--suffix=.<sfx>] - [--ignore-if-in-upstream] + [--ignore-if-in-upstream] [--always] [--cover-from-description=<mode>] [--rfc] [--subject-prefix=<subject prefix>] [(--reroll-count|-v) <n>]
@@ -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.
Signature · 1 line
gitgitgadget
PATCH v3 2/2 am: support --empty-commit option to handle empty patches
In reply to Aleen via GitGitGadgetFrom: Aleen <[email protected]>
--- Documentation/git-am.txt | 9 +++++++ builtin/am.c | 48 +++++++++++++++++++++++++++++---- t/t4150-am.sh | 58 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 5 deletions(-)
Documentation/git-am.txt +9 -0
@@ -16,6 +16,7 @@ SYNOPSIS [--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet] [--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>] [--quoted-cr=<action>] + [--empty-commit=(die|skip|asis)] [(<mbox> | <Maildir>)...] 'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)])
@@ -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]),
builtin/am.c +43 -5
90 lines not on this page · raw message
t/t4150-am.sh +58 -0
68 lines not on this page · raw message
Signature · 1 line
gitgitgadget
Re: [PATCH v3 2/2] am: support --empty-commit option to handle empty patches
Dears Hamano,
Sorry about the late submission, and I have modified it to support the --empty-commit=(die|skip|asis) pattern.
t/t4150-am.sh test_expect_success 'apply binary blob in partial clone' ' · line 1211
Quoted 13 lines
t/t4150-am.sh +13
-0+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:
Quoted 2 lines
Signature · 1 line
2.34.0.rc2.390.gef33ce8c6f
2. information of cover letter:
Quoted 4 lines
*** 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
v4 cover am: support --empty-commit=(die|skip|asis) option to am empty commits
In reply to Aleen via GitGitGadgetSince 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
----------------------------------------------------------------------------
Aleen (2):
doc: git-format-patch: describe the option --always
am: support --empty-commit option to handle empty patches
Documentation/git-am.txt | 9 ++++ Documentation/git-format-patch.txt | 6 ++- builtin/am.c | 48 ++++++++++++++++++-- t/t4150-am.sh | 73 ++++++++++++++++++++++++++++++ 4 files changed, 130 insertions(+), 6 deletions(-)
base-commit: b550198c73edd4cc058832dcf74b41aeec2adba2
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1076%2Faleen42%2Fnext-v4
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1076/aleen42/next-v4
Pull-Request: https://github.com/gitgitgadget/git/pull/1076
Range-diff vs v3:
1: 9f1b3dd6d0b = 1: 9f1b3dd6d0b doc: git-format-patch: describe the option --always
2: ef33ce8c6f9 ! 2: b7e30c9b7ab am: support --empty-commit option to handle empty patches
@@ t/t4150-am.sh: test_expect_success setup '
+ git commit -m "empty commit" --allow-empty &&
+
+ git format-patch --stdout empty-commit^ >empty.patch &&
++ git format-patch --stdout --cover-letter empty-commit^ >cover-letter.patch &&
+ git format-patch --always --stdout empty-commit^ >empty-commit.patch &&
+
# reset time
@@ t/t4150-am.sh: test_expect_success 'apply binary blob in partial clone' '
+
+ git am --empty-commit=skip cover-letter.patch >err &&
+ test_path_is_missing .git/rebase-apply &&
-+ git rev-parse empty-commit^ >expected &&
-+ git rev-parse HEAD >actual &&
-+ test_cmp expected actual
++ test_cmp_rev empty-commit^ HEAD
+'
+
+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 empty-commit --format="%B" &&
++ echo "--" &&
++ git version | sed -e "s/^git version //" &&
++ echo
++ } >expected &&
+ git show HEAD --format="%B" >actual &&
-+ grep -f actual expected &&
++ test_cmp actual expected &&
+
+ git am --empty-commit=asis cover-letter.patch &&
+ test_path_is_missing .git/rebase-apply &&
-+ git show empty-commit --format="%B" >expected &&
++ {
++ echo "*** SUBJECT HERE ***" &&
++ echo &&
++ echo "*** BLURB HERE ***" &&
++ echo &&
++ echo "A U Thor (1):" &&
++ printf " " &&
++ git show empty-commit --format="%B" &&
++ echo "--" &&
++ git version | sed -e "s/^git version //" &&
++ echo
++ } >expected &&
+ git show HEAD --format="%B" >actual &&
-+ grep -f actual expected
++ test_cmp actual expected
+'
+
test_doneSignature · 1 line
gitgitgadget
PATCH v4 1/2 doc: git-format-patch: describe the option --always
From: Aleen <[email protected]>
--- Documentation/git-format-patch.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
Documentation/git-format-patch.txt +5 -1
@@ -18,7 +18,7 @@ SYNOPSIS [-n | --numbered | -N | --no-numbered] [--start-number <n>] [--numbered-files] [--in-reply-to=<message id>] [--suffix=.<sfx>] - [--ignore-if-in-upstream] + [--ignore-if-in-upstream] [--always] [--cover-from-description=<mode>] [--rfc] [--subject-prefix=<subject prefix>] [(--reroll-count|-v) <n>]
@@ -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.
Signature · 1 line
gitgitgadget
PATCH v4 2/2 am: support --empty-commit option to handle empty patches
In reply to Aleen via GitGitGadgetFrom: Aleen <[email protected]>
--- Documentation/git-am.txt | 9 +++++ builtin/am.c | 48 +++++++++++++++++++++++--- t/t4150-am.sh | 73 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+), 5 deletions(-)
Documentation/git-am.txt +9 -0
@@ -16,6 +16,7 @@ SYNOPSIS [--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet] [--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>] [--quoted-cr=<action>] + [--empty-commit=(die|skip|asis)] [(<mbox> | <Maildir>)...] 'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)])
@@ -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]),
builtin/am.c +43 -5
90 lines not on this page · raw message
t/t4150-am.sh +73 -0
83 lines not on this page · raw message
Signature · 1 line
gitgitgadget
Re: [PATCH v4 2/2] am: support --empty-commit option to handle empty patches
Hi Aleen
Thanks for working on this
Quoted 22 lines · Aleen via GitGitGadget
From: Aleen <[email protected]>
Signed-off-by Aleen <[email protected]>--- Documentation/git-am.txt | 9 +++++ builtin/am.c | 48 +++++++++++++++++++++++--- t/t4150-am.sh | 73 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+), 5 deletions(-)Documentation/git-am.txt +1
-0@@ -16,6 +16,7 @@ SYNOPSIS [--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet] [--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>] [--quoted-cr=<action>] + [--empty-commit=(die|skip|asis)] [(<mbox> | <Maildir>)...] 'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)])
Documentation/git-am.txt OPTIONS · line 73
Quoted 10 lines
Documentation/git-am.txt +7
-0@@ -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 194 lines
Documentation/git-am.txt +0
-0-m:: --message-id:: Pass the `-m` flag to 'git mailinfo' (see linkgit:git-mailinfo[1]),builtin/am.c +43
-5@@ -87,6 +87,12 @@ enum show_patch_type { SHOW_PATCH_DIFF = 1, }; +enum empty_commit_action { +DIE_EMPTY_COMMIT =0 ,/* output errors */ +SKIP_EMPTY_COMMIT ,/* skip without outputting errors */ +ASIS_EMPTY_COMMIT /* keep recording as empty commits */ +}; +struct am_state {/* state directory path */ char *dir;@@ -118,6 +124,7 @@ struct am_state {int message_id;int scissors;/* enum scissors_type */ int quoted_cr;/* enum quoted_cr_action */ +int empty_commit;/* enum empty_commit_action */ struct strvec git_apply_opts;const char *resolvemsg;int committer_date_is_author_date;@@ -178,6 +185,23 @@ static int am_option_parse_quoted_cr(const struct option *opt,return 0 ; } +static int am_option_parse_empty_commit (const struct option *opt, +const char *arg,int unset) +{ +int *opt_value = opt->value; + +if (unset || !strcmp (arg,"die" )) + *opt_value =DIE_EMPTY_COMMIT ; +else if (!strcmp (arg,"skip" )) + *opt_value =SKIP_EMPTY_COMMIT ; +else if (!strcmp (arg,"asis" )) + *opt_value =ASIS_EMPTY_COMMIT ; +else +return error (_ ("Invalid value for --empty-commit: %s" ), arg); + +return 0 ; +} +/** * Returns path relative to the am_state directory. */ @@ -1248,11 +1272,6 @@ static int parse_mail(struct am_state *state, const char *mail) goto finish; } -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)) goto next; +if (is_empty_or_missing_file (am_path (state,"patch" ))) { +if (state->empty_commit ==SKIP_EMPTY_COMMIT ) + goto next; +else if (state->empty_commit ==ASIS_EMPTY_COMMIT ) { +if (run_applypatch_msg_hook (state)) +exit (1 ); +else + goto commit; + }else if (state->empty_commit ==DIE_EMPTY_COMMIT ) { +printf_ln (_ ("Patch is empty." )); +die_user_resolve (state); + } + } +if (run_applypatch_msg_hook (state))exit (1 );@@ -1827,6 +1860,7 @@ static void am_run(struct am_state *state, int resume)die_user_resolve (state); } +commit:do_commit (state); next:@@ -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 ()t/t4150-am.sh +73
-0@@ -196,6 +196,13 @@ test_expect_success setup ' git format-patch -M --stdout lorem^ >rename-add.patch && + git checkout -b empty-commit && + git commit -m "empty commit" --allow-empty && + + git format-patch --stdout empty-commit^ >empty.patch && + git format-patch --stdout --cover-letter empty-commit^ >cover-letter.patch && + git format-patch --always --stdout empty-commit^ >empty-commit.patch && + # reset time sane_unset test_tick && test_tick@@ -1152,4 +1159,70 @@ test_expect_success 'apply binary blob in partial clone' ' git -C client am ../patch ' +test_expect_success 'still output error with --empty-commit when meeting empty files' ' + test_must_fail git am --empty-commit=skip empty.patch 2>actual && + echo Patch format detection failed. >expected && + test_cmp expected actual +' + +test_expect_success 'error when meeting e-mail message that lacks a patch by default' ' + git checkout empty-commit^ && + test_must_fail git am empty-commit.patch >err && + test_path_is_dir .git/rebase-apply && + test_i18ngrep "Patch is empty." err && + rm -fr .git/rebase-apply && + + test_must_fail git am --empty-commit=die empty-commit.patch >err && + test_path_is_dir .git/rebase-apply && + test_i18ngrep "Patch is empty." err && + rm -fr .git/rebase-apply && + + test_must_fail git am --empty-commit=die cover-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' ' + git am --empty-commit=skip empty-commit.patch >err && + test_path_is_missing .git/rebase-apply && + git rev-parse empty-commit^ >expected && + git rev-parse HEAD >actual && + test_cmp expected actual && + + git am --empty-commit=skip cover-letter.patch >err && + test_path_is_missing .git/rebase-apply && + test_cmp_rev empty-commit^ HEAD +' + +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" && + echo "--" && + git version | sed -e "s/^git version //" && + echo + } >expected && + git show HEAD --format="%B" >actual && + test_cmp actual expected && + + git am --empty-commit=asis cover-letter.patch && + test_path_is_missing .git/rebase-apply && + { + echo "*** SUBJECT HERE ***" && + echo && + echo "*** BLURB HERE ***" && + echo && + echo "A U Thor (1):" && + printf " " && + git show empty-commit --format="%B" && + echo "--" && + git version | sed -e "s/^git version //" && + echo + } >expected && + git show HEAD --format="%B" >actual && + test_cmp actual expected +' + test_done
Re: [PATCH v4 2/2] am: support --empty-commit option to handle empty patches
Quoted 15 lines
Documentation/git-am.txt OPTIONS · line 73
Quoted 7 lines
+--empty-commit=(die|skip|asis)::
Documentation/git-am.txt +6
-0+ 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.
Quoted 3 lines
Best Wishes
Phillip
Dears Phillip,
It seems a good idea. Can Hamano make a decision?
Aleen
Re: [PATCH v4 2/2] am: support --empty-commit option to handle empty patches
In reply to Phillip WoodQuoted 8 lines · Phillip Wood
Documentation/git-am.txt OPTIONS · line 73
Quoted 7 lines
+--empty-commit=(die|skip|asis)::
Documentation/git-am.txt +6
-0+ 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.
Quoted 7 lines
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".
v5 cover am: support --empty-commit=(die|skip|asis) option to am empty commits
In reply to Aleen via GitGitGadgetSince 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.
----------------------------------------------------------------------------
Aleen (2):
doc: git-format-patch: describe the option --always
am: support --empty option to handle empty patches
Documentation/git-am.txt | 9 ++++ Documentation/git-format-patch.txt | 6 ++- builtin/am.c | 48 ++++++++++++++++++-- t/t4150-am.sh | 73 ++++++++++++++++++++++++++++++ 4 files changed, 130 insertions(+), 6 deletions(-)
base-commit: b550198c73edd4cc058832dcf74b41aeec2adba2
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1076%2Faleen42%2Fnext-v5
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1076/aleen42/next-v5
Pull-Request: https://github.com/gitgitgadget/git/pull/1076
Range-diff vs v4:
1: 9f1b3dd6d0b = 1: 9f1b3dd6d0b doc: git-format-patch: describe the option --always
2: b7e30c9b7ab ! 2: 96d8573dc80 am: support --empty-commit option to handle empty patches
@@ Metadata
Author: Aleen <[email protected]>
## Commit message ##
- am: support --empty-commit option to handle empty patches
+ am: support --empty option to handle empty patches
Signed-off-by: Aleen <[email protected]>
@@ Documentation/git-am.txt: SYNOPSIS
[--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet]
[--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>]
[--quoted-cr=<action>]
-+ [--empty-commit=(die|skip|asis)]
++ [--empty=(die|drop|keep)]
[(<mbox> | <Maildir>)...]
'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)])
@@ Documentation/git-am.txt: OPTIONS
--quoted-cr=<action>::
This flag will be passed down to 'git mailinfo' (see linkgit:git-mailinfo[1]).
-+--empty-commit=(die|skip|asis)::
++--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
-+ 'skip', skip such an e-mail message without outputting error.
-+ When this option is set to 'asis', create an empty commit,
++ '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.
+
@@ builtin/am.c: enum show_patch_type {
SHOW_PATCH_DIFF = 1,
};
-+enum empty_commit_action {
++enum empty_action {
+ DIE_EMPTY_COMMIT = 0, /* output errors */
-+ SKIP_EMPTY_COMMIT, /* skip without outputting errors */
-+ ASIS_EMPTY_COMMIT /* keep recording as empty commits */
++ DROP_EMPTY_COMMIT, /* skip without outputting errors */
++ KEEP_EMPTY_COMMIT /* keep recording as empty commits */
+};
+
struct am_state {
@@ builtin/am.c: struct am_state {
int message_id;
int scissors; /* enum scissors_type */
int quoted_cr; /* enum quoted_cr_action */
-+ int empty_commit; /* enum empty_commit_action */
++ int empty_type; /* enum empty_action */
struct strvec git_apply_opts;
const char *resolvemsg;
int committer_date_is_author_date;
@@ builtin/am.c: static int am_option_parse_quoted_cr(const struct option *opt,
+
+ if (unset || !strcmp(arg, "die"))
+ *opt_value = DIE_EMPTY_COMMIT;
-+ else if (!strcmp(arg, "skip"))
-+ *opt_value = SKIP_EMPTY_COMMIT;
-+ else if (!strcmp(arg, "asis"))
-+ *opt_value = ASIS_EMPTY_COMMIT;
++ else if (!strcmp(arg, "drop"))
++ *opt_value = DROP_EMPTY_COMMIT;
++ else if (!strcmp(arg, "keep"))
++ *opt_value = KEEP_EMPTY_COMMIT;
+ else
-+ return error(_("Invalid value for --empty-commit: %s"), arg);
++ return error(_("Invalid value for --empty: %s"), arg);
+
+ return 0;
+}
@@ builtin/am.c: static void am_run(struct am_state *state, int resume)
goto next;
+ if (is_empty_or_missing_file(am_path(state, "patch"))) {
-+ if (state->empty_commit == SKIP_EMPTY_COMMIT)
++ if (state->empty_type == DROP_EMPTY_COMMIT)
+ goto next;
-+ else if (state->empty_commit == ASIS_EMPTY_COMMIT) {
++ else if (state->empty_type == KEEP_EMPTY_COMMIT) {
+ if (run_applypatch_msg_hook(state))
+ exit(1);
+ else
+ goto commit;
-+ } else if (state->empty_commit == DIE_EMPTY_COMMIT) {
++ } else if (state->empty_type == DIE_EMPTY_COMMIT) {
+ printf_ln(_("Patch is empty."));
+ die_user_resolve(state);
+ }
@@ 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) "" },
-+ { OPTION_CALLBACK, 0, "empty-commit", &state.empty_commit,
-+ "(die|skip|asis)",
++ { 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,
@@ t/t4150-am.sh: test_expect_success 'apply binary blob in partial clone' '
git -C client am ../patch
'
-+test_expect_success 'still output error with --empty-commit when meeting empty files' '
-+ test_must_fail git am --empty-commit=skip empty.patch 2>actual &&
++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
+'
@@ t/t4150-am.sh: test_expect_success 'apply binary blob in partial clone' '
+ test_i18ngrep "Patch is empty." err &&
+ rm -fr .git/rebase-apply &&
+
-+ test_must_fail git am --empty-commit=die empty-commit.patch >err &&
++ test_must_fail git am --empty=die empty-commit.patch >err &&
+ test_path_is_dir .git/rebase-apply &&
+ test_i18ngrep "Patch is empty." err &&
+ rm -fr .git/rebase-apply &&
+
-+ test_must_fail git am --empty-commit=die cover-letter.patch >err &&
++ test_must_fail git am --empty=die cover-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' '
-+ git am --empty-commit=skip empty-commit.patch >err &&
++ git am --empty=drop empty-commit.patch >err &&
+ test_path_is_missing .git/rebase-apply &&
+ git rev-parse empty-commit^ >expected &&
+ git rev-parse HEAD >actual &&
+ test_cmp expected actual &&
+
-+ git am --empty-commit=skip cover-letter.patch >err &&
++ git am --empty=drop cover-letter.patch >err &&
+ test_path_is_missing .git/rebase-apply &&
+ test_cmp_rev empty-commit^ HEAD
+'
+
+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 &&
++ git am --empty=keep empty-commit.patch &&
+ test_path_is_missing .git/rebase-apply &&
+ {
+ git show empty-commit --format="%B" &&
@@ t/t4150-am.sh: test_expect_success 'apply binary blob in partial clone' '
+ git show HEAD --format="%B" >actual &&
+ test_cmp actual expected &&
+
-+ git am --empty-commit=asis cover-letter.patch &&
++ git am --empty=keep cover-letter.patch &&
+ test_path_is_missing .git/rebase-apply &&
+ {
+ echo "*** SUBJECT HERE ***" &&Signature · 1 line
gitgitgadget
PATCH v5 1/2 doc: git-format-patch: describe the option --always
From: Aleen <[email protected]>
--- Documentation/git-format-patch.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
Documentation/git-format-patch.txt +5 -1
@@ -18,7 +18,7 @@ SYNOPSIS [-n | --numbered | -N | --no-numbered] [--start-number <n>] [--numbered-files] [--in-reply-to=<message id>] [--suffix=.<sfx>] - [--ignore-if-in-upstream] + [--ignore-if-in-upstream] [--always] [--cover-from-description=<mode>] [--rfc] [--subject-prefix=<subject prefix>] [(--reroll-count|-v) <n>]
@@ -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.
Signature · 1 line
gitgitgadget
PATCH v5 2/2 am: support --empty option to handle empty patches
In reply to Aleen via GitGitGadgetFrom: Aleen <[email protected]>
--- Documentation/git-am.txt | 9 +++++ builtin/am.c | 48 +++++++++++++++++++++++--- t/t4150-am.sh | 73 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+), 5 deletions(-)
Documentation/git-am.txt +9 -0
@@ -16,6 +16,7 @@ SYNOPSIS [--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet] [--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>] [--quoted-cr=<action>] + [--empty=(die|drop|keep)] [(<mbox> | <Maildir>)...] 'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)])
@@ -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]),
builtin/am.c +43 -5
90 lines not on this page · raw message
t/t4150-am.sh +73 -0
83 lines not on this page · raw message
Signature · 1 line
gitgitgadget
PATCH v6 1/3 doc: git-format-patch: describe the option --always
In reply to Aleen via GitGitGadgetFrom: Aleen <[email protected]>
--- Documentation/git-format-patch.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
Documentation/git-format-patch.txt +5 -1
@@ -18,7 +18,7 @@ SYNOPSIS [-n | --numbered | -N | --no-numbered] [--start-number <n>] [--numbered-files] [--in-reply-to=<message id>] [--suffix=.<sfx>] - [--ignore-if-in-upstream] + [--ignore-if-in-upstream] [--always] [--cover-from-description=<mode>] [--rfc] [--subject-prefix=<subject prefix>] [(--reroll-count|-v) <n>]
@@ -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.
Signature · 1 line
gitgitgadget
v6 cover am: support --empty=(die|drop|keep) option to handle empty patches
In reply to Aleen via GitGitGadgetSince 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
Signature · 1 line
gitgitgadget
PATCH v6 2/3 am: support --empty option to handle empty patches
From: Aleen <[email protected]>
--- Documentation/git-am.txt | 9 +++++ builtin/am.c | 48 +++++++++++++++++++++++--- t/t4150-am.sh | 73 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+), 5 deletions(-)
Documentation/git-am.txt +9 -0
@@ -16,6 +16,7 @@ SYNOPSIS [--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet] [--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>] [--quoted-cr=<action>] + [--empty=(die|drop|keep)] [(<mbox> | <Maildir>)...] 'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)])
@@ -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]),
builtin/am.c +43 -5
90 lines not on this page · raw message
t/t4150-am.sh +73 -0
83 lines not on this page · raw message
Signature · 1 line
gitgitgadget
PATCH v6 3/3 am: throw an error when passing --empty option without value
In reply to Aleen via GitGitGadgetFrom: Aleen <[email protected]>
--- builtin/am.c | 13 +++++++------ t/t4150-am.sh | 8 +++++++- 2 files changed, 14 insertions(+), 7 deletions(-)
builtin/am.c +7 -6
@@ -185,12 +185,14 @@ static int am_option_parse_quoted_cr(const struct option *opt,return 0 ; } -static int am_option_parse_empty_commit (const struct option *opt, +static int am_option_parse_empty (const struct option *opt,const char *arg,int unset) {int *opt_value = opt->value; -if (unset || !strcmp (arg,"die" )) +BUG_ON_OPT_NEG (unset); + +if (!strcmp (arg,"die" )) *opt_value =DIE_EMPTY_COMMIT ;else if (!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 ()
t/t4150-am.sh +7 -1
@@ -1165,8 +1165,14 @@ test_expect_success 'still output error with --empty when meeting empty files' ' test_cmp expected actual ' -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' ' git checkout empty-commit^ && + test_must_fail git am --empty empty-commit.patch 2>err && + echo "error: Invalid value for --empty: empty-commit.patch" >expected && + test_cmp expected err +' + +test_expect_success 'error when meeting e-mail message that lacks a patch by default' ' test_must_fail git am empty-commit.patch >err && test_path_is_dir .git/rebase-apply && test_i18ngrep "Patch is empty." err &&
Signature · 1 line
gitgitgadget
Re: [PATCH v6 0/3] am: support --empty=(die|drop|keep) option to handle empty patches
In reply to Aleen via GitGitGadgetAs per https://git-scm.com/docs/SubmittingPatches#sign-off:
Please don’t hide your real name.
I suspect your real name is not Aleen, but something with x and w in it.
Re: [PATCH v6 2/3] am: support --empty option to handle empty patches
In reply to Aleen via GitGitGadgetQuoted 1 line · Aleen via GitGitGadget
From: Aleen <[email protected]>
Here is a place to explain to readers what it exactly means to "support --empty option to handle empty patches". You know what you meant, I happen to know what you meant because I haven't forgotten yet, but we are writing for developers in the future who need to fix bugs in 6 months down the road to decide if this commit is involved in the bug in "git am" they are hunting.
Quoted 20 lines
Signed-off-by Aleen <[email protected]>--- Documentation/git-am.txt | 9 +++++ builtin/am.c | 48 +++++++++++++++++++++++--- t/t4150-am.sh | 73 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+), 5 deletions(-)Documentation/git-am.txt +1
-0@@ -16,6 +16,7 @@ SYNOPSIS [--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet] [--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>] [--quoted-cr=<action>] + [--empty=(die|drop|keep)] [(<mbox> | <Maildir>)...] 'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)])
Documentation/git-am.txt OPTIONS · line 70
Quoted 7 lines
Documentation/git-am.txt +4
-0@@ -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.
"without outputting error" -> "instead".
The first sentence used "to error" as a verb to mean "stop the operation in the middle with a message that diagnoses what is wrong". Saying "outputting error" to use the same word as a noun is not a good idea, especially the use of verb "to output", as it makes the word "error" look as if it is only the "message" part, and it becomes unclear if the "stopping due to an error" is also skipped.
I actually think it makes sense to give a notice/info message when "drop" skips an empty patch, unless "--quiet" is given.
Documentation/git-am.txt OPTIONS · line 73
Quoted 3 lines
Documentation/git-am.txt +3
-0+ 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.
"is specified by default" sounds a bit strange. Perhaps lose the last sentence, and update the first line like so:
By default, or when the option is set to 'die', the command errors out on an input e-mail message that lacks a patch.
builtin/am.c enum show_patch_type { · line 92
Quoted 11 lines
builtin/am.c +3
-0@@ -87,6 +87,12 @@ enum show_patch_type { SHOW_PATCH_DIFF = 1, }; +enum empty_action { +DIE_EMPTY_COMMIT =0 ,/* output errors */ +DROP_EMPTY_COMMIT ,/* skip without outputting errors */
I think the user deserves "info:" (unless "--quiet").
Quoted 24 lines
builtin/am.c +10
-0+KEEP_EMPTY_COMMIT /* keep recording as empty commits */ +}; +struct am_state {/* state directory path */ char *dir;@@ -118,6 +124,7 @@ struct am_state {int message_id;int scissors;/* enum scissors_type */ int quoted_cr;/* enum quoted_cr_action */ +int empty_type;/* enum empty_action */ struct strvec git_apply_opts;const char *resolvemsg;int committer_date_is_author_date;@@ -178,6 +185,23 @@ static int am_option_parse_quoted_cr(const struct option *opt,return 0 ; } +static int am_option_parse_empty_commit (const struct option *opt, +const char *arg,int unset) +{ +int *opt_value = opt->value; + +if (unset || !strcmp (arg,"die" ))
builtin/am.c static int am_option_parse_quoted_cr(const struct option *opt, · line 203
Quoted 10 lines
builtin/am.c +10
-0+ *opt_value =DIE_EMPTY_COMMIT ; + else if (!strcmp(arg, "drop")) + *opt_value =DROP_EMPTY_COMMIT ; + else if (!strcmp(arg, "keep")) + *opt_value =KEEP_EMPTY_COMMIT ; + else + return error(_("Invalid value for --empty: %s"), arg); + +return 0 ; +}
OK.
builtin/am.c static void am_run(struct am_state *state, int resume) · line 1821
Quoted 12 lines
builtin/am.c +8
-0@@ -1792,6 +1811,20 @@ static void am_run(struct am_state *state, int resume)if (state->interactive &&do_interactive (state)) goto next; +if (is_empty_or_missing_file (am_path (state,"patch" ))) { +if (state->empty_type ==DROP_EMPTY_COMMIT ) + goto next; +else if (state->empty_type ==KEEP_EMPTY_COMMIT ) { +if (run_applypatch_msg_hook (state)) +exit (1 ); +else + goto commit;
It probably is easier to read without "else", i.e.
else if (state->empty_type == KEEP_EMPTY_COMMIT) {
if (run_applypatch_msg_hook(state))
exit(1);
goto commit;Running hook here and outside this if() block a bit ugly. Can't we instead set a flag variable or something and let the existing call to run_applypatch_msg_hook() used?
builtin/am.c static void am_run(struct am_state *state, int resume) · line 1825
Quoted 4 lines
builtin/am.c +4
-0+ }else if (state->empty_type ==DIE_EMPTY_COMMIT ) { +printf_ln (_ ("Patch is empty." )); +die_user_resolve (state); + }
Also, if developers ever add another possible value for the state->empty_type member (by the way, "empty" in its name is good, but "type" is iffy), it would be a bug if they do not consider what should happen inside this "if (is_empty_or_missing_file())" block, no? In such a case, instead of if/else if/... cascade, consider using switch(). Taking them together.
while (state->cur <= state->last) {
const char *mail = am_path(state, msgnum(state));
int apply_status;
int to_keep;
...
to_keep = 0;
if (is_empty_or_missing_file(am_path(state, "patch"))) {
switch (state->empty_type) {
case DROP_EMPTY_COMMIT:
say(state, stdout, _("Skipping empty patch '%.*s",
linelen(state->msg0, state->msg);
goto next;
break;
case KEEP_EMPTY_COMMIT:
to_keep = 1;
break;
case DIE_EMPTY_COMMIT:
pritnf_ln(_("Patch is empty."));
die_user_resolve(state);
break;
}
}
if (run_applypatch_msg_hook(state))
exit(1);
if (to_keep)
goto commit; /* empty: just record a message */or something like that.
t/t4150-am.sh test_expect_success setup ' · line 202
Quoted 12 lines
t/t4150-am.sh +4
-0@@ -196,6 +196,13 @@ test_expect_success setup ' git format-patch -M --stdout lorem^ >rename-add.patch && + git checkout -b empty-commit && + git commit -m "empty commit" --allow-empty && + + git format-patch --stdout empty-commit^ >empty.patch &&
Unless this is a test for "format-patch" command to make sure that the above command will not output a single byte, I would rather see the above line written like this:
: >empty.patch &&
t/t4150-am.sh test_expect_success setup ' · line 203
Quoted 1 line
t/t4150-am.sh +1
-0+ git format-patch --stdout --cover-letter empty-commit^ >cover-letter.patch &&
This only creates a cover letter without anything, which sort of looks like an empty commit.
t/t4150-am.sh test_expect_success setup ' · line 204
Quoted 1 line
t/t4150-am.sh +1
-0+ git format-patch --always --stdout empty-commit^ >empty-commit.patch &&
And this gives another empty patch with only a message.
I would sort-of understand if there is
git format-patch --stdout --always --cover-letter HEAD^ >both.patch
that has two e-mail messages in it, but what's the significance of testing both cover-letter.patch and empty-commit.patch?
The receiving end would not care what's in the actual e-mail message, as long as it lacks the patch part, no? Or am I missing some subtle reason why we want to test both?
t/t4150-am.sh test_expect_success 'apply binary blob in partial clone' ' · line 1163
Quoted 6 lines
t/t4150-am.sh +2
-0@@ -1152,4 +1159,70 @@ test_expect_success 'apply binary blob in partial clone' ' git -C client am ../patch ' +test_expect_success 'still output error with --empty when meeting empty files' ' + test_must_fail git am --empty=drop empty.patch 2>actual &&
Nobody will understand "still", unless they know it used to be unconditionally a failure to feed an e-mail message that lacks a patch.
test_expect_success 'An empty input file is error regardless of --empty option' '
or something like that?
t/t4150-am.sh test_expect_success 'apply binary blob in partial clone' ' · line 1173
Quoted 10 lines
t/t4150-am.sh +10
-0+ echo Patch format detection failed. >expected && + test_cmp expected actual +' + +test_expect_success 'error when meeting e-mail message that lacks a patch by default' ' + git checkout empty-commit^ && + test_must_fail git am empty-commit.patch >err && + test_path_is_dir .git/rebase-apply && + test_i18ngrep "Patch is empty." err && + rm -fr .git/rebase-apply &&
If any command before "rm" fails, it won't be cleaned up.
test_expect_success 'a message without a patch is an error (default)' '
test_when_finished "git am --abort || :" &&
git checkout --detach empty-commit^ &&
test_must_fail git am empty-commit.patch >err &&
grep "Patch is empty" err
'or something like that. The title says it tests the default case, so do not test --empty=die case in the same test. Use a separate test to do the same for the case where an explicit "--empty=die" is given.
As I said, I do not quite see the point of testing with both empty-commit.patch and cover-letter.patch (unless the latter has an empty commit and a cover letter, totally in two messages).
t/t4150-am.sh test_expect_success 'apply binary blob in partial clone' ' · line 1187
Quoted 13 lines
t/t4150-am.sh +13
-0+ test_must_fail git am --empty=die empty-commit.patch >err && + test_path_is_dir .git/rebase-apply && + test_i18ngrep "Patch is empty." err && + rm -fr .git/rebase-apply && + + test_must_fail git am --empty=die cover-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' ' + git am --empty=drop empty-commit.patch >err &&
The output 'err' is used by nobody; do not redirect it and just leave the standard output alone.
t/t4150-am.sh test_expect_success 'apply binary blob in partial clone' ' · line 1187
Quoted 1 line
t/t4150-am.sh +1
-0+ test_path_is_missing .git/rebase-apply &&
Don't test this condition when testing success or failure from "am". That is too much implementation detail.
t/t4150-am.sh test_expect_success 'apply binary blob in partial clone' ' · line 1191
Quoted 3 lines
t/t4150-am.sh +3
-0+ git rev-parse empty-commit^ >expected && + git rev-parse HEAD >actual && + test_cmp expected actual &&
OK, we make sure that HEAD does not move.
t/t4150-am.sh test_expect_success 'apply binary blob in partial clone' ' · line 1195
Quoted 3 lines
t/t4150-am.sh +3
-0+ git am --empty=drop cover-letter.patch >err && + test_path_is_missing .git/rebase-apply && + test_cmp_rev empty-commit^ HEAD
Lose this one? As I said, I may be missing some subtle reason why both need to be tested---and if it is the case, test it in a separate test, not 2 of them in a single test like this.
t/t4150-am.sh test_expect_success 'apply binary blob in partial clone' ' · line 1203
Quoted 8 lines
t/t4150-am.sh +8
-0+' + +test_expect_success 'record as an empty commit when meeting e-mail message that lacks a patch' ' + git am --empty=keep empty-commit.patch && + test_path_is_missing .git/rebase-apply && + { + git show empty-commit --format="%B" && + echo "--" &&
Did this test pass? Without a trailing whitespace after double-dash, I do not think this shell snippet reproduces a patch e-mail correctly
In any case, don't do this. Imagine a future developer may want to improve the patch output by adding other things after the "-- " signature line, in addition to the "git version". Or perhaps the "git version" trailer gets removed by default for privacy concerns.
Should such changes be prevented from being made, only because this test expects exact output we have today? No.
Verify what we _care_, e.g. "does the title of the resulting commit reproduce the one-liner message given to '-m' when the empty commit was made?" is a sensible question to ask.
Quoted 10 lines
t/t4150-am.sh +9
-0+ git version | sed -e "s/^git version //" && + echo + } >expected && + git show HEAD --format="%B" >actual && + test_cmp actual expected && + + git am --empty=keep cover-letter.patch && + test_path_is_missing .git/rebase-apply && + {
t/t4150-am.sh test_expect_success 'apply binary blob in partial clone' ' · line 1222
Quoted 10 lines
t/t4150-am.sh +10
-0+ echo "*** SUBJECT HERE ***" && + echo && + echo "*** BLURB HERE ***" && + echo && + echo "A U Thor (1):" && + printf " " && + git show empty-commit --format="%B" && + echo "--" && + git version | sed -e "s/^git version //" && + echo
Don't do this. Imagine a future developer may want to improve the cover letter template. Should that change be prevented from being made, because this test expects exact output we have today? No.
t/t4150-am.sh test_expect_success 'apply binary blob in partial clone' ' · line 1228
Quoted 6 lines
t/t4150-am.sh +5
-0+ } >expected && + git show HEAD --format="%B" >actual && + test_cmp actual expected +' + test_done
Thanks.
Re: [PATCH v6 3/3] am: throw an error when passing --empty option without value
In reply to Aleen via GitGitGadgetQuoted 1 line · Aleen via GitGitGadget
From: Aleen <[email protected]>
Here is a place for you to explain why this change might be a good idea to defend it. If we applied 1/3 and 2/3 but not this one, what happens? "am --empty" (not "am --empty=<choice>") is accepted and behaves just like "am --empty=die"? Is that a bad thing?
If it is unconditonally a bad thing, then this patch does not stand on its own. It should be squashed into the previous step; otherwise it would be "oops, we didn't think it through and failed to detect an argument-less --error as an error in the previous step, and here is a fix for that mistake". We try not to deliberately commit a mistake and then fix it to gain commit counts in this project (or putting it differently, we try to pretend we are better than we really are and did not make a mistake in the first place).
Or are you giving list participants and reviewers a choice between "'--empty' is a synonym to '--empty=die'" and "'--empty' alone is an error" because you cannot decide yourself? If that is the case, you really really need to make it clear in this place between "From:" and "Signed-off-by:". Why would we want to use this patch? Why would we be better without this patch?
I haven't thought things through, but my gut feeling is that the semantics of the --empty=<choice> option is better _with_ this, in other words, it makes more sense to forbid "--empty" alone. So if I were doing this series, I would probably have squashed this into the previous one, making it a two-patch series.
Thanks.
Quoted 64 lines
Signed-off-by Aleen <[email protected]>--- builtin/am.c | 13 +++++++------ t/t4150-am.sh | 8 +++++++- 2 files changed, 14 insertions(+), 7 deletions(-)builtin/am.c +6
-6@@ -185,12 +185,14 @@ static int am_option_parse_quoted_cr(const struct option *opt,return 0 ; } -static int am_option_parse_empty_commit (const struct option *opt, +static int am_option_parse_empty (const struct option *opt,const char *arg,int unset) {int *opt_value = opt->value; -if (unset || !strcmp (arg,"die" )) +BUG_ON_OPT_NEG (unset); +if (!strcmp (arg,"die" )) *opt_value =DIE_EMPTY_COMMIT ;else if (!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 ()t/t4150-am.sh +7
-1@@ -1165,8 +1165,14 @@ test_expect_success 'still output error with --empty when meeting empty files' ' test_cmp expected actual ' -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' ' git checkout empty-commit^ && + test_must_fail git am --empty empty-commit.patch 2>err && + echo "error: Invalid value for --empty: empty-commit.patch" >expected && + test_cmp expected err +' + +test_expect_success 'error when meeting e-mail message that lacks a patch by default' ' test_must_fail git am empty-commit.patch >err && test_path_is_dir .git/rebase-apply && test_i18ngrep "Patch is empty." err &&
Re: [PATCH v6 0/3] am: support --empty=(die|drop|keep) option to handle empty patches
In reply to Junio C HamanoQuoted 10 lines
-----Original Messages-----From:"Junio C Hamano" <[email protected]>Sent Time:2021-11-19 07:47:11 (Friday)To:"Aleen via GitGitGadget" <[email protected]>Cc:[email protected], "René Scharfe" <[email protected]>, "Phillip Wood" <[email protected]>, "Aleen 徐沛文" <[email protected]>, Aleen <[email protected]>Subject:Re: [PATCH v6 0/3] am: support --empty=(die|drop|keep) option to handle empty patches
As per https://git-scm.com/docs/SubmittingPatches#sign-off:
Please don’t hide your real name.
I suspect your real name is not Aleen, but something with x and w in it.
I have used "Aleen" <[email protected]> as my GitHub account to send this pull request, but the e-mail service disgusts me that it is slow to send emails to the domain "vger.kernel.org". So I decided to use another mail service to discuss, "Aleen 徐沛文" <[email protected]> as you saw.
In the open-source world, I usually signed off "Aleen" rather than "Aleen 徐沛文", and is that necessary to change?
Re: [PATCH v6 3/3] am: throw an error when passing --empty option without value
In reply to Junio C HamanoQuoted 21 lines
Here is a place for you to explain why this change might be a good idea to defend it. If we applied 1/3 and 2/3 but not this one, what happens? "am --empty" (not "am --empty=<choice>") is accepted and behaves just like "am --empty=die"? Is that a bad thing?
If it is unconditonally a bad thing, then this patch does not stand on its own. It should be squashed into the previous step; otherwise it would be "oops, we didn't think it through and failed to detect an argument-less --error as an error in the previous step, and here is a fix for that mistake". We try not to deliberately commit a mistake and then fix it to gain commit counts in this project (or putting it differently, we try to pretend we are better than we really are and did not make a mistake in the first place).
Or are you giving list participants and reviewers a choice between "'--empty' is a synonym to '--empty=die'" and "'--empty' alone is an error" because you cannot decide yourself? If that is the case, you really really need to make it clear in this place between "From:" and "Signed-off-by:". Why would we want to use this patch? Why would we be better without this patch?
Quoted 7 lines
I haven't thought things through, but my gut feeling is that the semantics of the --empty=<choice> option is better _with_ this, in other words, it makes more sense to forbid "--empty" alone. So if I were doing this series, I would probably have squashed this into the previous one, making it a two-patch series.
Thanks.
Hamano, I could not make this decision like what you said between "'--empty' is a synonym to '--empty=die'" and "'--empty' alone is an error". In my opinion, it is a little wired that '--empty' should not act as "died" semantically. Reversely, it may be better to support a synonym between '--quiet' and '--empty=skip'.
I will squash the commit into the previous one later and hope all participants and reviewers make a decision.
Re: [PATCH v6 0/3] am: support --empty=(die|drop|keep) option to handle empty patches
In reply to Junio C HamanoQuoted 6 lines
As per https://git-scm.com/docs/SubmittingPatches#sign-off:
Please don’t hide your real name.
I suspect your real name is not Aleen, but something with x and w in it.
BTW, gitgitgadget has defined that developers should sign off the user name of the GitHub account, and I can't change it at all.
v7 cover am: support --empty=(die|drop|keep) option to handle empty patches
In reply to Aleen via GitGitGadgetSince 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.
----------------------------------------------------------------------------
cc: René Scharfe [email protected] cc: Phillip Wood [email protected] cc:
Aleen 徐沛文 [email protected]
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 +++++++++++++++++++++++++++--- po/bg.po | 2 +- po/ca.po | 2 +- po/de.po | 2 +- po/el.po | 2 +- po/es.po | 2 +- po/fr.po | 2 +- po/git.pot | 2 +- po/id.po | 2 +- po/it.po | 2 +- po/ko.po | 2 +- po/pl.po | 2 +- po/pt_PT.po | 8 ++--- po/ru.po | 4 +-- po/sv.po | 2 +- po/tr.po | 2 +- po/vi.po | 2 +- po/zh_CN.po | 9 +++-- po/zh_TW.po | 7 +++- t/t4150-am.sh | 49 ++++++++++++++++++++++++++ 22 files changed, 145 insertions(+), 29 deletions(-)
base-commit: ca35af825273b98fc8dc11527488952f5db8eb80
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1076%2Faleen42%2Fnext-v7
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1076/aleen42/next-v7
Pull-Request: https://github.com/gitgitgadget/git/pull/1076
Range-diff vs v6:
1: 9f1b3dd6d0b ! 1: d612bc49d57 doc: git-format-patch: describe the option --always
@@ Metadata
## Commit message ##
doc: git-format-patch: describe the option --always
+ This commit has described how to use '--always' option in the command
+ 'git-format-patch' to include patches for commits that emit no changes.
+
## Documentation/git-format-patch.txt ##
2: 96d8573dc80 ! 2: 9e60e77c041 am: support --empty option to handle empty patches
@@ Metadata
Author: Aleen <[email protected]>
## Commit message ##
- am: support --empty option to handle empty patches
+ am: support --empty=<option> to handle empty patches
+
+ 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 <[email protected]>
@@ Documentation/git-am.txt: OPTIONS
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.
++ 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.
-+ 'die' is specified by default.
+
-m::
--message-id::
@@ builtin/am.c: enum show_patch_type {
+enum empty_action {
+ DIE_EMPTY_COMMIT = 0, /* output errors */
-+ DROP_EMPTY_COMMIT, /* skip without outputting errors */
++ 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 int am_option_parse_quoted_cr(const struct option *opt,
return 0;
}
-+static int am_option_parse_empty_commit(const struct option *opt,
++static int am_option_parse_empty(const struct option *opt,
+ const char *arg, int unset)
+{
+ int *opt_value = opt->value;
+
-+ if (unset || !strcmp(arg, "die"))
++ BUG_ON_OPT_NEG(unset);
++
++ if (!strcmp(arg, "die"))
+ *opt_value = DIE_EMPTY_COMMIT;
+ else if (!strcmp(arg, "drop"))
+ *opt_value = DROP_EMPTY_COMMIT;
@@ builtin/am.c: static int parse_mail(struct am_state *state, const char *mail)
strbuf_addstr(&msg, "\n\n");
strbuf_addbuf(&msg, &mi.log_message);
strbuf_stripspace(&msg, 0);
+@@ builtin/am.c: static void am_run(struct am_state *state, int resume)
+ while (state->cur <= state->last) {
+ const char *mail = am_path(state, msgnum(state));
+ int apply_status;
++ int to_keep;
+
+ reset_ident_date();
+
@@ builtin/am.c: static void am_run(struct am_state *state, int resume)
if (state->interactive && do_interactive(state))
goto next;
++ to_keep = 0;
+ if (is_empty_or_missing_file(am_path(state, "patch"))) {
-+ if (state->empty_type == DROP_EMPTY_COMMIT)
++ switch (state->empty_type) {
++ case DROP_EMPTY_COMMIT:
++ say(state, stdout, _("Skipping: %.*s"), linelen(state->msg), state->msg);
+ goto next;
-+ else if (state->empty_type == KEEP_EMPTY_COMMIT) {
-+ if (run_applypatch_msg_hook(state))
-+ exit(1);
-+ else
-+ goto commit;
-+ } else if (state->empty_type == DIE_EMPTY_COMMIT) {
++ break;
++ case KEEP_EMPTY_COMMIT:
++ to_keep = 1;
++ break;
++ case DIE_EMPTY_COMMIT:
+ printf_ln(_("Patch is empty."));
+ die_user_resolve(state);
++ break;
+ }
+ }
+
if (run_applypatch_msg_hook(state))
exit(1);
++ if (to_keep)
++ goto commit;
+
+ say(state, stdout, _("Applying: %.*s"), linelen(state->msg), state->msg);
@@ builtin/am.c: static void am_run(struct am_state *state, int resume)
die_user_resolve(state);
@@ 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) "" },
-+ { 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()
+ ## po/bg.po ##
+@@ po/bg.po: msgid "Dirty index: cannot apply patches (dirty: %s)"
+ msgstr ""
+ "Индексът не е чист: кръпките не може да бъдат приложени (замърсени са: %s)"
+
+-#: builtin/am.c:1798 builtin/am.c:1865
++#: builtin/am.c:1834 builtin/am.c:1902
+ #, c-format
+ msgid "Applying: %.*s"
+ msgstr "Прилагане: %.*s"
+
+ ## po/ca.po ##
+@@ po/ca.po: msgstr "no s'ha pogut escriure el fitxer d'índex"
+ msgid "Dirty index: cannot apply patches (dirty: %s)"
+ msgstr "Índex brut: no es poden aplicar pedaços (bruts: %s)"
+
+-#: builtin/am.c:1798 builtin/am.c:1865
++#: builtin/am.c:1834 builtin/am.c:1902
+ #, c-format
+ msgid "Applying: %.*s"
+ msgstr "S'està aplicant: %.*s"
+
+ ## po/de.po ##
+@@ po/de.po: msgstr "Konnte Index-Datei nicht schreiben."
+ msgid "Dirty index: cannot apply patches (dirty: %s)"
+ msgstr "Geänderter Index: kann Patches nicht anwenden (geändert: %s)"
+
+-#: builtin/am.c:1798 builtin/am.c:1865
++#: builtin/am.c:1834 builtin/am.c:1902
+ #, c-format
+ msgid "Applying: %.*s"
+ msgstr "Wende an: %.*s"
+
+ ## po/el.po ##
+@@ po/el.po: msgstr "Να γίνει εφαρμογή; [y]es/[n]o/[e]dit/[v]iew patch/[a]ccep
+ msgid "Dirty index: cannot apply patches (dirty: %s)"
+ msgstr ""
+
+-#: builtin/am.c:1749 builtin/am.c:1817
++#: builtin/am.c:1834 builtin/am.c:1902
+ #, c-format
+ msgid "Applying: %.*s"
+ msgstr ""
+
+ ## po/es.po ##
+@@ po/es.po: 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-format
+ msgid "Applying: %.*s"
+ msgstr "Aplicando: %.*s"
+
+ ## po/fr.po ##
+@@ po/fr.po: msgstr "impossible d'écrire le fichier d'index"
+ msgid "Dirty index: cannot apply patches (dirty: %s)"
+ msgstr "Index sale : impossible d'appliquer des patchs (sales : %s)"
+
+-#: builtin/am.c:1798 builtin/am.c:1865
++#: builtin/am.c:1834 builtin/am.c:1902
+ #, c-format
+ msgid "Applying: %.*s"
+ msgstr "Application de %.*s"
+
+ ## po/git.pot ##
+@@ po/git.pot: msgstr ""
+ msgid "Dirty index: cannot apply patches (dirty: %s)"
+ msgstr ""
+
+-#: builtin/am.c:1798 builtin/am.c:1865
++#: builtin/am.c:1834 builtin/am.c:1902
+ #, c-format
+ msgid "Applying: %.*s"
+ msgstr ""
+
+ ## po/id.po ##
+@@ po/id.po: msgstr "tidak dapat menulis berkas indeks"
+ msgid "Dirty index: cannot apply patches (dirty: %s)"
+ msgstr "Indeks kotor: tidak dapat menerapkan tambalan (kotor: %s)"
+
+-#: builtin/am.c:1798 builtin/am.c:1865
++#: builtin/am.c:1834 builtin/am.c:1902
+ #, c-format
+ msgid "Applying: %.*s"
+ msgstr "Menerapkan: %.*s"
+
+ ## po/it.po ##
+@@ po/it.po: msgstr "impossibile scrivere il file indice"
+ msgid "Dirty index: cannot apply patches (dirty: %s)"
+ msgstr "Indice sporco: impossibile applicare le patch (elemento sporco: %s)"
+
+-#: builtin/am.c:1761 builtin/am.c:1829
++#: builtin/am.c:1834 builtin/am.c:1902
+ #, c-format
+ msgid "Applying: %.*s"
+ msgstr "Applicazione in corso: %.*s"
+
+ ## po/ko.po ##
+@@ po/ko.po: msgstr "적용? 예[y]/아니오[n]/편집[e]/패치 보기[v]/모두 적용[a]:
+ msgid "Dirty index: cannot apply patches (dirty: %s)"
+ msgstr "변경된 인덱스: 패치를 적용할 수 없습니다 (dirty: %s)"
+
+-#: builtin/am.c:1808 builtin/am.c:1879
++#: builtin/am.c:1834 builtin/am.c:1902
+ #, c-format
+ msgid "Applying: %.*s"
+ msgstr "적용하는 중: %.*s"
+
+ ## po/pl.po ##
+@@ po/pl.po: msgstr "nie można zapisać pliku indeksu"
+ msgid "Dirty index: cannot apply patches (dirty: %s)"
+ msgstr "Brudny indeks: nie można zastosować łatek (brudny: %s)"
+
+-#: builtin/am.c:1798 builtin/am.c:1865
++#: builtin/am.c:1834 builtin/am.c:1902
+ #, c-format
+ msgid "Applying: %.*s"
+ msgstr "Stosowanie: %.*s"
+
+ ## po/pt_PT.po ##
+@@
+ # bisect | bisetar
+ # blame | blame
+ # blob object | objeto-blob
+-# branch | ramo
++# branch | ramo
+ # bug | bug
+ # bundle | conjunto
+ # bypass | desviar
+@@
+ # loose refs | refs soltas
+ # mark | marca
+ # master | master
+-# merge | junção
++# merge | junção
+ # mergetag | etiqueta-junção
+ # object | objeto
+ # object database | base dados de objeto
+@@
+ # token | token
+ # unset | desdefinir
+ # untrack | desmonitorizar
+-#
++#
+ #
+ msgid ""
+ msgstr ""
+@@ po/pt_PT.po: msgstr "incapaz escrever ficheiro de index"
+ msgid "Dirty index: cannot apply patches (dirty: %s)"
+ msgstr "Index sujo: incapaz aplicar patches (sujo: %s)"
+
+-#: builtin/am.c:1797 builtin/am.c:1865
++#: builtin/am.c:1834 builtin/am.c:1902
+ #, c-format
+ msgid "Applying: %.*s"
+ msgstr "A aplicar: %.*s"
+
+ ## po/ru.po ##
+@@
+ # 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 <[email protected]>, 2020
+ # Dimitriy Ryazantcev <[email protected]>, 2014-2021
+@@ po/ru.po: msgstr "не удалось записать индекс"
+ msgid "Dirty index: cannot apply patches (dirty: %s)"
+ msgstr "Индекс изменён: нельзя применять патчи (изменено: %s)"
+
+-#: builtin/am.c:1748 builtin/am.c:1816
++#: builtin/am.c:1834 builtin/am.c:1902
+ #, c-format
+ msgid "Applying: %.*s"
+ msgstr "Применение: %.*s"
+
+ ## po/sv.po ##
+@@ po/sv.po: msgstr "kan inte skriva indexfil"
+ msgid "Dirty index: cannot apply patches (dirty: %s)"
+ msgstr "Smutsigt index: kan inte tillämpa patchar (smutsiga: %s)"
+
+-#: builtin/am.c:1798 builtin/am.c:1865
++#: builtin/am.c:1834 builtin/am.c:1902
+ #, c-format
+ msgid "Applying: %.*s"
+ msgstr "Tillämpar: %.*s"
+
+ ## po/tr.po ##
+@@ po/tr.po: msgstr "indeks dosyası yazılamıyor"
+ msgid "Dirty index: cannot apply patches (dirty: %s)"
+ msgstr "Kirli indeks: Yamalar uygulanamıyor (kirli: %s)"
+
+-#: builtin/am.c:1798 builtin/am.c:1865
++#: builtin/am.c:1834 builtin/am.c:1902
+ #, c-format
+ msgid "Applying: %.*s"
+ msgstr "Uygulanıyor: %.*s"
+
+ ## po/vi.po ##
+@@ po/vi.po: msgstr "không thể ghi tập tin lưu mục lục"
+ msgid "Dirty index: cannot apply patches (dirty: %s)"
+ msgstr "Bảng mục lục bẩn: không thể áp dụng các miếng vá (bẩn: %s)"
+
+-#: builtin/am.c:1798 builtin/am.c:1865
++#: builtin/am.c:1834 builtin/am.c:1902
+ #, c-format
+ msgid "Applying: %.*s"
+ msgstr "Áp dụng: %.*s"
+
+ ## po/zh_CN.po ##
+@@ po/zh_CN.po: msgstr "坏的索引文件 sha1 签名"
+ msgid "index uses %.4s extension, which we do not understand"
+ msgstr "索引使用不被支持的 %.4s 扩展"
+
+-#
++#
+ #: read-cache.c:1834
+ #, c-format
+ msgid "ignoring %.4s extension"
+@@ po/zh_CN.po: msgstr "无法写入索引文件"
+ msgid "Dirty index: cannot apply patches (dirty: %s)"
+ msgstr "脏索引:不能应用补丁(脏文件:%s)"
+
+-#: builtin/am.c:1798 builtin/am.c:1865
++#: builtin/am.c:1834 builtin/am.c:1902
+ #, c-format
+ msgid "Applying: %.*s"
+ msgstr "应用:%.*s"
+
++#: builtin/am.c:1818
++#, c-format
++msgid "Skipping: %.*s"
++msgstr "跳过:%.*s"
++
+ #: builtin/am.c:1815
+ msgid "No changes -- Patch already applied."
+ msgstr "没有变更 —— 补丁已经应用过。"
+
+ ## po/zh_TW.po ##
+@@ po/zh_TW.po: msgstr "無法寫入索引檔案"
+ msgid "Dirty index: cannot apply patches (dirty: %s)"
+ msgstr "髒索引:不能套用修補檔(髒檔案:%s)"
+
+-#: builtin/am.c:1798 builtin/am.c:1865
++#: builtin/am.c:1834 builtin/am.c:1902
+ #, c-format
+ msgid "Applying: %.*s"
+ msgstr "套用:%.*s"
+
++#: builtin/am.c:1818
++#, c-format
++msgid "Skipping: %.*s"
++msgstr "忽略:%.*s"
++
+ #: builtin/am.c:1815
+ msgid "No changes -- Patch already applied."
+ msgstr "沒有變更——修補檔已經套用過。"
+
## t/t4150-am.sh ##
@@ t/t4150-am.sh: test_expect_success setup '
@@ t/t4150-am.sh: test_expect_success setup '
+ git checkout -b empty-commit &&
+ git commit -m "empty commit" --allow-empty &&
+
-+ git format-patch --stdout empty-commit^ >empty.patch &&
-+ git format-patch --stdout --cover-letter empty-commit^ >cover-letter.patch &&
++ : >empty.patch &&
+ git format-patch --always --stdout empty-commit^ >empty-commit.patch &&
+
# reset time
@@ t/t4150-am.sh: test_expect_success 'apply binary blob in partial clone' '
git -C client am ../patch
'
-+test_expect_success 'still output error with --empty when meeting empty files' '
++test_expect_success 'An empty input file is error regardless of --empty option' '
+ test_must_fail git am --empty=drop empty.patch 2>actual &&
+ echo Patch format detection failed. >expected &&
+ test_cmp expected actual
+'
+
-+test_expect_success 'error when meeting e-mail message that lacks a patch by default' '
++test_expect_success 'invalid when passing the --empty option alone' '
+ git checkout empty-commit^ &&
++ test_must_fail git am --empty empty-commit.patch 2>err &&
++ echo "error: Invalid value for --empty: empty-commit.patch" >expected &&
++ test_cmp expected err
++'
++
++test_expect_success 'a message without a patch is an error (default)' '
++ test_when_finished "git am --abort || :" &&
+ test_must_fail git am empty-commit.patch >err &&
-+ test_path_is_dir .git/rebase-apply &&
-+ test_i18ngrep "Patch is empty." err &&
-+ rm -fr .git/rebase-apply &&
++ 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_fail git am --empty=die empty-commit.patch >err &&
-+ test_path_is_dir .git/rebase-apply &&
-+ test_i18ngrep "Patch is empty." err &&
-+ rm -fr .git/rebase-apply &&
-+
-+ test_must_fail git am --empty=die cover-letter.patch >err &&
-+ test_path_is_dir .git/rebase-apply &&
-+ test_i18ngrep "Patch is empty." err &&
++ grep "Patch is empty." err &&
+ rm -fr .git/rebase-apply
+'
+
-+test_expect_success 'skip without error when meeting e-mail message that lacks a patch' '
-+ git am --empty=drop empty-commit.patch >err &&
-+ test_path_is_missing .git/rebase-apply &&
++test_expect_success 'a message without a patch will be skipped when "--empty=drop" is given' '
++ git am --empty=drop empty-commit.patch >output &&
+ git rev-parse empty-commit^ >expected &&
+ git rev-parse HEAD >actual &&
+ test_cmp expected actual &&
-+
-+ git am --empty=drop cover-letter.patch >err &&
-+ test_path_is_missing .git/rebase-apply &&
-+ test_cmp_rev empty-commit^ HEAD
++ grep "Skipping: empty commit" output
+'
+
+test_expect_success 'record as an empty commit when meeting e-mail message that lacks a patch' '
+ git am --empty=keep empty-commit.patch &&
+ test_path_is_missing .git/rebase-apply &&
-+ {
-+ git show empty-commit --format="%B" &&
-+ echo "--" &&
-+ git version | sed -e "s/^git version //" &&
-+ echo
-+ } >expected &&
-+ git show HEAD --format="%B" >actual &&
-+ test_cmp actual expected &&
-+
-+ git am --empty=keep cover-letter.patch &&
-+ test_path_is_missing .git/rebase-apply &&
-+ {
-+ echo "*** SUBJECT HERE ***" &&
-+ echo &&
-+ echo "*** BLURB HERE ***" &&
-+ echo &&
-+ echo "A U Thor (1):" &&
-+ printf " " &&
-+ git show empty-commit --format="%B" &&
-+ echo "--" &&
-+ git version | sed -e "s/^git version //" &&
-+ echo
-+ } >expected &&
-+ git show HEAD --format="%B" >actual &&
++ git show empty-commit --format="%s" >expected &&
++ git show HEAD --format="%s" >actual &&
+ test_cmp actual expected
+'
+ 3: e907a2b2faa < -: ----------- am: throw an error when passing --empty option without value
Signature · 1 line
gitgitgadget
PATCH v7 1/2 doc: git-format-patch: describe the option --always
From: Aleen <[email protected]>
This commit has described how to use '--always' option in the command 'git-format-patch' to include patches for commits that emit no changes.
--- Documentation/git-format-patch.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
Documentation/git-format-patch.txt +5 -1
@@ -18,7 +18,7 @@ SYNOPSIS [-n | --numbered | -N | --no-numbered] [--start-number <n>] [--numbered-files] [--in-reply-to=<message id>] [--suffix=.<sfx>] - [--ignore-if-in-upstream] + [--ignore-if-in-upstream] [--always] [--cover-from-description=<mode>] [--rfc] [--subject-prefix=<subject prefix>] [(--reroll-count|-v) <n>]
@@ -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.
Signature · 1 line
gitgitgadget
PATCH v7 2/2 am: support --empty=<option> to handle empty patches
In reply to Aleen via GitGitGadgetFrom: Aleen <[email protected]>
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').
--- Documentation/git-am.txt | 8 ++++++ builtin/am.c | 55 ++++++++++++++++++++++++++++++++++++---- po/bg.po | 2 +- po/ca.po | 2 +- po/de.po | 2 +- po/el.po | 2 +- po/es.po | 2 +- po/fr.po | 2 +- po/git.pot | 2 +- po/id.po | 2 +- po/it.po | 2 +- po/ko.po | 2 +- po/pl.po | 2 +- po/pt_PT.po | 8 +++--- po/ru.po | 4 +-- po/sv.po | 2 +- po/tr.po | 2 +- po/vi.po | 2 +- po/zh_CN.po | 9 +++++-- po/zh_TW.po | 7 ++++- t/t4150-am.sh | 49 +++++++++++++++++++++++++++++++++++ 21 files changed, 140 insertions(+), 28 deletions(-)
Documentation/git-am.txt +8 -0
@@ -16,6 +16,7 @@ SYNOPSIS [--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet] [--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>] [--quoted-cr=<action>] + [--empty=(die|drop|keep)] [(<mbox> | <Maildir>)...] 'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)])
@@ -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]),
builtin/am.c +50 -5
105 lines not on this page · raw message
po/bg.po +1 -1
@@ -11194,7 +11194,7 @@ msgid "Dirty index: cannot apply patches (dirty: %s)" msgstr "" "Индексът не е чист: кръпките не може да бъдат приложени (замърсени са: %s)" -#: builtin/am.c:1798 builtin/am.c:1865 +#: builtin/am.c:1834 builtin/am.c:1902 #, c-format msgid "Applying: %.*s" msgstr "Прилагане: %.*s"
po/ca.po +1 -1
@@ -10931,7 +10931,7 @@ msgstr "no s'ha pogut escriure el fitxer d'índex" msgid "Dirty index: cannot apply patches (dirty: %s)" msgstr "Índex brut: no es poden aplicar pedaços (bruts: %s)" -#: builtin/am.c:1798 builtin/am.c:1865 +#: builtin/am.c:1834 builtin/am.c:1902 #, c-format msgid "Applying: %.*s" msgstr "S'està aplicant: %.*s"
po/de.po +1 -1
@@ -10999,7 +10999,7 @@ msgstr "Konnte Index-Datei nicht schreiben." msgid "Dirty index: cannot apply patches (dirty: %s)" msgstr "Geänderter Index: kann Patches nicht anwenden (geändert: %s)" -#: builtin/am.c:1798 builtin/am.c:1865 +#: builtin/am.c:1834 builtin/am.c:1902 #, c-format msgid "Applying: %.*s" msgstr "Wende an: %.*s"
po/el.po +1 -1
@@ -7801,7 +7801,7 @@ msgstr "Να γίνει εφαρμογή; [y]es/[n]o/[e]dit/[v]iew patch/[a]ccep msgid "Dirty index: cannot apply patches (dirty: %s)" msgstr "" -#: builtin/am.c:1749 builtin/am.c:1817 +#: builtin/am.c:1834 builtin/am.c:1902 #, c-format msgid "Applying: %.*s" msgstr ""
po/es.po +1 -1
@@ -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-format msgid "Applying: %.*s" msgstr "Aplicando: %.*s"
po/fr.po +1 -1
@@ -11013,7 +11013,7 @@ msgstr "impossible d'écrire le fichier d'index" msgid "Dirty index: cannot apply patches (dirty: %s)" msgstr "Index sale : impossible d'appliquer des patchs (sales : %s)" -#: builtin/am.c:1798 builtin/am.c:1865 +#: builtin/am.c:1834 builtin/am.c:1902 #, c-format msgid "Applying: %.*s" msgstr "Application de %.*s"
po/git.pot +1 -1
@@ -9985,7 +9985,7 @@ msgstr "" msgid "Dirty index: cannot apply patches (dirty: %s)" msgstr "" -#: builtin/am.c:1798 builtin/am.c:1865 +#: builtin/am.c:1834 builtin/am.c:1902 #, c-format msgid "Applying: %.*s" msgstr ""
po/id.po +1 -1
@@ -10306,7 +10306,7 @@ msgstr "tidak dapat menulis berkas indeks" msgid "Dirty index: cannot apply patches (dirty: %s)" msgstr "Indeks kotor: tidak dapat menerapkan tambalan (kotor: %s)" -#: builtin/am.c:1798 builtin/am.c:1865 +#: builtin/am.c:1834 builtin/am.c:1902 #, c-format msgid "Applying: %.*s" msgstr "Menerapkan: %.*s"
po/it.po +1 -1
@@ -10229,7 +10229,7 @@ msgstr "impossibile scrivere il file indice" msgid "Dirty index: cannot apply patches (dirty: %s)" msgstr "Indice sporco: impossibile applicare le patch (elemento sporco: %s)" -#: builtin/am.c:1761 builtin/am.c:1829 +#: builtin/am.c:1834 builtin/am.c:1902 #, c-format msgid "Applying: %.*s" msgstr "Applicazione in corso: %.*s"
po/ko.po +1 -1
@@ -5681,7 +5681,7 @@ msgstr "적용? 예[y]/아니오[n]/편집[e]/패치 보기[v]/모두 적용[a]: msgid "Dirty index: cannot apply patches (dirty: %s)" msgstr "변경된 인덱스: 패치를 적용할 수 없습니다 (dirty: %s)" -#: builtin/am.c:1808 builtin/am.c:1879 +#: builtin/am.c:1834 builtin/am.c:1902 #, c-format msgid "Applying: %.*s" msgstr "적용하는 중: %.*s"
po/pl.po +1 -1
@@ -10811,7 +10811,7 @@ msgstr "nie można zapisać pliku indeksu" msgid "Dirty index: cannot apply patches (dirty: %s)" msgstr "Brudny indeks: nie można zastosować łatek (brudny: %s)" -#: builtin/am.c:1798 builtin/am.c:1865 +#: builtin/am.c:1834 builtin/am.c:1902 #, c-format msgid "Applying: %.*s" msgstr "Stosowanie: %.*s"
po/pt_PT.po +4 -4
@@ -24,7 +24,7 @@ # bisect | bisetar # blame | blame # blob object | objeto-blob -# branch | ramo +# branch | ramo # bug | bug # bundle | conjunto # bypass | desviar
@@ -74,7 +74,7 @@ # loose refs | refs soltas # mark | marca # master | master -# merge | junção +# merge | junção # mergetag | etiqueta-junção # object | objeto # object database | base dados de objeto
@@ -211,7 +211,7 @@ # token | token # unset | desdefinir # untrack | desmonitorizar -# +# # msgid "" msgstr ""
@@ -10485,7 +10485,7 @@ msgstr "incapaz escrever ficheiro de index" msgid "Dirty index: cannot apply patches (dirty: %s)" msgstr "Index sujo: incapaz aplicar patches (sujo: %s)" -#: builtin/am.c:1797 builtin/am.c:1865 +#: builtin/am.c:1834 builtin/am.c:1902 #, c-format msgid "Applying: %.*s" msgstr "A aplicar: %.*s"
po/ru.po +2 -2
@@ -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 <[email protected]>, 2020 # Dimitriy Ryazantcev <[email protected]>, 2014-2021
@@ -9398,7 +9398,7 @@ msgstr "не удалось записать индекс" msgid "Dirty index: cannot apply patches (dirty: %s)" msgstr "Индекс изменён: нельзя применять патчи (изменено: %s)" -#: builtin/am.c:1748 builtin/am.c:1816 +#: builtin/am.c:1834 builtin/am.c:1902 #, c-format msgid "Applying: %.*s" msgstr "Применение: %.*s"
po/sv.po +1 -1
@@ -10746,7 +10746,7 @@ msgstr "kan inte skriva indexfil" msgid "Dirty index: cannot apply patches (dirty: %s)" msgstr "Smutsigt index: kan inte tillämpa patchar (smutsiga: %s)" -#: builtin/am.c:1798 builtin/am.c:1865 +#: builtin/am.c:1834 builtin/am.c:1902 #, c-format msgid "Applying: %.*s" msgstr "Tillämpar: %.*s"
po/tr.po +1 -1
@@ -10810,7 +10810,7 @@ msgstr "indeks dosyası yazılamıyor" msgid "Dirty index: cannot apply patches (dirty: %s)" msgstr "Kirli indeks: Yamalar uygulanamıyor (kirli: %s)" -#: builtin/am.c:1798 builtin/am.c:1865 +#: builtin/am.c:1834 builtin/am.c:1902 #, c-format msgid "Applying: %.*s" msgstr "Uygulanıyor: %.*s"
po/vi.po +1 -1
@@ -10807,7 +10807,7 @@ msgstr "không thể ghi tập tin lưu mục lục" msgid "Dirty index: cannot apply patches (dirty: %s)" msgstr "Bảng mục lục bẩn: không thể áp dụng các miếng vá (bẩn: %s)" -#: builtin/am.c:1798 builtin/am.c:1865 +#: builtin/am.c:1834 builtin/am.c:1902 #, c-format msgid "Applying: %.*s" msgstr "Áp dụng: %.*s"
po/zh_CN.po +7 -2
@@ -6463,7 +6463,7 @@ msgstr "坏的索引文件 sha1 签名" msgid "index uses %.4s extension, which we do not understand" msgstr "索引使用不被支持的 %.4s 扩展" -# +# #: read-cache.c:1834 #, c-format msgid "ignoring %.4s extension"
@@ -10673,11 +10673,16 @@ msgstr "无法写入索引文件" msgid "Dirty index: cannot apply patches (dirty: %s)" msgstr "脏索引:不能应用补丁(脏文件:%s)" -#: builtin/am.c:1798 builtin/am.c:1865 +#: builtin/am.c:1834 builtin/am.c:1902 #, c-format msgid "Applying: %.*s" msgstr "应用:%.*s" +#: builtin/am.c:1818 +#, c-format +msgid "Skipping: %.*s" +msgstr "跳过:%.*s" + #: builtin/am.c:1815 msgid "No changes -- Patch already applied." msgstr "没有变更 —— 补丁已经应用过。"
po/zh_TW.po +6 -1
@@ -10538,11 +10538,16 @@ msgstr "無法寫入索引檔案" msgid "Dirty index: cannot apply patches (dirty: %s)" msgstr "髒索引:不能套用修補檔(髒檔案:%s)" -#: builtin/am.c:1798 builtin/am.c:1865 +#: builtin/am.c:1834 builtin/am.c:1902 #, c-format msgid "Applying: %.*s" msgstr "套用:%.*s" +#: builtin/am.c:1818 +#, c-format +msgid "Skipping: %.*s" +msgstr "忽略:%.*s" + #: builtin/am.c:1815 msgid "No changes -- Patch already applied." msgstr "沒有變更——修補檔已經套用過。"
t/t4150-am.sh +49 -0
59 lines not on this page · raw message
Signature · 1 line
gitgitgadget
Re: [PATCH v6 0/3] am: support --empty=(die|drop|keep) option to handle empty patches
In reply to Aleen 徐沛文Quoted 8 lines · Aleen 徐沛文
Quoted 7 lines
As per https://git-scm.com/docs/SubmittingPatches#sign-off:
Please don’t hide your real name.
I suspect your real name is not Aleen, but something with x and w in it.
Quoted 8 lines
I have used "Aleen" <[email protected]> as my GitHub account to send this pull request, but the e-mail service disgusts me that it is slow to send emails to the domain "vger.kernel.org". So I decided to use another mail service to discuss, "Aleen 徐沛文" <[email protected]> as you saw.
In the open-source world, I usually signed off "Aleen" rather than "Aleen 徐沛文", and is that necessary to change?
Yes.
As the URL you were referred to explains, the sign-off procedure is to keep track of provenance of the code, which is a more "legal" formal requirement than just "I use this pseudonym everywhere". When a big company comes to us, claiming that "this code is our intellectual property stolen from us" and pointing at code added by a patch from you, we do not want to see us in the position to have to say "eh, somebody who uses psuedonym X signed DCO, but we do not even know their real name".
Re: [PATCH v6 0/3] am: support --empty=(die|drop|keep) option to handle empty patches
Quoted 10 lines
Yes.
As the URL you were referred to explains, the sign-off procedure is to keep track of provenance of the code, which is a more "legal" formal requirement than just "I use this pseudonym everywhere". When a big company comes to us, claiming that "this code is our intellectual property stolen from us" and pointing at code added by a patch from you, we do not want to see us in the position to have to say "eh, somebody who uses psuedonym X signed DCO, but we do not even know their real name".
I know it, and as I said before that gitgitgadget need PR creators to sign off user name of GitHub account, according to the DCO check. I can confirmed that "Aleen" and "Aleen 徐沛文" are both the real name of mine, the committer. I can use the account [email protected] to confirm this.
RE: [PATCH v6 0/3] am: support --empty=(die|drop|keep) option to handle empty patches
Quoted 4 lines
I know it, and as I said before that gitgitgadget need PR creators to sign off user name of GitHub account, according to the DCO check. I can confirmed that "Aleen" and "Aleen 徐沛文" are both the real name of mine, the committer. I can use the account [email protected] to confirm this.
Confirmed.
Re: [PATCH v6 2/3] am: support --empty option to handle empty patches
In reply to Aleen via GitGitGadgett/t4150-am.sh test_expect_success 'apply binary blob in partial clone' ' · line 1166
Quoted 5 lines · Aleen via GitGitGadget
t/t4150-am.sh +5
-0+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?
Signature · 1 line
An old man doll... just what I always wanted! - Clara
Re: [PATCH v6 2/3] am: support --empty option to handle empty patches
Quoted 8 lines · Bagas Sanjaya
t/t4150-am.sh test_expect_success 'apply binary blob in partial clone' ' · line 1166
Quoted 5 lines · Aleen via GitGitGadget
t/t4150-am.sh +5
-0+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.
Re: [PATCH v6 2/3] am: support --empty option to handle empty patches
Quoted 8 lines · Ævar Arnfjörð Bjarmason
Quoted 7 lines · Bagas Sanjaya
Quoted 5 lines · Aleen via GitGitGadget
t/t4150-am.sh +5
-0+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 +'
Quoted 8 lines
Quoted 1 line
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/
Re: [PATCH v6 2/3] am: support --empty option to handle empty patches
In reply to Bagas SanjayaQuoted 8 lines · Bagas Sanjaya
t/t4150-am.sh test_expect_success 'apply binary blob in partial clone' ' · line 1166
Quoted 5 lines · Aleen via GitGitGadget
t/t4150-am.sh +5
-0+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?
You may doing so without realizing, but such a "why does the code not do X" question, especially without stating why you think the code should do X, gets irritating quickly.
I think it is better to quote the arguments to echo to make it a single string, because ...
would have helped the author of the patch.
If this were one-off, I would have let it go, but I thought it may be worth commenting, as you seem to often ask this kind of "questions".
Re: [PATCH v6 2/3] am: support --empty option to handle empty patches
In reply to Eric SunshineQuoted 11 lines · Eric Sunshine
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 ... >expectstatement gives me a moment's pause since it relies upon the fact thatechowill 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 withecho.But, it's a fairly minor objection.
It indeed is minor enough that a patch to turn an existing
echo A B C >expect && test_cmp expect actual
into
echo "A B C" >expect && test_cmp expect actual
is not welcome. But it still is worth pointing out and correcting in a patch to add new code, I would think. It all depends on what we care about, and the use of test_cmp means we do care about exact shape of the string, including the inter-word spacing.
Thanks.
Re: [PATCH v6 0/3] am: support --empty=(die|drop|keep) option to handle empty patches
In reply to Aleen 徐沛文Quoted 11 lines · Aleen 徐沛文
Quoted 10 lines
Yes.
As the URL you were referred to explains, the sign-off procedure is to keep track of provenance of the code, which is a more "legal" formal requirement than just "I use this pseudonym everywhere". When a big company comes to us, claiming that "this code is our intellectual property stolen from us" and pointing at code added by a patch from you, we do not want to see us in the position to have to say "eh, somebody who uses psuedonym X signed DCO, but we do not even know their real name".
Quoted 4 lines
I know it, and as I said before that gitgitgadget need PR creators to sign off user name of GitHub account, according to the DCO check. I can confirmed that "Aleen" and "Aleen 徐沛文" are both the real name of mine, the committer. I can use the account [email protected] to confirm this.
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.
Re: [PATCH v6 0/3] am: support --empty=(die|drop|keep) option to handle empty patches
Quoted 7 lines
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.
When it comes to GGG, I just want to know whether this is the only way to contribute to Git? I think we can directly use GitHub to run the reviewing procedure, rather than sending emails in this old fashioned way, since that Git code has been maintained in GitHub. E-mails does well in playing the role as a notification way. They helps nothing in reviewing code, especially when we need to point out problems or suggestions referred to certain code snippets.
Re: [PATCH v6 0/3] am: support --empty=(die|drop|keep) option to handle empty patches
Quoted 11 lines · Aleen 徐沛文
Quoted 6 lines
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.
When it comes to GGG, I just want to know whether this is the only way to contribute to Git? I think we can directly use GitHub to run the reviewing procedure, rather than sending emails in this old fashioned way, since that Git code has been maintained in GitHub.
No, we do not develop or maintain at GitHub at all. The repository at GitHub is one of the several publishing point and development is done here.
Re: [PATCH v7 2/2] am: support --empty=<option> to handle empty patches
In reply to Aleen via GitGitGadgetQuoted 24 lines · Aleen via GitGitGadget
From: Aleen <[email protected]>
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 <[email protected]>--- Documentation/git-am.txt | 8 ++++++ builtin/am.c | 55 ++++++++++++++++++++++++++++++++++++---- t/t4150-am.sh | 49 +++++++++++++++++++++++++++++++++++po/bg.po | 2 +- po/ca.po | 2 +- po/de.po | 2 +- po/el.po | 2 +- po/es.po | 2 +- po/fr.po | 2 +- po/git.pot | 2 +- po/id.po | 2 +- po/it.po | 2 +- po/ko.po | 2 +-
Quoted 8 lines
po/pl.po | 2 +- po/pt_PT.po | 8 +++--- po/ru.po | 4 +-- po/sv.po | 2 +- po/tr.po | 2 +- po/vi.po | 2 +- po/zh_CN.po | 9 +++++-- po/zh_TW.po | 7 ++++-
Please do not touch these po/ files. They will be updated when i18n coordinator decides to update the translation.
Re: [PATCH v7 2/2] am: support --empty=<option> to handle empty patches
In reply to Aleen via GitGitGadgetQuoted 1 line · Aleen via GitGitGadget
+test_expect_success 'An empty input file is error regardless of --empty option' '
Titles of all the other tests seem to begin with lowercase, so "An empty" -> "an empty", probably.
t/t4150-am.sh test_expect_success 'apply binary blob in partial clone' ' · line 1163
Quoted 2 lines
t/t4150-am.sh +2
-0+ test_must_fail git am --empty=drop empty.patch 2>actual && + echo Patch format detection failed. >expected &&
Quote for exactness, like the next test does.
echo "Patch format detection failed." >expected
t/t4150-am.sh test_expect_success 'apply binary blob in partial clone' ' · line 1172
Quoted 9 lines
t/t4150-am.sh +9
-0+ test_cmp expected actual +' + +test_expect_success 'invalid when passing the --empty option alone' ' + git checkout empty-commit^ && + test_must_fail git am --empty empty-commit.patch 2>err && + echo "error: Invalid value for --empty: empty-commit.patch" >expected && + test_cmp expected err +'
This mode of failure of "am" may not leave ".git/rebase-apply" behind right now, or it may leave one in the future. We do not want to worry about left-over cruft to interfere with the next test, so cleaning after ourselves with test_when_finished would be a good idea, i.e.
test_expect_success 'invalid when passing the --empty option alone' '
test_when_finished "git am --abort || :" &&
git checkout empty-commit^ &&
test_must_fail git am --empty empty-commit.patch 2>err &&
echo "error: Invalid value for --empty: empty-commit.patch" >expected &&
test_cmp expected err
't/t4150-am.sh test_expect_success 'apply binary blob in partial clone' ' · line 1179
Quoted 6 lines
t/t4150-am.sh +6
-0+test_expect_success 'a message without a patch is an error (default)' ' + test_when_finished "git am --abort || :" && + test_must_fail git am empty-commit.patch >err && + grep "Patch is empty" err && + rm -fr .git/rebase-apply +'
And the point of test_when_finished is to run the clean-up even when other steps in the test fails. For example, "test_must_fail git am" may fail to fail for any reason. Or "grep" after it may fail. Because the pieces in a single test is strung together with &&, any such failure means the control would NOT reach "rm -fr".
Since we have test_when_finished that cleans up after ourselves even in such a case, the last "rm -fr" step is unnecessary.
t/t4150-am.sh test_expect_success 'apply binary blob in partial clone' ' · line 1186
Quoted 6 lines
t/t4150-am.sh +6
-0+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 && + rm -fr .git/rebase-apply +'
Likewise.
Other than that (and po/ that should not be part of this patch), things are looking good.
Thanks.
PATCH v8 1/2 doc: git-format-patch: describe the option --always
In reply to Aleen via GitGitGadgetFrom: Aleen <[email protected]>
This commit has described how to use '--always' option in the command 'git-format-patch' to include patches for commits that emit no changes.
--- Documentation/git-format-patch.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
Documentation/git-format-patch.txt +5 -1
@@ -18,7 +18,7 @@ SYNOPSIS [-n | --numbered | -N | --no-numbered] [--start-number <n>] [--numbered-files] [--in-reply-to=<message id>] [--suffix=.<sfx>] - [--ignore-if-in-upstream] + [--ignore-if-in-upstream] [--always] [--cover-from-description=<mode>] [--rfc] [--subject-prefix=<subject prefix>] [(--reroll-count|-v) <n>]
@@ -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.
Signature · 1 line
gitgitgadget
v8 cover am: support --empty=(die|drop|keep) option to handle empty patches
In reply to Aleen via GitGitGadgetSince 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. update code according to the seen branch
2. fix wrong document of git-am
----------------------------------------------------------------------------
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-v8
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1076/aleen42/next-v8
Pull-Request: https://github.com/gitgitgadget/git/pull/1076
Range-diff vs v7:
1: d612bc49d57 ! 1: 5d98a088e14 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 <[email protected]>
+ Signed-off-by: Aleen 徐沛文 <[email protected]>
## Documentation/git-format-patch.txt ##
@@ Documentation/git-format-patch.txt: SYNOPSIS
2: 9e60e77c041 ! 2: 3ff18e16a7a 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 <[email protected]>
+ Signed-off-by: Aleen 徐沛文 <[email protected]>
## Documentation/git-am.txt ##
@@ Documentation/git-am.txt: SYNOPSIS
@@ Documentation/git-am.txt: OPTIONS
--quoted-cr=<action>::
This flag will be passed down to 'git mailinfo' (see linkgit:git-mailinfo[1]).
-+--empty-commit=(die|drop|keep)::
++--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.
@@ builtin/am.c: int cmd_am(int argc, const char **argv, const char *prefix)
N_("(internal use for git-rebase)")),
OPT_END()
- ## po/bg.po ##
-@@ po/bg.po: msgid "Dirty index: cannot apply patches (dirty: %s)"
- msgstr ""
- "Индексът не е чист: кръпките не може да бъдат приложени (замърсени са: %s)" -
--#: builtin/am.c:1798 builtin/am.c:1865
-+#: builtin/am.c:1834 builtin/am.c:1902
- #, c-format
- msgid "Applying: %.*s"
- msgstr "Прилагане: %.*s"
-
- ## po/ca.po ##
-@@ po/ca.po: msgstr "no s'ha pogut escriure el fitxer d'índex"
- msgid "Dirty index: cannot apply patches (dirty: %s)"
- msgstr "Índex brut: no es poden aplicar pedaços (bruts: %s)"
-
--#: builtin/am.c:1798 builtin/am.c:1865
-+#: builtin/am.c:1834 builtin/am.c:1902
- #, c-format
- msgid "Applying: %.*s"
- msgstr "S'està aplicant: %.*s"
-
- ## po/de.po ##
-@@ po/de.po: msgstr "Konnte Index-Datei nicht schreiben."
- msgid "Dirty index: cannot apply patches (dirty: %s)"
- msgstr "Geänderter Index: kann Patches nicht anwenden (geändert: %s)" -
--#: builtin/am.c:1798 builtin/am.c:1865
-+#: builtin/am.c:1834 builtin/am.c:1902
- #, c-format
- msgid "Applying: %.*s"
- msgstr "Wende an: %.*s"
-
- ## po/el.po ##
-@@ po/el.po: msgstr "Να γίνει εφαρμογή; [y]es/[n]o/[e]dit/[v]iew patch/[a]ccep
- msgid "Dirty index: cannot apply patches (dirty: %s)"
- msgstr ""
-
--#: builtin/am.c:1749 builtin/am.c:1817
-+#: builtin/am.c:1834 builtin/am.c:1902
- #, c-format
- msgid "Applying: %.*s"
- msgstr ""
-
- ## po/es.po ##
-@@ po/es.po: 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-format
- msgid "Applying: %.*s"
- msgstr "Aplicando: %.*s"
-
- ## po/fr.po ##
-@@ po/fr.po: msgstr "impossible d'écrire le fichier d'index"
- msgid "Dirty index: cannot apply patches (dirty: %s)"
- msgstr "Index sale : impossible d'appliquer des patchs (sales : %s)" -
--#: builtin/am.c:1798 builtin/am.c:1865
-+#: builtin/am.c:1834 builtin/am.c:1902
- #, c-format
- msgid "Applying: %.*s"
- msgstr "Application de %.*s"
-
- ## po/git.pot ##
-@@ po/git.pot: msgstr ""
- msgid "Dirty index: cannot apply patches (dirty: %s)"
- msgstr ""
-
--#: builtin/am.c:1798 builtin/am.c:1865
-+#: builtin/am.c:1834 builtin/am.c:1902
- #, c-format
- msgid "Applying: %.*s"
- msgstr ""
-
- ## po/id.po ##
-@@ po/id.po: msgstr "tidak dapat menulis berkas indeks"
- msgid "Dirty index: cannot apply patches (dirty: %s)"
- msgstr "Indeks kotor: tidak dapat menerapkan tambalan (kotor: %s)" -
--#: builtin/am.c:1798 builtin/am.c:1865
-+#: builtin/am.c:1834 builtin/am.c:1902
- #, c-format
- msgid "Applying: %.*s"
- msgstr "Menerapkan: %.*s"
-
- ## po/it.po ##
-@@ po/it.po: msgstr "impossibile scrivere il file indice"
- msgid "Dirty index: cannot apply patches (dirty: %s)"
- msgstr "Indice sporco: impossibile applicare le patch (elemento sporco: %s)" -
--#: builtin/am.c:1761 builtin/am.c:1829
-+#: builtin/am.c:1834 builtin/am.c:1902
- #, c-format
- msgid "Applying: %.*s"
- msgstr "Applicazione in corso: %.*s"
-
- ## po/ko.po ##
-@@ po/ko.po: msgstr "적용? 예[y]/아니오[n]/편집[e]/패치 보기[v]/모두 적용[a]:
- msgid "Dirty index: cannot apply patches (dirty: %s)"
- msgstr "변경된 인덱스: 패치를 적용할 수 없습니다 (dirty: %s)"
-
--#: builtin/am.c:1808 builtin/am.c:1879
-+#: builtin/am.c:1834 builtin/am.c:1902
- #, c-format
- msgid "Applying: %.*s"
- msgstr "적용하는 중: %.*s"
-
- ## po/pl.po ##
-@@ po/pl.po: msgstr "nie można zapisać pliku indeksu"
- msgid "Dirty index: cannot apply patches (dirty: %s)"
- msgstr "Brudny indeks: nie można zastosować łatek (brudny: %s)" -
--#: builtin/am.c:1798 builtin/am.c:1865
-+#: builtin/am.c:1834 builtin/am.c:1902
- #, c-format
- msgid "Applying: %.*s"
- msgstr "Stosowanie: %.*s"
-
- ## po/pt_PT.po ##
-@@
- # bisect | bisetar
- # blame | blame
- # blob object | objeto-blob
--# branch | ramo
-+# branch | ramo
- # bug | bug
- # bundle | conjunto
- # bypass | desviar
-@@
- # loose refs | refs soltas
- # mark | marca
- # master | master
--# merge | junção
-+# merge | junção
- # mergetag | etiqueta-junção
- # object | objeto
- # object database | base dados de objeto
-@@
- # token | token
- # unset | desdefinir
- # untrack | desmonitorizar
--#
-+#
- #
- msgid ""
- msgstr ""
-@@ po/pt_PT.po: msgstr "incapaz escrever ficheiro de index"
- msgid "Dirty index: cannot apply patches (dirty: %s)"
- msgstr "Index sujo: incapaz aplicar patches (sujo: %s)"
-
--#: builtin/am.c:1797 builtin/am.c:1865
-+#: builtin/am.c:1834 builtin/am.c:1902
- #, c-format
- msgid "Applying: %.*s"
- msgstr "A aplicar: %.*s"
-
- ## po/ru.po ##
-@@
- # 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 <[email protected]>, 2020
- # Dimitriy Ryazantcev <[email protected]>, 2014-2021
-@@ po/ru.po: msgstr "не удалось записать индекс"
- msgid "Dirty index: cannot apply patches (dirty: %s)"
- msgstr "Индекс изменён: нельзя применять патчи (изменено: %s)" -
--#: builtin/am.c:1748 builtin/am.c:1816
-+#: builtin/am.c:1834 builtin/am.c:1902
- #, c-format
- msgid "Applying: %.*s"
- msgstr "Применение: %.*s"
-
- ## po/sv.po ##
-@@ po/sv.po: msgstr "kan inte skriva indexfil"
- msgid "Dirty index: cannot apply patches (dirty: %s)"
- msgstr "Smutsigt index: kan inte tillämpa patchar (smutsiga: %s)" -
--#: builtin/am.c:1798 builtin/am.c:1865
-+#: builtin/am.c:1834 builtin/am.c:1902
- #, c-format
- msgid "Applying: %.*s"
- msgstr "Tillämpar: %.*s"
-
- ## po/tr.po ##
-@@ po/tr.po: msgstr "indeks dosyası yazılamıyor"
- msgid "Dirty index: cannot apply patches (dirty: %s)"
- msgstr "Kirli indeks: Yamalar uygulanamıyor (kirli: %s)"
-
--#: builtin/am.c:1798 builtin/am.c:1865
-+#: builtin/am.c:1834 builtin/am.c:1902
- #, c-format
- msgid "Applying: %.*s"
- msgstr "Uygulanıyor: %.*s"
-
- ## po/vi.po ##
-@@ po/vi.po: msgstr "không thể ghi tập tin lưu mục lục"
- msgid "Dirty index: cannot apply patches (dirty: %s)"
- msgstr "Bảng mục lục bẩn: không thể áp dụng các miếng vá (bẩn: %s)" -
--#: builtin/am.c:1798 builtin/am.c:1865
-+#: builtin/am.c:1834 builtin/am.c:1902
- #, c-format
- msgid "Applying: %.*s"
- msgstr "Áp dụng: %.*s"
-
- ## po/zh_CN.po ##
-@@ po/zh_CN.po: msgstr "坏的索引文件 sha1 签名"
- msgid "index uses %.4s extension, which we do not understand"
- msgstr "索引使用不被支持的 %.4s 扩展"
-
--#
-+#
- #: read-cache.c:1834
- #, c-format
- msgid "ignoring %.4s extension"
-@@ po/zh_CN.po: msgstr "无法写入索引文件"
- msgid "Dirty index: cannot apply patches (dirty: %s)"
- msgstr "脏索引:不能应用补丁(脏文件:%s)"
-
--#: builtin/am.c:1798 builtin/am.c:1865
-+#: builtin/am.c:1834 builtin/am.c:1902
- #, c-format
- msgid "Applying: %.*s"
- msgstr "应用:%.*s"
-
-+#: builtin/am.c:1818
-+#, c-format
-+msgid "Skipping: %.*s"
-+msgstr "跳过:%.*s"
-+
- #: builtin/am.c:1815
- msgid "No changes -- Patch already applied."
- msgstr "没有变更 —— 补丁已经应用过。"
-
- ## po/zh_TW.po ##
-@@ po/zh_TW.po: msgstr "無法寫入索引檔案"
- msgid "Dirty index: cannot apply patches (dirty: %s)"
- msgstr "髒索引:不能套用修補檔(髒檔案:%s)"
-
--#: builtin/am.c:1798 builtin/am.c:1865
-+#: builtin/am.c:1834 builtin/am.c:1902
- #, c-format
- msgid "Applying: %.*s"
- msgstr "套用:%.*s"
-
-+#: builtin/am.c:1818
-+#, c-format
-+msgid "Skipping: %.*s"
-+msgstr "忽略:%.*s"
-+
- #: builtin/am.c:1815
- msgid "No changes -- Patch already applied."
- msgstr "沒有變更——修補檔已經套用過。"
-
## t/t4150-am.sh ##
@@ t/t4150-am.sh: test_expect_success setup '
@@ t/t4150-am.sh: test_expect_success 'apply binary blob in partial clone' '
git -C client am ../patch
'
-+test_expect_success 'An empty input file is error regardless of --empty option' ' ++test_expect_success 'an empty input file is error regardless of --empty option' '
++ test_when_finished "git am --abort || :" &&
+ test_must_fail git am --empty=drop empty.patch 2>actual &&
-+ echo Patch format detection failed. >expected &&
++ echo "Patch format detection failed." >expected &&
+ test_cmp expected actual
+'
+
+test_expect_success 'invalid when passing the --empty option alone' '
++ test_when_finished "git am --abort || :" &&
+ git checkout empty-commit^ &&
+ test_must_fail git am --empty empty-commit.patch 2>err &&
+ echo "error: Invalid value for --empty: empty-commit.patch" >expected &&
@@ t/t4150-am.sh: test_expect_success 'apply binary blob in partial clone' '
+test_expect_success 'a message without a patch is an error (default)' '
+ test_when_finished "git am --abort || :" &&
+ test_must_fail git am empty-commit.patch >err &&
-+ grep "Patch is empty" err &&
-+ rm -fr .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 &&
-+ rm -fr .git/rebase-apply
++ grep "Patch is empty." err
+'
+
+test_expect_success 'a message without a patch will be skipped when "--empty=drop" is given' '
Signature · 1 line
gitgitgadget
PATCH v8 2/2 am: support --empty=<option> to handle empty patches
From: Aleen <[email protected]>
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').
--- Documentation/git-am.txt | 8 ++++++ builtin/am.c | 55 ++++++++++++++++++++++++++++++++++++---- t/t4150-am.sh | 49 +++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 5 deletions(-)
Documentation/git-am.txt +8 -0
@@ -16,6 +16,7 @@ SYNOPSIS [--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet] [--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>] [--quoted-cr=<action>] + [--empty=(die|drop|keep)] [(<mbox> | <Maildir>)...] 'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)])
@@ -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]),
builtin/am.c +50 -5
105 lines not on this page · raw message
t/t4150-am.sh +49 -0
59 lines not on this page · raw message
Signature · 1 line
gitgitgadget
v9 cover am: support --empty=(die|drop|keep) option to handle empty patches
In reply to Aleen via GitGitGadgetSince 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 <[email protected]>
+Author: Aleen 徐沛文 <[email protected]>
## 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 <[email protected]>
+Author: Aleen 徐沛文 <[email protected]>
## Commit message ##
am: support --empty=<option> to handle empty patches
Signature · 1 line
gitgitgadget
PATCH v9 1/2 doc: git-format-patch: describe the option --always
From: =?UTF-8?q?Aleen=20=E5=BE=90=E6=B2=9B=E6=96=87?= <[email protected]>
This commit has described how to use '--always' option in the command 'git-format-patch' to include patches for commits that emit no changes.
--- Documentation/git-format-patch.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
Documentation/git-format-patch.txt +5 -1
@@ -18,7 +18,7 @@ SYNOPSIS [-n | --numbered | -N | --no-numbered] [--start-number <n>] [--numbered-files] [--in-reply-to=<message id>] [--suffix=.<sfx>] - [--ignore-if-in-upstream] + [--ignore-if-in-upstream] [--always] [--cover-from-description=<mode>] [--rfc] [--subject-prefix=<subject prefix>] [(--reroll-count|-v) <n>]
@@ -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.
Signature · 1 line
gitgitgadget
PATCH v9 2/2 am: support --empty=<option> to handle empty patches
In reply to Aleen via GitGitGadgetFrom: =?UTF-8?q?Aleen=20=E5=BE=90=E6=B2=9B=E6=96=87?= <[email protected]>
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').
--- Documentation/git-am.txt | 8 ++++++ builtin/am.c | 55 ++++++++++++++++++++++++++++++++++++---- t/t4150-am.sh | 49 +++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 5 deletions(-)
Documentation/git-am.txt +8 -0
@@ -16,6 +16,7 @@ SYNOPSIS [--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet] [--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>] [--quoted-cr=<action>] + [--empty=(die|drop|keep)] [(<mbox> | <Maildir>)...] 'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)])
@@ -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]),
builtin/am.c +50 -5
105 lines not on this page · raw message
t/t4150-am.sh +49 -0
59 lines not on this page · raw message
Signature · 1 line
gitgitgadget
Re: [PATCH v9 2/2] am: support --empty=<option> to handle empty patches
Quoted 6 lines
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.
Quoted 1 line
--empty-commit=(die|drop|keep)::
Besides, I have also fixed a missed mistake, which also exists in the seen branch.
Re: [PATCH v8 2/2] am: support --empty=<option> to handle empty patches
In reply to Aleen via GitGitGadgetQuoted 9 lines · Aleen via GitGitGadget
From: Aleen <[email protected]>
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 徐沛文 <[email protected]>
Perhaps this line should imitate what Hans Krentel did in
https://lore.kernel.org/git/[email protected]/,
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 1 line
+--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.
Re: [PATCH v8 2/2] am: support --empty=<option> to handle empty patches
Quoted 10 lines
Perhaps this line should imitate what Hans Krentel did in
https://lore.kernel.org/git/[email protected]/,
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 7 lines
Quoted 1 line
+--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) <[email protected]>".
PATCH v10 1/2 doc: git-format-patch: describe the option --always
In reply to Aleen via GitGitGadgetFrom: Aleen <[email protected]>
This commit has described how to use '--always' option in the command 'git-format-patch' to include patches for commits that emit no changes.
--- Documentation/git-format-patch.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
Documentation/git-format-patch.txt +5 -1
@@ -18,7 +18,7 @@ SYNOPSIS [-n | --numbered | -N | --no-numbered] [--start-number <n>] [--numbered-files] [--in-reply-to=<message id>] [--suffix=.<sfx>] - [--ignore-if-in-upstream] + [--ignore-if-in-upstream] [--always] [--cover-from-description=<mode>] [--rfc] [--subject-prefix=<subject prefix>] [(--reroll-count|-v) <n>]
@@ -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.
Signature · 1 line
gitgitgadget
v10 cover am: support --empty=(die|drop|keep) option to handle empty patches
In reply to Aleen via GitGitGadgetSince 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/[email protected] .
cc: René Scharfe [email protected] cc: Phillip Wood [email protected] cc:
Aleen 徐沛文 [email protected]
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 徐沛文 <[email protected]>
+Author: Aleen <[email protected]>
## 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 徐沛文 <[email protected]>
+ Signed-off-by: 徐沛文 (Aleen) <[email protected]>
## 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 徐沛文 <[email protected]>
+Author: Aleen <[email protected]>
## 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 徐沛文 <[email protected]>
+ Signed-off-by: 徐沛文 (Aleen) <[email protected]>
## Documentation/git-am.txt ##
@@ Documentation/git-am.txt: SYNOPSIS
Signature · 1 line
gitgitgadget
PATCH v10 2/2 am: support --empty=<option> to handle empty patches
From: Aleen <[email protected]>
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').
--- Documentation/git-am.txt | 8 ++++++ builtin/am.c | 55 ++++++++++++++++++++++++++++++++++++---- t/t4150-am.sh | 49 +++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 5 deletions(-)
Documentation/git-am.txt +8 -0
@@ -16,6 +16,7 @@ SYNOPSIS [--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet] [--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>] [--quoted-cr=<action>] + [--empty=(die|drop|keep)] [(<mbox> | <Maildir>)...] 'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)])
@@ -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]),
builtin/am.c +50 -5
105 lines not on this page · raw message
t/t4150-am.sh +49 -0
59 lines not on this page · raw message
Signature · 1 line
gitgitgadget
Re: [PATCH v6 0/3] am: support --empty=(die|drop|keep) option to handle empty patches
In reply to Junio C HamanoHi Junio & Aleen,
Quoted 18 lines · Junio C Hamano
Quoted 11 lines · Aleen 徐沛文
Quoted 10 lines
Yes.
As the URL you were referred to explains, the sign-off procedure is to keep track of provenance of the code, which is a more "legal" formal requirement than just "I use this pseudonym everywhere". When a big company comes to us, claiming that "this code is our intellectual property stolen from us" and pointing at code added by a patch from you, we do not want to see us in the position to have to say "eh, somebody who uses psuedonym X signed DCO, but we do not even know their real name".
Quoted 4 lines
I know it, and as I said before that gitgitgadget need PR creators to sign off user name of GitHub account, according to the DCO check. I can confirmed that "Aleen" and "Aleen 徐沛文" are both the real name of mine, the committer. I can use the account [email protected] to confirm this.
Quoted 6 lines
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.
GitGitGadget looks at the author information, so you need to ensure that the "Author:" line in the output of git log shows the desired name. If it does not, you need to configure user.name (and user.email) as desired, and then re-commit with git commit --amend --reset-author`, then force-push.
Ciao,
Johannes
Re: [PATCH v10 1/2] doc: git-format-patch: describe the option --always
In reply to Aleen via GitGitGadgetHi Aleen,
Quoted 1 line · Aleen via GitGitGadget
From: Aleen <[email protected]>
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
Re: [PATCH v10 1/2] doc: git-format-patch: describe the option --always
Quoted 10 lines
Hi Aleen,
Quoted 1 line · Aleen via GitGitGadget
From: Aleen <[email protected]>
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:
Quoted 7 lines
git config --global user.name "徐沛文 (Aleen)" git rebase -x "git commit --amend --no-edit --reset-author" HEAD~2and then force-push to your branch.
Ciao,
Dscho
The main problem is that it broke when I tried to submit via GGG:
https://github.com/gitgitgadget/git/pull/1076#issuecomment-976087421
Re: [PATCH v10 1/2] doc: git-format-patch: describe the option --always
Hi Aleen,
Quoted 13 lines · Aleen 徐沛文
Quoted 13 lines
Hi Aleen,
Quoted 1 line · Aleen via GitGitGadget
From: Aleen <[email protected]>
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
Quoted 7 lines
Quoted 4 lines
and then force-push to your branch.
Ciao,
DschoThe main problem is that it broke when I tried to submit via GGG:
https://github.com/gitgitgadget/git/pull/1076#issuecomment-976087421
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
v11 cover am: support --empty=(die|drop|keep) option to handle empty patches
In reply to Aleen via GitGitGadgetSince 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/[email protected] .
cc: René Scharfe [email protected] cc: Phillip Wood [email protected] cc:
Aleen 徐沛文 [email protected]
徐沛文 (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 <[email protected]>
+Author: 徐沛文 (Aleen) <[email protected]>
## 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 <[email protected]>
+Author: 徐沛文 (Aleen) <[email protected]>
## Commit message ##
am: support --empty=<option> to handle empty patches
Signature · 1 line
gitgitgadget
PATCH v11 1/2 doc: git-format-patch: describe the option --always
From: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
<[email protected]>
This commit has described how to use '--always' option in the command 'git-format-patch' to include patches for commits that emit no changes.
--- Documentation/git-format-patch.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
Documentation/git-format-patch.txt +5 -1
@@ -18,7 +18,7 @@ SYNOPSIS [-n | --numbered | -N | --no-numbered] [--start-number <n>] [--numbered-files] [--in-reply-to=<message id>] [--suffix=.<sfx>] - [--ignore-if-in-upstream] + [--ignore-if-in-upstream] [--always] [--cover-from-description=<mode>] [--rfc] [--subject-prefix=<subject prefix>] [(--reroll-count|-v) <n>]
@@ -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.
Signature · 1 line
gitgitgadget
PATCH v11 2/2 am: support --empty=<option> to handle empty patches
In reply to Aleen via GitGitGadgetFrom: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
<[email protected]>
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').
--- Documentation/git-am.txt | 8 ++++++ builtin/am.c | 55 ++++++++++++++++++++++++++++++++++++---- t/t4150-am.sh | 49 +++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 5 deletions(-)
Documentation/git-am.txt +8 -0
@@ -16,6 +16,7 @@ SYNOPSIS [--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet] [--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>] [--quoted-cr=<action>] + [--empty=(die|drop|keep)] [(<mbox> | <Maildir>)...] 'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)])
@@ -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]),
builtin/am.c +50 -5
105 lines not on this page · raw message
t/t4150-am.sh +49 -0
59 lines not on this page · raw message
Signature · 1 line
gitgitgadget
Re: [PATCH v11 1/2] doc: git-format-patch: describe the option --always
In reply to 徐沛文 (Aleen) via GitGitGadgetHi,
Quoted 2 lines · 徐沛文 (Aleen) via GitGitGadget
From: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
<[email protected]>
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
Re: [PATCH v11 1/2] doc: git-format-patch: describe the option --always
Quoted 11 lines · Johannes Schindelin
Quoted 2 lines · 徐沛文 (Aleen) via GitGitGadget
From: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
<[email protected]>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.
;-) Thanks for double-checking carefully.
These two are identical to what has been in my tree (as I manually tweaked the patches from the previous rounds).
1: 6112004764 = 1: e9181bd6fd doc: git-format-patch: describe the option --always 2: b26f121395 = 2: ca426b823b am: support --empty=<option> to handle empty patches
I'll pretend that I took v11 but please do not get alarmed if the author and committer times are from v10.
Thanks, both.
Re: [PATCH v11 2/2] am: support --empty=<option> to handle empty patches
In reply to 徐沛文 (Aleen) via GitGitGadgetQuoted 30 lines · 徐沛文 (Aleen) via GitGitGadget
From: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
<[email protected]>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) <[email protected]>--- Documentation/git-am.txt | 8 ++++++ builtin/am.c | 55 ++++++++++++++++++++++++++++++++++++---- t/t4150-am.sh | 49 +++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 5 deletions(-)Documentation/git-am.txt +1
-0@@ -16,6 +16,7 @@ SYNOPSIS [--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet] [--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>] [--quoted-cr=<action>] + [--empty=(die|drop|keep)] [(<mbox> | <Maildir>)...] 'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)])
Documentation/git-am.txt OPTIONS · line 72
Quoted 9 lines
Documentation/git-am.txt +6
-0@@ -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 188 lines
Documentation/git-am.txt +1
-0+ -m:: --message-id:: Pass the `-m` flag to 'git mailinfo' (see linkgit:git-mailinfo[1]),builtin/am.c +50
-5@@ -87,6 +87,12 @@ enum show_patch_type { SHOW_PATCH_DIFF = 1, }; +enum empty_action { +DIE_EMPTY_COMMIT =0 ,/* output errors */ +DROP_EMPTY_COMMIT ,/* skip with a notice message, unless "--quiet" has been passed */ +KEEP_EMPTY_COMMIT /* keep recording as empty commits */ +}; +struct am_state {/* state directory path */ char *dir;@@ -118,6 +124,7 @@ struct am_state {int message_id;int scissors;/* enum scissors_type */ int quoted_cr;/* enum quoted_cr_action */ +int empty_type;/* enum empty_action */ struct strvec git_apply_opts;const char *resolvemsg;int committer_date_is_author_date;@@ -178,6 +185,25 @@ static int am_option_parse_quoted_cr(const struct option *opt,return 0 ; } +static int am_option_parse_empty (const struct option *opt, +const char *arg,int unset) +{ +int *opt_value = opt->value; + +BUG_ON_OPT_NEG (unset); + +if (!strcmp (arg,"die" )) + *opt_value =DIE_EMPTY_COMMIT ; +else if (!strcmp (arg,"drop" )) + *opt_value =DROP_EMPTY_COMMIT ; +else if (!strcmp (arg,"keep" )) + *opt_value =KEEP_EMPTY_COMMIT ; +else +return error (_ ("Invalid value for --empty: %s" ), arg); + +return 0 ; +} +/** * Returns path relative to the am_state directory. */ @@ -1248,11 +1274,6 @@ static int parse_mail(struct am_state *state, const char *mail) goto finish; } -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 );@@ -1763,6 +1784,7 @@ static void am_run(struct am_state *state, int resume)while (state->cur <= state->last) {const char *mail =am_path (state,msgnum (state));int apply_status; +int to_keep;reset_ident_date ();@@ -1792,8 +1814,27 @@ static void am_run(struct am_state *state, int resume)if (state->interactive &&do_interactive (state)) goto next; + to_keep =0 ; +if (is_empty_or_missing_file (am_path (state,"patch" ))) { +switch (state->empty_type) { +case DROP_EMPTY_COMMIT : +say (state, stdout,_ ("Skipping: %.*s" ),linelen (state->msg), state->msg); + goto next; +break ; +case KEEP_EMPTY_COMMIT : + to_keep =1 ; +break ; +case DIE_EMPTY_COMMIT : +printf_ln (_ ("Patch is empty." )); +die_user_resolve (state); +break ; + } + } +if (run_applypatch_msg_hook (state))exit (1 ); +if (to_keep) + goto commit;say (state, stdout,_ ("Applying: %.*s" ),linelen (state->msg), state->msg);@@ -1827,6 +1868,7 @@ static void am_run(struct am_state *state, int resume)die_user_resolve (state); } +commit:do_commit (state); next:@@ -2357,6 +2399,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) "" }, +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 ()t/t4150-am.sh +49
-1@@ -196,6 +196,12 @@ test_expect_success setup ' git format-patch -M --stdout lorem^ >rename-add.patch && + git checkout -b empty-commit && + git commit -m "empty commit" --allow-empty && + + : >empty.patch && + git format-patch --always --stdout empty-commit^ >empty-commit.patch && + # reset time sane_unset test_tick && test_tick@@ -1152,4 +1158,47 @@ test_expect_success 'apply binary blob in partial clone' ' git -C client am ../patch ' +test_expect_success 'an empty input file is error regardless of --empty option' ' + test_when_finished "git am --abort || :" && + test_must_fail git am --empty=drop empty.patch 2>actual && + echo "Patch format detection failed." >expected && + test_cmp expected actual +' + +test_expect_success 'invalid when passing the --empty option alone' ' + test_when_finished "git am --abort || :" && + git checkout empty-commit^ && + test_must_fail git am --empty empty-commit.patch 2>err && + echo "error: Invalid value for --empty: empty-commit.patch" >expected && + test_cmp expected err +' + +test_expect_success 'a message without a patch is an error (default)' ' + test_when_finished "git am --abort || :" && + test_must_fail git am empty-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_fail git am --empty=die empty-commit.patch >err && + grep "Patch is empty." err +' + +test_expect_success 'a message without a patch will be skipped when "--empty=drop" is given' ' + git am --empty=drop empty-commit.patch >output && + git rev-parse empty-commit^ >expected && + git rev-parse HEAD >actual && + test_cmp expected actual && + grep "Skipping: empty commit" output +' + +test_expect_success 'record as an empty commit when meeting e-mail message that lacks a patch' ' + git am --empty=keep empty-commit.patch && + test_path_is_missing .git/rebase-apply && + git show empty-commit --format="%s" >expected && + git show HEAD --format="%s" >actual && + test_cmp actual expected +' + test_done --gitgitgadget
Re: [PATCH v11 2/2] am: support --empty=<option> to handle empty patches
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 53 lines
Documentation/git-am.txt OPTIONS · line 72
Quoted 6 lines
+--empty=(die|drop|keep)::
Documentation/git-am.txt +5
-0+ 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 bygit rebase --empty=askwhen 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"""
Re: Re: [PATCH v11 2/2] am: support --empty=<option> to handle empty patches
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?
Quoted 12 lines
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
Re: [PATCH v11 2/2] am: support --empty=<option> to handle empty patches
In reply to Elijah NewrenQuoted 10 lines · Elijah Newren
Documentation/git-am.txt OPTIONS · line 72
Quoted 6 lines
+--empty=(die|drop|keep)::
Documentation/git-am.txt +5
-0+ 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?
I think it is the same as how "git am" without this sees a piece of e-mail without any patch in it. It exits with non-zero status, but keeps the contents of .git/rebase-apply directory intact so that the user can decide what the next action should be. "the command stops with non-zero status and gives control back to the user" might be a better explanation.
As to the name of the option's value, I think 'die' is a much better word than 'ask' for this behaviour. It is not like we retain control, give "do you want to do X or Y?" prompt and do either X or Y ourselves, which is what I expect out of 'ask'. If we just exit with non-zero value and give the control back to the user, then we are not asking.
This is a tangent, but in the current Documentation/git-am.txt, the phrasing for "--skip" and "--resolved" are a bit inconsistent.
- The "--skip" operation calls the situation it is designed to handle "an aborted patch".
- The "--resolved" operation calls it "a patch failure".
The "--abort" operation interestingly does not use any word to explain the situation it is designed to be used in. It just assumes that the user knows "git am" session is somehow still in effect.
Re: Re: [PATCH v11 2/2] am: support --empty=<option> to handle empty patches
In reply to Aleen 徐沛文Quoted 4 lines · Aleen 徐沛文
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 2 lines
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 12 lines
Quoted 12 lines
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
Re: [PATCH v11 2/2] am: support --empty=<option> to handle empty patches
In reply to Junio C HamanoQuoted 21 lines · Junio C Hamano
Quoted 10 lines · Elijah Newren
Documentation/git-am.txt OPTIONS · line 72
Quoted 6 lines
+--empty=(die|drop|keep)::
Documentation/git-am.txt +5
-0+ 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?
I think it is the same as how "git am" without this sees a piece of e-mail without any patch in it. It exits with non-zero status, but keeps the contents of .git/rebase-apply directory intact so that the user can decide what the next action should be. "the command stops with non-zero status and gives control back to the user" might be a better explanation.
Quoted 6 lines
As to the name of the option's value, I think 'die' is a much better word than 'ask' for this behaviour. It is not like we retain control, give "do you want to do X or Y?" prompt and do either X or Y ourselves, which is what I expect out of 'ask'. If we just exit with non-zero value and give the control back to the user, then we are not asking.
Well, I still think 'die' implies aborting the entire overall am operation, and is thus a confusing term. To me, 'stop' or 'interrupt' would be better if you want a one-word term and don't like 'ask'.
If you don't like the term 'ask' here, perhaps we should also change rebase? rebase --empty has 'ask' as a choice for stopping/interrupting the rebase operation and letting the user decide how to handle it. (There is a very subtly different context for rebase's --empty=ask, namely in that it is only triggered for patches that were not originally empty but become so do the the new base the patches are being applied upon already having the changes from the patch in question, but that doesn't seem like a big enough difference to suggest it should have a different name.)
There's another bit to my query on the semantics, though. The second half of my critique was that the current form of the series does not inform the user how to handle the situation when git-am stops. It only tells the user how to drop the patch. (If there's only one option, why doesn't git just take it automatically?) I think it should also tell the user how to keep the patch. Now, if both options are presented to the user when the operation stops, would that qualify as the user having been 'asked' what to do?
v12 cover am: support --empty=(die|drop|keep) option and --allow-empty option to handle empty patches
In reply to Aleen via GitGitGadgetSince 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/[email protected] .
----------------------------------------------------------------------------
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
Signature · 1 line
gitgitgadget
PATCH v12 1/3 doc: git-format-patch: describe the option --always
From: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
<[email protected]>
This commit has described how to use '--always' option in the command 'git-format-patch' to include patches for commits that emit no changes.
--- Documentation/git-format-patch.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
Documentation/git-format-patch.txt +5 -1
@@ -18,7 +18,7 @@ SYNOPSIS [-n | --numbered | -N | --no-numbered] [--start-number <n>] [--numbered-files] [--in-reply-to=<message id>] [--suffix=.<sfx>] - [--ignore-if-in-upstream] + [--ignore-if-in-upstream] [--always] [--cover-from-description=<mode>] [--rfc] [--subject-prefix=<subject prefix>] [(--reroll-count|-v) <n>]
@@ -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.
Signature · 1 line
gitgitgadget
PATCH v12 2/3 am: support --empty=<option> to handle empty patches
In reply to Aleen via GitGitGadgetFrom: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
<[email protected]>
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').
--- Documentation/git-am.txt | 8 ++++++ builtin/am.c | 55 ++++++++++++++++++++++++++++++++++++---- t/t4150-am.sh | 49 +++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 5 deletions(-)
Documentation/git-am.txt +8 -0
@@ -16,6 +16,7 @@ SYNOPSIS [--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet] [--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>] [--quoted-cr=<action>] + [--empty=(die|drop|keep)] [(<mbox> | <Maildir>)...] 'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)])
@@ -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]),
builtin/am.c +50 -5
105 lines not on this page · raw message
t/t4150-am.sh +49 -0
59 lines not on this page · raw message
Signature · 1 line
gitgitgadget
PATCH v12 3/3 am: support --allow-empty to record specific empty patches
In reply to Aleen via GitGitGadgetFrom: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
<[email protected]>
This option helps to record specific empty patches in the middle of an am session.
--- Documentation/git-am.txt | 6 +++++- builtin/am.c | 24 +++++++++++++++++++----- t/t4150-am.sh | 12 ++++++++++++ t/t7512-status-help.sh | 1 + wt-status.c | 3 +++ 5 files changed, 40 insertions(+), 6 deletions(-)
Documentation/git-am.txt +5 -1
@@ -18,7 +18,7 @@ SYNOPSIS [--quoted-cr=<action>] [--empty=(die|drop|keep)] [(<mbox> | <Maildir>)...] -'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)]) +'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)] | --allow-empty) DESCRIPTION -----------
@@ -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 ----------
builtin/am.c +19 -5
@@ -1825,7 +1825,8 @@ static void am_run(struct am_state *state, int resume) to_keep =1 ;break ;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\"." ));die_user_resolve (state);break ; }
@@ -1898,10 +1899,15 @@ next:/** * Resume the current am session after patch application failure. The user did * 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. */ -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);
@@ -1928,6 +1934,7 @@ static void am_resolve(struct am_state *state)repo_rerere (the_repository,0 ); +commit:do_commit (state); next:
@@ -2237,7 +2244,8 @@ enum resume_type {RESUME_SKIP ,RESUME_ABORT ,RESUME_QUIT , -RESUME_SHOW_PATCH +RESUME_SHOW_PATCH , +RESUME_ALLOW_EMPTY }; struct resume_mode {
@@ -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")),
@@ -2498,7 +2509,10 @@ int cmd_am(int argc, const char **argv, const char *prefix)am_run (&state,1 );break ;case RESUME_RESOLVED : -am_resolve (&state); +am_resolve (&state,0 ); +break ; +case RESUME_ALLOW_EMPTY : +am_resolve (&state,1 );break ;case RESUME_SKIP :am_skip (&state);
t/t4150-am.sh +12 -0
@@ -1201,4 +1201,16 @@ test_expect_success 'record as an empty commit when meeting e-mail message that test_cmp actual expected ' + +test_expect_success 'record 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 && + git am --allow-empty && + git show empty-commit --format="%s" >expected && + git show HEAD --format="%s" >actual && + test_cmp actual expected +' + test_done
t/t7512-status-help.sh +1 -0
@@ -658,6 +658,7 @@ test_expect_success 'status in an am session: empty patch' ' 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 --skip" to skip this patch) (use "git am --abort" to restore the original branch)
wt-status.c +3 -0
@@ -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,
Signature · 1 line
gitgitgadget
Re: [PATCH v12 3/3] am: support --allow-empty to record specific empty patches
In reply to Elijah NewrenI 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.
Quoted 34 lines · Aleen 徐沛文
Quoted 4 lines
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 2 lines
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 12 lines
Quoted 12 lines
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
Re: [PATCH v12 3/3] am: support --allow-empty to record specific empty patches
In reply to 徐沛文 (Aleen) via GitGitGadget""徐沛文 (Aleen)" via GitGitGadget" <[email protected]>
Quoted 44 lines · writes:
From: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
<[email protected]>This option helps to record specific empty patches in the middle of an am session.
Signed-off-by 徐沛文 (Aleen) <[email protected]>--- Documentation/git-am.txt | 6 +++++- builtin/am.c | 24 +++++++++++++++++++----- t/t4150-am.sh | 12 ++++++++++++ t/t7512-status-help.sh | 1 + wt-status.c | 3 +++ 5 files changed, 40 insertions(+), 6 deletions(-)Documentation/git-am.txt +5
-1@@ -18,7 +18,7 @@ SYNOPSIS [--quoted-cr=<action>] [--empty=(die|drop|keep)] [(<mbox> | <Maildir>)...] -'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)]) +'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)] | --allow-empty) DESCRIPTION -----------@@ -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 ----------builtin/am.c +0
-0
builtin/am.c static void am_run(struct am_state *state, int resume) · line 1829
Quoted 6 lines
builtin/am.c +2
-1@@ -1825,7 +1825,8 @@ static void am_run(struct am_state *state, int resume) to_keep =1 ;break ;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\"." ));
An overly deep indentation. Make "If" align with "Patch", probably. Also "to keep recording it" -> "to record it".
"If you want to record the e-mail text as the log message of an empty commit" may be a bit too much, but just saying "record it" may not be clear enough to explain what gets recorded how.
Quoted 4 lines
builtin/am.c +0
-0@@ -1898,10 +1899,15 @@ next:/** * Resume the current am session after patch application failure. The user did * all the hard work, and we do not have to do any patch application. Just
builtin/am.c next: · line 1909
Quoted 10 lines
builtin/am.c +6
-2-* 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. */ -static void am_resolve (struct am_state *state) +static void am_resolve (struct am_state *state,int allow_empty) { +if (allow_empty) { + goto commit; + }
Lose {} around a single statement block.
But more importantly, doesn't this break "git am" when the user gives "--allow-empty" in cases where you are not expecting?
Like when the patch application (with or without -3) fails, either during "git am -i" or "git am" without "-i"?
The parameter claims to be "allow empty", implying that the option is about allowing to end up in an empty commit (and depending on the input, the resulting commit may not be empty and that is OK). But what the code does is to _ignore_ the unmerged check, not recording the manual resolution the user did for later reuse, and force a call to do_commit() fail if the index is still unmerged.
builtin/am.c next: · line 1913
Quoted 3 lines
builtin/am.c +0
-0validate_resume_state (state);say (state, stdout,_ ("Applying: %.*s" ),linelen (state->msg), state->msg);
I suspect that the real code that wants to be changed is below this line, where we say "if the index does not have changes (relative to the HEAD), then complain and die". Perhaps it should become something along this line:
if (!repo_index_has_changes(...)) {
if (allow_empty) {
printf_ln(_("No changes - recording an empty commit.");
} else {
printf_ln(_("No changes - did you forget ..."
"..."));
die_user_resolve(state);
}
}i.e. "when the index does not have changes, tell the user that we'd create an empty commit, if allow-empty is in effect. otherwise, complain and die".
I suspect that the worst failure mode may be "git am" (without -3) first fails to apply a patch (hence the index is unchanged wrt HEAD), then "git am" that is run with "--allow-empty" ignores the failure and creates an empty commit. Even with the "something along this line" change above, such a failure mode still exists. You really need to see if we had an input without any patch and do the skipping only when it is the case, I think.
v13 cover am: support --empty=(die|drop|keep) option and --allow-empty option to handle empty patches
In reply to Aleen via GitGitGadgetSince 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/[email protected] .
----------------------------------------------------------------------------
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,Signature · 1 line
gitgitgadget
PATCH v13 1/3 doc: git-format-patch: describe the option --always
From: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
<[email protected]>
This commit has described how to use '--always' option in the command 'git-format-patch' to include patches for commits that emit no changes.
--- Documentation/git-format-patch.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
Documentation/git-format-patch.txt +5 -1
@@ -18,7 +18,7 @@ SYNOPSIS [-n | --numbered | -N | --no-numbered] [--start-number <n>] [--numbered-files] [--in-reply-to=<message id>] [--suffix=.<sfx>] - [--ignore-if-in-upstream] + [--ignore-if-in-upstream] [--always] [--cover-from-description=<mode>] [--rfc] [--subject-prefix=<subject prefix>] [(--reroll-count|-v) <n>]
@@ -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.
Signature · 1 line
gitgitgadget
PATCH v13 2/3 am: support --empty=<option> to handle empty patches
In reply to Aleen via GitGitGadgetFrom: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
<[email protected]>
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').
--- Documentation/git-am.txt | 8 ++++++ builtin/am.c | 55 ++++++++++++++++++++++++++++++++++++---- t/t4150-am.sh | 49 +++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 5 deletions(-)
Documentation/git-am.txt +8 -0
@@ -16,6 +16,7 @@ SYNOPSIS [--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet] [--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>] [--quoted-cr=<action>] + [--empty=(die|drop|keep)] [(<mbox> | <Maildir>)...] 'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)])
@@ -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]),
builtin/am.c +50 -5
105 lines not on this page · raw message
t/t4150-am.sh +49 -0
59 lines not on this page · raw message
Signature · 1 line
gitgitgadget
PATCH v13 3/3 am: support --allow-empty to record specific empty patches
In reply to Aleen via GitGitGadgetFrom: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
<[email protected]>
This option helps to record specific empty patches in the middle of an am session.
--- Documentation/git-am.txt | 6 +++++- builtin/am.c | 29 ++++++++++++++++++++--------- t/t4150-am.sh | 24 ++++++++++++++++++++++++ t/t7512-status-help.sh | 1 + wt-status.c | 3 +++ 5 files changed, 53 insertions(+), 10 deletions(-)
Documentation/git-am.txt +5 -1
@@ -18,7 +18,7 @@ SYNOPSIS [--quoted-cr=<action>] [--empty=(die|drop|keep)] [(<mbox> | <Maildir>)...] -'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)]) +'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)] | --allow-empty) DESCRIPTION -----------
@@ -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 ----------
builtin/am.c +20 -9
@@ -1825,7 +1825,8 @@ static void am_run(struct am_state *state, int resume) to_keep =1 ;break ;case DIE_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:/** * Resume the current am session after patch application failure. The user did * 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 when there is no changes. */ -static void am_resolve (struct am_state *state) +static void am_resolve (struct am_state *state,int allow_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 ()) {
@@ -2237,7 +2243,8 @@ enum resume_type {RESUME_SKIP ,RESUME_ABORT ,RESUME_QUIT , -RESUME_SHOW_PATCH +RESUME_SHOW_PATCH , +RESUME_ALLOW_EMPTY }; struct resume_mode {
@@ -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")),
@@ -2498,7 +2508,8 @@ int cmd_am(int argc, const char **argv, const char *prefix)am_run (&state,1 );break ;case RESUME_RESOLVED : -am_resolve (&state); +case RESUME_ALLOW_EMPTY : +am_resolve (&state, resume.mode ==RESUME_ALLOW_EMPTY ?1 :0 );break ;case RESUME_SKIP :am_skip (&state);
t/t4150-am.sh +24 -0
@@ -1201,4 +1201,28 @@ test_expect_success 'record as an empty commit when meeting e-mail message that 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 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 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 +' + test_done
t/t7512-status-help.sh +1 -0
@@ -658,6 +658,7 @@ test_expect_success 'status in an am session: empty patch' ' On branch am_empty You are in the middle of an am session. The current patch is empty. + (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 +3 -0
@@ -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,
Signature · 1 line
gitgitgadget
v14 cover am: support --empty=(die|drop|keep) option and --allow-empty option to handle empty patches
In reply to Aleen via GitGitGadgetSince 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/[email protected] .
----------------------------------------------------------------------------
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
Signature · 1 line
gitgitgadget
PATCH v14 1/3 doc: git-format-patch: describe the option --always
From: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
<[email protected]>
This commit has described how to use '--always' option in the command 'git-format-patch' to include patches for commits that emit no changes.
--- Documentation/git-format-patch.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
Documentation/git-format-patch.txt +5 -1
@@ -18,7 +18,7 @@ SYNOPSIS [-n | --numbered | -N | --no-numbered] [--start-number <n>] [--numbered-files] [--in-reply-to=<message id>] [--suffix=.<sfx>] - [--ignore-if-in-upstream] + [--ignore-if-in-upstream] [--always] [--cover-from-description=<mode>] [--rfc] [--subject-prefix=<subject prefix>] [(--reroll-count|-v) <n>]
@@ -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.
Signature · 1 line
gitgitgadget
PATCH v14 2/3 am: support --empty=<option> to handle empty patches
In reply to Aleen via GitGitGadgetFrom: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
<[email protected]>
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').
--- Documentation/git-am.txt | 9 +++++++ builtin/am.c | 55 ++++++++++++++++++++++++++++++++++++---- t/t4150-am.sh | 49 +++++++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+), 5 deletions(-)
Documentation/git-am.txt +9 -0
@@ -16,6 +16,7 @@ SYNOPSIS [--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet] [--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>] [--quoted-cr=<action>] + [--empty=(die|drop|keep)] [(<mbox> | <Maildir>)...] 'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)])
@@ -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]),
builtin/am.c +50 -5
105 lines not on this page · raw message
t/t4150-am.sh +49 -0
59 lines not on this page · raw message
Signature · 1 line
gitgitgadget
PATCH v14 3/3 am: support --allow-empty to record specific empty patches
In reply to Aleen via GitGitGadgetFrom: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
<[email protected]>
This option helps to record specific empty patches in the middle of an am session.
--- Documentation/git-am.txt | 7 ++++++- builtin/am.c | 29 ++++++++++++++++++++--------- t/t4150-am.sh | 24 ++++++++++++++++++++++++ t/t7512-status-help.sh | 1 + wt-status.c | 3 +++ 5 files changed, 54 insertions(+), 10 deletions(-)
Documentation/git-am.txt +6 -1
@@ -18,7 +18,7 @@ SYNOPSIS [--quoted-cr=<action>] [--empty=(die|drop|keep)] [(<mbox> | <Maildir>)...] -'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)]) +'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)] | --allow-empty) DESCRIPTION -----------
@@ -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 ----------
builtin/am.c +20 -9
@@ -1825,7 +1825,8 @@ static void am_run(struct am_state *state, int resume) to_keep =1 ;break ;case DIE_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:/** * Resume the current am session after patch application failure. The user did * 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 when there is no changes. */ -static void am_resolve (struct am_state *state) +static void am_resolve (struct am_state *state,int allow_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 ()) {
@@ -2237,7 +2243,8 @@ enum resume_type {RESUME_SKIP ,RESUME_ABORT ,RESUME_QUIT , -RESUME_SHOW_PATCH +RESUME_SHOW_PATCH , +RESUME_ALLOW_EMPTY }; struct resume_mode {
@@ -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")),
@@ -2498,7 +2508,8 @@ int cmd_am(int argc, const char **argv, const char *prefix)am_run (&state,1 );break ;case RESUME_RESOLVED : -am_resolve (&state); +case RESUME_ALLOW_EMPTY : +am_resolve (&state, resume.mode ==RESUME_ALLOW_EMPTY ?1 :0 );break ;case RESUME_SKIP :am_skip (&state);
t/t4150-am.sh +24 -0
@@ -1201,4 +1201,28 @@ test_expect_success 'record as an empty commit when meeting e-mail message that 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 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 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 +' + test_done
t/t7512-status-help.sh +1 -0
@@ -658,6 +658,7 @@ test_expect_success 'status in an am session: empty patch' ' On branch am_empty You are in the middle of an am session. The current patch is empty. + (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 +3 -0
@@ -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,
Signature · 1 line
gitgitgadget
Re: [PATCH v14 3/3] am: support --allow-empty to record specific empty patches
""徐沛文 (Aleen)" via GitGitGadget" <[email protected]>
Quoted 13 lines · writes:
t/t4150-am.sh +13
-0+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 an empty patch as an empty commit in the middle of an am session' '
t/t4150-am.sh test_expect_success 'record as an empty commit when meeting e-mail message that · line 1226
Quoted 10 lines
t/t4150-am.sh +10
-0+ 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 --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 +'
These two are "positive" tests, i.e. the feature does the right thing when used in the expected situation.
I am worried about the cases where "--allow-empty" is used and creates a commit that is empty, when it is reasonably expected to either create a non-empty commit or still fail the same way to give the user another chance to try.
For example, when "git am -3" fails on such an email message (there are two failure modes: (a) one results in an unmerged index due to merge conflicts, (b) the other results in a clean index due to not finding the blob object recorded as a preimage), what happens when the user runs "git am --allow-empty", after:
(1) doing nothing since the failed "git am -3" application,
(2) resolving the conflicts in working tree, or
(3) resolving the conflicts in working tree and recording the resolution in the index.
There are 6 cases in the above matrix, and "git am --allow-empty" should not create an empty commit in any one of them. In 1a and 1b, "git am --allow-empty" should continue to fail ("git am --skip" would be a way to ignore and proceed). 3a and 3b should record a non-empty commit as the result.
Similarly, when an email message with a patch is given to "git am" and the application fails, and the user runs "git am --allow-empty" without doing anything in the working tree, what happens? It should not happily create an empty commit with only the log message, without the change, but continue to fail. If the user resolves and registers the resolution to the index before "git am --allow-empty", then the command should create a non-empty commit.
Having positive tests are of course important to avoid regression in the future, but negative tests, the new and shiny feature does not misbehave when it shouldn't even kick in, is even more important.
Thanks.
Re: [PATCH v14 2/3] am: support --empty=<option> to handle empty patches
In reply to 徐沛文 (Aleen) via GitGitGadgetHi Aleen,
Documentation/git-am.txt SYNOPSIS · line 19
Quoted 9 lines · 徐沛文 (Aleen) via GitGitGadget
Documentation/git-am.txt +1
-0@@ -16,6 +16,7 @@ SYNOPSIS [--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet] [--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>] [--quoted-cr=<action>] + [--empty=(die|drop|keep)]
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.
Re: [PATCH v14 3/3] am: support --allow-empty to record specific empty patches
In reply to Junio C HamanoDears Hamano,
For those 6 cases, it seems git-am should only work when the am session was stopped in the middle according to an empty patch, but not when the index has not changed. Does that mean we should record a new state for the am state? If that's right, I will try to patch it via version 15, and try to add additional test cases for these 6 situations. I was a little busy those days and sorry for the late answer.
Aleen
Quoted 38 lines
These two are "positive" tests, i.e. the feature does the right thing when used in the expected situation.
I am worried about the cases where "--allow-empty" is used and creates a commit that is empty, when it is reasonably expected to either create a non-empty commit or still fail the same way to give the user another chance to try.
For example, when "git am -3" fails on such an email message (there are two failure modes: (a) one results in an unmerged index due to merge conflicts, (b) the other results in a clean index due to not finding the blob object recorded as a preimage), what happens when the user runs "git am --allow-empty", after:
(1) doing nothing since the failed "git am -3" application,
(2) resolving the conflicts in working tree, or
(3) resolving the conflicts in working tree and recording the resolution in the index.There are 6 cases in the above matrix, and "git am --allow-empty" should not create an empty commit in any one of them. In 1a and 1b, "git am --allow-empty" should continue to fail ("git am --skip" would be a way to ignore and proceed). 3a and 3b should record a non-empty commit as the result.
Similarly, when an email message with a patch is given to "git am" and the application fails, and the user runs "git am --allow-empty" without doing anything in the working tree, what happens? It should not happily create an empty commit with only the log message, without the change, but continue to fail. If the user resolves and registers the resolution to the index before "git am --allow-empty", then the command should create a non-empty commit.
Having positive tests are of course important to avoid regression in the future, but negative tests, the new and shiny feature does not misbehave when it shouldn't even kick in, is even more important.
Thanks.
v15 cover am: support --empty=(die|drop|keep) option and --allow-empty option to handle empty patches
In reply to Aleen via GitGitGadgetSince 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/[email protected] .
----------------------------------------------------------------------------
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) <[email protected]>
@@ 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_doneSignature · 1 line
gitgitgadget
PATCH v15 1/3 doc: git-format-patch: describe the option --always
From: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
<[email protected]>
This commit has described how to use '--always' option in the command 'git-format-patch' to include patches for commits that emit no changes.
--- Documentation/git-format-patch.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
Documentation/git-format-patch.txt +5 -1
@@ -18,7 +18,7 @@ SYNOPSIS [-n | --numbered | -N | --no-numbered] [--start-number <n>] [--numbered-files] [--in-reply-to=<message id>] [--suffix=.<sfx>] - [--ignore-if-in-upstream] + [--ignore-if-in-upstream] [--always] [--cover-from-description=<mode>] [--rfc] [--subject-prefix=<subject prefix>] [(--reroll-count|-v) <n>]
@@ -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.
Signature · 1 line
gitgitgadget
PATCH v15 2/3 am: support --empty=<option> to handle empty patches
In reply to Aleen via GitGitGadgetFrom: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
<[email protected]>
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').
--- Documentation/git-am.txt | 9 ++++++ builtin/am.c | 60 ++++++++++++++++++++++++++++++++++++---- t/t4150-am.sh | 50 +++++++++++++++++++++++++++++++++ 3 files changed, 114 insertions(+), 5 deletions(-)
Documentation/git-am.txt +9 -0
@@ -16,6 +16,7 @@ SYNOPSIS [--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet] [--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>] [--quoted-cr=<action>] + [--empty=(die|drop|keep)] [(<mbox> | <Maildir>)...] 'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)])
@@ -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]),
builtin/am.c +55 -5
110 lines not on this page · raw message
t/t4150-am.sh +50 -0
60 lines not on this page · raw message
Signature · 1 line
gitgitgadget
PATCH v15 3/3 am: support --allow-empty to record specific empty patches
In reply to Aleen via GitGitGadgetFrom: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
<[email protected]>
This option helps to record specific empty patches in the middle of an am session. However, it is a valid resume value only when:
1. index has not changed
2. lacking a branch
--- Documentation/git-am.txt | 7 +++++- builtin/am.c | 42 ++++++++++++++++++++++++------- t/t4150-am.sh | 53 ++++++++++++++++++++++++++++++++++++++++ t/t7512-status-help.sh | 1 + wt-status.c | 3 +++ 5 files changed, 96 insertions(+), 10 deletions(-)
Documentation/git-am.txt +6 -1
@@ -18,7 +18,7 @@ SYNOPSIS [--quoted-cr=<action>] [--empty=(die|drop|keep)] [(<mbox> | <Maildir>)...] -'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)]) +'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)] | --allow-empty) DESCRIPTION -----------
@@ -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 ----------
builtin/am.c +33 -9
81 lines not on this page · raw message
t/t4150-am.sh +53 -0
57 lines not on this page · raw message
t/t7512-status-help.sh +1 -0
@@ -658,6 +658,7 @@ test_expect_success 'status in an am session: empty patch' ' On branch am_empty You are in the middle of an am session. The current patch is empty. + (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 +3 -0
@@ -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,
Signature · 1 line
gitgitgadget
v16 cover am: support --empty=(die|drop|keep) option and --allow-empty option to handle empty patches
In reply to Aleen via GitGitGadgetSince 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/[email protected] .
----------------------------------------------------------------------------
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
----------------------------------------------------------------------------
Changes since v15:
1. rename "die" to "stop".
徐沛文 (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 | 90 +++++++++++++++++++++---- t/t4150-am.sh | 102 +++++++++++++++++++++++++++++ t/t7512-status-help.sh | 1 + wt-status.c | 3 + 6 files changed, 203 insertions(+), 15 deletions(-)
base-commit: abe6bb3905392d5eb6b01fa6e54d7e784e0522aa
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1076%2Faleen42%2Fnext-v16
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1076/aleen42/next-v16
Pull-Request: https://github.com/gitgitgadget/git/pull/1076
Range-diff vs v15:
1: a524ca6adfa = 1: a524ca6adfa doc: git-format-patch: describe the option --always
2: 8ec8e212672 ! 2: b9e03f2342b am: support --empty=<option> to handle empty patches
@@ Commit message
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').
+ valid options ('stop', 'drop' and 'keep').
Signed-off-by: 徐沛文 (Aleen) <[email protected]>
@@ Documentation/git-am.txt: SYNOPSIS
[--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet]
[--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>]
[--quoted-cr=<action>]
-+ [--empty=(die|drop|keep)]
++ [--empty=(stop|drop|keep)]
[(<mbox> | <Maildir>)...]
'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)])
@@ Documentation/git-am.txt: 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.
++--empty=(stop|drop|keep)::
++ By default, or when the option is set to 'stop', 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.
+
@@ builtin/am.c: enum show_patch_type {
};
+enum empty_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 */
++ STOP_ON_EMPTY_COMMIT = 0, /* output errors and stop in the middle of an am session */
++ DROP_EMPTY_COMMIT, /* skip with a notice message, unless "--quiet" has been passed */
++ KEEP_EMPTY_COMMIT /* keep recording as empty commits */
+};
+
struct am_state {
@@ builtin/am.c: static int am_option_parse_quoted_cr(const struct option *opt,
+
+ BUG_ON_OPT_NEG(unset);
+
-+ if (!strcmp(arg, "die"))
-+ *opt_value = DIE_EMPTY_COMMIT;
++ if (!strcmp(arg, "stop"))
++ *opt_value = STOP_ON_EMPTY_COMMIT;
+ else if (!strcmp(arg, "drop"))
+ *opt_value = DROP_EMPTY_COMMIT;
+ else if (!strcmp(arg, "keep"))
@@ builtin/am.c: static void am_run(struct am_state *state, int resume)
+ case KEEP_EMPTY_COMMIT:
+ to_keep = 1;
+ break;
-+ case DIE_EMPTY_COMMIT:
-+ am_destroy(state);
-+ die(_("Patch is empty."));
-+ break;
-+ case ERR_EMPTY_COMMIT:
++ case STOP_ON_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(ERR_EMPTY_COMMIT, "empty", &state.empty_type, "{die,drop,keep}",
++ OPT_CALLBACK_F(STOP_ON_EMPTY_COMMIT, "empty", &state.empty_type, "{stop,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 and stop in the middle of an am session (default)' '
++test_expect_success 'a message without a patch is an error (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 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 is an error where an explicit "--empty=stop" is given' '
++ test_when_finished "git am --abort || :" &&
++ test_must_fail git am --empty=stop empty-commit.patch >err &&
++ grep "Patch is empty." err
+'
+
+test_expect_success 'a message without a patch will be skipped when "--empty=drop" is given' ' 3: d669406a312 ! 3: abcdfa1b375 am: support --allow-empty to record specific empty patches
@@ Commit message
## Documentation/git-am.txt ##
@@ Documentation/git-am.txt: SYNOPSIS
[--quoted-cr=<action>]
- [--empty=(die|drop|keep)]
+ [--empty=(stop|drop|keep)]
[(<mbox> | <Maildir>)...]
-'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)]) +'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)] | --allow-empty)
@@ 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)
- die(_("Patch is empty."));
+ to_keep = 1;
break;
- case ERR_EMPTY_COMMIT:
+ case STOP_ON_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:
* 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 when there is no changes.
++ * is true, commit as an empty commit when index had not changed and lacking a patch.
*/
-static void am_resolve(struct am_state *state)
+static void am_resolve(struct am_state *state, int allow_empty)
@@ builtin/am.c: next:
- 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."));
-+ /**
-+ * "--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."));
Signature · 1 line
gitgitgadget
PATCH v16 1/3 doc: git-format-patch: describe the option --always
From: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
<[email protected]>
This commit has described how to use '--always' option in the command 'git-format-patch' to include patches for commits that emit no changes.
--- Documentation/git-format-patch.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
Documentation/git-format-patch.txt +5 -1
@@ -18,7 +18,7 @@ SYNOPSIS [-n | --numbered | -N | --no-numbered] [--start-number <n>] [--numbered-files] [--in-reply-to=<message id>] [--suffix=.<sfx>] - [--ignore-if-in-upstream] + [--ignore-if-in-upstream] [--always] [--cover-from-description=<mode>] [--rfc] [--subject-prefix=<subject prefix>] [(--reroll-count|-v) <n>]
@@ -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.
Signature · 1 line
gitgitgadget
PATCH v16 2/3 am: support --empty=<option> to handle empty patches
In reply to Aleen via GitGitGadgetFrom: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
<[email protected]>
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 ('stop', 'drop' and 'keep').
--- Documentation/git-am.txt | 9 +++++++ builtin/am.c | 55 ++++++++++++++++++++++++++++++++++++---- t/t4150-am.sh | 49 +++++++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+), 5 deletions(-)
Documentation/git-am.txt +9 -0
@@ -16,6 +16,7 @@ SYNOPSIS [--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet] [--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>] [--quoted-cr=<action>] + [--empty=(stop|drop|keep)] [(<mbox> | <Maildir>)...] 'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)])
@@ -63,6 +64,14 @@ OPTIONS --quoted-cr=<action>:: This flag will be passed down to 'git mailinfo' (see linkgit:git-mailinfo[1]). +--empty=(stop|drop|keep):: + By default, or when the option is set to 'stop', 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]),
builtin/am.c +50 -5
105 lines not on this page · raw message
t/t4150-am.sh +49 -0
59 lines not on this page · raw message
Signature · 1 line
gitgitgadget
PATCH v16 3/3 am: support --allow-empty to record specific empty patches
In reply to Aleen via GitGitGadgetFrom: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
<[email protected]>
This option helps to record specific empty patches in the middle of an am session. However, it is a valid resume value only when:
1. index has not changed
2. lacking a branch
--- Documentation/git-am.txt | 7 +++++- builtin/am.c | 37 +++++++++++++++++++++------- t/t4150-am.sh | 53 ++++++++++++++++++++++++++++++++++++++++ t/t7512-status-help.sh | 1 + wt-status.c | 3 +++ 5 files changed, 91 insertions(+), 10 deletions(-)
Documentation/git-am.txt +6 -1
@@ -18,7 +18,7 @@ SYNOPSIS [--quoted-cr=<action>] [--empty=(stop|drop|keep)] [(<mbox> | <Maildir>)...] -'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)]) +'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)] | --allow-empty) DESCRIPTION -----------
@@ -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 ----------
builtin/am.c +28 -9
@@ -1825,7 +1825,8 @@ static void am_run(struct am_state *state, int resume) to_keep =1 ;break ;case STOP_ON_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,21 +1899,34 @@ next:/** * Resume the current am session after patch application failure. The user did * 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 when index had not changed and lacking a patch. */ -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 )) { -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." )); + 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 { +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 ()) { 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"
@@ -2237,7 +2251,8 @@ enum resume_type {RESUME_SKIP ,RESUME_ABORT ,RESUME_QUIT , -RESUME_SHOW_PATCH +RESUME_SHOW_PATCH , +RESUME_ALLOW_EMPTY }; struct resume_mode {
@@ -2390,6 +2405,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")),
@@ -2498,7 +2516,8 @@ int cmd_am(int argc, const char **argv, const char *prefix)am_run (&state,1 );break ;case RESUME_RESOLVED : -am_resolve (&state); +case RESUME_ALLOW_EMPTY : +am_resolve (&state, resume.mode ==RESUME_ALLOW_EMPTY ?1 :0 );break ;case RESUME_SKIP :am_skip (&state);
t/t4150-am.sh +53 -0
57 lines not on this page · raw message
t/t7512-status-help.sh +1 -0
@@ -658,6 +658,7 @@ test_expect_success 'status in an am session: empty patch' ' On branch am_empty You are in the middle of an am session. The current patch is empty. + (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 +3 -0
@@ -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,
Signature · 1 line
gitgitgadget
v17 cover am: support --empty=(die|drop|keep) option and --allow-empty option to handle empty patches
In reply to Aleen via GitGitGadgetSince 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/[email protected] .
----------------------------------------------------------------------------
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
----------------------------------------------------------------------------
Changes since v15:
1. rename "die" to "stop".
----------------------------------------------------------------------------
Changes since v16:
1. fix typo from "had" to "has" in the comment.
徐沛文 (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 | 90 +++++++++++++++++++++---- t/t4150-am.sh | 102 +++++++++++++++++++++++++++++ t/t7512-status-help.sh | 1 + wt-status.c | 3 + 6 files changed, 203 insertions(+), 15 deletions(-)
base-commit: abe6bb3905392d5eb6b01fa6e54d7e784e0522aa
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1076%2Faleen42%2Fnext-v17
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1076/aleen42/next-v17
Pull-Request: https://github.com/gitgitgadget/git/pull/1076
Range-diff vs v16:
1: a524ca6adfa = 1: a524ca6adfa doc: git-format-patch: describe the option --always 2: b9e03f2342b = 2: b9e03f2342b am: support --empty=<option> to handle empty patches 3: abcdfa1b375 ! 3: ea2dc088b37 am: support --allow-empty to record specific empty patches
@@ 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 when index had not changed and lacking a patch. ++ * is true, commit as an empty commit when index has not changed and lacking a patch.
*/
-static void am_resolve(struct am_state *state)
+static void am_resolve(struct am_state *state, int allow_empty)
Signature · 1 line
gitgitgadget
PATCH v17 1/3 doc: git-format-patch: describe the option --always
From: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
<[email protected]>
This commit has described how to use '--always' option in the command 'git-format-patch' to include patches for commits that emit no changes.
--- Documentation/git-format-patch.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
Documentation/git-format-patch.txt +5 -1
@@ -18,7 +18,7 @@ SYNOPSIS [-n | --numbered | -N | --no-numbered] [--start-number <n>] [--numbered-files] [--in-reply-to=<message id>] [--suffix=.<sfx>] - [--ignore-if-in-upstream] + [--ignore-if-in-upstream] [--always] [--cover-from-description=<mode>] [--rfc] [--subject-prefix=<subject prefix>] [(--reroll-count|-v) <n>]
@@ -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.
Signature · 1 line
gitgitgadget
PATCH v17 2/3 am: support --empty=<option> to handle empty patches
In reply to Aleen via GitGitGadgetFrom: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
<[email protected]>
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 ('stop', 'drop' and 'keep').
--- Documentation/git-am.txt | 9 +++++++ builtin/am.c | 55 ++++++++++++++++++++++++++++++++++++---- t/t4150-am.sh | 49 +++++++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+), 5 deletions(-)
Documentation/git-am.txt +9 -0
@@ -16,6 +16,7 @@ SYNOPSIS [--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet] [--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>] [--quoted-cr=<action>] + [--empty=(stop|drop|keep)] [(<mbox> | <Maildir>)...] 'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)])
@@ -63,6 +64,14 @@ OPTIONS --quoted-cr=<action>:: This flag will be passed down to 'git mailinfo' (see linkgit:git-mailinfo[1]). +--empty=(stop|drop|keep):: + By default, or when the option is set to 'stop', 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]),
builtin/am.c +50 -5
105 lines not on this page · raw message
t/t4150-am.sh +49 -0
59 lines not on this page · raw message
Signature · 1 line
gitgitgadget
PATCH v17 3/3 am: support --allow-empty to record specific empty patches
In reply to Aleen via GitGitGadgetFrom: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
<[email protected]>
This option helps to record specific empty patches in the middle of an am session. However, it is a valid resume value only when:
1. index has not changed
2. lacking a branch
--- Documentation/git-am.txt | 7 +++++- builtin/am.c | 37 +++++++++++++++++++++------- t/t4150-am.sh | 53 ++++++++++++++++++++++++++++++++++++++++ t/t7512-status-help.sh | 1 + wt-status.c | 3 +++ 5 files changed, 91 insertions(+), 10 deletions(-)
Documentation/git-am.txt +6 -1
@@ -18,7 +18,7 @@ SYNOPSIS [--quoted-cr=<action>] [--empty=(stop|drop|keep)] [(<mbox> | <Maildir>)...] -'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)]) +'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)] | --allow-empty) DESCRIPTION -----------
@@ -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 ----------
builtin/am.c +28 -9
@@ -1825,7 +1825,8 @@ static void am_run(struct am_state *state, int resume) to_keep =1 ;break ;case STOP_ON_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,21 +1899,34 @@ next:/** * Resume the current am session after patch application failure. The user did * 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 when index has not changed and lacking a patch. */ -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 )) { -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." )); + 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 { +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 ()) { 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"
@@ -2237,7 +2251,8 @@ enum resume_type {RESUME_SKIP ,RESUME_ABORT ,RESUME_QUIT , -RESUME_SHOW_PATCH +RESUME_SHOW_PATCH , +RESUME_ALLOW_EMPTY }; struct resume_mode {
@@ -2390,6 +2405,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")),
@@ -2498,7 +2516,8 @@ int cmd_am(int argc, const char **argv, const char *prefix)am_run (&state,1 );break ;case RESUME_RESOLVED : -am_resolve (&state); +case RESUME_ALLOW_EMPTY : +am_resolve (&state, resume.mode ==RESUME_ALLOW_EMPTY ?1 :0 );break ;case RESUME_SKIP :am_skip (&state);
t/t4150-am.sh +53 -0
57 lines not on this page · raw message
t/t7512-status-help.sh +1 -0
@@ -658,6 +658,7 @@ test_expect_success 'status in an am session: empty patch' ' On branch am_empty You are in the middle of an am session. The current patch is empty. + (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 +3 -0
@@ -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,
Signature · 1 line
gitgitgadget
Re: [PATCH v17 2/3] am: support --empty=<option> to handle empty patches
In reply to 徐沛文 (Aleen) via GitGitGadget""徐沛文 (Aleen)" via GitGitGadget" <[email protected]> writes:
This step look mostly good and well done, except for just a few things that remain.
builtin/am.c enum show_patch_type { · line 94
Quoted 5 lines
builtin/am.c +5
-0+enum empty_action { +STOP_ON_EMPTY_COMMIT =0 ,/* output errors and stop in the middle of an am session */ +DROP_EMPTY_COMMIT ,/* skip with a notice message, unless "--quiet" has been passed */ +KEEP_EMPTY_COMMIT /* keep recording as empty commits */ +};
It is friendly to future developers to end the last item in enum with a comma, unless the current last item MUST stay to be the last one even when they add new ones. I.e.
KEEP_EMPTY_COMMIT, /* keep recording as empty commits */
builtin/am.c struct am_state { · line 127
Quoted 8 lines
struct
am_state{builtin/am.c +1
-0/* state directory path */ char *dir;@@ -118,6 +124,7 @@ struct am_state {int message_id;int scissors;/* enum scissors_type */ int quoted_cr;/* enum quoted_cr_action */ +int empty_type;/* enum empty_action */
Mental note. After this series graduates to 'master', at some point in the future, we should clean these members up to be of their respective enum types, not "int".
Quoted 11 lines
builtin/am.c +1
-0@@ -1763,6 +1784,7 @@ static void am_run(struct am_state *state, int resume)while (state->cur <= state->last) {const char *mail =am_path (state,msgnum (state));int apply_status; +int to_keep;reset_ident_date ();@@ -1792,8 +1814,27 @@ static void am_run(struct am_state *state, int resume)if (state->interactive &&do_interactive (state)) goto next;
builtin/am.c static void am_run(struct am_state *state, int resume) · line 1825
Quoted 10 lines
builtin/am.c +9
-0+ to_keep =0 ; +if (is_empty_or_missing_file (am_path (state,"patch" ))) { +switch (state->empty_type) { +case DROP_EMPTY_COMMIT : +say (state, stdout,_ ("Skipping: %.*s" ),linelen (state->msg), state->msg); + goto next; +break ; +case KEEP_EMPTY_COMMIT : + to_keep =1 ;
This causes the code that produces the "Applying" message jumped over, so the user will not see anything done for this step.
I think we want to mimic the above case arm and do something like
say(state, stdout, _("Creating an empty commit: %.*s"),
linelen(state->msg), state->msg);to avoid being mum about what was done in this step.
Quoted 19 lines
builtin/am.c +10
-0+break ; +case STOP_ON_EMPTY_COMMIT : +printf_ln (_ ("Patch is empty." )); +die_user_resolve (state); +break ; + } + } +if (run_applypatch_msg_hook (state))exit (1 ); +if (to_keep) + goto commit;say (state, stdout,_ ("Applying: %.*s" ),linelen (state->msg), state->msg);@@ -1827,6 +1868,7 @@ static void am_run(struct am_state *state, int resume)die_user_resolve (state); }
builtin/am.c static void am_run(struct am_state *state, int resume)
Quoted 10 lines
builtin/am.c +6
-0+commit:do_commit (state); next: +test_expect_success 'record as an empty commit when meeting e-mail message that lacks a patch' ' + git am --empty=keep empty-commit.patch && + test_path_is_missing .git/rebase-apply && + git show empty-commit --format="%s" >expected && + git show HEAD --format="%s" >actual &&
For the test data prepared by the earlier part of this patch, this does not make a difference, but by using %B instead of %s, I think you can catch a future bug that only keeps the subject intact while munging the body of the message.
Other than these, looking quite good.
Thanks.
Re: [PATCH v17 3/3] am: support --allow-empty to record specific empty patches
In reply to 徐沛文 (Aleen) via GitGitGadget""徐沛文 (Aleen)" via GitGitGadget" <[email protected]>
Quoted 32 lines · writes:
From: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
<[email protected]>This option helps to record specific empty patches in the middle of an am session. However, it is a valid resume value only when:
1. index has not changed
2. lacking a branchSigned-off-by 徐沛文 (Aleen) <[email protected]>--- Documentation/git-am.txt | 7 +++++- builtin/am.c | 37 +++++++++++++++++++++------- t/t4150-am.sh | 53 ++++++++++++++++++++++++++++++++++++++++ t/t7512-status-help.sh | 1 + wt-status.c | 3 +++ 5 files changed, 91 insertions(+), 10 deletions(-)Documentation/git-am.txt +1
-1@@ -18,7 +18,7 @@ SYNOPSIS [--quoted-cr=<action>] [--empty=(stop|drop|keep)] [(<mbox> | <Maildir>)...] -'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)]) +'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)] | --allow-empty) DESCRIPTION -----------
Documentation/git-am.txt default. You can use `--no-utf8` to override this. · line 206
Quoted 7 lines
Documentation/git-am.txt +4
-0@@ -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.
"The user can still do X" is not technically incorrect, but this is not merely a possiblity but does actively does X, so
After a patch failure on an input e-mail message lacking a patch, create an empty commit with the contents of the e-mail message as its log message.
or something.
builtin/am.c static void am_run(struct am_state *state, int resume) · line 1829
Quoted 11 lines
builtin/am.c +2
-1@@ -1825,7 +1825,8 @@ static void am_run(struct am_state *state, int resume) to_keep =1 ;break ;case STOP_ON_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\"." ));
It would be better to hide the new part of the message behind advice_if_enabled(), and advise "--skip" first before giving "--allow-empty" as another possibility. It is rather a common mistake to grab patches with the cover letter and see "am" die on the cover letter.
If we were to add an advice message there, that is. I am not sure if it is necessary, especially since we give them in "git status".
Quoted 13 lines
builtin/am.c +5
-2@@ -1898,21 +1899,34 @@ next:/** * Resume the current am session after patch application failure. The user did * 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 when index has not changed and lacking a patch. */ -static void am_resolve (struct am_state *state) +static void am_resolve (struct am_state *state,int allow_empty) { +int index_changed; +
builtin/am.c next: · line 1914
Quoted 10 lines
builtin/am.c +2
-4validate_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." )); + index_changed =repo_index_has_changes (the_repository,NULL ,NULL ); +if (allow_empty && (index_changed || !is_empty_or_missing_file (am_path (state,"patch" )))) {
Overlong line.
builtin/am.c next: · line 1915
Quoted 1 line
builtin/am.c +1
-0+printf_ln (_ ("Invalid resume value." ));
It is unclear to the user what "resume value" means. I am guessing that this is saying that the user gave us the "--allow-empty" option, but it is an inappropriate option for the situation. So
"--allow-empty is not appropriate in this situation"
would be a slight improvement, but it is not clear what makes it inappropriate, iow, what the situation is, to the users.
Stepping back a bit, if we disect that overlong condition:
if (allow_empty &&
(index_changed || !is_empty_or_missing_file(am_path(state, "patch")))) {it seems to be computing something not quite right. What we want with "allow" empty is (1) if we have recorded changes to the index, that is perfectly fine. We'll create a non-empty commit, and (2) if we do not have any change in the index because the input did not have a patch, it is OK to create an empty commit out of the current index. But the condition is there only to complain about "--allow-empty" given when either (1) we have changes, or (2) when the input had a patch. These are conditions that we can internally ignore allow_empty settings and let the existing code handle the message as before this patch.
builtin/am.c next: · line 1916
Quoted 1 line
builtin/am.c +0
-0die_user_resolve (state);
And I do not see how "when you have resolved with this problem, do one of these things" message would help in this situation. Perhaps we can get rid of the above block. We still need to compute index_changed, and make "no changes--we will die" conditional.
builtin/am.c next: · line 1921
Quoted 3 lines
builtin/am.c +3
-0+if (!index_changed) { +if (allow_empty) +printf_ln (_ ("No changes - record it as an empty commit." ));
A command to the user to "record it as an empty commit" is not what we want to give. Perhaps "recorded it as ..." would work better as a report of what we did for the user.
Also style:
if (allow_empty) {
printf_ln(...);
} else {
... original multi-statement block come here ...
}That is, when one arm of if/else if/.../else cascade needs {}, put {} to all of them.
I think there is a logic error here once we remove the way too aggressive "you may not say --allow-empty when there is a patch" check we saw earlier.
When we see no changes added to the index and "--allow-empty" given, we shouldn't be blindly creating an empty commit without checking if we didn't have any patch. If the last failure that gave the control back from "am" to the user was a patch that did not apply, we do not want to create an empty commit, do we? So something like
if (!repo_index_has_changes(the_repository, NULL, NULL)) {
if (allow_empty &&
is_empty_or_missing_file(am_path(state, "patch"))) {
printf_ln(_("No changes - recorded an empty commit."));
} else {
... original block ...perhaps?
Quoted 9 lines
builtin/am.c +7
-0+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); + } + }
builtin/am.c enum resume_type { · line 2255
Quoted 6 lines
builtin/am.c +2
-1@@ -2237,7 +2251,8 @@ enum resume_type {RESUME_SKIP ,RESUME_ABORT ,RESUME_QUIT , -RESUME_SHOW_PATCH +RESUME_SHOW_PATCH , +RESUME_ALLOW_EMPTY
Advice on the trailing comma applies here equally.
t/t7512-status-help.sh test_expect_success 'status in an am session: empty patch' ' · line 663
Quoted 13 lines
builtin/am.c +0
-0};t/t7512-status-help.sh +1
-0@@ -658,6 +658,7 @@ test_expect_success 'status in an am session: empty patch' ' On branch am_empty You are in the middle of an am session. The current patch is empty. + (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)
You do not want to add the new one the first. "--skip" should come first, and perhaps this new one, and "--abort" at the end.
The general rule of thumb is to give common ones early before the less common ones and ones, and give ones with more severe consequence the last.
Quoted 14 lines
wt-status.c +3
-0@@ -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,
Re: [PATCH v17 0/3] am: support --empty=(die|drop|keep) option and --allow-empty option to handle empty patches
In reply to Aleen via GitGitGadgetQuoted 7 lines · Aleen via GitGitGadget
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 v16:1. fix typo from "had" to "has" in the comment.
I read the patches in full again and saw some issues that want to be fixed, but overall it was a pleasant read.
Thanks.
v18 cover am: support --empty=(die|drop|keep) option and --allow-empty option to handle empty patches
In reply to Aleen via GitGitGadgetSince 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/[email protected] .
----------------------------------------------------------------------------
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
----------------------------------------------------------------------------
Changes since v15:
1. rename "die" to "stop".
----------------------------------------------------------------------------
Changes since v16:
1. fix the typo from "had" to "has" in the comment.
----------------------------------------------------------------------------
Changes since v17:
1. add trailing comma, show tips of creating an empty commit, and use "%B" to construct test cases.
2. remove the error "Invalid resume value.".
3. hint "--allow-empty" after "--skip".
徐沛文 (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 | 96 ++++++++++++++++++++++---- t/t4150-am.sh | 104 +++++++++++++++++++++++++++++ t/t7512-status-help.sh | 1 + wt-status.c | 8 ++- 6 files changed, 215 insertions(+), 16 deletions(-)
base-commit: abe6bb3905392d5eb6b01fa6e54d7e784e0522aa
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1076%2Faleen42%2Fnext-v18
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1076/aleen42/next-v18
Pull-Request: https://github.com/gitgitgadget/git/pull/1076
Range-diff vs v17:
1: a524ca6adfa = 1: a524ca6adfa doc: git-format-patch: describe the option --always
2: b9e03f2342b ! 2: 56953d416d9 am: support --empty=<option> to handle empty patches
@@ builtin/am.c: enum show_patch_type {
+enum empty_action {
+ STOP_ON_EMPTY_COMMIT = 0, /* output errors and stop in the middle of an am session */
+ DROP_EMPTY_COMMIT, /* skip with a notice message, unless "--quiet" has been passed */
-+ KEEP_EMPTY_COMMIT /* keep recording as empty commits */
++ KEEP_EMPTY_COMMIT, /* keep recording as empty commits */
+};
+
struct am_state {
@@ builtin/am.c: static void am_run(struct am_state *state, int resume)
+ break;
+ case KEEP_EMPTY_COMMIT:
+ to_keep = 1;
++ say(state, stdout, _("Creating an empty commit: %.*s"),
++ linelen(state->msg), state->msg);
+ break;
+ case STOP_ON_EMPTY_COMMIT:
+ printf_ln(_("Patch is empty."));
@@ t/t4150-am.sh: test_expect_success 'apply binary blob in partial clone' '
+'
+
+test_expect_success 'record as an empty commit when meeting e-mail message that lacks a patch' '
-+ git am --empty=keep empty-commit.patch &&
++ git am --empty=keep empty-commit.patch >output &&
+ test_path_is_missing .git/rebase-apply &&
-+ git show empty-commit --format="%s" >expected &&
-+ git show HEAD --format="%s" >actual &&
-+ test_cmp actual expected
++ git show empty-commit --format="%B" >expected &&
++ git show HEAD --format="%B" >actual &&
++ grep -f actual expected &&
++ grep "Creating an empty commit: empty commit" output
+'
+
test_done
3: ea2dc088b37 ! 3: 4c3077f9384 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. However, it is a valid resume value only when:
+ of an am session, which does create empty commits only when:
1. index has not changed
2. lacking a branch
@@ Documentation/git-am.txt: default. You can use `--no-utf8` to override this.
+--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.
++ create an empty commit with the contents of the e-mail message
++ as its log message.
+
DISCUSSION
----------
## builtin/am.c ##
-@@ builtin/am.c: static void am_run(struct am_state *state, int resume)
- to_keep = 1;
- break;
- case STOP_ON_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;
- }
+@@ builtin/am.c: static void NORETURN die_user_resolve(const struct am_state *state)
+
+ printf_ln(_("When you have resolved this problem, run \"%s --continue\"."), cmdline);
+ printf_ln(_("If you prefer to skip this patch, run \"%s --skip\" instead."), cmdline);
++
++ if (advice_enabled(ADVICE_AM_WORK_DIR) &&
++ is_empty_or_missing_file(am_path(state, "patch")) &&
++ !repo_index_has_changes(the_repository, NULL, NULL))
++ printf_ln(_("To record the empty patch as an empty commit, run \"%s --allow-empty\"."), cmdline);
++
+ printf_ln(_("To restore the original branch and stop patching, run \"%s --abort\"."), cmdline);
+ }
+
@@ builtin/am.c: next:
/**
* Resume the current am session after patch application failure. The user did
@@ builtin/am.c: next:
- "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."));
+ 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."));
++ if (allow_empty &&
++ !(!index_changed && is_empty_or_missing_file(am_path(state, "patch"))))
die_user_resolve(state);
- }
-
++
+ if (!index_changed) {
-+ if (allow_empty)
-+ printf_ln(_("No changes - record it as an empty commit."));
-+ else {
++ if (allow_empty) {
++ printf_ln(_("No changes - recorded 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()) {
- 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,
RESUME_QUIT,
- RESUME_SHOW_PATCH
+ RESUME_SHOW_PATCH,
-+ RESUME_ALLOW_EMPTY
++ RESUME_ALLOW_EMPTY,
};
struct resume_mode {
@@ builtin/am.c: int cmd_am(int argc, const char **argv, const char *prefix)
## t/t4150-am.sh ##
@@ t/t4150-am.sh: test_expect_success 'record as an empty commit when meeting e-mail message that
- test_cmp actual expected
+ grep "Creating an empty commit: empty commit" output
'
+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 &&
++ grep "To record the empty patch 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 &&
@@ t/t4150-am.sh: test_expect_success 'record as an empty commit when meeting e-mai
+ 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 --allow-empty &&
++ grep "To record the empty patch as an empty commit, run \"git am --allow-empty\"." err &&
++ git am --allow-empty >output &&
++ grep "No changes - recorded it as an empty commit." output &&
+ test_path_is_missing .git/rebase-apply &&
-+ git show empty-commit --format="%s" >expected &&
-+ git show HEAD --format="%s" >actual &&
-+ test_cmp actual expected
++ git show empty-commit --format="%B" >expected &&
++ git show HEAD --format="%B" >actual &&
++ grep -f actual expected
+'
+
+test_expect_success 'cannot create empty commits when the index is changed' '
@@ t/t4150-am.sh: test_expect_success 'record as an empty commit when meeting e-mai
+ : >empty-file &&
+ git add empty-file &&
+ test_must_fail git am --allow-empty >err &&
-+ grep "Invalid resume value." err
++ ! grep "To record the empty patch as an empty commit, run \"git am --allow-empty\"." err
+'
+
+test_expect_success 'cannot create empty commits when there is a clean index due to merge conflicts' '
@@ t/t4150-am.sh: test_expect_success 'record as an empty commit when meeting e-mai
+ 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 &&
++ ! grep "To record the empty patch as an empty commit, run \"git am --allow-empty\"." err &&
+ git rev-parse HEAD >actual &&
+ test_cmp actual expected
+'
@@ t/t4150-am.sh: test_expect_success 'record as an empty commit when meeting e-mai
+ 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 &&
++ ! grep "To record the empty patch as an empty commit, run \"git am --allow-empty\"." err &&
+ git rev-parse HEAD >actual &&
+ test_cmp actual expected
+'
@@ t/t4150-am.sh: test_expect_success 'record as an empty commit when meeting e-mai
test_done
## t/t7512-status-help.sh ##
-@@ t/t7512-status-help.sh: test_expect_success 'status in an am session: empty patch' '
- On branch am_empty
+@@ t/t7512-status-help.sh: On branch am_empty
You are in the middle of an am session.
The current patch is empty.
-+ (use "git am --allow-empty" to record this patch as an empty commit)
(use "git am --skip" to skip this patch)
++ (use "git am --allow-empty" to record this patch as an empty commit)
(use "git am --abort" to restore the original branch)
+ nothing to commit (use -u to show untracked files)
## wt-status.c ##
-@@ wt-status.c: static void show_am_in_progress(struct wt_status *s,
- if (!s->state.am_empty_patch)
+@@ wt-status.c: static void show_merge_in_progress(struct wt_status *s,
+ static void show_am_in_progress(struct wt_status *s,
+ const char *color)
+ {
++ int am_empty_patch;
++
+ status_printf_ln(s, color,
+ _("You are in the middle of an am session."));
+ if (s->state.am_empty_patch)
+ status_printf_ln(s, color,
+ _("The current patch is empty."));
+ if (s->hints) {
+- if (!s->state.am_empty_patch)
++ am_empty_patch = s->state.am_empty_patch;
++ if (!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)"));
++ if (am_empty_patch)
++ 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 --abort\" to restore the original branch)"));
+ }Signature · 1 line
gitgitgadget
PATCH v18 1/3 doc: git-format-patch: describe the option --always
From: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
<[email protected]>
This commit has described how to use '--always' option in the command 'git-format-patch' to include patches for commits that emit no changes.
--- Documentation/git-format-patch.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
Documentation/git-format-patch.txt +5 -1
@@ -18,7 +18,7 @@ SYNOPSIS [-n | --numbered | -N | --no-numbered] [--start-number <n>] [--numbered-files] [--in-reply-to=<message id>] [--suffix=.<sfx>] - [--ignore-if-in-upstream] + [--ignore-if-in-upstream] [--always] [--cover-from-description=<mode>] [--rfc] [--subject-prefix=<subject prefix>] [(--reroll-count|-v) <n>]
@@ -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.
Signature · 1 line
gitgitgadget
PATCH v18 2/3 am: support --empty=<option> to handle empty patches
In reply to Aleen via GitGitGadgetFrom: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
<[email protected]>
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 ('stop', 'drop' and 'keep').
--- Documentation/git-am.txt | 9 +++++++ builtin/am.c | 57 ++++++++++++++++++++++++++++++++++++---- t/t4150-am.sh | 50 +++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+), 5 deletions(-)
Documentation/git-am.txt +9 -0
@@ -16,6 +16,7 @@ SYNOPSIS [--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet] [--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>] [--quoted-cr=<action>] + [--empty=(stop|drop|keep)] [(<mbox> | <Maildir>)...] 'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)])
@@ -63,6 +64,14 @@ OPTIONS --quoted-cr=<action>:: This flag will be passed down to 'git mailinfo' (see linkgit:git-mailinfo[1]). +--empty=(stop|drop|keep):: + By default, or when the option is set to 'stop', 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]),
builtin/am.c +52 -5
107 lines not on this page · raw message
t/t4150-am.sh +50 -0
60 lines not on this page · raw message
Signature · 1 line
gitgitgadget
PATCH v18 3/3 am: support --allow-empty to record specific empty patches
In reply to Aleen via GitGitGadgetFrom: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
<[email protected]>
This option helps to record specific empty patches in the middle of an am session, which does create empty commits only when:
1. index has not changed
2. lacking a branch
--- Documentation/git-am.txt | 7 +++++- builtin/am.c | 39 +++++++++++++++++++++++------ t/t4150-am.sh | 54 ++++++++++++++++++++++++++++++++++++++++ t/t7512-status-help.sh | 1 + wt-status.c | 8 +++++- 5 files changed, 99 insertions(+), 10 deletions(-)
Documentation/git-am.txt +6 -1
@@ -18,7 +18,7 @@ SYNOPSIS [--quoted-cr=<action>] [--empty=(stop|drop|keep)] [(<mbox> | <Maildir>)...] -'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)]) +'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)] | --allow-empty) DESCRIPTION -----------
@@ -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, + create an empty commit with the contents of the e-mail message + as its log message. + DISCUSSION ----------
builtin/am.c +31 -8
@@ -1152,6 +1152,12 @@ static void NORETURN die_user_resolve(const struct am_state *state)printf_ln (_ ("When you have resolved this problem, run \"%s --continue\"." ), cmdline);printf_ln (_ ("If you prefer to skip this patch, run \"%s --skip\" instead." ), cmdline); + +if (advice_enabled (ADVICE_AM_WORK_DIR ) && +is_empty_or_missing_file (am_path (state,"patch" )) && + !repo_index_has_changes (the_repository,NULL ,NULL )) +printf_ln (_ ("To record the empty patch as an empty commit, run \"%s --allow-empty\"." ), cmdline); +printf_ln (_ ("To restore the original branch and stop patching, run \"%s --abort\"." ), cmdline); }
@@ -1900,19 +1906,31 @@ next:/** * Resume the current am session after patch application failure. The user did * 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 when index has not changed and lacking a patch. */ -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 )) { -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." )); + index_changed =repo_index_has_changes (the_repository,NULL ,NULL ); +if (allow_empty && + !(!index_changed &&is_empty_or_missing_file (am_path (state,"patch" ))))die_user_resolve (state); + +if (!index_changed) { +if (allow_empty) { +printf_ln (_ ("No changes - recorded 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 ()) {
@@ -2239,7 +2257,8 @@ enum resume_type {RESUME_SKIP ,RESUME_ABORT ,RESUME_QUIT , -RESUME_SHOW_PATCH +RESUME_SHOW_PATCH , + RESUME_ALLOW_EMPTY, }; struct resume_mode {
@@ -2392,6 +2411,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")),
@@ -2500,7 +2522,8 @@ int cmd_am(int argc, const char **argv, const char *prefix)am_run (&state,1 );break ;case RESUME_RESOLVED : -am_resolve (&state); +case RESUME_ALLOW_EMPTY : +am_resolve (&state, resume.mode ==RESUME_ALLOW_EMPTY ?1 :0 );break ;case RESUME_SKIP :am_skip (&state);
t/t4150-am.sh +54 -0
58 lines not on this page · raw message
t/t7512-status-help.sh +1 -0
@@ -659,6 +659,7 @@ On branch am_empty You are in the middle of an am session. The current patch is empty. (use "git am --skip" to skip this patch) + (use "git am --allow-empty" to record this patch as an empty commit) (use "git am --abort" to restore the original branch) nothing to commit (use -u to show untracked files)
wt-status.c +7 -1
@@ -1218,17 +1218,23 @@ static void show_merge_in_progress(struct wt_status *s,static void show_am_in_progress (struct wt_status *s,const char *color) { +int am_empty_patch; +status_printf_ln (s, color,_ ("You are in the middle of an am session." ));if (s->state.am_empty_patch)status_printf_ln (s, color,_ ("The current patch is empty." ));if (s->hints) { -if (!s->state.am_empty_patch) + am_empty_patch = s->state.am_empty_patch; +if (!am_empty_patch)status_printf_ln (s, color,_ (" (fix conflicts and then run \"git am --continue\")" ));status_printf_ln (s, color,_ (" (use \"git am --skip\" to skip this patch)" )); +if (am_empty_patch) +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 --abort\" to restore the original branch)" )); }
Signature · 1 line
gitgitgadget
Re: [PATCH v18 3/3] am: support --allow-empty to record specific empty patches
""徐沛文 (Aleen)" via GitGitGadget" <[email protected]>
builtin/am.c static void NORETURN die_user_resolve(const struct am_state *state) · line 1160
Quoted 10 lines · writes:
builtin/am.c +6
-0@@ -1152,6 +1152,12 @@ static void NORETURN die_user_resolve(const struct am_state *state)printf_ln (_ ("When you have resolved this problem, run \"%s --continue\"." ), cmdline);printf_ln (_ ("If you prefer to skip this patch, run \"%s --skip\" instead." ), cmdline); + +if (advice_enabled (ADVICE_AM_WORK_DIR ) && +is_empty_or_missing_file (am_path (state,"patch" )) && + !repo_index_has_changes (the_repository,NULL ,NULL )) +printf_ln (_ ("To record the empty patch as an empty commit, run \"%s --allow-empty\"." ), cmdline); +
OK, so the idea is when we give back control to the user, if the reason we stopped is because we did not have a usable patch in the message and we didn't have any change to the index, we can offer "--allow-empty" as an extra choice.
I guess that makes sense.
Quoted 17 lines
builtin/am.c +5
-2@@ -1900,19 +1906,31 @@ next:/** * Resume the current am session after patch application failure. The user did * 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 when index has not changed and lacking a patch. */ -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);
builtin/am.c next: · line 1925
Quoted 10 lines
builtin/am.c +3
-4-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." )); + index_changed =repo_index_has_changes (the_repository,NULL ,NULL ); +if (allow_empty && + !(!index_changed &&is_empty_or_missing_file (am_path (state,"patch" ))))die_user_resolve (state);
Why do we need this?
Intuitively, because "--allow-XYZ" is "we normally die when the condition XYZ holds, but with the option, we do not die in such a case", any new condition that leads to "die" that only kicks in when "--allow-XYZ" is given smell like a BUG.
The condition reads:
unless we saw an empty patch (i.e. "patch" file is missing or empty, and did not result in any change to the index), it is an error to give "--allow-empty" to the command.
That somehow does not make any sense to me. Whether failed patch application and manual tweaking resulted in the same tree as HEAD, or a tree different from HEAD, if the user wants to say "I allow Git to create an empty commit as necessary, instead of stopping", shouldn't the user be allowed to? After all, the option is not "create nothing but an empty commit, it is an error if there is something to commit." It merely allows creation of an empty one.
This series has been trying to add code to punish users who give "--allow-empty" when the command would have worked the same way without it at least since the last round, and I am not sure where that wish to stop users comes from. Please explain. I am starting to think I may be missing something and this extra rigidity may be helping a user (but again, I do not see how).
builtin/am.c next: · line 1926
Quoted 2 lines
builtin/am.c +2
-0+if (!index_changed) { +if (allow_empty) {
The index_changed variable being false is "the result is an empty change", and is-empty-or-missing on "patch" file is "the input is an empty change". Ideally we would want to create an empty commit only when both input and result are empty, but in order to prevent mistakes, we may want to react to the case where the result is empty but the input is not empty.
Here is where we can use is-empty-or-missing on "patch" and give a different message (i.e. "even though the patch file is not empty, the result of your patch application did not change anything"), if we wanted to. Or you could choose to reject such an attempt, which might be simpler. I.e.
if (allow_empty &&
is_empty_or_missing_file(am_path(state, "patch"))
"No changes - recorded an empty commit."
else
... the original error for no changes ...
Hmm?
Re: [PATCH v18 3/3] am: support --allow-empty to record specific empty patches
Quoted 27 lines
builtin/am.c next: · line 1923
Quoted 5 lines
builtin/am.c +3
-0+ index_changed =repo_index_has_changes (the_repository,NULL ,NULL ); +if (allow_empty && + !(!index_changed &&is_empty_or_missing_file (am_path (state,"patch" ))))die_user_resolve (state);Why do we need this?
Intuitively, because "--allow-XYZ" is "we normally die when the condition XYZ holds, but with the option, we do not die in such a case", any new condition that leads to "die" that only kicks in when "--allow-XYZ" is given smell like a BUG.
The condition reads:
unless we saw an empty patch (i.e. "patch" file is missing or empty, and did not result in any change to the index), it is an error to give "--allow-empty" to the command.
That somehow does not make any sense to me. Whether failed patch application and manual tweaking resulted in the same tree as HEAD, or a tree different from HEAD, if the user wants to say "I allow Git to create an empty commit as necessary, instead of stopping", shouldn't the user be allowed to? After all, the option is not "create nothing but an empty commit, it is an error if there is something to commit." It merely allows creation of an empty one.
Quoted 6 lines
This series has been trying to add code to punish users who give "--allow-empty" when the command would have worked the same way without it at least since the last round, and I am not sure where that wish to stop users comes from. Please explain. I am starting to think I may be missing something and this extra rigidity may be helping a user (but again, I do not see how).
If there is no such code to check, the user can use "--allow-empty" to do the same thing as "--continue" or "--resolved" after resolving conflicts because they all go into am_resolve(). In my opinion, "--allow-empty" only makes sense to allow the user to create empty commits when:
1. the result is an empty change (!index_changed)
2. the input is an empty change (is_empty_or_missing_file(am_path(state, "patch")))
Quoted 16 lines
builtin/am.c next: · line 1926
Quoted 2 lines
builtin/am.c +2
-0+if (!index_changed) { +if (allow_empty) {The
index_changedvariable being false is "the result is an empty change", and is-empty-or-missing on "patch" file is "the input is an empty change". Ideally we would want to create an empty commit only when both input and result are empty, but in order to prevent mistakes, we may want to react to the case where the result is empty but the input is not empty.Here is where we can use is-empty-or-missing on "patch" and give a different message (i.e. "even though the patch file is not empty, the result of your patch application did not change anything"), if we wanted to. Or you could choose to reject such an attempt, which might be simpler. I.e.
Quoted 8 lines
if (
allow_empty&&
is_empty_or_missing_file(am_path(state, "patch"))
"No changes - recorded an empty commit."
else
... the original error for no changes ...Hmm?
Based on the previous checking, there is no need to check is_empty_or_missing_file(am_path(state, "patch")) here because it is permanently true.
Re: [PATCH v18 3/3] am: support --allow-empty to record specific empty patches
Quoted 11 lines · Aleen 徐沛文
Quoted 6 lines
This series has been trying to add code to punish users who give "--allow-empty" when the command would have worked the same way without it at least since the last round, and I am not sure where that wish to stop users comes from. Please explain. I am starting to think I may be missing something and this extra rigidity may be helping a user (but again, I do not see how).
If there is no such code to check, the user can use "--allow-empty" to do the same thing as "--continue" or "--resolved" after resolving conflicts because they all go into
am_resolve().
Yes, exactly. That is the point of "allow"; we continue normally, and even in a narrow situation (i.e. input is empty, and no change is made to the index) where we normally stop, we allow it to continue by creating an empty commit.
Quoted 5 lines
In my opinion, "--allow-empty" only makes sense
to allow the user to create empty commits when:1. the result is an empty change (
!index_changed)
2. the input is an empty change (is_empty_or_missing_file(am_path(state, "patch")))
Then you are forcing the user to use it ONLY whe nhe input is empty and no other time. Whatever that is, that is not "allow" empty.
Quoted 13 lines
Quoted 13 lines
Here is where we can use is-empty-or-missing on "patch" and give a different message (i.e. "even though the patch file is not empty, the result of your patch application did not change anything"), if we wanted to. Or you could choose to reject such an attempt, which might be simpler. I.e.
if (
allow_empty&&
is_empty_or_missing_file(am_path(state, "patch"))
"No changes - recorded an empty commit."
else
... the original error for no changes ...
Quoted 4 lines
Quoted 1 line
Hmm?
Based on the previous checking, there is no need to check
is_empty_or_missing_file(am_path(state, "patch"))here because it is permanently true.
I think you misunderstood.
If we correct the overly strict check that makes "--allow-empty" to mean "only create empty, anything else is an error", the "is patch an empty file?" must be checked here.
v19 cover am: support --empty=(die|drop|keep) option and --allow-empty option to handle empty patches
In reply to Aleen via GitGitGadgetSince 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/[email protected] .
----------------------------------------------------------------------------
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
----------------------------------------------------------------------------
Changes since v15:
1. rename "die" to "stop".
----------------------------------------------------------------------------
Changes since v16:
1. fix the typo from "had" to "has" in the comment.
----------------------------------------------------------------------------
Changes since v17:
1. add trailing comma, show tips of creating an empty commit, and use "%B" to construct test cases.
2. remove the error "Invalid resume value.".
3. hint "--allow-empty" after "--skip".
----------------------------------------------------------------------------
Changes since v18:
1. remove strict checking of "--allow-empty".
徐沛文 (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 | 89 ++++++++++++++++++++---- t/t4150-am.sh | 107 +++++++++++++++++++++++++++++ t/t7512-status-help.sh | 1 + wt-status.c | 8 ++- 6 files changed, 211 insertions(+), 16 deletions(-)
base-commit: abe6bb3905392d5eb6b01fa6e54d7e784e0522aa
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1076%2Faleen42%2Fnext-v19
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1076/aleen42/next-v19
Pull-Request: https://github.com/gitgitgadget/git/pull/1076
Range-diff vs v18:
1: a524ca6adfa = 1: a524ca6adfa doc: git-format-patch: describe the option --always
2: 56953d416d9 = 2: 56953d416d9 am: support --empty=<option> to handle empty patches
3: 4c3077f9384 ! 3: 37875e8d313 am: support --allow-empty to record specific empty patches
@@ Commit message
This option helps to record specific empty patches in the middle
of an am session, which does create empty commits only when:
- 1. index has not changed
+ 1. the index has not changed
2. lacking a branch
+ When the index has changed, "--allow-empty" will create a non-empty
+ commit like passing "--continue" or "--resolved".
+
Signed-off-by: 徐沛文 (Aleen) <[email protected]>
## Documentation/git-am.txt ##
@@ 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."));
-+ index_changed = repo_index_has_changes(the_repository, NULL, NULL);
-+ if (allow_empty &&
-+ !(!index_changed && is_empty_or_missing_file(am_path(state, "patch"))))
- die_user_resolve(state);
-+
-+ if (!index_changed) {
-+ if (allow_empty) {
+- die_user_resolve(state);
++ if (allow_empty && is_empty_or_missing_file(am_path(state, "patch"))) {
+ printf_ln(_("No changes - recorded it as an empty commit."));
+ } else {
+ printf_ln(_("No changes - did you forget to use 'git add'?\n"
@@ t/t4150-am.sh: test_expect_success 'record as an empty commit when meeting e-mai
+ grep -f actual expected
+'
+
-+test_expect_success 'cannot create empty commits when the index is changed' '
++test_expect_success 'create an non-empty commit when the index IS changed though "--allow-empty" is given' '
+ 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 "To record the empty patch as an empty commit, run \"git am --allow-empty\"." err
++ git am --allow-empty &&
++ git show empty-commit --format="%B" >expected &&
++ git show HEAD --format="%B" >actual &&
++ grep -f actual expected &&
++ git diff HEAD^..HEAD --name-only
+'
+
+test_expect_success 'cannot create empty commits when there is a clean index due to merge conflicts' 'Signature · 1 line
gitgitgadget
PATCH v19 1/3 doc: git-format-patch: describe the option --always
From: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
<[email protected]>
This commit has described how to use '--always' option in the command 'git-format-patch' to include patches for commits that emit no changes.
--- Documentation/git-format-patch.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
Documentation/git-format-patch.txt +5 -1
@@ -18,7 +18,7 @@ SYNOPSIS [-n | --numbered | -N | --no-numbered] [--start-number <n>] [--numbered-files] [--in-reply-to=<message id>] [--suffix=.<sfx>] - [--ignore-if-in-upstream] + [--ignore-if-in-upstream] [--always] [--cover-from-description=<mode>] [--rfc] [--subject-prefix=<subject prefix>] [(--reroll-count|-v) <n>]
@@ -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.
Signature · 1 line
gitgitgadget
PATCH v19 2/3 am: support --empty=<option> to handle empty patches
In reply to Aleen via GitGitGadgetFrom: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
<[email protected]>
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 ('stop', 'drop' and 'keep').
--- Documentation/git-am.txt | 9 +++++++ builtin/am.c | 57 ++++++++++++++++++++++++++++++++++++---- t/t4150-am.sh | 50 +++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+), 5 deletions(-)
Documentation/git-am.txt +9 -0
@@ -16,6 +16,7 @@ SYNOPSIS [--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet] [--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>] [--quoted-cr=<action>] + [--empty=(stop|drop|keep)] [(<mbox> | <Maildir>)...] 'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)])
@@ -63,6 +64,14 @@ OPTIONS --quoted-cr=<action>:: This flag will be passed down to 'git mailinfo' (see linkgit:git-mailinfo[1]). +--empty=(stop|drop|keep):: + By default, or when the option is set to 'stop', 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]),
builtin/am.c +52 -5
107 lines not on this page · raw message
t/t4150-am.sh +50 -0
60 lines not on this page · raw message
Signature · 1 line
gitgitgadget
PATCH v19 3/3 am: support --allow-empty to record specific empty patches
In reply to Aleen via GitGitGadgetFrom: =?UTF-8?q?=E5=BE=90=E6=B2=9B=E6=96=87=20=28Aleen=29?=
<[email protected]>
This option helps to record specific empty patches in the middle of an am session, which does create empty commits only when:
1. the index has not changed
2. lacking a branch
When the index has changed, "--allow-empty" will create a non-empty commit like passing "--continue" or "--resolved".
--- Documentation/git-am.txt | 7 ++++- builtin/am.c | 32 ++++++++++++++++------ t/t4150-am.sh | 57 ++++++++++++++++++++++++++++++++++++++++ t/t7512-status-help.sh | 1 + wt-status.c | 8 +++++- 5 files changed, 95 insertions(+), 10 deletions(-)
Documentation/git-am.txt +6 -1
@@ -18,7 +18,7 @@ SYNOPSIS [--quoted-cr=<action>] [--empty=(stop|drop|keep)] [(<mbox> | <Maildir>)...] -'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)]) +'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)] | --allow-empty) DESCRIPTION -----------
@@ -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, + create an empty commit with the contents of the e-mail message + as its log message. + DISCUSSION ----------
builtin/am.c +24 -8
@@ -1152,6 +1152,12 @@ static void NORETURN die_user_resolve(const struct am_state *state)printf_ln (_ ("When you have resolved this problem, run \"%s --continue\"." ), cmdline);printf_ln (_ ("If you prefer to skip this patch, run \"%s --skip\" instead." ), cmdline); + +if (advice_enabled (ADVICE_AM_WORK_DIR ) && +is_empty_or_missing_file (am_path (state,"patch" )) && + !repo_index_has_changes (the_repository,NULL ,NULL )) +printf_ln (_ ("To record the empty patch as an empty commit, run \"%s --allow-empty\"." ), cmdline); +printf_ln (_ ("To restore the original branch and stop patching, run \"%s --abort\"." ), cmdline); }
@@ -1900,19 +1906,24 @@ next:/** * Resume the current am session after patch application failure. The user did * 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 when index has not changed and lacking a patch. */ -static void am_resolve (struct am_state *state) +static void am_resolve (struct am_state *state,int allow_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 &&is_empty_or_missing_file (am_path (state,"patch" ))) { +printf_ln (_ ("No changes - recorded 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 ()) {
@@ -2239,7 +2250,8 @@ enum resume_type {RESUME_SKIP ,RESUME_ABORT ,RESUME_QUIT , -RESUME_SHOW_PATCH +RESUME_SHOW_PATCH , + RESUME_ALLOW_EMPTY, }; struct resume_mode {
@@ -2392,6 +2404,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")),
@@ -2500,7 +2515,8 @@ int cmd_am(int argc, const char **argv, const char *prefix)am_run (&state,1 );break ;case RESUME_RESOLVED : -am_resolve (&state); +case RESUME_ALLOW_EMPTY : +am_resolve (&state, resume.mode ==RESUME_ALLOW_EMPTY ?1 :0 );break ;case RESUME_SKIP :am_skip (&state);
t/t4150-am.sh +57 -0
61 lines not on this page · raw message
t/t7512-status-help.sh +1 -0
@@ -659,6 +659,7 @@ On branch am_empty You are in the middle of an am session. The current patch is empty. (use "git am --skip" to skip this patch) + (use "git am --allow-empty" to record this patch as an empty commit) (use "git am --abort" to restore the original branch) nothing to commit (use -u to show untracked files)
wt-status.c +7 -1
@@ -1218,17 +1218,23 @@ static void show_merge_in_progress(struct wt_status *s,static void show_am_in_progress (struct wt_status *s,const char *color) { +int am_empty_patch; +status_printf_ln (s, color,_ ("You are in the middle of an am session." ));if (s->state.am_empty_patch)status_printf_ln (s, color,_ ("The current patch is empty." ));if (s->hints) { -if (!s->state.am_empty_patch) + am_empty_patch = s->state.am_empty_patch; +if (!am_empty_patch)status_printf_ln (s, color,_ (" (fix conflicts and then run \"git am --continue\")" ));status_printf_ln (s, color,_ (" (use \"git am --skip\" to skip this patch)" )); +if (am_empty_patch) +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 --abort\" to restore the original branch)" )); }
Signature · 1 line
gitgitgadget
Re: [PATCH v19 1/3] doc: git-format-patch: describe the option --always
In reply to 徐沛文 (Aleen) via GitGitGadgetReview
Quoted 4 lines · 徐沛文 (Aleen) via GitGitGadget
+--always::
(quoted diff) +3
-0+ Include patches for commits that do not introduce any change, + which are omitted by default. +
What about this wording below?
Documentation/git-format-patch.txt +2 -2
@@ -193,8 +193,8 @@ will want to ensure that threading is disabled for `git send-email`. ignored. --always:: - Include patches for commits that do not introduce any change, - which are omitted by default. + Always generate patches, even if there are empty-change commits. + Default is to omit such commits. --cover-from-description=<mode>:: Controls which parts of the cover letter will be automatically
Signature · 1 line
An old man doll... just what I always wanted! - Clara
Re: [PATCH v19 1/3] doc: git-format-patch: describe the option --always
Quoted 21 lines
What about this wording below?
Documentation/git-format-patch.txt +2
-2@@ -193,8 +193,8 @@ will want to ensure that threading is disabled for `git send-email`. ignored. --always:: - Include patches for commits that do not introduce any change, - which are omitted by default. + Always generate patches, even if there are empty-change commits. + Default is to omit such commits. --cover-from-description=<mode>:: Controls which parts of the cover letter will be automaticallySignature · 2 lines
-- An old man doll... just what I always wanted! - Clara
Dears Sanjaya,
Thanks for your suggestion. I don't see the actual difference between the two sentences, and do you want to enhance the word "always"? If you do, how about just describing the option as "Always include patches..."?
Aleen
Re: [PATCH v19 1/3] doc: git-format-patch: describe the option --always
Quoted 8 lines · Aleen 徐沛文
Dears Sanjaya,
Thanks for your suggestion. I don't see the actual difference between the two sentences, and do you want to enhance the word "always"? If you do, how about just describing the option as "Always include patches..."?
Aleen
Semantically speaking, I choose "generate" because git format-patch **generates** patches from the specified commits.
Signature · 1 line
An old man doll... just what I always wanted! - Clara
Re: [PATCH v19 1/3] doc: git-format-patch: describe the option --always
Quoted 11 lines · Bagas Sanjaya
Quoted 7 lines · Aleen 徐沛文
Dears Sanjaya,
Thanks for your suggestion. I don't see the actual difference
between
the two sentences, and do you want to enhance the word "always"? If you do, how about just describing the option as "Always include patches..."?
AleenSemantically speaking, I choose "generate" because git format-patch **generates** patches from the specified commits.
But the given commit is empty and does not result in a patch at all, which is the whole point of having this option, no? A typical format-patch output message consists of the message part and the patch part, and calling an output created for an empty commit a "patch" leads to confusion, I am afraid.
So, between the two sentences, I do not see much difference either way.