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 <gitster@pobox.com>
Junio C Hamano committed
Aug 23, 2009 at 01:56 UTC
200c75f0d6c83039c201ec6784e4ef3fb95f8fcf
6 files changed
+233
-2
builtin-mailinfo.c
+70
-1
@@ -712,6 +712,56 @@ static inline int patchbreak(const struct strbuf *line)
712
return 0;
713
}
714
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
+
765
static int handle_commit_msg(struct strbuf *line)
766
{
767
static int still_looking = 1;
@@ -723,7 +773,8 @@ static int handle_commit_msg(struct strbuf *line)
773
strbuf_ltrim(line);
774
if (!line->len)
775
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)
778
return 0;
779
}
780
@@ -731,6 +782,24 @@ static int handle_commit_msg(struct strbuf *line)
782
if (metainfo_charset)
783
convert_to_utf8(line, charset.buf);
784
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
+
803
if (patchbreak(line)) {
804
fclose(cmitmsg);
805
cmitmsg = NULL;
t/t5100-mailinfo.sh
+1
-1
@@ -11,7 +11,7 @@ test_expect_success 'split sample box' \
11
'git mailsplit -o. "$TEST_DIRECTORY"/t5100/sample.mbox >last &&
12
last=`cat last` &&
13
echo total is $last &&
14
- test `cat last` = 13'
14
+ test `cat last` = 14'
15
16
for mail in `echo 00*`
17
do
t/t5100/info0014
new
+5
@@ -0,0 +1,5 @@
1
+Author: Junio C Hamano
2
+Email: gitster@pobox.com
3
+Subject: Teach mailinfo to ignore everything before -- >8 -- mark
4
+Date: Thu, 20 Aug 2009 17:18:22 -0700
5
+
t/t5100/msg0014
new
+4
@@ -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 <gitster@pobox.com>
t/t5100/patch0014
new
+64
@@ -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
+89
@@ -561,3 +561,92 @@ From: <a.u.thor@example.com> (A U Thor)
561
Date: Fri, 9 Jun 2006 00:44:16 -0700
562
Subject: [PATCH] a patch
563
564
+From nobody Mon Sep 17 00:00:00 2001
565
+From: Junio Hamano <junkio@cox.net>
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 <gitster@pobox.com>
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 <gitster@pobox.com>
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