Skip to content

Commit

Permalink
Merge branch 'jc/mailinfo-scissors'
Browse files Browse the repository at this point in the history
* jc/mailinfo-scissors:
  mailinfo.scissors: new configuration
  am/mailinfo: Disable scissors processing by default
  Documentation: describe the scissors mark support of "git am"
  Teach mailinfo to ignore everything before -- >8 -- mark
  builtin-mailinfo.c: fix confusing internal API to mailinfo()
  • Loading branch information
Junio C Hamano committed Sep 7, 2009
2 parents 2da9f8e + 43485d3 commit b8711f5
Show file tree
Hide file tree
Showing 12 changed files with 395 additions and 27 deletions.
13 changes: 8 additions & 5 deletions Documentation/git-am.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ SYNOPSIS
[--3way] [--interactive] [--committer-date-is-author-date]
[--ignore-date] [--ignore-space-change | --ignore-whitespace]
[--whitespace=<option>] [-C<n>] [-p<n>] [--directory=<dir>]
[--reject] [-q | --quiet]
[--reject] [-q | --quiet] [--scissors]
[<mbox> | <Maildir>...]
'git am' (--skip | --resolved | --abort)

Expand All @@ -39,6 +39,11 @@ OPTIONS
--keep::
Pass `-k` flag to 'git-mailinfo' (see linkgit:git-mailinfo[1]).

-c::
--scissors::
Remove everything in body before a scissors line (see
linkgit:git-mailinfo[1]).

-q::
--quiet::
Be quiet. Only print error messages.
Expand Down Expand Up @@ -128,10 +133,8 @@ the commit, after stripping common prefix "[PATCH <anything>]".
The "Subject: " line is supposed to concisely describe what the
commit is about in one line of text.

"From: " and "Subject: " lines starting the body (the rest of the
message after the blank line terminating the RFC2822 headers)
override the respective commit author name and title values taken
from the headers.
"From: " and "Subject: " lines starting the body override the respective
commit author name and title values taken from the headers.

The commit message is formed by the title taken from the
"Subject: ", a blank line and the body of the message up to
Expand Down
16 changes: 15 additions & 1 deletion Documentation/git-mailinfo.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ git-mailinfo - Extracts patch and authorship from a single e-mail message

SYNOPSIS
--------
'git mailinfo' [-k] [-u | --encoding=<encoding> | -n] <msg> <patch>
'git mailinfo' [-k] [-u | --encoding=<encoding> | -n] [--scissors] <msg> <patch>


DESCRIPTION
Expand Down Expand Up @@ -49,6 +49,20 @@ conversion, even with this flag.
-n::
Disable all charset re-coding of the metadata.

--scissors::
Remove everything in body before a scissors line. A line that
mainly consists of scissors (either ">8" or "8<") and perforation
(dash "-") marks is called a scissors line, and is used to request
the reader to cut the message at that line. If such a line
appears in the body of the message before the patch, everything
before it (including the scissors line itself) is ignored when
this option is used.
+
This is useful if you want to begin your message in a discussion thread
with comments and suggestions on the message you are responding to, and to
conclude it with a patch submission, separating the discussion and the
beginning of the proposed commit log message with a scissors line.

<msg>::
The commit log message extracted from e-mail, usually
except the title line which comes from e-mail Subject.
Expand Down
97 changes: 90 additions & 7 deletions builtin-mailinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ static enum {
static struct strbuf charset = STRBUF_INIT;
static int patch_lines;
static struct strbuf **p_hdr_data, **s_hdr_data;
static int use_scissors;

#define MAX_HDR_PARSED 10
#define MAX_BOUNDARIES 5
Expand Down Expand Up @@ -712,6 +713,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;
Expand All @@ -723,14 +774,33 @@ 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;
}

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

if (use_scissors && 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;
Expand Down Expand Up @@ -885,12 +955,9 @@ static void handle_info(void)
fprintf(fout, "\n");
}

static int mailinfo(FILE *in, FILE *out, int ks, const char *encoding,
const char *msg, const char *patch)
static int mailinfo(FILE *in, FILE *out, const char *msg, const char *patch)
{
int peek;
keep_subject = ks;
metainfo_charset = encoding;
fin = in;
fout = out;

Expand Down Expand Up @@ -924,6 +991,18 @@ static int mailinfo(FILE *in, FILE *out, int ks, const char *encoding,
return 0;
}

static int git_mailinfo_config(const char *var, const char *value, void *unused)
{
if (prefixcmp(var, "mailinfo."))
return git_default_config(var, value, unused);
if (!strcmp(var, "mailinfo.scissors")) {
use_scissors = git_config_bool(var, value);
return 0;
}
/* perhaps others here */
return 0;
}

static const char mailinfo_usage[] =
"git mailinfo [-k] [-u | --encoding=<encoding> | -n] msg patch <mail >info";

Expand All @@ -934,7 +1013,7 @@ int cmd_mailinfo(int argc, const char **argv, const char *prefix)
/* NEEDSWORK: might want to do the optional .git/ directory
* discovery
*/
git_config(git_default_config, NULL);
git_config(git_mailinfo_config, NULL);

def_charset = (git_commit_encoding ? git_commit_encoding : "UTF-8");
metainfo_charset = def_charset;
Expand All @@ -948,6 +1027,10 @@ int cmd_mailinfo(int argc, const char **argv, const char *prefix)
metainfo_charset = NULL;
else if (!prefixcmp(argv[1], "--encoding="))
metainfo_charset = argv[1] + 11;
else if (!strcmp(argv[1], "--scissors"))
use_scissors = 1;
else if (!strcmp(argv[1], "--no-scissors"))
use_scissors = 0;
else
usage(mailinfo_usage);
argc--; argv++;
Expand All @@ -956,5 +1039,5 @@ int cmd_mailinfo(int argc, const char **argv, const char *prefix)
if (argc != 3)
usage(mailinfo_usage);

return !!mailinfo(stdin, stdout, keep_subject, metainfo_charset, argv[1], argv[2]);
return !!mailinfo(stdin, stdout, argv[1], argv[2]);
}
23 changes: 17 additions & 6 deletions git-am.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ q,quiet be quiet
s,signoff add a Signed-off-by line to the commit message
u,utf8 recode into utf8 (default)
k,keep pass -k flag to git-mailinfo
c,scissors strip everything before a scissors line
whitespace= pass it through git-apply
ignore-space-change pass it through git-apply
ignore-whitespace pass it through git-apply
Expand Down Expand Up @@ -288,7 +289,7 @@ split_patches () {
prec=4
dotest="$GIT_DIR/rebase-apply"
sign= utf8=t keep= skip= interactive= resolved= rebasing= abort=
resolvemsg= resume=
resolvemsg= resume= scissors=
git_apply_opt=
committer_date_is_author_date=
ignore_date=
Expand All @@ -310,14 +311,18 @@ do
utf8= ;;
-k|--keep)
keep=t ;;
-c|--scissors)
scissors=t ;;
--no-scissors)
scissors=f ;;
-r|--resolved)
resolved=t ;;
--skip)
skip=t ;;
--abort)
abort=t ;;
--rebasing)
rebasing=t threeway=t keep=t ;;
rebasing=t threeway=t keep=t scissors=f ;;
-d|--dotest)
die "-d option is no longer supported. Do not use."
;;
Expand Down Expand Up @@ -435,14 +440,14 @@ else

split_patches "$@"

# -s, -u, -k, --whitespace, -3, -C, -q and -p flags are kept
# for the resuming session after a patch failure.
# -i can and must be given when resuming.
# -i can and must be given when resuming; everything
# else is kept
echo " $git_apply_opt" >"$dotest/apply-opt"
echo "$threeway" >"$dotest/threeway"
echo "$sign" >"$dotest/sign"
echo "$utf8" >"$dotest/utf8"
echo "$keep" >"$dotest/keep"
echo "$scissors" >"$dotest/scissors"
echo "$GIT_QUIET" >"$dotest/quiet"
echo 1 >"$dotest/next"
if test -n "$rebasing"
Expand Down Expand Up @@ -484,6 +489,12 @@ if test "$(cat "$dotest/keep")" = t
then
keep=-k
fi
case "$(cat "$dotest/scissors")" in
t)
scissors=--scissors ;;
f)
scissors=--no-scissors ;;
esac
if test "$(cat "$dotest/quiet")" = t
then
GIT_QUIET=t
Expand Down Expand Up @@ -538,7 +549,7 @@ do
# by the user, or the user can tell us to do so by --resolved flag.
case "$resume" in
'')
git mailinfo $keep $utf8 "$dotest/msg" "$dotest/patch" \
git mailinfo $keep $scissors $utf8 "$dotest/msg" "$dotest/patch" \
<"$dotest/$msgnum" >"$dotest/info" ||
stop_here $this

Expand Down
24 changes: 16 additions & 8 deletions t/t5100-mailinfo.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,26 @@ test_expect_success 'split sample box' \
'git mailsplit -o. "$TEST_DIRECTORY"/t5100/sample.mbox >last &&
last=`cat last` &&
echo total is $last &&
test `cat last` = 13'
test `cat last` = 14'

check_mailinfo () {
mail=$1 opt=$2
mo="$mail$opt"
git mailinfo -u $opt msg$mo patch$mo <$mail >info$mo &&
test_cmp "$TEST_DIRECTORY"/t5100/msg$mo msg$mo &&
test_cmp "$TEST_DIRECTORY"/t5100/patch$mo patch$mo &&
test_cmp "$TEST_DIRECTORY"/t5100/info$mo info$mo
}


for mail in `echo 00*`
do
test_expect_success "mailinfo $mail" '
git mailinfo -u msg$mail patch$mail <$mail >info$mail &&
echo msg &&
test_cmp "$TEST_DIRECTORY"/t5100/msg$mail msg$mail &&
echo patch &&
test_cmp "$TEST_DIRECTORY"/t5100/patch$mail patch$mail &&
echo info &&
test_cmp "$TEST_DIRECTORY"/t5100/info$mail info$mail
check_mailinfo $mail "" &&
if test -f "$TEST_DIRECTORY"/t5100/msg$mail--scissors
then
check_mailinfo $mail --scissors
fi
'
done

Expand Down
5 changes: 5 additions & 0 deletions t/t5100/info0014
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Author: Junio Hamano
Email: junkio@cox.net
Subject: BLAH ONE
Date: Thu, 20 Aug 2009 17:18:22 -0700

5 changes: 5 additions & 0 deletions t/t5100/info0014--scissors
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Author: Junio C Hamano
Email: gitster@pobox.com
Subject: Teach mailinfo to ignore everything before -- >8 -- mark
Date: Thu, 20 Aug 2009 17:18:22 -0700

18 changes: 18 additions & 0 deletions t/t5100/msg0014
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
In real life, we will see a discussion that inspired this patch
discussing related and unrelated things around >8 scissors mark
in this part of the message.

Subject: [PATCH] BLAH TWO

And then we will see the scissors.

This line is not a scissors mark -- >8 -- but talks about it.
- - >8 - - please remove everything above this line - - >8 - -

Subject: [PATCH] Teach mailinfo to ignore everything before -- >8 -- mark
From: Junio C Hamano <gitster@pobox.com>

This teaches mailinfo the scissors -- >8 -- mark; the command ignores
everything before it in the message body.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 changes: 4 additions & 0 deletions t/t5100/msg0014--scissors
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
This teaches mailinfo the scissors -- >8 -- mark; the command ignores
everything before it in the message body.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
Loading

0 comments on commit b8711f5

Please sign in to comment.