Skip to content

Commit 200c75f

Browse files
committed
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 <[email protected]>
1 parent 606417b commit 200c75f

File tree

6 files changed

+233
-2
lines changed

6 files changed

+233
-2
lines changed

builtin-mailinfo.c

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,56 @@ static inline int patchbreak(const struct strbuf *line)
712712
return 0;
713713
}
714714

715+
static int is_scissors_line(const struct strbuf *line)
716+
{
717+
size_t i, len = line->len;
718+
int scissors = 0, gap = 0;
719+
int first_nonblank = -1;
720+
int last_nonblank = 0, visible, perforation = 0, in_perforation = 0;
721+
const char *buf = line->buf;
722+
723+
for (i = 0; i < len; i++) {
724+
if (isspace(buf[i])) {
725+
if (in_perforation) {
726+
perforation++;
727+
gap++;
728+
}
729+
continue;
730+
}
731+
last_nonblank = i;
732+
if (first_nonblank < 0)
733+
first_nonblank = i;
734+
if (buf[i] == '-') {
735+
in_perforation = 1;
736+
perforation++;
737+
continue;
738+
}
739+
if (i + 1 < len &&
740+
(!memcmp(buf + i, ">8", 2) || !memcmp(buf + i, "8<", 2))) {
741+
in_perforation = 1;
742+
perforation += 2;
743+
scissors += 2;
744+
i++;
745+
continue;
746+
}
747+
in_perforation = 0;
748+
}
749+
750+
/*
751+
* The mark must be at least 8 bytes long (e.g. "-- >8 --").
752+
* Even though there can be arbitrary cruft on the same line
753+
* (e.g. "cut here"), in order to avoid misidentification, the
754+
* perforation must occupy more than a third of the visible
755+
* width of the line, and dashes and scissors must occupy more
756+
* than half of the perforation.
757+
*/
758+
759+
visible = last_nonblank - first_nonblank + 1;
760+
return (scissors && 8 <= visible &&
761+
visible < perforation * 3 &&
762+
gap * 2 < perforation);
763+
}
764+
715765
static int handle_commit_msg(struct strbuf *line)
716766
{
717767
static int still_looking = 1;
@@ -723,14 +773,33 @@ static int handle_commit_msg(struct strbuf *line)
723773
strbuf_ltrim(line);
724774
if (!line->len)
725775
return 0;
726-
if ((still_looking = check_header(line, s_hdr_data, 0)) != 0)
776+
still_looking = check_header(line, s_hdr_data, 0);
777+
if (still_looking)
727778
return 0;
728779
}
729780

730781
/* normalize the log message to UTF-8. */
731782
if (metainfo_charset)
732783
convert_to_utf8(line, charset.buf);
733784

785+
if (is_scissors_line(line)) {
786+
int i;
787+
rewind(cmitmsg);
788+
ftruncate(fileno(cmitmsg), 0);
789+
still_looking = 1;
790+
791+
/*
792+
* We may have already read "secondary headers"; purge
793+
* them to give ourselves a clean restart.
794+
*/
795+
for (i = 0; header[i]; i++) {
796+
if (s_hdr_data[i])
797+
strbuf_release(s_hdr_data[i]);
798+
s_hdr_data[i] = NULL;
799+
}
800+
return 0;
801+
}
802+
734803
if (patchbreak(line)) {
735804
fclose(cmitmsg);
736805
cmitmsg = NULL;

t/t5100-mailinfo.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ test_expect_success 'split sample box' \
1111
'git mailsplit -o. "$TEST_DIRECTORY"/t5100/sample.mbox >last &&
1212
last=`cat last` &&
1313
echo total is $last &&
14-
test `cat last` = 13'
14+
test `cat last` = 14'
1515

1616
for mail in `echo 00*`
1717
do

t/t5100/info0014

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Author: Junio C Hamano
2+
3+
Subject: Teach mailinfo to ignore everything before -- >8 -- mark
4+
Date: Thu, 20 Aug 2009 17:18:22 -0700
5+

t/t5100/msg0014

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
This teaches mailinfo the scissors -- >8 -- mark; the command ignores
2+
everything before it in the message body.
3+
4+
Signed-off-by: Junio C Hamano <[email protected]>

t/t5100/patch0014

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
---
2+
builtin-mailinfo.c | 37 ++++++++++++++++++++++++++++++++++++-
3+
1 files changed, 36 insertions(+), 1 deletions(-)
4+
5+
diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
6+
index b0b5d8f..461c47e 100644
7+
--- a/builtin-mailinfo.c
8+
+++ b/builtin-mailinfo.c
9+
@@ -712,6 +712,34 @@ static inline int patchbreak(const struct strbuf *line)
10+
return 0;
11+
}
12+
13+
+static int scissors(const struct strbuf *line)
14+
+{
15+
+ size_t i, len = line->len;
16+
+ int scissors_dashes_seen = 0;
17+
+ const char *buf = line->buf;
18+
+
19+
+ for (i = 0; i < len; i++) {
20+
+ if (isspace(buf[i]))
21+
+ continue;
22+
+ if (buf[i] == '-') {
23+
+ scissors_dashes_seen |= 02;
24+
+ continue;
25+
+ }
26+
+ if (i + 1 < len && !memcmp(buf + i, ">8", 2)) {
27+
+ scissors_dashes_seen |= 01;
28+
+ i++;
29+
+ continue;
30+
+ }
31+
+ if (i + 7 < len && !memcmp(buf + i, "cut here", 8)) {
32+
+ i += 7;
33+
+ continue;
34+
+ }
35+
+ /* everything else --- not scissors */
36+
+ break;
37+
+ }
38+
+ return scissors_dashes_seen == 03;
39+
+}
40+
+
41+
static int handle_commit_msg(struct strbuf *line)
42+
{
43+
static int still_looking = 1;
44+
@@ -723,10 +751,17 @@ static int handle_commit_msg(struct strbuf *line)
45+
strbuf_ltrim(line);
46+
if (!line->len)
47+
return 0;
48+
- if ((still_looking = check_header(line, s_hdr_data, 0)) != 0)
49+
+ still_looking = check_header(line, s_hdr_data, 0);
50+
+ if (still_looking)
51+
return 0;
52+
}
53+
54+
+ if (scissors(line)) {
55+
+ fseek(cmitmsg, 0L, SEEK_SET);
56+
+ still_looking = 1;
57+
+ return 0;
58+
+ }
59+
+
60+
/* normalize the log message to UTF-8. */
61+
if (metainfo_charset)
62+
convert_to_utf8(line, charset.buf);
63+
--
64+
1.6.4.1

t/t5100/sample.mbox

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,3 +561,92 @@ From: <[email protected]> (A U Thor)
561561
Date: Fri, 9 Jun 2006 00:44:16 -0700
562562
Subject: [PATCH] a patch
563563

564+
From nobody Mon Sep 17 00:00:00 2001
565+
From: Junio Hamano <[email protected]>
566+
Date: Thu, 20 Aug 2009 17:18:22 -0700
567+
Subject: Why doesn't git-am does not like >8 scissors mark?
568+
569+
Subject: [PATCH] BLAH ONE
570+
571+
In real life, we will see a discussion that inspired this patch
572+
discussing related and unrelated things around >8 scissors mark
573+
in this part of the message.
574+
575+
Subject: [PATCH] BLAH TWO
576+
577+
And then we will see the scissors.
578+
579+
This line is not a scissors mark -- >8 -- but talks about it.
580+
- - >8 - - please remove everything above this line - - >8 - -
581+
582+
Subject: [PATCH] Teach mailinfo to ignore everything before -- >8 -- mark
583+
From: Junio C Hamano <[email protected]>
584+
585+
This teaches mailinfo the scissors -- >8 -- mark; the command ignores
586+
everything before it in the message body.
587+
588+
Signed-off-by: Junio C Hamano <[email protected]>
589+
---
590+
builtin-mailinfo.c | 37 ++++++++++++++++++++++++++++++++++++-
591+
1 files changed, 36 insertions(+), 1 deletions(-)
592+
593+
diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
594+
index b0b5d8f..461c47e 100644
595+
--- a/builtin-mailinfo.c
596+
+++ b/builtin-mailinfo.c
597+
@@ -712,6 +712,34 @@ static inline int patchbreak(const struct strbuf *line)
598+
return 0;
599+
}
600+
601+
+static int scissors(const struct strbuf *line)
602+
+{
603+
+ size_t i, len = line->len;
604+
+ int scissors_dashes_seen = 0;
605+
+ const char *buf = line->buf;
606+
+
607+
+ for (i = 0; i < len; i++) {
608+
+ if (isspace(buf[i]))
609+
+ continue;
610+
+ if (buf[i] == '-') {
611+
+ scissors_dashes_seen |= 02;
612+
+ continue;
613+
+ }
614+
+ if (i + 1 < len && !memcmp(buf + i, ">8", 2)) {
615+
+ scissors_dashes_seen |= 01;
616+
+ i++;
617+
+ continue;
618+
+ }
619+
+ if (i + 7 < len && !memcmp(buf + i, "cut here", 8)) {
620+
+ i += 7;
621+
+ continue;
622+
+ }
623+
+ /* everything else --- not scissors */
624+
+ break;
625+
+ }
626+
+ return scissors_dashes_seen == 03;
627+
+}
628+
+
629+
static int handle_commit_msg(struct strbuf *line)
630+
{
631+
static int still_looking = 1;
632+
@@ -723,10 +751,17 @@ static int handle_commit_msg(struct strbuf *line)
633+
strbuf_ltrim(line);
634+
if (!line->len)
635+
return 0;
636+
- if ((still_looking = check_header(line, s_hdr_data, 0)) != 0)
637+
+ still_looking = check_header(line, s_hdr_data, 0);
638+
+ if (still_looking)
639+
return 0;
640+
}
641+
642+
+ if (scissors(line)) {
643+
+ fseek(cmitmsg, 0L, SEEK_SET);
644+
+ still_looking = 1;
645+
+ return 0;
646+
+ }
647+
+
648+
/* normalize the log message to UTF-8. */
649+
if (metainfo_charset)
650+
convert_to_utf8(line, charset.buf);
651+
--
652+
1.6.4.1

0 commit comments

Comments
 (0)