am: support --patch-format=mboxrd
Combined with "git format-patch --pretty=mboxrd", this should allow us to round-trip commit messages with embedded mbox "From " lines without corruption. Signed-off-by: Eric Wong <e@80x24.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Eric Wong committed
Jun 5, 2016 at 04:46 UTC
d9925d1a714a440f4063f64e1bd776194d2dd918
3 files changed
+33
-4
Documentation/git-am.txt
+2
-1
@@ -116,7 +116,8 @@ default. You can use `--no-utf8` to override this.
116
By default the command will try to detect the patch format
117
automatically. This option allows the user to bypass the automatic
118
detection and specify the patch format that the patch(es) should be
119
- interpreted as. Valid formats are mbox, stgit, stgit-series and hg.
119
+ interpreted as. Valid formats are mbox, mboxrd,
120
+ stgit, stgit-series and hg.
121
122
-i::
123
--interactive::
builtin/am.c
+11
-3
@@ -70,7 +70,8 @@ enum patch_format {
70
PATCH_FORMAT_MBOX,
71
PATCH_FORMAT_STGIT,
72
PATCH_FORMAT_STGIT_SERIES,
73
- PATCH_FORMAT_HG
73
+ PATCH_FORMAT_HG,
74
+ PATCH_FORMAT_MBOXRD
75
};
76
77
enum keep_type {
@@ -712,7 +713,8 @@ done:
713
* Splits out individual email patches from `paths`, where each path is either
714
* a mbox file or a Maildir. Returns 0 on success, -1 on failure.
715
*/
715
-static int split_mail_mbox(struct am_state *state, const char **paths, int keep_cr)
716
+static int split_mail_mbox(struct am_state *state, const char **paths,
717
+ int keep_cr, int mboxrd)
718
{
719
struct child_process cp = CHILD_PROCESS_INIT;
720
struct strbuf last = STRBUF_INIT;
@@ -724,6 +726,8 @@ static int split_mail_mbox(struct am_state *state, const char **paths, int keep_
726
argv_array_push(&cp.args, "-b");
727
if (keep_cr)
728
argv_array_push(&cp.args, "--keep-cr");
729
+ if (mboxrd)
730
+ argv_array_push(&cp.args, "--mboxrd");
731
argv_array_push(&cp.args, "--");
732
argv_array_pushv(&cp.args, paths);
733
@@ -965,13 +969,15 @@ static int split_mail(struct am_state *state, enum patch_format patch_format,
969
970
switch (patch_format) {
971
case PATCH_FORMAT_MBOX:
968
- return split_mail_mbox(state, paths, keep_cr);
972
+ return split_mail_mbox(state, paths, keep_cr, 0);
973
case PATCH_FORMAT_STGIT:
974
return split_mail_conv(stgit_patch_to_mail, state, paths, keep_cr);
975
case PATCH_FORMAT_STGIT_SERIES:
976
return split_mail_stgit_series(state, paths, keep_cr);
977
case PATCH_FORMAT_HG:
978
return split_mail_conv(hg_patch_to_mail, state, paths, keep_cr);
979
+ case PATCH_FORMAT_MBOXRD:
980
+ return split_mail_mbox(state, paths, keep_cr, 1);
981
default:
982
die("BUG: invalid patch_format");
983
}
@@ -2201,6 +2207,8 @@ static int parse_opt_patchformat(const struct option *opt, const char *arg, int
2207
*opt_value = PATCH_FORMAT_STGIT_SERIES;
2208
else if (!strcmp(arg, "hg"))
2209
*opt_value = PATCH_FORMAT_HG;
2210
+ else if (!strcmp(arg, "mboxrd"))
2211
+ *opt_value = PATCH_FORMAT_MBOXRD;
2212
else
2213
return error(_("Invalid value for --patch-format: %s"), arg);
2214
return 0;
t/t4150-am.sh
+20
@@ -957,4 +957,24 @@ test_expect_success 'am -s unexpected trailer block' '
957
test_cmp expect actual
958
'
959
960
+test_expect_success 'am --patch-format=mboxrd handles mboxrd' '
961
+ rm -fr .git/rebase-apply &&
962
+ git checkout -f first &&
963
+ echo mboxrd >>file &&
964
+ git add file &&
965
+ cat >msg <<-\INPUT_END &&
966
+ mboxrd should escape the body
967
+
968
+ From could trip up a loose mbox parser
969
+ >From extra escape for reversibility
970
+ INPUT_END
971
+ git commit -F msg &&
972
+ git format-patch --pretty=mboxrd --stdout -1 >mboxrd1 &&
973
+ grep "^>From could trip up a loose mbox parser" mboxrd1 &&
974
+ git checkout -f first &&
975
+ git am --patch-format=mboxrd mboxrd1 &&
976
+ git cat-file commit HEAD | tail -n4 >out &&
977
+ test_cmp msg out
978
+'
979
+
980
test_done