From: Junio C Hamano Date: Mon, 23 May 2016 21:54:37 +0000 (-0700) Subject: Merge branch 'jc/rerere-multi' X-Git-Tag: v2.9.0-rc0~2 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/ec34a8b135182ed41786cd87295d7086283dee64?ds=inline;hp=-c Merge branch 'jc/rerere-multi' * jc/rerere-multi: rerere: remove an null statement rerere: plug memory leaks upon "rerere forget" failure --- ec34a8b135182ed41786cd87295d7086283dee64 diff --combined rerere.c index 1810c040da,d4929a66ae..aaadec17d8 --- a/rerere.c +++ b/rerere.c @@@ -21,6 -21,8 +21,6 @@@ static int rerere_enabled = -1 /* automatically update cleanly resolved paths to the index */ static int rerere_autoupdate; -static char *merge_rr_path; - static int rerere_dir_nr; static int rerere_dir_alloc; @@@ -200,7 -202,7 +200,7 @@@ static struct rerere_id *new_rerere_id( static void read_rr(struct string_list *rr) { struct strbuf buf = STRBUF_INIT; - FILE *in = fopen(merge_rr_path, "r"); + FILE *in = fopen(git_path_merge_rr(), "r"); if (!in) return; @@@ -501,7 -503,8 +501,7 @@@ static int handle_file(const char *path error("There were errors while writing %s (%s)", path, strerror(io.io.wrerror)); if (io.io.output && fclose(io.io.output)) - io.io.wrerror = error("Failed to flush %s: %s", - path, strerror(errno)); + io.io.wrerror = error_errno("Failed to flush %s", path); if (hunk_no < 0) { if (output) @@@ -597,8 -600,6 +597,8 @@@ static int find_conflict(struct string_ int rerere_remaining(struct string_list *merge_rr) { int i; + if (setup_rerere(merge_rr, RERERE_READONLY)) + return 0; if (read_cache() < 0) return error("Could not read index"); @@@ -683,17 -684,20 +683,17 @@@ static int merge(const struct rerere_i * Mark that "postimage" was used to help gc. */ if (utime(rerere_path(id, "postimage"), NULL) < 0) - warning("failed utime() on %s: %s", - rerere_path(id, "postimage"), - strerror(errno)); + warning_errno("failed utime() on %s", + rerere_path(id, "postimage")); /* Update "path" with the resolution */ f = fopen(path, "w"); if (!f) - return error("Could not open %s: %s", path, - strerror(errno)); + return error_errno("Could not open %s", path); if (fwrite(result.ptr, result.size, 1, f) != 1) - error("Could not write %s: %s", path, strerror(errno)); + error_errno("Could not write %s", path); if (fclose(f)) - return error("Writing %s failed: %s", path, - strerror(errno)); + return error_errno("Writing %s failed", path); out: free(cur.ptr); @@@ -866,21 -870,21 +866,21 @@@ static void git_rerere_config(void git_config(git_default_config, NULL); } +static GIT_PATH_FUNC(git_path_rr_cache, "rr-cache") + static int is_rerere_enabled(void) { - const char *rr_cache; int rr_cache_exists; if (!rerere_enabled) return 0; - rr_cache = git_path("rr-cache"); - rr_cache_exists = is_directory(rr_cache); + rr_cache_exists = is_directory(git_path_rr_cache()); if (rerere_enabled < 0) return rr_cache_exists; - if (!rr_cache_exists && mkdir_in_gitdir(rr_cache)) - die("Could not create directory %s", rr_cache); + if (!rr_cache_exists && mkdir_in_gitdir(git_path_rr_cache())) + die("Could not create directory %s", git_path_rr_cache()); return 1; } @@@ -894,11 -898,9 +894,11 @@@ int setup_rerere(struct string_list *me if (flags & (RERERE_AUTOUPDATE|RERERE_NOAUTOUPDATE)) rerere_autoupdate = !!(flags & RERERE_AUTOUPDATE); - merge_rr_path = git_pathdup("MERGE_RR"); - fd = hold_lock_file_for_update(&write_lock, merge_rr_path, - LOCK_DIE_ON_ERROR); + if (flags & RERERE_READONLY) + fd = 0; + else + fd = hold_lock_file_for_update(&write_lock, git_path_merge_rr(), + LOCK_DIE_ON_ERROR); read_rr(merge_rr); return fd; } @@@ -1050,8 -1052,8 +1050,8 @@@ static int rerere_forget_one_path(cons handle_cache(path, sha1, rerere_path(id, "thisimage")); if (read_mmfile(&cur, rerere_path(id, "thisimage"))) { free(cur.ptr); - return error("Failed to update conflicted state in '%s'", - path); + error("Failed to update conflicted state in '%s'", path); + goto fail_exit; } cleanly_resolved = !try_merge(id, path, &cur, &result); free(result.ptr); @@@ -1060,14 -1062,19 +1060,19 @@@ break; } - if (id->collection->status_nr <= id->variant) - return error("no remembered resolution for '%s'", path); + if (id->collection->status_nr <= id->variant) { + error("no remembered resolution for '%s'", path); + goto fail_exit; + } filename = rerere_path(id, "postimage"); - if (unlink(filename)) - return (errno == ENOENT - ? error("no remembered resolution for %s", path) - : error_errno("cannot unlink %s", filename)); + if (unlink(filename)) { + if (errno == ENOENT) + error("no remembered resolution for %s", path); + else - error("cannot unlink %s: %s", filename, strerror(errno)); ++ error_errno("cannot unlink %s", filename); + goto fail_exit; + } /* * Update the preimage so that the user can resolve the @@@ -1086,6 -1093,10 +1091,10 @@@ item->util = id; fprintf(stderr, "Forgot resolution for %s\n", path); return 0; + + fail_exit: + free(id); + return -1; } int rerere_forget(struct pathspec *pathspec) @@@ -1098,8 -1109,6 +1107,8 @@@ return error("Could not read index"); fd = setup_rerere(&merge_rr, RERERE_NOAUTOUPDATE); + if (fd < 0) + return 0; /* * The paths may have been resolved (incorrectly); @@@ -1175,9 -1184,6 +1184,9 @@@ void rerere_gc(struct string_list *rr int cutoff_noresolve = 15; int cutoff_resolve = 60; + if (setup_rerere(rr, 0) < 0) + return; + git_config_get_int("gc.rerereresolved", &cutoff_resolve); git_config_get_int("gc.rerereunresolved", &cutoff_noresolve); git_config(git_default_config, NULL); @@@ -1213,7 -1219,6 +1222,7 @@@ for (i = 0; i < to_remove.nr; i++) rmdir(git_path("rr-cache/%s", to_remove.items[i].string)); string_list_clear(&to_remove, 0); + rollback_lock_file(&write_lock); } /* @@@ -1227,9 -1232,6 +1236,9 @@@ void rerere_clear(struct string_list *m { int i; + if (setup_rerere(merge_rr, 0) < 0) + return; + for (i = 0; i < merge_rr->nr; i++) { struct rerere_id *id = merge_rr->items[i].util; if (!has_rerere_resolution(id)) { @@@ -1237,6 -1239,5 +1246,6 @@@ rmdir(rerere_path(id, NULL)); } } - unlink_or_warn(git_path("MERGE_RR")); + unlink_or_warn(git_path_merge_rr()); + rollback_lock_file(&write_lock); }