From c2ca1d79dbd54b06a05e5d14a897699e59dc9f9f Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 4 Aug 2009 22:31:59 -0500 Subject: Allow mailsplit (and hence git-am) to handle mails with CRLF line-endings It is not that uncommon to have mails with DOS line-ending, notably Thunderbird and web mailers like Gmail (when saving what they call "original" message). So modify mailsplit to convert CRLF line-endings to just LF. Since git-rebase is built on top of git-am, add an option to mailsplit to be used by git-am when it is acting on behalf of git-rebase, to refrain from doing this conversion. And add a test to make sure that rebase still works. Signed-off-by: Brandon Casey Signed-off-by: Junio C Hamano diff --git a/builtin-mailsplit.c b/builtin-mailsplit.c index d288fde..ee6ca0e 100644 --- a/builtin-mailsplit.c +++ b/builtin-mailsplit.c @@ -44,6 +44,7 @@ static int is_from_line(const char *line, int len) } static struct strbuf buf = STRBUF_INIT; +static int keep_cr; /* Called with the first line (potentially partial) * already in buf[] -- normally that should begin with @@ -69,6 +70,12 @@ static int split_one(FILE *mbox, const char *name, int allow_bare) * "From " and having something that looks like a date format. */ for (;;) { + if (!keep_cr && buf.len > 1 && buf.buf[buf.len-1] == '\n' && + buf.buf[buf.len-2] == '\r') { + strbuf_setlen(&buf, buf.len-2); + strbuf_addch(&buf, '\n'); + } + if (fwrite(buf.buf, 1, buf.len, output) != buf.len) die_errno("cannot write output"); @@ -226,6 +233,8 @@ int cmd_mailsplit(int argc, const char **argv, const char *prefix) nr = strtol(arg+2, NULL, 10); } else if ( arg[1] == 'b' && !arg[2] ) { allow_bare = 1; + } else if (!strcmp(arg, "--keep-cr")) { + keep_cr = 1; } else if ( arg[1] == 'o' && arg[2] ) { dir = arg+2; } else if ( arg[1] == '-' && !arg[2] ) { diff --git a/git-am.sh b/git-am.sh index d64d997..985226b 100755 --- a/git-am.sh +++ b/git-am.sh @@ -197,7 +197,13 @@ check_patch_format () { split_patches () { case "$patch_format" in mbox) - git mailsplit -d"$prec" -o"$dotest" -b -- "$@" > "$dotest/last" || + case "$rebasing" in + '') + keep_cr= ;; + ?*) + keep_cr=--keep-cr ;; + esac + git mailsplit -d"$prec" -o"$dotest" -b $keep_cr -- "$@" > "$dotest/last" || clean_abort ;; stgit-series) diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh index c5c29cc..4e6a44b 100755 --- a/t/t3400-rebase.sh +++ b/t/t3400-rebase.sh @@ -3,9 +3,10 @@ # Copyright (c) 2005 Amos Waterland # -test_description='git rebase should not destroy author information +test_description='git rebase assorted tests -This test runs git rebase and checks that the author information is not lost. +This test runs git rebase and checks that the author information is not lost +among other things. ' . ./test-lib.sh @@ -133,4 +134,25 @@ test_expect_success 'rebase -q is quiet' ' test ! -s output.out ' +q_to_cr () { + tr Q '\015' +} + +test_expect_success 'Rebase a commit that sprinkles CRs in' ' + ( + echo "One" + echo "TwoQ" + echo "Three" + echo "FQur" + echo "Five" + ) | q_to_cr >CR && + git add CR && + test_tick && + git commit -a -m "A file with a line with CR" && + git tag file-with-cr && + git checkout HEAD^0 && + git rebase --onto HEAD^^ HEAD^ && + git diff --exit-code file-with-cr:CR HEAD:CR +' + test_done -- cgit v0.10.2-6-g49f6