rerere: explain MERGE_RR management helpers
Explain the internals of rerere as in-code comments, while sprinkling "NEEDSWORK" comment to highlight iffy bits and questionable assumptions. This one covers the "$GIT_DIR/MERGE_RR" file and in-core merge_rr that are used to keep track of the status of "rerere" session in progress. Signed-off-by: Junio C Hamano <gitster@pobox.com>
Junio C Hamano committed
Jun 30, 2015 at 22:36 UTC
4b68c2a0877b18d1fe591dd7aee55aa1158fada0
1 file changed
+41
rerere.c
+41
@@ -33,6 +33,13 @@ static int has_rerere_resolution(const char *hex)
33
return !stat(rerere_path(hex, "postimage"), &st);
34
}
35
36
+/*
37
+ * $GIT_DIR/MERGE_RR file is a collection of records, each of which is
38
+ * "conflict ID", a HT and pathname, terminated with a NUL, and is
39
+ * used to keep track of the set of paths that "rerere" may need to
40
+ * work on (i.e. what is left by the previous invocation of "git
41
+ * rerere" during the current conflict resolution session).
42
+ */
43
static void read_rr(struct string_list *rr)
44
{
45
struct strbuf buf = STRBUF_INIT;
@@ -403,6 +410,14 @@ static int handle_cache(const char *path, unsigned char *sha1, const char *outpu
410
return hunk_no;
411
}
412
413
+/*
414
+ * Look at a cache entry at "i" and see if it is not conflicting,
415
+ * conflicting and we are willing to handle, or conflicting and
416
+ * we are unable to handle, and return the determination in *type.
417
+ * Return the cache index to be looked at next, by skipping the
418
+ * stages we have already looked at in this invocation of this
419
+ * function.
420
+ */
421
static int check_one_conflict(int i, int *type)
422
{
423
const struct cache_entry *e = active_cache[i];
@@ -434,6 +449,17 @@ static int check_one_conflict(int i, int *type)
449
return i;
450
}
451
452
+/*
453
+ * Scan the index and find paths that have conflicts that rerere can
454
+ * handle, i.e. the ones that has both stages #2 and #3.
455
+ *
456
+ * NEEDSWORK: we do not record or replay a previous "resolve by
457
+ * deletion" for a delete-modify conflict, as that is inherently risky
458
+ * without knowing what modification is being discarded. The only
459
+ * safe case, i.e. both side doing the deletion and modification that
460
+ * are identical to the previous round, might want to be handled,
461
+ * though.
462
+ */
463
static int find_conflict(struct string_list *conflict)
464
{
465
int i;
@@ -450,6 +476,21 @@ static int find_conflict(struct string_list *conflict)
476
return 0;
477
}
478
479
+/*
480
+ * The merge_rr list is meant to hold outstanding conflicted paths
481
+ * that rerere could handle. Abuse the list by adding other types of
482
+ * entries to allow the caller to show "rerere remaining".
483
+ *
484
+ * - Conflicted paths that rerere does not handle are added
485
+ * - Conflicted paths that have been resolved are marked as such
486
+ * by storing RERERE_RESOLVED to .util field (where conflict ID
487
+ * is expected to be stored).
488
+ *
489
+ * Do *not* write MERGE_RR file out after calling this function.
490
+ *
491
+ * NEEDSWORK: we may want to fix the caller that implements "rerere
492
+ * remaining" to do this without abusing merge_rr.
493
+ */
494
int rerere_remaining(struct string_list *merge_rr)
495
{
496
int i;