mirror of
https://github.com/git/git
synced 2024-11-05 18:59:29 +00:00
Merge branch 'ar/commit-cleanup'
* ar/commit-cleanup: Allow selection of different cleanup modes for commit messages builtin-commit: avoid double-negation in the code. builtin-commit: fix amending of the initial commit t7005: do not exit inside test.
This commit is contained in:
commit
97d0c52980
4 changed files with 125 additions and 16 deletions
|
@ -11,7 +11,7 @@ SYNOPSIS
|
||||||
'git-commit' [-a | --interactive] [-s] [-v] [-u]
|
'git-commit' [-a | --interactive] [-s] [-v] [-u]
|
||||||
[(-c | -C) <commit> | -F <file> | -m <msg> | --amend]
|
[(-c | -C) <commit> | -F <file> | -m <msg> | --amend]
|
||||||
[--allow-empty] [--no-verify] [-e] [--author <author>]
|
[--allow-empty] [--no-verify] [-e] [--author <author>]
|
||||||
[--] [[-i | -o ]<file>...]
|
[--cleanup=<mode>] [--] [[-i | -o ]<file>...]
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
|
@ -95,6 +95,16 @@ OPTIONS
|
||||||
from making such a commit. This option bypasses the safety, and
|
from making such a commit. This option bypasses the safety, and
|
||||||
is primarily for use by foreign scm interface scripts.
|
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::
|
-e|--edit::
|
||||||
The message taken from file with `-F`, command line with
|
The message taken from file with `-F`, command line with
|
||||||
`-m`, and from file with `-C` are usually used as the
|
`-m`, and from file with `-C` are usually used as the
|
||||||
|
|
|
@ -47,8 +47,21 @@ static char *logfile, *force_author, *template_file;
|
||||||
static char *edit_message, *use_message;
|
static char *edit_message, *use_message;
|
||||||
static int all, edit_flag, also, interactive, only, amend, signoff;
|
static int all, edit_flag, also, interactive, only, amend, signoff;
|
||||||
static int quiet, verbose, untracked_files, no_verify, allow_empty;
|
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 no_edit, initial_commit, in_merge;
|
static int use_editor = 1, initial_commit, in_merge;
|
||||||
const char *only_include_assumed;
|
const char *only_include_assumed;
|
||||||
struct strbuf message;
|
struct strbuf message;
|
||||||
|
|
||||||
|
@ -88,6 +101,7 @@ static struct option builtin_commit_options[] = {
|
||||||
OPT_BOOLEAN(0, "amend", &amend, "amend previous commit"),
|
OPT_BOOLEAN(0, "amend", &amend, "amend previous commit"),
|
||||||
OPT_BOOLEAN(0, "untracked-files", &untracked_files, "show all untracked files"),
|
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_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()
|
OPT_END()
|
||||||
};
|
};
|
||||||
|
@ -346,7 +360,8 @@ static int prepare_log_message(const char *index_file, const char *prefix)
|
||||||
if (fp == NULL)
|
if (fp == NULL)
|
||||||
die("could not open %s", git_path(commit_editmsg));
|
die("could not open %s", git_path(commit_editmsg));
|
||||||
|
|
||||||
stripspace(&sb, 0);
|
if (cleanup_mode != CLEANUP_NONE)
|
||||||
|
stripspace(&sb, 0);
|
||||||
|
|
||||||
if (signoff) {
|
if (signoff) {
|
||||||
struct strbuf sob;
|
struct strbuf sob;
|
||||||
|
@ -372,9 +387,9 @@ static int prepare_log_message(const char *index_file, const char *prefix)
|
||||||
|
|
||||||
strbuf_release(&sb);
|
strbuf_release(&sb);
|
||||||
|
|
||||||
if (no_edit) {
|
if (!use_editor) {
|
||||||
struct rev_info rev;
|
struct rev_info rev;
|
||||||
unsigned char sha1[40];
|
unsigned char sha1[20];
|
||||||
const char *parent = "HEAD";
|
const char *parent = "HEAD";
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
@ -382,12 +397,12 @@ static int prepare_log_message(const char *index_file, const char *prefix)
|
||||||
if (!active_nr && read_cache() < 0)
|
if (!active_nr && read_cache() < 0)
|
||||||
die("Cannot read index");
|
die("Cannot read index");
|
||||||
|
|
||||||
if (get_sha1("HEAD", sha1) != 0)
|
|
||||||
return !!active_nr;
|
|
||||||
|
|
||||||
if (amend)
|
if (amend)
|
||||||
parent = "HEAD^1";
|
parent = "HEAD^1";
|
||||||
|
|
||||||
|
if (get_sha1(parent, sha1))
|
||||||
|
return !!active_nr;
|
||||||
|
|
||||||
init_revisions(&rev, "");
|
init_revisions(&rev, "");
|
||||||
rev.abbrev = 0;
|
rev.abbrev = 0;
|
||||||
setup_revisions(0, NULL, &rev, parent);
|
setup_revisions(0, NULL, &rev, parent);
|
||||||
|
@ -398,7 +413,7 @@ static int prepare_log_message(const char *index_file, const char *prefix)
|
||||||
return !!DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES);
|
return !!DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_merge && !no_edit)
|
if (in_merge)
|
||||||
fprintf(fp,
|
fprintf(fp,
|
||||||
"#\n"
|
"#\n"
|
||||||
"# It looks like you may be committing a MERGE.\n"
|
"# It looks like you may be committing a MERGE.\n"
|
||||||
|
@ -411,7 +426,12 @@ static int prepare_log_message(const char *index_file, const char *prefix)
|
||||||
fprintf(fp,
|
fprintf(fp,
|
||||||
"\n"
|
"\n"
|
||||||
"# Please enter the commit message for your changes.\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)
|
if (only_include_assumed)
|
||||||
fprintf(fp, "# %s\n", only_include_assumed);
|
fprintf(fp, "# %s\n", only_include_assumed);
|
||||||
|
|
||||||
|
@ -435,10 +455,13 @@ static int message_is_empty(struct strbuf *sb, int start)
|
||||||
const char *nl;
|
const char *nl;
|
||||||
int eol, i;
|
int eol, i;
|
||||||
|
|
||||||
|
if (cleanup_mode == CLEANUP_NONE && sb->len)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* See if the template is just a prefix of the message. */
|
/* See if the template is just a prefix of the message. */
|
||||||
strbuf_init(&tmpl, 0);
|
strbuf_init(&tmpl, 0);
|
||||||
if (template_file && strbuf_read_file(&tmpl, template_file, 0) > 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 &&
|
if (start + tmpl.len <= sb->len &&
|
||||||
memcmp(tmpl.buf, sb->buf + start, tmpl.len) == 0)
|
memcmp(tmpl.buf, sb->buf + start, tmpl.len) == 0)
|
||||||
start += tmpl.len;
|
start += tmpl.len;
|
||||||
|
@ -513,9 +536,9 @@ static int parse_and_validate_options(int argc, const char *argv[],
|
||||||
argc = parse_options(argc, argv, builtin_commit_options, usage, 0);
|
argc = parse_options(argc, argv, builtin_commit_options, usage, 0);
|
||||||
|
|
||||||
if (logfile || message.len || use_message)
|
if (logfile || message.len || use_message)
|
||||||
no_edit = 1;
|
use_editor = 0;
|
||||||
if (edit_flag)
|
if (edit_flag)
|
||||||
no_edit = 0;
|
use_editor = 1;
|
||||||
|
|
||||||
if (get_sha1("HEAD", head_sha1))
|
if (get_sha1("HEAD", head_sha1))
|
||||||
initial_commit = 1;
|
initial_commit = 1;
|
||||||
|
@ -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...";
|
only_include_assumed = "Explicit paths specified without -i nor -o; assuming --only paths...";
|
||||||
also = 0;
|
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)
|
if (all && argc > 0)
|
||||||
die("Paths with -a does not make sense.");
|
die("Paths with -a does not make sense.");
|
||||||
|
@ -796,7 +829,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
|
||||||
|
|
||||||
/* Get the commit message and validate it */
|
/* Get the commit message and validate it */
|
||||||
header_len = sb.len;
|
header_len = sb.len;
|
||||||
if (!no_edit) {
|
if (use_editor) {
|
||||||
char index[PATH_MAX];
|
char index[PATH_MAX];
|
||||||
const char *env[2] = { index, NULL };
|
const char *env[2] = { index, NULL };
|
||||||
snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file);
|
snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file);
|
||||||
|
@ -817,7 +850,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
|
||||||
if (p != NULL)
|
if (p != NULL)
|
||||||
strbuf_setlen(&sb, p - sb.buf + 1);
|
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)) {
|
if (sb.len < header_len || message_is_empty(&sb, header_len)) {
|
||||||
rollback_index_files();
|
rollback_index_files();
|
||||||
die("no commit message? aborting commit.");
|
die("no commit message? aborting commit.");
|
||||||
|
|
|
@ -37,7 +37,7 @@ test_expect_success 'dumb should error out when falling back on vi' '
|
||||||
if git commit --amend
|
if git commit --amend
|
||||||
then
|
then
|
||||||
echo "Oops?"
|
echo "Oops?"
|
||||||
exit 1
|
false
|
||||||
else
|
else
|
||||||
: happy
|
: happy
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -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
|
test_done
|
||||||
|
|
Loading…
Reference in a new issue