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;