Skip to content

Commit

Permalink
Allow selection of different cleanup modes for commit messages
Browse files Browse the repository at this point in the history
Although we traditionally stripped away excess blank lines, trailing
whitespaces and lines that begin with "#" from the commit log message,
sometimes the message just has to be the way user wants it.

For instance, a commit message template can contain lines that begin with
"#", the message must be kept as close to its original source as possible
if you are converting from a foreign SCM, or maybe the message has a shell
script including its comments for future reference.

The cleanup modes are default, verbatim, whitespace and strip. The
default mode depends on if the message is being edited and will either
strip whitespace and comments (if editor active) or just strip the
whitespace (for where the message is given explicitely).

Signed-off-by: Alex Riesen <raa.lkml@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Alex Riesen authored and Junio C Hamano committed Dec 23, 2007
1 parent 4803466 commit 5f06573
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 5 deletions.
12 changes: 11 additions & 1 deletion Documentation/git-commit.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ SYNOPSIS
'git-commit' [-a | --interactive] [-s] [-v] [-u]
[(-c | -C) <commit> | -F <file> | -m <msg> | --amend]
[--allow-empty] [--no-verify] [-e] [--author <author>]
[--] [[-i | -o ]<file>...]
[--cleanup=<mode>] [--] [[-i | -o ]<file>...]

DESCRIPTION
-----------
Expand Down Expand Up @@ -95,6 +95,16 @@ OPTIONS
from making such a commit. This option bypasses the safety, and
is primarily for use by foreign scm interface scripts.

--cleanup=<mode>::
This option sets how the commit message is cleaned up.
The '<mode>' can be one of 'verbatim', 'whitespace', 'strip',
and 'default'. The 'default' mode will strip leading and
trailing empty lines and #commentary from the commit message
only if the message is to be edited. Otherwise only whitespace
removed. The 'verbatim' mode does not change message at all,
'whitespace' removes just leading/trailing whitespace lines
and 'strip' removes both whitespace and commentary.

-e|--edit::
The message taken from file with `-F`, command line with
`-m`, and from file with `-C` are usually used as the
Expand Down
42 changes: 38 additions & 4 deletions builtin-commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,19 @@ static char *logfile, *force_author, *template_file;
static char *edit_message, *use_message;
static int all, edit_flag, also, interactive, only, amend, signoff;
static int quiet, verbose, untracked_files, no_verify, allow_empty;
/*
* The default commit message cleanup mode will remove the lines
* beginning with # (shell comments) and leading and trailing
* whitespaces (empty lines or containing only whitespaces)
* if editor is used, and only the whitespaces if the message
* is specified explicitly.
*/
static enum {
CLEANUP_SPACE,
CLEANUP_NONE,
CLEANUP_ALL,
} cleanup_mode;
static char *cleanup_arg;

static int use_editor = 1, initial_commit, in_merge;
const char *only_include_assumed;
Expand Down Expand Up @@ -88,6 +101,7 @@ static struct option builtin_commit_options[] = {
OPT_BOOLEAN(0, "amend", &amend, "amend previous commit"),
OPT_BOOLEAN(0, "untracked-files", &untracked_files, "show all untracked files"),
OPT_BOOLEAN(0, "allow-empty", &allow_empty, "ok to record an empty change"),
OPT_STRING(0, "cleanup", &cleanup_arg, "default", "how to strip spaces and #comments from message"),

OPT_END()
};
Expand Down Expand Up @@ -346,7 +360,8 @@ static int prepare_log_message(const char *index_file, const char *prefix)
if (fp == NULL)
die("could not open %s", git_path(commit_editmsg));

stripspace(&sb, 0);
if (cleanup_mode != CLEANUP_NONE)
stripspace(&sb, 0);

if (signoff) {
struct strbuf sob;
Expand Down Expand Up @@ -411,7 +426,12 @@ static int prepare_log_message(const char *index_file, const char *prefix)
fprintf(fp,
"\n"
"# Please enter the commit message for your changes.\n"
"# (Comment lines starting with '#' will not be included)\n");
"# (Comment lines starting with '#' will ");
if (cleanup_mode == CLEANUP_ALL)
fprintf(fp, "not be included)\n");
else /* CLEANUP_SPACE, that is. */
fprintf(fp, "be kept.\n"
"# You can remove them yourself if you want to)\n");
if (only_include_assumed)
fprintf(fp, "# %s\n", only_include_assumed);

Expand All @@ -435,10 +455,13 @@ static int message_is_empty(struct strbuf *sb, int start)
const char *nl;
int eol, i;

if (cleanup_mode == CLEANUP_NONE && sb->len)
return 0;

/* See if the template is just a prefix of the message. */
strbuf_init(&tmpl, 0);
if (template_file && strbuf_read_file(&tmpl, template_file, 0) > 0) {
stripspace(&tmpl, 1);
stripspace(&tmpl, cleanup_mode == CLEANUP_ALL);
if (start + tmpl.len <= sb->len &&
memcmp(tmpl.buf, sb->buf + start, tmpl.len) == 0)
start += tmpl.len;
Expand Down Expand Up @@ -591,6 +614,16 @@ static int parse_and_validate_options(int argc, const char *argv[],
only_include_assumed = "Explicit paths specified without -i nor -o; assuming --only paths...";
also = 0;
}
if (!cleanup_arg || !strcmp(cleanup_arg, "default"))
cleanup_mode = use_editor ? CLEANUP_ALL : CLEANUP_SPACE;
else if (!strcmp(cleanup_arg, "verbatim"))
cleanup_mode = CLEANUP_NONE;
else if (!strcmp(cleanup_arg, "whitespace"))
cleanup_mode = CLEANUP_SPACE;
else if (!strcmp(cleanup_arg, "strip"))
cleanup_mode = CLEANUP_ALL;
else
die("Invalid cleanup mode %s", cleanup_arg);

if (all && argc > 0)
die("Paths with -a does not make sense.");
Expand Down Expand Up @@ -817,7 +850,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
if (p != NULL)
strbuf_setlen(&sb, p - sb.buf + 1);

stripspace(&sb, 1);
if (cleanup_mode != CLEANUP_NONE)
stripspace(&sb, cleanup_mode == CLEANUP_ALL);
if (sb.len < header_len || message_is_empty(&sb, header_len)) {
rollback_index_files();
die("no commit message? aborting commit.");
Expand Down
65 changes: 65 additions & 0 deletions t/t7502-commit.sh
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,69 @@ test_expect_success 'verbose' '
'

test_expect_success 'cleanup commit messages (verbatim,-t)' '
echo >>negative &&
{ echo;echo "# text";echo; } >expect &&
git commit --cleanup=verbatim -t expect -a &&
git cat-file -p HEAD |sed -e "1,/^\$/d" |head -n 3 >actual &&
diff -u expect actual
'

test_expect_success 'cleanup commit messages (verbatim,-F)' '
echo >>negative &&
git commit --cleanup=verbatim -F expect -a &&
git cat-file -p HEAD |sed -e "1,/^\$/d">actual &&
diff -u expect actual
'

test_expect_success 'cleanup commit messages (verbatim,-m)' '
echo >>negative &&
git commit --cleanup=verbatim -m "$(cat expect)" -a &&
git cat-file -p HEAD |sed -e "1,/^\$/d">actual &&
diff -u expect actual
'

test_expect_success 'cleanup commit messages (whitespace,-F)' '
echo >>negative &&
{ echo;echo "# text";echo; } >text &&
echo "# text" >expect &&
git commit --cleanup=whitespace -F text -a &&
git cat-file -p HEAD |sed -e "1,/^\$/d">actual &&
diff -u expect actual
'

test_expect_success 'cleanup commit messages (strip,-F)' '
echo >>negative &&
{ echo;echo "# text";echo sample;echo; } >text &&
echo sample >expect &&
git commit --cleanup=strip -F text -a &&
git cat-file -p HEAD |sed -e "1,/^\$/d">actual &&
diff -u expect actual
'

echo "sample
# Please enter the commit message for your changes.
# (Comment lines starting with '#' will not be included)" >expect

test_expect_success 'cleanup commit messages (strip,-F,-e)' '
echo >>negative &&
{ echo;echo sample;echo; } >text &&
git commit -e -F text -a &&
head -n 4 .git/COMMIT_EDITMSG >actual &&
diff -u expect actual
'

test_done

0 comments on commit 5f06573

Please sign in to comment.