diff options
author | Junio C Hamano <gitster@pobox.com> | 2009-08-23 01:56:19 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2009-08-26 22:21:32 -0700 |
commit | 200c75f0d6c83039c201ec6784e4ef3fb95f8fcf (patch) | |
tree | a57c4b3e674d3014e85f80e2ed7d57b700500748 /builtin-mailinfo.c | |
parent | 606417bc6dba270ea2b0867cd490c2b57cb3bfa8 (diff) | |
download | git-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.c | 71 |
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; |