Add a function to update HEAD after creating a commit
[gitweb.git] / builtin / commit.c
index 605ea8c0e9663726c64950dba07afe21516c9b26..7c28144446644a665f7b7d8f4b6c0a5855aef01b 100644 (file)
@@ -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);
 
@@ -1652,13 +1591,11 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
        struct strbuf sb = STRBUF_INIT;
        struct strbuf author_ident = STRBUF_INIT;
        const char *index_file, *reflog_msg;
-       char *nl;
        struct object_id oid;
        struct commit_list *parents = NULL;
        struct stat statbuf;
        struct commit *current_head = NULL;
        struct commit_extra_header *extra = NULL;
-       struct ref_transaction *transaction;
        struct strbuf err = STRBUF_INIT;
 
        if (argc == 2 && !strcmp(argv[1], "-h"))
@@ -1749,17 +1686,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);
@@ -1781,25 +1718,11 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
        strbuf_release(&author_ident);
        free_commit_extra_headers(extra);
 
-       nl = strchr(sb.buf, '\n');
-       if (nl)
-               strbuf_setlen(&sb, nl + 1 - sb.buf);
-       else
-               strbuf_addch(&sb, '\n');
-       strbuf_insert(&sb, 0, reflog_msg, strlen(reflog_msg));
-       strbuf_insert(&sb, strlen(reflog_msg), ": ", 2);
-
-       transaction = ref_transaction_begin(&err);
-       if (!transaction ||
-           ref_transaction_update(transaction, "HEAD", &oid,
-                                  current_head
-                                  ? &current_head->object.oid : &null_oid,
-                                  0, sb.buf, &err) ||
-           ref_transaction_commit(transaction, &err)) {
+       if (update_head_with_reflog(current_head, &oid, reflog_msg, &sb,
+                                   &err)) {
                rollback_index_files();
                die("%s", err.buf);
        }
-       ref_transaction_free(transaction);
 
        unlink(git_path_cherry_pick_head());
        unlink(git_path_revert_head());