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>
This commit is contained in:
Eric Wong 2016-06-05 04:46:41 +00:00 committed by Junio C Hamano
parent c88098d7f1
commit d9925d1a71
3 changed files with 33 additions and 4 deletions

View file

@ -116,7 +116,8 @@ default. You can use `--no-utf8` to override this.
By default the command will try to detect the patch format
automatically. This option allows the user to bypass the automatic
detection and specify the patch format that the patch(es) should be
interpreted as. Valid formats are mbox, stgit, stgit-series and hg.
interpreted as. Valid formats are mbox, mboxrd,
stgit, stgit-series and hg.
-i::
--interactive::

View file

@ -70,7 +70,8 @@ enum patch_format {
PATCH_FORMAT_MBOX,
PATCH_FORMAT_STGIT,
PATCH_FORMAT_STGIT_SERIES,
PATCH_FORMAT_HG
PATCH_FORMAT_HG,
PATCH_FORMAT_MBOXRD
};
enum keep_type {
@ -712,7 +713,8 @@ static int detect_patch_format(const char **paths)
* Splits out individual email patches from `paths`, where each path is either
* a mbox file or a Maildir. Returns 0 on success, -1 on failure.
*/
static int split_mail_mbox(struct am_state *state, const char **paths, int keep_cr)
static int split_mail_mbox(struct am_state *state, const char **paths,
int keep_cr, int mboxrd)
{
struct child_process cp = CHILD_PROCESS_INIT;
struct strbuf last = STRBUF_INIT;
@ -724,6 +726,8 @@ static int split_mail_mbox(struct am_state *state, const char **paths, int keep_
argv_array_push(&cp.args, "-b");
if (keep_cr)
argv_array_push(&cp.args, "--keep-cr");
if (mboxrd)
argv_array_push(&cp.args, "--mboxrd");
argv_array_push(&cp.args, "--");
argv_array_pushv(&cp.args, paths);
@ -965,13 +969,15 @@ static int split_mail(struct am_state *state, enum patch_format patch_format,
switch (patch_format) {
case PATCH_FORMAT_MBOX:
return split_mail_mbox(state, paths, keep_cr);
return split_mail_mbox(state, paths, keep_cr, 0);
case PATCH_FORMAT_STGIT:
return split_mail_conv(stgit_patch_to_mail, state, paths, keep_cr);
case PATCH_FORMAT_STGIT_SERIES:
return split_mail_stgit_series(state, paths, keep_cr);
case PATCH_FORMAT_HG:
return split_mail_conv(hg_patch_to_mail, state, paths, keep_cr);
case PATCH_FORMAT_MBOXRD:
return split_mail_mbox(state, paths, keep_cr, 1);
default:
die("BUG: invalid patch_format");
}
@ -2201,6 +2207,8 @@ static int parse_opt_patchformat(const struct option *opt, const char *arg, int
*opt_value = PATCH_FORMAT_STGIT_SERIES;
else if (!strcmp(arg, "hg"))
*opt_value = PATCH_FORMAT_HG;
else if (!strcmp(arg, "mboxrd"))
*opt_value = PATCH_FORMAT_MBOXRD;
else
return error(_("Invalid value for --patch-format: %s"), arg);
return 0;

View file

@ -957,4 +957,24 @@ test_expect_success 'am -s unexpected trailer block' '
test_cmp expect actual
'
test_expect_success 'am --patch-format=mboxrd handles mboxrd' '
rm -fr .git/rebase-apply &&
git checkout -f first &&
echo mboxrd >>file &&
git add file &&
cat >msg <<-\INPUT_END &&
mboxrd should escape the body
From could trip up a loose mbox parser
>From extra escape for reversibility
INPUT_END
git commit -F msg &&
git format-patch --pretty=mboxrd --stdout -1 >mboxrd1 &&
grep "^>From could trip up a loose mbox parser" mboxrd1 &&
git checkout -f first &&
git am --patch-format=mboxrd mboxrd1 &&
git cat-file commit HEAD | tail -n4 >out &&
test_cmp msg out
'
test_done