Browse Source

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>
maint
Junio C Hamano 10 years ago
parent
commit
4b68c2a087
  1. 41
      rerere.c

41
rerere.c

@ -33,6 +33,13 @@ static int has_rerere_resolution(const char *hex) @@ -33,6 +33,13 @@ static int has_rerere_resolution(const char *hex)
return !stat(rerere_path(hex, "postimage"), &st);
}

/*
* $GIT_DIR/MERGE_RR file is a collection of records, each of which is
* "conflict ID", a HT and pathname, terminated with a NUL, and is
* used to keep track of the set of paths that "rerere" may need to
* work on (i.e. what is left by the previous invocation of "git
* rerere" during the current conflict resolution session).
*/
static void read_rr(struct string_list *rr)
{
struct strbuf buf = STRBUF_INIT;
@ -403,6 +410,14 @@ static int handle_cache(const char *path, unsigned char *sha1, const char *outpu @@ -403,6 +410,14 @@ static int handle_cache(const char *path, unsigned char *sha1, const char *outpu
return hunk_no;
}

/*
* Look at a cache entry at "i" and see if it is not conflicting,
* conflicting and we are willing to handle, or conflicting and
* we are unable to handle, and return the determination in *type.
* Return the cache index to be looked at next, by skipping the
* stages we have already looked at in this invocation of this
* function.
*/
static int check_one_conflict(int i, int *type)
{
const struct cache_entry *e = active_cache[i];
@ -434,6 +449,17 @@ static int check_one_conflict(int i, int *type) @@ -434,6 +449,17 @@ static int check_one_conflict(int i, int *type)
return i;
}

/*
* Scan the index and find paths that have conflicts that rerere can
* handle, i.e. the ones that has both stages #2 and #3.
*
* NEEDSWORK: we do not record or replay a previous "resolve by
* deletion" for a delete-modify conflict, as that is inherently risky
* without knowing what modification is being discarded. The only
* safe case, i.e. both side doing the deletion and modification that
* are identical to the previous round, might want to be handled,
* though.
*/
static int find_conflict(struct string_list *conflict)
{
int i;
@ -450,6 +476,21 @@ static int find_conflict(struct string_list *conflict) @@ -450,6 +476,21 @@ static int find_conflict(struct string_list *conflict)
return 0;
}

/*
* The merge_rr list is meant to hold outstanding conflicted paths
* that rerere could handle. Abuse the list by adding other types of
* entries to allow the caller to show "rerere remaining".
*
* - Conflicted paths that rerere does not handle are added
* - Conflicted paths that have been resolved are marked as such
* by storing RERERE_RESOLVED to .util field (where conflict ID
* is expected to be stored).
*
* Do *not* write MERGE_RR file out after calling this function.
*
* NEEDSWORK: we may want to fix the caller that implements "rerere
* remaining" to do this without abusing merge_rr.
*/
int rerere_remaining(struct string_list *merge_rr)
{
int i;

Loading…
Cancel
Save