Skip to content

Commit

Permalink
Teach mailinfo to ignore everything before -- >8 -- mark
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
gitster committed Aug 27, 2009
1 parent 606417b commit 200c75f
Show file tree
Hide file tree
Showing 6 changed files with 233 additions and 2 deletions.
71 changes: 70 additions & 1 deletion builtin-mailinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -723,14 +773,33 @@ 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;
}

/* normalize the log message to UTF-8. */
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;
Expand Down
2 changes: 1 addition & 1 deletion t/t5100-mailinfo.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions t/t5100/info0014
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Author: Junio C Hamano
Email: [email protected]
Subject: Teach mailinfo to ignore everything before -- >8 -- mark
Date: Thu, 20 Aug 2009 17:18:22 -0700

4 changes: 4 additions & 0 deletions t/t5100/msg0014
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>
64 changes: 64 additions & 0 deletions t/t5100/patch0014
Original file line number Diff line number Diff line change
@@ -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
89 changes: 89 additions & 0 deletions t/t5100/sample.mbox
Original file line number Diff line number Diff line change
Expand Up @@ -561,3 +561,92 @@ From: <[email protected]> (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 <[email protected]>
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 <[email protected]>

This teaches mailinfo the scissors -- >8 -- mark; the command ignores
everything before it in the message body.

Signed-off-by: Junio C Hamano <[email protected]>
---
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

0 comments on commit 200c75f

Please sign in to comment.