From 606417bc6dba270ea2b0867cd490c2b57cb3bfa8 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 26 Aug 2009 22:17:25 -0700 Subject: [PATCH 1/5] builtin-mailinfo.c: fix confusing internal API to mailinfo() It fed two arguments to override the corresponding global variables, but the caller always assigned the values to the global variables first and then passed those global variables to this function. Stop pretending to be a proper API to confuse people. Signed-off-by: Junio C Hamano --- builtin-mailinfo.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c index b0b5d8f6c..50326d911 100644 --- a/builtin-mailinfo.c +++ b/builtin-mailinfo.c @@ -885,12 +885,9 @@ static void handle_info(void) fprintf(fout, "\n"); } -static int mailinfo(FILE *in, FILE *out, int ks, const char *encoding, - const char *msg, const char *patch) +static int mailinfo(FILE *in, FILE *out, const char *msg, const char *patch) { int peek; - keep_subject = ks; - metainfo_charset = encoding; fin = in; fout = out; @@ -956,5 +953,5 @@ int cmd_mailinfo(int argc, const char **argv, const char *prefix) if (argc != 3) usage(mailinfo_usage); - return !!mailinfo(stdin, stdout, keep_subject, metainfo_charset, argv[1], argv[2]); + return !!mailinfo(stdin, stdout, argv[1], argv[2]); } From 200c75f0d6c83039c201ec6784e4ef3fb95f8fcf Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 23 Aug 2009 01:56:19 -0700 Subject: [PATCH 2/5] Teach mailinfo to ignore everything before -- >8 -- mark This teaches mailinfo the scissors -- >8 -- mark; the command ignores everything before it in the message body. For lefties among us, we also support -- 8< -- ;-) Signed-off-by: Junio C Hamano --- builtin-mailinfo.c | 71 +++++++++++++++++++++++++++++++++++- t/t5100-mailinfo.sh | 2 +- t/t5100/info0014 | 5 +++ t/t5100/msg0014 | 4 ++ t/t5100/patch0014 | 64 ++++++++++++++++++++++++++++++++ t/t5100/sample.mbox | 89 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 233 insertions(+), 2 deletions(-) create mode 100644 t/t5100/info0014 create mode 100644 t/t5100/msg0014 create mode 100644 t/t5100/patch0014 diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c index 50326d911..a6f6b123b 100644 --- a/builtin-mailinfo.c +++ b/builtin-mailinfo.c @@ -712,6 +712,56 @@ static inline int patchbreak(const struct strbuf *line) return 0; } +static int is_scissors_line(const struct strbuf *line) +{ + size_t i, len = line->len; + int scissors = 0, gap = 0; + int first_nonblank = -1; + int last_nonblank = 0, visible, perforation = 0, in_perforation = 0; + const char *buf = line->buf; + + for (i = 0; i < len; i++) { + if (isspace(buf[i])) { + if (in_perforation) { + perforation++; + gap++; + } + continue; + } + last_nonblank = i; + if (first_nonblank < 0) + first_nonblank = i; + if (buf[i] == '-') { + in_perforation = 1; + perforation++; + continue; + } + if (i + 1 < len && + (!memcmp(buf + i, ">8", 2) || !memcmp(buf + i, "8<", 2))) { + in_perforation = 1; + perforation += 2; + scissors += 2; + i++; + continue; + } + in_perforation = 0; + } + + /* + * The mark must be at least 8 bytes long (e.g. "-- >8 --"). + * Even though there can be arbitrary cruft on the same line + * (e.g. "cut here"), in order to avoid misidentification, the + * perforation must occupy more than a third of the visible + * width of the line, and dashes and scissors must occupy more + * than half of the perforation. + */ + + visible = last_nonblank - first_nonblank + 1; + return (scissors && 8 <= visible && + visible < perforation * 3 && + gap * 2 < perforation); +} + static int handle_commit_msg(struct strbuf *line) { static int still_looking = 1; @@ -723,7 +773,8 @@ static int handle_commit_msg(struct strbuf *line) strbuf_ltrim(line); if (!line->len) return 0; - if ((still_looking = check_header(line, s_hdr_data, 0)) != 0) + still_looking = check_header(line, s_hdr_data, 0); + if (still_looking) return 0; } @@ -731,6 +782,24 @@ static int handle_commit_msg(struct strbuf *line) if (metainfo_charset) convert_to_utf8(line, charset.buf); + if (is_scissors_line(line)) { + int i; + rewind(cmitmsg); + ftruncate(fileno(cmitmsg), 0); + still_looking = 1; + + /* + * We may have already read "secondary headers"; purge + * them to give ourselves a clean restart. + */ + for (i = 0; header[i]; i++) { + if (s_hdr_data[i]) + strbuf_release(s_hdr_data[i]); + s_hdr_data[i] = NULL; + } + return 0; + } + if (patchbreak(line)) { fclose(cmitmsg); cmitmsg = NULL; diff --git a/t/t5100-mailinfo.sh b/t/t5100-mailinfo.sh index e70ea94a1..e84855665 100755 --- a/t/t5100-mailinfo.sh +++ b/t/t5100-mailinfo.sh @@ -11,7 +11,7 @@ test_expect_success 'split sample box' \ 'git mailsplit -o. "$TEST_DIRECTORY"/t5100/sample.mbox >last && last=`cat last` && echo total is $last && - test `cat last` = 13' + test `cat last` = 14' for mail in `echo 00*` do diff --git a/t/t5100/info0014 b/t/t5100/info0014 new file mode 100644 index 000000000..ab9c8d090 --- /dev/null +++ b/t/t5100/info0014 @@ -0,0 +1,5 @@ +Author: Junio C Hamano +Email: gitster@pobox.com +Subject: Teach mailinfo to ignore everything before -- >8 -- mark +Date: Thu, 20 Aug 2009 17:18:22 -0700 + diff --git a/t/t5100/msg0014 b/t/t5100/msg0014 new file mode 100644 index 000000000..259c6a46d --- /dev/null +++ b/t/t5100/msg0014 @@ -0,0 +1,4 @@ +This teaches mailinfo the scissors -- >8 -- mark; the command ignores +everything before it in the message body. + +Signed-off-by: Junio C Hamano diff --git a/t/t5100/patch0014 b/t/t5100/patch0014 new file mode 100644 index 000000000..124efd234 --- /dev/null +++ b/t/t5100/patch0014 @@ -0,0 +1,64 @@ +--- + builtin-mailinfo.c | 37 ++++++++++++++++++++++++++++++++++++- + 1 files changed, 36 insertions(+), 1 deletions(-) + +diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c +index b0b5d8f..461c47e 100644 +--- a/builtin-mailinfo.c ++++ b/builtin-mailinfo.c +@@ -712,6 +712,34 @@ static inline int patchbreak(const struct strbuf *line) + return 0; + } + ++static int scissors(const struct strbuf *line) ++{ ++ size_t i, len = line->len; ++ int scissors_dashes_seen = 0; ++ const char *buf = line->buf; ++ ++ for (i = 0; i < len; i++) { ++ if (isspace(buf[i])) ++ continue; ++ if (buf[i] == '-') { ++ scissors_dashes_seen |= 02; ++ continue; ++ } ++ if (i + 1 < len && !memcmp(buf + i, ">8", 2)) { ++ scissors_dashes_seen |= 01; ++ i++; ++ continue; ++ } ++ if (i + 7 < len && !memcmp(buf + i, "cut here", 8)) { ++ i += 7; ++ continue; ++ } ++ /* everything else --- not scissors */ ++ break; ++ } ++ return scissors_dashes_seen == 03; ++} ++ + static int handle_commit_msg(struct strbuf *line) + { + static int still_looking = 1; +@@ -723,10 +751,17 @@ static int handle_commit_msg(struct strbuf *line) + strbuf_ltrim(line); + if (!line->len) + return 0; +- if ((still_looking = check_header(line, s_hdr_data, 0)) != 0) ++ still_looking = check_header(line, s_hdr_data, 0); ++ if (still_looking) + return 0; + } + ++ if (scissors(line)) { ++ fseek(cmitmsg, 0L, SEEK_SET); ++ still_looking = 1; ++ return 0; ++ } ++ + /* normalize the log message to UTF-8. */ + if (metainfo_charset) + convert_to_utf8(line, charset.buf); +-- +1.6.4.1 diff --git a/t/t5100/sample.mbox b/t/t5100/sample.mbox index c3074ac57..13fa4ae03 100644 --- a/t/t5100/sample.mbox +++ b/t/t5100/sample.mbox @@ -561,3 +561,92 @@ From: (A U Thor) Date: Fri, 9 Jun 2006 00:44:16 -0700 Subject: [PATCH] a patch +From nobody Mon Sep 17 00:00:00 2001 +From: Junio Hamano +Date: Thu, 20 Aug 2009 17:18:22 -0700 +Subject: Why doesn't git-am does not like >8 scissors mark? + +Subject: [PATCH] BLAH ONE + +In real life, we will see a discussion that inspired this patch +discussing related and unrelated things around >8 scissors mark +in this part of the message. + +Subject: [PATCH] BLAH TWO + +And then we will see the scissors. + + This line is not a scissors mark -- >8 -- but talks about it. + - - >8 - - please remove everything above this line - - >8 - - + +Subject: [PATCH] Teach mailinfo to ignore everything before -- >8 -- mark +From: Junio C Hamano + +This teaches mailinfo the scissors -- >8 -- mark; the command ignores +everything before it in the message body. + +Signed-off-by: Junio C Hamano +--- + builtin-mailinfo.c | 37 ++++++++++++++++++++++++++++++++++++- + 1 files changed, 36 insertions(+), 1 deletions(-) + +diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c +index b0b5d8f..461c47e 100644 +--- a/builtin-mailinfo.c ++++ b/builtin-mailinfo.c +@@ -712,6 +712,34 @@ static inline int patchbreak(const struct strbuf *line) + return 0; + } + ++static int scissors(const struct strbuf *line) ++{ ++ size_t i, len = line->len; ++ int scissors_dashes_seen = 0; ++ const char *buf = line->buf; ++ ++ for (i = 0; i < len; i++) { ++ if (isspace(buf[i])) ++ continue; ++ if (buf[i] == '-') { ++ scissors_dashes_seen |= 02; ++ continue; ++ } ++ if (i + 1 < len && !memcmp(buf + i, ">8", 2)) { ++ scissors_dashes_seen |= 01; ++ i++; ++ continue; ++ } ++ if (i + 7 < len && !memcmp(buf + i, "cut here", 8)) { ++ i += 7; ++ continue; ++ } ++ /* everything else --- not scissors */ ++ break; ++ } ++ return scissors_dashes_seen == 03; ++} ++ + static int handle_commit_msg(struct strbuf *line) + { + static int still_looking = 1; +@@ -723,10 +751,17 @@ static int handle_commit_msg(struct strbuf *line) + strbuf_ltrim(line); + if (!line->len) + return 0; +- if ((still_looking = check_header(line, s_hdr_data, 0)) != 0) ++ still_looking = check_header(line, s_hdr_data, 0); ++ if (still_looking) + return 0; + } + ++ if (scissors(line)) { ++ fseek(cmitmsg, 0L, SEEK_SET); ++ still_looking = 1; ++ return 0; ++ } ++ + /* normalize the log message to UTF-8. */ + if (metainfo_charset) + convert_to_utf8(line, charset.buf); +-- +1.6.4.1 From f43c97f5720f48598e59629f7dc9892d082d8b0e Mon Sep 17 00:00:00 2001 From: Nanako Shiraishi Date: Tue, 25 Aug 2009 17:20:00 +0900 Subject: [PATCH 3/5] Documentation: describe the scissors mark support of "git am" Describe what a scissors mark looks like, and explain in what situation it is often used. Signed-off-by: Nanako Shiraishi Signed-off-by: Junio C Hamano --- Documentation/git-am.txt | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/Documentation/git-am.txt b/Documentation/git-am.txt index fcacc9465..e6ab3dfa5 100644 --- a/Documentation/git-am.txt +++ b/Documentation/git-am.txt @@ -128,10 +128,18 @@ the commit, after stripping common prefix "[PATCH ]". The "Subject: " line is supposed to concisely describe what the commit is about in one line of text. -"From: " and "Subject: " lines starting the body (the rest of the -message after the blank line terminating the RFC2822 headers) -override the respective commit author name and title values taken -from the headers. +A line that mainly consists of scissors (either ">8" or "8<") and +perforation (dash "-") marks is called a scissors line, and is used to +request the reader to cut the message at that line. If such a line +appears in the body of the message before the patch, everything before it +(including the scissors line itself) is ignored. This is useful if you +want to begin your message in a discussion thread with comments and +suggestions on the message you are responding to, and to conclude it with +a patch submission, separating the discussion and the beginning of the +proposed commit log message with a scissors line. + +"From: " and "Subject: " lines starting the body override the respective +commit author name and title values taken from the headers. The commit message is formed by the title taken from the "Subject: ", a blank line and the body of the message up to From 017678b4f47dc1b2a6691631373c46daf8f63206 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 26 Aug 2009 21:36:05 -0700 Subject: [PATCH 4/5] am/mailinfo: Disable scissors processing by default You can enable it by giving --scissors to "git am". Signed-off-by: Junio C Hamano --- Documentation/git-am.txt | 17 ++++----- Documentation/git-mailinfo.txt | 16 ++++++++- builtin-mailinfo.c | 7 +++- git-am.sh | 23 ++++++++---- t/t5100-mailinfo.sh | 22 ++++++++---- t/t5100/info0014 | 6 ++-- t/t5100/info0014--scissors | 5 +++ t/t5100/msg0014 | 14 ++++++++ t/t5100/msg0014--scissors | 4 +++ t/t5100/patch0014--scissors | 64 ++++++++++++++++++++++++++++++++++ 10 files changed, 149 insertions(+), 29 deletions(-) create mode 100644 t/t5100/info0014--scissors create mode 100644 t/t5100/msg0014--scissors create mode 100644 t/t5100/patch0014--scissors diff --git a/Documentation/git-am.txt b/Documentation/git-am.txt index e6ab3dfa5..87781f4a7 100644 --- a/Documentation/git-am.txt +++ b/Documentation/git-am.txt @@ -13,7 +13,7 @@ SYNOPSIS [--3way] [--interactive] [--committer-date-is-author-date] [--ignore-date] [--ignore-space-change | --ignore-whitespace] [--whitespace=