about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2016-05-30 22:42:42 +0000
committerEric Wong <e@80x24.org>2016-06-05 04:16:57 +0000
commit1ab223c4f7b8d6cc246f873795d89ac97da84ae1 (patch)
tree9fa4ce3c6e7ece9ce5212e7e62820be0eb35973b
parentdad99ea996744f7e02c0eeb1044b9771abe26fa0 (diff)
downloadgit-svn-mboxrd-v2.tar.gz
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>
-rw-r--r--Documentation/git-am.txt3
-rw-r--r--builtin/am.c14
-rwxr-xr-xt/t4150-am.sh20
3 files changed, 33 insertions, 4 deletions
diff --git a/Documentation/git-am.txt b/Documentation/git-am.txt
index 13cdd7f3b6..6348c29fea 100644
--- a/Documentation/git-am.txt
+++ b/Documentation/git-am.txt
@@ -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::
diff --git a/builtin/am.c b/builtin/am.c
index 3dfe70b7a0..d5da5fe090 100644
--- a/builtin/am.c
+++ b/builtin/am.c
@@ -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 @@ done:
  * 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;
diff --git a/t/t4150-am.sh b/t/t4150-am.sh
index b41bd17264..9ce9424d15 100755
--- a/t/t4150-am.sh
+++ b/t/t4150-am.sh
@@ -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