From: Junio C Hamano Date: Mon, 25 Apr 2016 22:17:14 +0000 (-0700) Subject: Merge branch 'jc/rerere-multi' X-Git-Tag: v2.9.0-rc0~100 X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fgit.git;a=commitdiff_plain;h=5b715ec48fe616b443abd87ff038c94c64fc1063 Merge branch 'jc/rerere-multi' "git rerere" can encounter two or more files with the same conflict signature that have to be resolved in different ways, but there was no way to record these separate resolutions. * jc/rerere-multi: rerere: adjust 'forget' to multi-variant world order rerere: split code to call ll_merge() further rerere: move code related to "forget" together rerere: gc and clear rerere: do use multiple variants t4200: rerere a merge with two identical conflicts rerere: allow multiple variants to exist rerere: delay the recording of preimage rerere: handle leftover rr-cache/$ID directory and postimage files rerere: scan $GIT_DIR/rr-cache/$ID when instantiating a rerere_id rerere: split conflict ID further --- 5b715ec48fe616b443abd87ff038c94c64fc1063 diff --cc rerere.c index 587b7e2717,16938662dd..c8b9f40787 --- a/rerere.c +++ b/rerere.c @@@ -20,6 -21,31 +21,29 @@@ 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; + + #define RR_HAS_POSTIMAGE 1 + #define RR_HAS_PREIMAGE 2 + static struct rerere_dir { + unsigned char sha1[20]; + int status_alloc, status_nr; + unsigned char *status; + } **rerere_dir; + + static void free_rerere_dirs(void) + { + int i; + for (i = 0; i < rerere_dir_nr; i++) { + free(rerere_dir[i]->status); + free(rerere_dir[i]); + } + free(rerere_dir); + rerere_dir_nr = rerere_dir_alloc = 0; + rerere_dir = NULL; + } + static void free_rerere_id(struct string_list_item *item) { free(item->util); @@@ -977,11 -1205,11 +1212,12 @@@ void rerere_gc(struct string_list *rr string_list_append(&to_remove, e->d_name); } closedir(dir); - /* ... and then remove them one-by-one */ + + /* ... and then remove the empty directories */ for (i = 0; i < to_remove.nr; i++) - unlink_rr_item(dirname_to_id(to_remove.items[i].string)); + rmdir(git_path("rr-cache/%s", to_remove.items[i].string)); string_list_clear(&to_remove, 0); + rollback_lock_file(&write_lock); } /* @@@ -995,14 -1223,12 +1231,16 @@@ 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)) + if (!has_rerere_resolution(id)) { unlink_rr_item(id); + rmdir(rerere_path(id, NULL)); + } } - unlink_or_warn(git_path("MERGE_RR")); + unlink_or_warn(git_path_merge_rr()); + rollback_lock_file(&write_lock); }