summaryrefslogtreecommitdiff
path: root/builtin-mailinfo.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2009-08-23 01:56:19 -0700
committerJunio C Hamano <gitster@pobox.com>2009-08-26 22:21:32 -0700
commit200c75f0d6c83039c201ec6784e4ef3fb95f8fcf (patch)
treea57c4b3e674d3014e85f80e2ed7d57b700500748 /builtin-mailinfo.c
parent606417bc6dba270ea2b0867cd490c2b57cb3bfa8 (diff)
downloadgit-200c75f0d6c83039c201ec6784e4ef3fb95f8fcf.tar.gz
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>
Diffstat (limited to 'builtin-mailinfo.c')
-rw-r--r--builtin-mailinfo.c71
1 files changed, 70 insertions, 1 deletions
diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
index 50326d911c..a6f6b123b4 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;