Skip to content

Commit f3b4822

Browse files
bonzinigitster
authored andcommitted
am: support --show-current-patch=raw as a synonym for--show-current-patch
When "git am --show-current-patch" was added in commit 984913a ("am: add --show-current-patch", 2018-02-12), "git am" started recommending it as a replacement for .git/rebase-merge/patch. Unfortunately the suggestion is somewhat misguided; for example, the output "git am --show-current-patch" cannot be passed to "git apply" if it is encoded as quoted-printable or base64. To simplify worktree operations and to avoid that users poke into .git, it would be better if "git am" also provided a mode that copies .git/rebase-merge/patch to stdout. One possibility could be to have completely separate options, introducing for example --show-current-message (for .git/rebase-apply/NNNN) and --show-current-diff (for .git/rebase-apply/patch), while possibly deprecating --show-current-patch. That would even remove the need for the first two patches in the series. However, the long common prefix would have prevented using an abbreviated option such as "--show". Therefore, I chose instead to add a string argument to --show-current-patch. The new argument is optional, so that "git am --show-current-patch"'s behavior remains backwards-compatible. The next choice to make is how to handle multiple --show-current-patch options. Right now, something like "git am --abort --show-current-patch" is rejected, and the previous suggestion would likewise have naturally rejected a command line like git am --show-current-message --show-current-diff Therefore, I decided to also reject for example git am --show-current-patch=diff --show-current-patch=raw In other words the whole of --show-current-patch=xxx (including the optional argument) is treated as the command mode. I found this to be more consistent and intuitive, even though it differs from the usual "last one wins" semantics of the git command line. Add the code to parse submodes based on the above design, where for now "raw" is the only valid submode. "raw" prints the full e-mail message just like "git am --show-current-patch". Signed-off-by: Paolo Bonzini <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent e8ef1e8 commit f3b4822

File tree

4 files changed

+73
-10
lines changed

4 files changed

+73
-10
lines changed

Documentation/git-am.txt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ SYNOPSIS
1616
[--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet]
1717
[--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>]
1818
[(<mbox> | <Maildir>)...]
19-
'git am' (--continue | --skip | --abort | --quit | --show-current-patch)
19+
'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=raw])
2020

2121
DESCRIPTION
2222
-----------
@@ -176,9 +176,10 @@ default. You can use `--no-utf8` to override this.
176176
Abort the patching operation but keep HEAD and the index
177177
untouched.
178178

179-
--show-current-patch::
180-
Show the entire e-mail message "git am" has stopped at, because
181-
of conflicts.
179+
--show-current-patch[=raw]::
180+
Show the raw contents of the e-mail message at which `git am`
181+
has stopped due to conflicts. The argument must be omitted or
182+
`raw`.
182183

183184
DISCUSSION
184185
----------

builtin/am.c

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ enum signoff_type {
8181
SIGNOFF_EXPLICIT /* --signoff was set on the command-line */
8282
};
8383

84+
enum show_patch_type {
85+
SHOW_PATCH_RAW = 0,
86+
};
87+
8488
struct am_state {
8589
/* state directory path */
8690
char *dir;
@@ -2061,7 +2065,7 @@ static void am_abort(struct am_state *state)
20612065
am_destroy(state);
20622066
}
20632067

2064-
static int show_patch(struct am_state *state)
2068+
static int show_patch(struct am_state *state, enum show_patch_type sub_mode)
20652069
{
20662070
struct strbuf sb = STRBUF_INIT;
20672071
const char *patch_path;
@@ -2078,7 +2082,14 @@ static int show_patch(struct am_state *state)
20782082
return ret;
20792083
}
20802084

2081-
patch_path = am_path(state, msgnum(state));
2085+
switch (sub_mode) {
2086+
case SHOW_PATCH_RAW:
2087+
patch_path = am_path(state, msgnum(state));
2088+
break;
2089+
default:
2090+
BUG("invalid mode for --show-current-patch");
2091+
}
2092+
20822093
len = strbuf_read_file(&sb, patch_path, 0);
20832094
if (len < 0)
20842095
die_errno(_("failed to read '%s'"), patch_path);
@@ -2130,8 +2141,42 @@ enum resume_type {
21302141

21312142
struct resume_mode {
21322143
enum resume_type mode;
2144+
enum show_patch_type sub_mode;
21332145
};
21342146

2147+
static int parse_opt_show_current_patch(const struct option *opt, const char *arg, int unset)
2148+
{
2149+
int *opt_value = opt->value;
2150+
struct resume_mode *resume = container_of(opt_value, struct resume_mode, mode);
2151+
2152+
/*
2153+
* Please update $__git_showcurrentpatch in git-completion.bash
2154+
* when you add new options
2155+
*/
2156+
const char *valid_modes[] = {
2157+
[SHOW_PATCH_RAW] = "raw"
2158+
};
2159+
int new_value = SHOW_PATCH_RAW;
2160+
2161+
if (arg) {
2162+
for (new_value = 0; new_value < ARRAY_SIZE(valid_modes); new_value++) {
2163+
if (!strcmp(arg, valid_modes[new_value]))
2164+
break;
2165+
}
2166+
if (new_value >= ARRAY_SIZE(valid_modes))
2167+
return error(_("Invalid value for --show-current-patch: %s"), arg);
2168+
}
2169+
2170+
if (resume->mode == RESUME_SHOW_PATCH && new_value != resume->sub_mode)
2171+
return error(_("--show-current-patch=%s is incompatible with "
2172+
"--show-current-patch=%s"),
2173+
arg, valid_modes[resume->sub_mode]);
2174+
2175+
resume->mode = RESUME_SHOW_PATCH;
2176+
resume->sub_mode = new_value;
2177+
return 0;
2178+
}
2179+
21352180
static int git_am_config(const char *k, const char *v, void *cb)
21362181
{
21372182
int status;
@@ -2233,9 +2278,11 @@ int cmd_am(int argc, const char **argv, const char *prefix)
22332278
OPT_CMDMODE(0, "quit", &resume.mode,
22342279
N_("abort the patching operation but keep HEAD where it is."),
22352280
RESUME_QUIT),
2236-
OPT_CMDMODE(0, "show-current-patch", &resume.mode,
2237-
N_("show the patch being applied."),
2238-
RESUME_SHOW_PATCH),
2281+
{ OPTION_CALLBACK, 0, "show-current-patch", &resume.mode,
2282+
"raw",
2283+
N_("show the patch being applied"),
2284+
PARSE_OPT_CMDMODE | PARSE_OPT_OPTARG | PARSE_OPT_NONEG | PARSE_OPT_LITERAL_ARGHELP,
2285+
parse_opt_show_current_patch, RESUME_SHOW_PATCH },
22392286
OPT_BOOL(0, "committer-date-is-author-date",
22402287
&state.committer_date_is_author_date,
22412288
N_("lie about committer date")),
@@ -2354,7 +2401,7 @@ int cmd_am(int argc, const char **argv, const char *prefix)
23542401
am_destroy(&state);
23552402
break;
23562403
case RESUME_SHOW_PATCH:
2357-
ret = show_patch(&state);
2404+
ret = show_patch(&state, resume.sub_mode);
23582405
break;
23592406
default:
23602407
BUG("invalid resume value");

contrib/completion/git-completion.bash

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,6 +1180,7 @@ __git_count_arguments ()
11801180

11811181
__git_whitespacelist="nowarn warn error error-all fix"
11821182
__git_patchformat="mbox stgit stgit-series hg mboxrd"
1183+
__git_showcurrentpatch="raw"
11831184
__git_am_inprogress_options="--skip --continue --resolved --abort --quit --show-current-patch"
11841185

11851186
_git_am ()
@@ -1198,6 +1199,10 @@ _git_am ()
11981199
__gitcomp "$__git_patchformat" "" "${cur##--patch-format=}"
11991200
return
12001201
;;
1202+
--show-current-patch=*)
1203+
__gitcomp "$__git_showcurrentpatch" "" "${cur##--show-current-patch=}"
1204+
return
1205+
;;
12011206
--*)
12021207
__gitcomp_builtin am "" \
12031208
"$__git_am_inprogress_options"

t/t4150-am.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,16 @@ test_expect_success 'am --show-current-patch' '
666666
test_cmp .git/rebase-apply/0001 actual.patch
667667
'
668668

669+
test_expect_success 'am --show-current-patch=raw' '
670+
git am --show-current-patch=raw >actual.patch &&
671+
test_cmp .git/rebase-apply/0001 actual.patch
672+
'
673+
674+
test_expect_success 'am accepts repeated --show-current-patch' '
675+
git am --show-current-patch --show-current-patch=raw >actual.patch &&
676+
test_cmp .git/rebase-apply/0001 actual.patch
677+
'
678+
669679
test_expect_success 'am --skip works' '
670680
echo goodbye >expected &&
671681
git am --skip &&

0 commit comments

Comments
 (0)