/* automatically update cleanly resolved paths to the index */
static int rerere_autoupdate;
-static char *merge_rr_path;
-
static void free_rerere_id(struct string_list_item *item)
{
free(item->util);
static struct rerere_id *new_rerere_id_hex(char *hex)
{
struct rerere_id *id = xmalloc(sizeof(*id));
- strcpy(id->hex, hex);
+ xsnprintf(id->hex, sizeof(id->hex), "%s", hex);
return 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;
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");
*/
static int merge(const struct rerere_id *id, const char *path)
{
+ FILE *f;
int ret;
mmfile_t cur = {NULL, 0}, base = {NULL, 0}, other = {NULL, 0};
mmbuffer_t result = {NULL, 0};
* Normalize the conflicts in path and write it out to
* "thisimage" temporary file.
*/
- if (handle_file(path, NULL, rerere_path(id, "thisimage")) < 0)
- return 1;
+ if (handle_file(path, NULL, rerere_path(id, "thisimage")) < 0) {
+ ret = 1;
+ goto out;
+ }
if (read_mmfile(&cur, rerere_path(id, "thisimage")) ||
read_mmfile(&base, rerere_path(id, "preimage")) ||
* low-level merge driver settings.
*/
ret = ll_merge(&result, path, &base, NULL, &cur, "", &other, "", NULL);
- if (!ret) {
- FILE *f;
+ if (ret)
+ goto out;
- /*
- * A successful replay of recorded resolution.
- * 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));
-
- /* Update "path" with the resolution */
- f = fopen(path, "w");
- if (!f)
- return error("Could not open %s: %s", path,
- strerror(errno));
- if (fwrite(result.ptr, result.size, 1, f) != 1)
- error("Could not write %s: %s", path, strerror(errno));
- if (fclose(f))
- return error("Writing %s failed: %s", path,
- strerror(errno));
- }
+ /*
+ * A successful replay of recorded resolution.
+ * 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));
+
+ /* Update "path" with the resolution */
+ f = fopen(path, "w");
+ if (!f)
+ return error("Could not open %s: %s", path,
+ strerror(errno));
+ if (fwrite(result.ptr, result.size, 1, f) != 1)
+ error("Could not write %s: %s", path, strerror(errno));
+ if (fclose(f))
+ return error("Writing %s failed: %s", path,
+ strerror(errno));
out:
free(cur.ptr);
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;
}
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;
}
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);
static struct rerere_id *dirname_to_id(const char *name)
{
static struct rerere_id id;
- strcpy(id.hex, name);
+ xsnprintf(id.hex, sizeof(id.hex), "%s", name);
return &id;
}
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);
for (i = 0; i < to_remove.nr; i++)
unlink_rr_item(dirname_to_id(to_remove.items[i].string));
string_list_clear(&to_remove, 0);
+ rollback_lock_file(&write_lock);
}
/*
{
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))
unlink_rr_item(id);
}
- unlink_or_warn(git_path("MERGE_RR"));
+ unlink_or_warn(git_path_merge_rr());
+ rollback_lock_file(&write_lock);
}