Merge branch 'jc/rerere-multi'
authorJunio C Hamano <gitster@pobox.com>
Mon, 25 Apr 2016 22:17:14 +0000 (15:17 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 25 Apr 2016 22:17:15 +0000 (15:17 -0700)
"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

1  2 
rerere.c
rerere.h
diff --cc rerere.c
index 587b7e2717b14748b92a5960f79947b5fba088f0,16938662dd4152f2d9bfaac31b9715209c3bbd51..c8b9f407872f431399a4c5c321742c32cded5711
+++ 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);
  }
diff --cc rerere.h
Simple merge