Commit d0aaa46f authored by Phillip Wood's avatar Phillip Wood Committed by Junio C Hamano

commit: move empty message checks to libgit

Move the functions that check for empty messages from bulitin/commit.c
to sequencer.c so they can be shared with other commands. The
functions are refactored to take an explicit cleanup mode and template
filename passed by the caller.
Signed-off-by: Phillip Wood's avatarPhillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
parent 60b61588
......@@ -128,12 +128,7 @@ static char *sign_commit;
* if editor is used, and only the whitespaces if the message
* is specified explicitly.
*/
static enum {
CLEANUP_SPACE,
CLEANUP_NONE,
CLEANUP_SCISSORS,
CLEANUP_ALL
} cleanup_mode;
static enum commit_msg_cleanup_mode cleanup_mode;
static const char *cleanup_arg;
static enum commit_whence whence;
......@@ -673,7 +668,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
struct strbuf sb = STRBUF_INIT;
const char *hook_arg1 = NULL;
const char *hook_arg2 = NULL;
int clean_message_contents = (cleanup_mode != CLEANUP_NONE);
int clean_message_contents = (cleanup_mode != COMMIT_MSG_CLEANUP_NONE);
int old_display_comment_prefix;
/* This checks and barfs if author is badly specified */
......@@ -812,7 +807,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
struct ident_split ci, ai;
if (whence != FROM_COMMIT) {
if (cleanup_mode == CLEANUP_SCISSORS)
if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS)
wt_status_add_cut_line(s->fp);
status_printf_ln(s, GIT_COLOR_NORMAL,
whence == FROM_MERGE
......@@ -832,14 +827,15 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
}
fprintf(s->fp, "\n");
if (cleanup_mode == CLEANUP_ALL)
if (cleanup_mode == COMMIT_MSG_CLEANUP_ALL)
status_printf(s, GIT_COLOR_NORMAL,
_("Please enter the commit message for your changes."
" Lines starting\nwith '%c' will be ignored, and an empty"
" message aborts the commit.\n"), comment_line_char);
else if (cleanup_mode == CLEANUP_SCISSORS && whence == FROM_COMMIT)
else if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS &&
whence == FROM_COMMIT)
wt_status_add_cut_line(s->fp);
else /* CLEANUP_SPACE, that is. */
else /* COMMIT_MSG_CLEANUP_SPACE, that is. */
status_printf(s, GIT_COLOR_NORMAL,
_("Please enter the commit message for your changes."
" Lines starting\n"
......@@ -984,65 +980,6 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
return 1;
}
static int rest_is_empty(struct strbuf *sb, int start)
{
int i, eol;
const char *nl;
/* Check if the rest is just whitespace and Signed-off-by's. */
for (i = start; i < sb->len; i++) {
nl = memchr(sb->buf + i, '\n', sb->len - i);
if (nl)
eol = nl - sb->buf;
else
eol = sb->len;
if (strlen(sign_off_header) <= eol - i &&
starts_with(sb->buf + i, sign_off_header)) {
i = eol;
continue;
}
while (i < eol)
if (!isspace(sb->buf[i++]))
return 0;
}
return 1;
}
/*
* Find out if the message in the strbuf contains only whitespace and
* Signed-off-by lines.
*/
static int message_is_empty(struct strbuf *sb)
{
if (cleanup_mode == CLEANUP_NONE && sb->len)
return 0;
return rest_is_empty(sb, 0);
}
/*
* See if the user edited the message in the editor or left what
* was in the template intact
*/
static int template_untouched(struct strbuf *sb)
{
struct strbuf tmpl = STRBUF_INIT;
const char *start;
if (cleanup_mode == CLEANUP_NONE && sb->len)
return 0;
if (!template_file || strbuf_read_file(&tmpl, template_file, 0) <= 0)
return 0;
strbuf_stripspace(&tmpl, cleanup_mode == CLEANUP_ALL);
if (!skip_prefix(sb->buf, tmpl.buf, &start))
start = sb->buf;
strbuf_release(&tmpl);
return rest_is_empty(sb, start - sb->buf);
}
static const char *find_author_by_nickname(const char *name)
{
struct rev_info revs;
......@@ -1214,15 +1151,17 @@ static int parse_and_validate_options(int argc, const char *argv[],
if (argc == 0 && (also || (only && !amend && !allow_empty)))
die(_("No paths with --include/--only does not make sense."));
if (!cleanup_arg || !strcmp(cleanup_arg, "default"))
cleanup_mode = use_editor ? CLEANUP_ALL : CLEANUP_SPACE;
cleanup_mode = use_editor ? COMMIT_MSG_CLEANUP_ALL :
COMMIT_MSG_CLEANUP_SPACE;
else if (!strcmp(cleanup_arg, "verbatim"))
cleanup_mode = CLEANUP_NONE;
cleanup_mode = COMMIT_MSG_CLEANUP_NONE;
else if (!strcmp(cleanup_arg, "whitespace"))
cleanup_mode = CLEANUP_SPACE;
cleanup_mode = COMMIT_MSG_CLEANUP_SPACE;
else if (!strcmp(cleanup_arg, "strip"))
cleanup_mode = CLEANUP_ALL;
cleanup_mode = COMMIT_MSG_CLEANUP_ALL;
else if (!strcmp(cleanup_arg, "scissors"))
cleanup_mode = use_editor ? CLEANUP_SCISSORS : CLEANUP_SPACE;
cleanup_mode = use_editor ? COMMIT_MSG_CLEANUP_SCISSORS :
COMMIT_MSG_CLEANUP_SPACE;
else
die(_("Invalid cleanup mode %s"), cleanup_arg);
......@@ -1749,17 +1688,17 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
}
if (verbose || /* Truncate the message just before the diff, if any. */
cleanup_mode == CLEANUP_SCISSORS)
cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS)
strbuf_setlen(&sb, wt_status_locate_end(sb.buf, sb.len));
if (cleanup_mode != CLEANUP_NONE)
strbuf_stripspace(&sb, cleanup_mode == CLEANUP_ALL);
if (cleanup_mode != COMMIT_MSG_CLEANUP_NONE)
strbuf_stripspace(&sb, cleanup_mode == COMMIT_MSG_CLEANUP_ALL);
if (message_is_empty(&sb) && !allow_empty_message) {
if (message_is_empty(&sb, cleanup_mode) && !allow_empty_message) {
rollback_index_files();
fprintf(stderr, _("Aborting commit due to empty commit message.\n"));
exit(1);
}
if (template_untouched(&sb) && !allow_empty_message) {
if (template_untouched(&sb, template_file, cleanup_mode) && !allow_empty_message) {
rollback_index_files();
fprintf(stderr, _("Aborting commit; you did not edit the message.\n"));
exit(1);
......
......@@ -691,6 +691,67 @@ static int run_git_commit(const char *defmsg, struct replay_opts *opts,
return run_command(&cmd);
}
static int rest_is_empty(const struct strbuf *sb, int start)
{
int i, eol;
const char *nl;
/* Check if the rest is just whitespace and Signed-off-by's. */
for (i = start; i < sb->len; i++) {
nl = memchr(sb->buf + i, '\n', sb->len - i);
if (nl)
eol = nl - sb->buf;
else
eol = sb->len;
if (strlen(sign_off_header) <= eol - i &&
starts_with(sb->buf + i, sign_off_header)) {
i = eol;
continue;
}
while (i < eol)
if (!isspace(sb->buf[i++]))
return 0;
}
return 1;
}
/*
* Find out if the message in the strbuf contains only whitespace and
* Signed-off-by lines.
*/
int message_is_empty(const struct strbuf *sb,
enum commit_msg_cleanup_mode cleanup_mode)
{
if (cleanup_mode == COMMIT_MSG_CLEANUP_NONE && sb->len)
return 0;
return rest_is_empty(sb, 0);
}
/*
* See if the user edited the message in the editor or left what
* was in the template intact
*/
int template_untouched(const struct strbuf *sb, const char *template_file,
enum commit_msg_cleanup_mode cleanup_mode)
{
struct strbuf tmpl = STRBUF_INIT;
const char *start;
if (cleanup_mode == COMMIT_MSG_CLEANUP_NONE && sb->len)
return 0;
if (!template_file || strbuf_read_file(&tmpl, template_file, 0) <= 0)
return 0;
strbuf_stripspace(&tmpl, cleanup_mode == COMMIT_MSG_CLEANUP_ALL);
if (!skip_prefix(sb->buf, tmpl.buf, &start))
start = sb->buf;
strbuf_release(&tmpl);
return rest_is_empty(sb, start - sb->buf);
}
static int is_original_commit_empty(struct commit *commit)
{
const struct object_id *ptree_oid;
......
......@@ -58,4 +58,15 @@ extern const char sign_off_header[];
void append_signoff(struct strbuf *msgbuf, int ignore_footer, unsigned flag);
void append_conflicts_hint(struct strbuf *msgbuf);
enum commit_msg_cleanup_mode {
COMMIT_MSG_CLEANUP_SPACE,
COMMIT_MSG_CLEANUP_NONE,
COMMIT_MSG_CLEANUP_SCISSORS,
COMMIT_MSG_CLEANUP_ALL
};
int message_is_empty(const struct strbuf *sb,
enum commit_msg_cleanup_mode cleanup_mode);
int template_untouched(const struct strbuf *sb, const char *template_file,
enum commit_msg_cleanup_mode cleanup_mode);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment