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 <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Phillip Wood committed
Nov 10, 2017 at 11:09 UTC
d0aaa46fd3e53801346a4cadebf398f05d79780b
3 files changed
+91
-80
builtin/commit.c
+19
-80
@@ -128,12 +128,7 @@ static char *sign_commit;
128
* if editor is used, and only the whitespaces if the message
129
* is specified explicitly.
130
*/
131
-static enum {
132
- CLEANUP_SPACE,
133
- CLEANUP_NONE,
134
- CLEANUP_SCISSORS,
135
- CLEANUP_ALL
136
-} cleanup_mode;
131
+static enum commit_msg_cleanup_mode cleanup_mode;
132
static const char *cleanup_arg;
133
134
static enum commit_whence whence;
@@ -673,7 +668,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
668
struct strbuf sb = STRBUF_INIT;
669
const char *hook_arg1 = NULL;
670
const char *hook_arg2 = NULL;
676
- int clean_message_contents = (cleanup_mode != CLEANUP_NONE);
671
+ int clean_message_contents = (cleanup_mode != COMMIT_MSG_CLEANUP_NONE);
672
int old_display_comment_prefix;
673
674
/* 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,
807
struct ident_split ci, ai;
808
809
if (whence != FROM_COMMIT) {
815
- if (cleanup_mode == CLEANUP_SCISSORS)
810
+ if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS)
811
wt_status_add_cut_line(s->fp);
812
status_printf_ln(s, GIT_COLOR_NORMAL,
813
whence == FROM_MERGE
@@ -832,14 +827,15 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
827
}
828
829
fprintf(s->fp, "\n");
835
- if (cleanup_mode == CLEANUP_ALL)
830
+ if (cleanup_mode == COMMIT_MSG_CLEANUP_ALL)
831
status_printf(s, GIT_COLOR_NORMAL,
832
_("Please enter the commit message for your changes."
833
" Lines starting\nwith '%c' will be ignored, and an empty"
834
" message aborts the commit.\n"), comment_line_char);
840
- else if (cleanup_mode == CLEANUP_SCISSORS && whence == FROM_COMMIT)
835
+ else if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS &&
836
+ whence == FROM_COMMIT)
837
wt_status_add_cut_line(s->fp);
842
- else /* CLEANUP_SPACE, that is. */
838
+ else /* COMMIT_MSG_CLEANUP_SPACE, that is. */
839
status_printf(s, GIT_COLOR_NORMAL,
840
_("Please enter the commit message for your changes."
841
" Lines starting\n"
@@ -984,65 +980,6 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
980
return 1;
981
}
982
987
-static int rest_is_empty(struct strbuf *sb, int start)
988
-{
989
- int i, eol;
990
- const char *nl;
991
-
992
- /* Check if the rest is just whitespace and Signed-off-by's. */
993
- for (i = start; i < sb->len; i++) {
994
- nl = memchr(sb->buf + i, '\n', sb->len - i);
995
- if (nl)
996
- eol = nl - sb->buf;
997
- else
998
- eol = sb->len;
999
-
1000
- if (strlen(sign_off_header) <= eol - i &&
1001
- starts_with(sb->buf + i, sign_off_header)) {
1002
- i = eol;
1003
- continue;
1004
- }
1005
- while (i < eol)
1006
- if (!isspace(sb->buf[i++]))
1007
- return 0;
1008
- }
1009
-
1010
- return 1;
1011
-}
1012
-
1013
-/*
1014
- * Find out if the message in the strbuf contains only whitespace and
1015
- * Signed-off-by lines.
1016
- */
1017
-static int message_is_empty(struct strbuf *sb)
1018
-{
1019
- if (cleanup_mode == CLEANUP_NONE && sb->len)
1020
- return 0;
1021
- return rest_is_empty(sb, 0);
1022
-}
1023
-
1024
-/*
1025
- * See if the user edited the message in the editor or left what
1026
- * was in the template intact
1027
- */
1028
-static int template_untouched(struct strbuf *sb)
1029
-{
1030
- struct strbuf tmpl = STRBUF_INIT;
1031
- const char *start;
1032
-
1033
- if (cleanup_mode == CLEANUP_NONE && sb->len)
1034
- return 0;
1035
-
1036
- if (!template_file || strbuf_read_file(&tmpl, template_file, 0) <= 0)
1037
- return 0;
1038
-
1039
- strbuf_stripspace(&tmpl, cleanup_mode == CLEANUP_ALL);
1040
- if (!skip_prefix(sb->buf, tmpl.buf, &start))
1041
- start = sb->buf;
1042
- strbuf_release(&tmpl);
1043
- return rest_is_empty(sb, start - sb->buf);
1044
-}
1045
-
983
static const char *find_author_by_nickname(const char *name)
984
{
985
struct rev_info revs;
@@ -1214,15 +1151,17 @@ static int parse_and_validate_options(int argc, const char *argv[],
1151
if (argc == 0 && (also || (only && !amend && !allow_empty)))
1152
die(_("No paths with --include/--only does not make sense."));
1153
if (!cleanup_arg || !strcmp(cleanup_arg, "default"))
1217
- cleanup_mode = use_editor ? CLEANUP_ALL : CLEANUP_SPACE;
1154
+ cleanup_mode = use_editor ? COMMIT_MSG_CLEANUP_ALL :
1155
+ COMMIT_MSG_CLEANUP_SPACE;
1156
else if (!strcmp(cleanup_arg, "verbatim"))
1219
- cleanup_mode = CLEANUP_NONE;
1157
+ cleanup_mode = COMMIT_MSG_CLEANUP_NONE;
1158
else if (!strcmp(cleanup_arg, "whitespace"))
1221
- cleanup_mode = CLEANUP_SPACE;
1159
+ cleanup_mode = COMMIT_MSG_CLEANUP_SPACE;
1160
else if (!strcmp(cleanup_arg, "strip"))
1223
- cleanup_mode = CLEANUP_ALL;
1161
+ cleanup_mode = COMMIT_MSG_CLEANUP_ALL;
1162
else if (!strcmp(cleanup_arg, "scissors"))
1225
- cleanup_mode = use_editor ? CLEANUP_SCISSORS : CLEANUP_SPACE;
1163
+ cleanup_mode = use_editor ? COMMIT_MSG_CLEANUP_SCISSORS :
1164
+ COMMIT_MSG_CLEANUP_SPACE;
1165
else
1166
die(_("Invalid cleanup mode %s"), cleanup_arg);
1167
@@ -1749,17 +1688,17 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
1688
}
1689
1690
if (verbose || /* Truncate the message just before the diff, if any. */
1752
- cleanup_mode == CLEANUP_SCISSORS)
1691
+ cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS)
1692
strbuf_setlen(&sb, wt_status_locate_end(sb.buf, sb.len));
1754
- if (cleanup_mode != CLEANUP_NONE)
1755
- strbuf_stripspace(&sb, cleanup_mode == CLEANUP_ALL);
1693
+ if (cleanup_mode != COMMIT_MSG_CLEANUP_NONE)
1694
+ strbuf_stripspace(&sb, cleanup_mode == COMMIT_MSG_CLEANUP_ALL);
1695
1757
- if (message_is_empty(&sb) && !allow_empty_message) {
1696
+ if (message_is_empty(&sb, cleanup_mode) && !allow_empty_message) {
1697
rollback_index_files();
1698
fprintf(stderr, _("Aborting commit due to empty commit message.\n"));
1699
exit(1);
1700
}
1762
- if (template_untouched(&sb) && !allow_empty_message) {
1701
+ if (template_untouched(&sb, template_file, cleanup_mode) && !allow_empty_message) {
1702
rollback_index_files();
1703
fprintf(stderr, _("Aborting commit; you did not edit the message.\n"));
1704
exit(1);
sequencer.c
+61
@@ -691,6 +691,67 @@ static int run_git_commit(const char *defmsg, struct replay_opts *opts,
691
return run_command(&cmd);
692
}
693
694
+static int rest_is_empty(const struct strbuf *sb, int start)
695
+{
696
+ int i, eol;
697
+ const char *nl;
698
+
699
+ /* Check if the rest is just whitespace and Signed-off-by's. */
700
+ for (i = start; i < sb->len; i++) {
701
+ nl = memchr(sb->buf + i, '\n', sb->len - i);
702
+ if (nl)
703
+ eol = nl - sb->buf;
704
+ else
705
+ eol = sb->len;
706
+
707
+ if (strlen(sign_off_header) <= eol - i &&
708
+ starts_with(sb->buf + i, sign_off_header)) {
709
+ i = eol;
710
+ continue;
711
+ }
712
+ while (i < eol)
713
+ if (!isspace(sb->buf[i++]))
714
+ return 0;
715
+ }
716
+
717
+ return 1;
718
+}
719
+
720
+/*
721
+ * Find out if the message in the strbuf contains only whitespace and
722
+ * Signed-off-by lines.
723
+ */
724
+int message_is_empty(const struct strbuf *sb,
725
+ enum commit_msg_cleanup_mode cleanup_mode)
726
+{
727
+ if (cleanup_mode == COMMIT_MSG_CLEANUP_NONE && sb->len)
728
+ return 0;
729
+ return rest_is_empty(sb, 0);
730
+}
731
+
732
+/*
733
+ * See if the user edited the message in the editor or left what
734
+ * was in the template intact
735
+ */
736
+int template_untouched(const struct strbuf *sb, const char *template_file,
737
+ enum commit_msg_cleanup_mode cleanup_mode)
738
+{
739
+ struct strbuf tmpl = STRBUF_INIT;
740
+ const char *start;
741
+
742
+ if (cleanup_mode == COMMIT_MSG_CLEANUP_NONE && sb->len)
743
+ return 0;
744
+
745
+ if (!template_file || strbuf_read_file(&tmpl, template_file, 0) <= 0)
746
+ return 0;
747
+
748
+ strbuf_stripspace(&tmpl, cleanup_mode == COMMIT_MSG_CLEANUP_ALL);
749
+ if (!skip_prefix(sb->buf, tmpl.buf, &start))
750
+ start = sb->buf;
751
+ strbuf_release(&tmpl);
752
+ return rest_is_empty(sb, start - sb->buf);
753
+}
754
+
755
static int is_original_commit_empty(struct commit *commit)
756
{
757
const struct object_id *ptree_oid;
sequencer.h
+11
@@ -58,4 +58,15 @@ extern const char sign_off_header[];
58
void append_signoff(struct strbuf *msgbuf, int ignore_footer, unsigned flag);
59
void append_conflicts_hint(struct strbuf *msgbuf);
60
61
+enum commit_msg_cleanup_mode {
62
+ COMMIT_MSG_CLEANUP_SPACE,
63
+ COMMIT_MSG_CLEANUP_NONE,
64
+ COMMIT_MSG_CLEANUP_SCISSORS,
65
+ COMMIT_MSG_CLEANUP_ALL
66
+};
67
+
68
+int message_is_empty(const struct strbuf *sb,
69
+ enum commit_msg_cleanup_mode cleanup_mode);
70
+int template_untouched(const struct strbuf *sb, const char *template_file,
71
+ enum commit_msg_cleanup_mode cleanup_mode);
72
#endif