Merge branch 'am/cherry-pick-rerere'
[gitweb.git] / builtin-commit.c
index ed3fe3f7ee033e09f87c0a86dc7db70b13c6a262..649c8beb3e716dd5797787ced61d2fee23b7140f 100644 (file)
@@ -21,7 +21,7 @@
 #include "strbuf.h"
 #include "utf8.h"
 #include "parse-options.h"
-#include "path-list.h"
+#include "string-list.h"
 #include "rerere.h"
 #include "unpack-trees.h"
 
@@ -46,7 +46,7 @@ static enum {
        COMMIT_PARTIAL,
 } commit_style;
 
-static char *logfile, *force_author;
+static const char *logfile, *force_author;
 static const char *template_file;
 static char *edit_message, *use_message;
 static char *author_name, *author_email, *author_date;
@@ -68,8 +68,8 @@ static enum {
 static char *cleanup_arg;
 
 static int use_editor = 1, initial_commit, in_merge;
-const char *only_include_assumed;
-struct strbuf message;
+static const char *only_include_assumed;
+static struct strbuf message;
 
 static int opt_parse_m(const struct option *opt, const char *arg, int unset)
 {
@@ -78,8 +78,7 @@ static int opt_parse_m(const struct option *opt, const char *arg, int unset)
                strbuf_setlen(buf, 0);
        else {
                strbuf_addstr(buf, arg);
-               strbuf_addch(buf, '\n');
-               strbuf_addch(buf, '\n');
+               strbuf_addstr(buf, "\n\n");
        }
        return 0;
 }
@@ -150,7 +149,7 @@ static int commit_index_files(void)
  * Take a union of paths in the index and the named tree (typically, "HEAD"),
  * and return the paths that match the given pattern in list.
  */
-static int list_paths(struct path_list *list, const char *with_tree,
+static int list_paths(struct string_list *list, const char *with_tree,
                      const char *prefix, const char **pattern)
 {
        int i;
@@ -169,24 +168,24 @@ static int list_paths(struct path_list *list, const char *with_tree,
                        continue;
                if (!pathspec_match(pattern, m, ce->name, 0))
                        continue;
-               path_list_insert(ce->name, list);
+               string_list_insert(ce->name, list);
        }
 
        return report_path_error(m, pattern, prefix ? strlen(prefix) : 0);
 }
 
-static void add_remove_files(struct path_list *list)
+static void add_remove_files(struct string_list *list)
 {
        int i;
        for (i = 0; i < list->nr; i++) {
                struct stat st;
-               struct path_list_item *p = &(list->items[i]);
+               struct string_list_item *p = &(list->items[i]);
 
-               if (!lstat(p->path, &st)) {
-                       if (add_to_cache(p->path, &st, 0))
+               if (!lstat(p->string, &st)) {
+                       if (add_to_cache(p->string, &st, 0))
                                die("updating files failed");
                } else
-                       remove_file_from_cache(p->path);
+                       remove_file_from_cache(p->string);
        }
 }
 
@@ -221,7 +220,7 @@ static void create_base_index(void)
 static char *prepare_index(int argc, const char **argv, const char *prefix)
 {
        int fd;
-       struct path_list partial;
+       struct string_list partial;
        const char **pathspec = NULL;
 
        if (interactive) {
@@ -305,7 +304,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix)
                die("cannot do a partial commit during a merge.");
 
        memset(&partial, 0, sizeof(partial));
-       partial.strdup_paths = 1;
+       partial.strdup_strings = 1;
        if (list_paths(&partial, initial_commit ? NULL : "HEAD", prefix, pathspec))
                exit(1);
 
@@ -555,13 +554,18 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
 
                fprintf(fp,
                        "\n"
-                       "# Please enter the commit message for your changes.\n"
-                       "# (Comment lines starting with '#' will ");
+                       "# Please enter the commit message for your changes.");
                if (cleanup_mode == CLEANUP_ALL)
-                       fprintf(fp, "not be included)\n");
+                       fprintf(fp,
+                               " Lines starting\n"
+                               "# with '#' will be ignored, and an empty"
+                               " message aborts the commit.\n");
                else /* CLEANUP_SPACE, that is. */
-                       fprintf(fp, "be kept.\n"
-                               "# You can remove them yourself if you want to)\n");
+                       fprintf(fp,
+                               " Lines starting\n"
+                               "# with '#' will be kept; you may remove them"
+                               " yourself if you want to.\n"
+                               "# An empty message aborts the commit.\n");
                if (only_include_assumed)
                        fprintf(fp, "# %s\n", only_include_assumed);
 
@@ -647,7 +651,11 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
                char index[PATH_MAX];
                const char *env[2] = { index, NULL };
                snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file);
-               launch_editor(git_path(commit_editmsg), NULL, env);
+               if (launch_editor(git_path(commit_editmsg), NULL, env)) {
+                       fprintf(stderr,
+                       "Please supply the message using either -m or -F option.\n");
+                       exit(1);
+               }
        }
 
        if (!no_verify &&
@@ -703,11 +711,14 @@ static int message_is_empty(struct strbuf *sb, int start)
 }
 
 static int parse_and_validate_options(int argc, const char *argv[],
-                                     const char * const usage[])
+                                     const char * const usage[],
+                                     const char *prefix)
 {
        int f = 0;
 
        argc = parse_options(argc, argv, builtin_commit_options, usage, 0);
+       logfile = parse_options_fix_filename(prefix, logfile);
+       template_file = parse_options_fix_filename(prefix, template_file);
 
        if (logfile || message.len || use_message)
                use_editor = 0;
@@ -828,7 +839,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
        if (wt_status_use_color == -1)
                wt_status_use_color = git_use_color_default;
 
-       argc = parse_and_validate_options(argc, argv, builtin_status_usage);
+       argc = parse_and_validate_options(argc, argv, builtin_status_usage, prefix);
 
        index_file = prepare_index(argc, argv, prefix);
 
@@ -877,7 +888,7 @@ static void print_summary(const char *prefix, const unsigned char *sha1)
        }
 }
 
-int git_commit_config(const char *k, const char *v, void *cb)
+static int git_commit_config(const char *k, const char *v, void *cb)
 {
        if (!strcmp(k, "commit.template"))
                return git_config_string(&template_file, k, v);
@@ -921,7 +932,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 
        git_config(git_commit_config, NULL);
 
-       argc = parse_and_validate_options(argc, argv, builtin_commit_usage);
+       argc = parse_and_validate_options(argc, argv, builtin_commit_usage, prefix);
 
        index_file = prepare_index(argc, argv, prefix);
 
@@ -1000,7 +1011,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
                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.");
+               fprintf(stderr, "Aborting commit due to empty commit message.\n");
+               exit(1);
        }
        strbuf_addch(&sb, '\0');
        if (is_encoding_utf8(git_commit_encoding) && !is_utf8(sb.buf))