]> asedeno.scripts.mit.edu Git - git.git/blobdiff - builtin-rerere.c
Merge branch 'jk/pager-config'
[git.git] / builtin-rerere.c
index addc5c73df0fd909d6e8e3aa799b73028819f0b7..839b26e8e0a10a498a81bf27d907543e7c256cb8 100644 (file)
@@ -16,6 +16,9 @@ static int cutoff_resolve = 60;
 /* if rerere_enabled == -1, fall back to detection of .git/rr-cache */
 static int rerere_enabled = -1;
 
+/* automatically update cleanly resolved paths to the index */
+static int rerere_autoupdate;
+
 static char *merge_rr_path;
 
 static const char *rr_path(const char *name, const char *file)
@@ -66,8 +69,12 @@ static int write_rr(struct path_list *rr, int out_fd)
 {
        int i;
        for (i = 0; i < rr->nr; i++) {
-               const char *path = rr->items[i].path;
-               int length = strlen(path) + 1;
+               const char *path;
+               int length;
+               if (!rr->items[i].util)
+                       continue;
+               path = rr->items[i].path;
+               length = strlen(path) + 1;
                if (write_in_full(out_fd, rr->items[i].util, 40) != 40 ||
                    write_in_full(out_fd, "\t", 1) != 1 ||
                    write_in_full(out_fd, path, length) != length)
@@ -272,9 +279,36 @@ static int diff_two(const char *file1, const char *label1,
        return 0;
 }
 
+static struct lock_file index_lock;
+
+static int update_paths(struct path_list *update)
+{
+       int i;
+       int fd = hold_locked_index(&index_lock, 0);
+       int status = 0;
+
+       if (fd < 0)
+               return -1;
+
+       for (i = 0; i < update->nr; i++) {
+               struct path_list_item *item = &update->items[i];
+               if (add_file_to_cache(item->path, ADD_CACHE_IGNORE_ERRORS))
+                       status = -1;
+       }
+
+       if (!status && active_cache_changed) {
+               if (write_cache(fd, active_cache, active_nr) ||
+                   commit_locked_index(&index_lock))
+                       die("Unable to write new index file");
+       } else if (fd >= 0)
+               rollback_lock_file(&index_lock);
+       return status;
+}
+
 static int do_plain_rerere(struct path_list *rr, int fd)
 {
        struct path_list conflict = { NULL, 0, 0, 1 };
+       struct path_list update = { NULL, 0, 0, 1 };
        int i;
 
        find_conflict(&conflict);
@@ -319,7 +353,9 @@ static int do_plain_rerere(struct path_list *rr, int fd)
                        if (!merge(name, path)) {
                                fprintf(stderr, "Resolved '%s' using "
                                                "previous resolution.\n", path);
-                               goto tail_optimization;
+                               if (rerere_autoupdate)
+                                       path_list_insert(path, &update);
+                               goto mark_resolved;
                        }
                }
 
@@ -330,15 +366,13 @@ static int do_plain_rerere(struct path_list *rr, int fd)
 
                fprintf(stderr, "Recorded resolution for '%s'.\n", path);
                copy_file(rr_path(name, "postimage"), path, 0666);
-tail_optimization:
-               if (i < rr->nr - 1)
-                       memmove(rr->items + i,
-                               rr->items + i + 1,
-                               sizeof(rr->items[0]) * (rr->nr - i - 1));
-               rr->nr--;
-               i--;
+       mark_resolved:
+               rr->items[i].util = NULL;
        }
 
+       if (update.nr)
+               update_paths(&update);
+
        return write_rr(rr, fd);
 }
 
@@ -350,6 +384,8 @@ static int git_rerere_config(const char *var, const char *value, void *cb)
                cutoff_noresolve = git_config_int(var, value);
        else if (!strcmp(var, "rerere.enabled"))
                rerere_enabled = git_config_bool(var, value);
+       else if (!strcmp(var, "rerere.autoupdate"))
+               rerere_autoupdate = git_config_bool(var, value);
        else
                return git_default_config(var, value, cb);
        return 0;