@matheusbsbs / matheus-bagliano / commits / 200c75f0d6
Fork 0

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