mailsplit: support unescaping mboxrd messages

This will allow us to parse the output of --pretty=mboxrd and the output of other mboxrd generators. 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 c88098d7f19c6322fbd911bb89e2efd246bf75c4
6 files changed +83 -1
Documentation/git-mailsplit.txt
+6 -1
@@ -8,7 +8,8 @@ git-mailsplit - Simple UNIX mbox splitter program
8 SYNOPSIS
9 --------
10 [verse]
11 -'git mailsplit' [-b] [-f<nn>] [-d<prec>] [--keep-cr] -o<directory> [--] [(<mbox>|<Maildir>)...]
11 +'git mailsplit' [-b] [-f<nn>] [-d<prec>] [--keep-cr] [--mboxrd]
12 + -o<directory> [--] [(<mbox>|<Maildir>)...]
13
14 DESCRIPTION
15 -----------
@@ -47,6 +48,10 @@ OPTIONS
48 --keep-cr::
49 Do not remove `\r` from lines ending with `\r\n`.
50
51 +--mboxrd::
52 + Input is of the "mboxrd" format and "^>+From " line escaping is
53 + reversed.
54 +
55 GIT
56 ---
57 Part of the linkgit:git[1] suite
builtin/mailsplit.c
+18
@@ -45,6 +45,19 @@ static int is_from_line(const char *line, int len)
45
46 static struct strbuf buf = STRBUF_INIT;
47 static int keep_cr;
48 +static int mboxrd;
49 +
50 +static int is_gtfrom(const struct strbuf *buf)
51 +{
52 + size_t min = strlen(">From ");
53 + size_t ngt;
54 +
55 + if (buf->len < min)
56 + return 0;
57 +
58 + ngt = strspn(buf->buf, ">");
59 + return ngt && starts_with(buf->buf + ngt, "From ");
60 +}
61
62 /* Called with the first line (potentially partial)
63 * already in buf[] -- normally that should begin with
@@ -77,6 +90,9 @@ static int split_one(FILE *mbox, const char *name, int allow_bare)
90 strbuf_addch(&buf, '\n');
91 }
92
93 + if (mboxrd && is_gtfrom(&buf))
94 + strbuf_remove(&buf, 0, 1);
95 +
96 if (fwrite(buf.buf, 1, buf.len, output) != buf.len)
97 die_errno("cannot write output");
98
@@ -271,6 +287,8 @@ int cmd_mailsplit(int argc, const char **argv, const char *prefix)
287 keep_cr = 1;
288 } else if ( arg[1] == 'o' && arg[2] ) {
289 dir = arg+2;
290 + } else if (!strcmp(arg, "--mboxrd")) {
291 + mboxrd = 1;
292 } else if ( arg[1] == '-' && !arg[2] ) {
293 argp++; /* -- marks end of options */
294 break;
t/t5100-mailinfo.sh
+31
@@ -111,4 +111,35 @@ test_expect_success 'mailinfo on message with quoted >From' '
111 test_cmp "$TEST_DIRECTORY"/t5100/quoted-from.expect quoted-from/msg
112 '
113
114 +test_expect_success 'mailinfo unescapes with --mboxrd' '
115 + mkdir mboxrd &&
116 + git mailsplit -omboxrd --mboxrd \
117 + "$TEST_DIRECTORY"/t5100/sample.mboxrd >last &&
118 + test x"$(cat last)" = x2 &&
119 + for i in 0001 0002
120 + do
121 + git mailinfo mboxrd/msg mboxrd/patch \
122 + <mboxrd/$i >mboxrd/out &&
123 + test_cmp "$TEST_DIRECTORY"/t5100/${i}mboxrd mboxrd/msg
124 + done &&
125 + sp=" " &&
126 + echo "From " >expect &&
127 + echo "From " >>expect &&
128 + echo >> expect &&
129 + cat >sp <<-INPUT_END &&
130 + From mboxrd Mon Sep 17 00:00:00 2001
131 + From: trailing spacer <sp@example.com>
132 + Subject: [PATCH] a commit with trailing space
133 +
134 + From$sp
135 + >From$sp
136 +
137 + INPUT_END
138 +
139 + git mailsplit -f2 -omboxrd --mboxrd <sp >last &&
140 + test x"$(cat last)" = x1 &&
141 + git mailinfo mboxrd/msg mboxrd/patch <mboxrd/0003 &&
142 + test_cmp expect mboxrd/msg
143 +'
144 +
145 test_done
t/t5100/0001mboxrd new
+4
@@ -0,0 +1,4 @@
1 +From the beginning, mbox should have been mboxrd
2 +>From escaped
3 +From not mangled but this line should have been escaped
4 +
t/t5100/0002mboxrd new
+5
@@ -0,0 +1,5 @@
1 + >From unchanged
2 + From also unchanged
3 +no trailing space, no escaping necessary and '>' was intended:
4 +>From
5 +
t/t5100/sample.mboxrd new
+19
@@ -0,0 +1,19 @@
1 +From mboxrd Mon Sep 17 00:00:00 2001
2 +From: mboxrd writer <mboxrd@example.com>
3 +Date: Fri, 9 Jun 2006 00:44:16 -0700
4 +Subject: [PATCH] a commit with escaped From lines
5 +
6 +>From the beginning, mbox should have been mboxrd
7 +>>From escaped
8 +From not mangled but this line should have been escaped
9 +
10 +From mboxrd Mon Sep 17 00:00:00 2001
11 +From: mboxrd writer <mboxrd@example.com>
12 +Date: Fri, 9 Jun 2006 00:44:16 -0700
13 +Subject: [PATCH 2/2] another with fake From lines
14 +
15 + >From unchanged
16 + From also unchanged
17 +no trailing space, no escaping necessary and '>' was intended:
18 +>From
19 +