Move pack_refs() and friends into libgit
[gitweb.git] / builtin-commit.c
index 4e51b9e354aab53de2a1fc721ab37b7da846c8da..90200ed643bcf21f28a66396f0d15db920a5d4c8 100644 (file)
@@ -102,7 +102,7 @@ static struct option builtin_commit_options[] = {
        OPT_BOOLEAN('o', "only", &only, "commit only specified files"),
        OPT_BOOLEAN('n', "no-verify", &no_verify, "bypass pre-commit hook"),
        OPT_BOOLEAN(0, "amend", &amend, "amend previous commit"),
-       OPT_BOOLEAN(0, "untracked-files", &untracked_files, "show all untracked files"),
+       OPT_BOOLEAN('u', "untracked-files", &untracked_files, "show all untracked files"),
        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"),
 
@@ -176,10 +176,13 @@ static void add_remove_files(struct path_list *list)
 {
        int i;
        for (i = 0; i < list->nr; i++) {
+               struct stat st;
                struct path_list_item *p = &(list->items[i]);
-               if (file_exists(p->path))
-                       add_file_to_cache(p->path, 0);
-               else
+
+               if (!lstat(p->path, &st)) {
+                       if (add_to_cache(p->path, &st, 0))
+                               die("updating files failed");
+               } else
                        remove_file_from_cache(p->path);
        }
 }
@@ -220,6 +223,8 @@ static char *prepare_index(int argc, const char **argv, const char *prefix)
 
        if (interactive) {
                interactive_add(argc, argv, prefix);
+               if (read_cache() < 0)
+                       die("index file corrupt");
                commit_style = COMMIT_AS_IS;
                return get_index_file();
        }
@@ -244,7 +249,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix)
         */
        if (all || (also && pathspec && *pathspec)) {
                int fd = hold_locked_index(&index_lock, 1);
-               add_files_to_cache(0, also ? prefix : NULL, pathspec);
+               add_files_to_cache(also ? prefix : NULL, pathspec, 0);
                refresh_cache(REFRESH_QUIET);
                if (write_cache(fd, active_cache, active_nr) ||
                    close_lock_file(&index_lock))
@@ -446,6 +451,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
        FILE *fp;
        const char *hook_arg1 = NULL;
        const char *hook_arg2 = NULL;
+       int ident_shown = 0;
 
        if (!no_verify && run_hook(index_file, "pre-commit", NULL))
                return 0;
@@ -527,6 +533,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
 
        determine_author_info();
 
+       /* This checks if committer ident is explicitly given */
+       git_committer_info(0);
        if (use_editor) {
                char *author_ident;
                const char *committer_ident;
@@ -558,12 +566,22 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
                                           getenv("GIT_COMMITTER_EMAIL"));
                if (strcmp(author_ident, committer_ident))
                        fprintf(fp,
-                               "#\n"
-                               "# Author:    %s\n"
-                               "#\n",
+                               "%s"
+                               "# Author:    %s\n",
+                               ident_shown++ ? "" : "#\n",
                                author_ident);
                free(author_ident);
 
+               if (!user_ident_explicitly_given)
+                       fprintf(fp,
+                               "%s"
+                               "# Committer: %s\n",
+                               ident_shown++ ? "" : "#\n",
+                               committer_ident);
+
+               if (ident_shown)
+                       fprintf(fp, "#\n");
+
                saved_color_setting = wt_status_use_color;
                wt_status_use_color = 0;
                commitable = run_status(fp, index_file, prefix, 1);
@@ -790,7 +808,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
        const char *index_file;
        int commitable;
 
-       git_config(git_status_config);
+       git_config(git_status_config, NULL);
 
        if (wt_status_use_color == -1)
                wt_status_use_color = git_use_color_default;
@@ -844,7 +862,7 @@ static void print_summary(const char *prefix, const unsigned char *sha1)
        }
 }
 
-int git_commit_config(const char *k, const char *v)
+int git_commit_config(const char *k, const char *v, void *cb)
 {
        if (!strcmp(k, "commit.template")) {
                if (!v)
@@ -853,7 +871,7 @@ int git_commit_config(const char *k, const char *v)
                return 0;
        }
 
-       return git_status_config(k, v);
+       return git_status_config(k, v, cb);
 }
 
 static const char commit_utf8_warn[] =
@@ -865,10 +883,19 @@ static void add_parent(struct strbuf *sb, const unsigned char *sha1)
 {
        struct object *obj = parse_object(sha1);
        const char *parent = sha1_to_hex(sha1);
+       const char *cp;
+
        if (!obj)
                die("Unable to find commit parent %s", parent);
        if (obj->type != OBJ_COMMIT)
                die("Parent %s isn't a proper commit", parent);
+
+       for (cp = sb->buf; cp && (cp = strstr(cp, "\nparent ")); cp += 8) {
+               if (!memcmp(cp + 8, parent, 40) && cp[48] == '\n') {
+                       error("duplicate parent %s ignored", parent);
+                       return;
+               }
+       }
        strbuf_addf(sb, "parent %s\n", parent);
 }
 
@@ -881,7 +908,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
        unsigned char commit_sha1[20];
        struct ref_lock *ref_lock;
 
-       git_config(git_commit_config);
+       git_config(git_commit_config, NULL);
 
        argc = parse_and_validate_options(argc, argv, builtin_commit_usage);