git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v3 03/11] rerere: handle leftover rr-cache/$ID directory and postimage files

From
Junio C Hamano <gitster@pobox.com>
Date
Apr 6, 2016, 23:05 UTC
Message-ID
<1459983935-25267-4-git-send-email-gitster@pobox.com>
In-Reply-To
<1459983935-25267-1-git-send-email-gitster@pobox.com>

If by some accident there is only $GIT_DIR/rr-cache/$ID directory existed, we wouldn't have recorded a preimage for a conflict that is newly encountered, which would mean after a manual resolution, we wouldn't have recorded it by storing the postimage, because the logic used to be "if there is no rr-cache/$ID directory, then we are the first so record the preimage". Instead, record preimage if we do not have one.

In addition, if there is only $GIT_DIR/rr-cache/$ID/postimage without corresponding preimage, we would have tried to call into merge() and punted.

These would have been a situation frustratingly hard to recover from.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 rerere.c          | 42 +++++++++++++++++++++++++-----------------
 t/t4200-rerere.sh | 17 ++++++++++++++++-
 2 files changed, 41 insertions(+), 18 deletions(-)
diff --git a/rerere.c b/rerere.c
index fbdade8..a1e2963 100644
--- a/rerere.c
+++ b/rerere.c
@@ -117,7 +117,9 @@ static struct rerere_dir *find_rerere_dir(const char *hex)
 
 static int has_rerere_resolution(const struct rerere_id *id)
 {
-	return (id->collection->status & RR_HAS_POSTIMAGE);
+	const int both = RR_HAS_POSTIMAGE|RR_HAS_PREIMAGE;
+
+	return ((id->collection->status & both) == both);
 }
 
 static struct rerere_id *new_rerere_id_hex(char *hex)
@@ -806,24 +808,30 @@ static int do_plain_rerere(struct string_list *rr, int fd)
 		string_list_insert(rr, path)->util = id;
 
 		/*
-		 * If the directory does not exist, create
-		 * it.  mkdir_in_gitdir() will fail with
-		 * EEXIST if there already is one.
-		 *
-		 * NEEDSWORK: make sure "gc" does not remove
-		 * preimage without removing the directory.
+		 * Ensure that the directory exists.
+		 * mkdir_in_gitdir() will fail with EEXIST if there
+		 * already is one.
 		 */
-		if (mkdir_in_gitdir(rerere_path(id, NULL)))
-			continue;
+		if (mkdir_in_gitdir(rerere_path(id, NULL)) &&
+		    errno != EEXIST)
+			continue; /* NEEDSWORK: perhaps we should die? */
 
-		/*
-		 * We are the first to encounter this
-		 * conflict.  Ask handle_file() to write the
-		 * normalized contents to the "preimage" file.
-		 */
-		handle_file(path, NULL, rerere_path(id, "preimage"));
-		id->collection->status |= RR_HAS_PREIMAGE;
-		fprintf(stderr, "Recorded preimage for '%s'\n", path);
+		if (id->collection->status & RR_HAS_PREIMAGE) {
+			;
+		} else {
+			/*
+			 * We are the first to encounter this
+			 * conflict.  Ask handle_file() to write the
+			 * normalized contents to the "preimage" file.
+			 *
+			 * NEEDSWORK: what should happen if we had a
+			 * leftover postimage that is totally
+			 * unrelated?  Perhaps we should unlink it?
+			 */
+			handle_file(path, NULL, rerere_path(id, "preimage"));
+			id->collection->status |= RR_HAS_PREIMAGE;
+			fprintf(stderr, "Recorded preimage for '%s'\n", path);
+		}
 	}
 
 	for (i = 0; i < rr->nr; i++)
diff --git a/t/t4200-rerere.sh b/t/t4200-rerere.sh
index ed9c91e..c428011 100755
--- a/t/t4200-rerere.sh
+++ b/t/t4200-rerere.sh
@@ -184,12 +184,27 @@ test_expect_success 'rerere updates postimage timestamp' '
 '
 
 test_expect_success 'rerere clear' '
-	rm $rr/postimage &&
+	mv $rr/postimage .git/post-saved &&
 	echo "$sha1	a1" | perl -pe "y/\012/\000/" >.git/MERGE_RR &&
 	git rerere clear &&
 	! test -d $rr
 '
 
+test_expect_success 'leftover directory' '
+	git reset --hard &&
+	mkdir -p $rr &&
+	test_must_fail git merge first &&
+	test -f $rr/preimage
+'
+
+test_expect_success 'missing preimage' '
+	git reset --hard &&
+	mkdir -p $rr &&
+	cp .git/post-saved $rr/postimage &&
+	test_must_fail git merge first &&
+	test -f $rr/preimage
+'
+
 test_expect_success 'set up for garbage collection tests' '
 	mkdir -p $rr &&
 	echo Hello >$rr/preimage &&
-- 
2.8.1-273-ga2cd0f9
Previous: Junio C HamanoNext: Junio C Hamano
Message 24 of 32 in “saving and replaying multiple variants with rerere”
  1. 0/7 saving and replaying multiple variants with rerereJunio C Hamano, Sep 14, 2015
  2. 1/7 rerere: split conflict ID furtherJunio C Hamano, Sep 14, 2015
  3. 2/7 rerere: scan $GIT_DIR/rr-cache/$ID when instantiating a rerere_idJunio C Hamano, Sep 14, 2015
  4. 3/7 rerere: handle leftover rr-cache/$ID directory and postimage filesJunio C Hamano, Sep 14, 2015
  5. 4/7 rerere: delay the recording of preimageJunio C Hamano, Sep 14, 2015
  6. 5/7 rerere: allow multiple variants to existJunio C Hamano, Sep 14, 2015
  7. 6/7 t4200: rerere a merge with two identical conflictsJunio C Hamano, Sep 14, 2015
  8. 7/7 rerere: do use multiple variantsJunio C Hamano, Sep 14, 2015
  9. 00/11 saving and replaying multiple variants with rerereJunio C Hamano, Mar 28, 2016
  10. 01/11 rerere: split conflict ID furtherJunio C Hamano, Mar 28, 2016
  11. 02/11 rerere: scan $GIT_DIR/rr-cache/$ID when instantiating a rerere_idJunio C Hamano, Mar 28, 2016
  12. 03/11 rerere: handle leftover rr-cache/$ID directory and postimage filesJunio C Hamano, Mar 28, 2016
  13. 04/11 rerere: delay the recording of preimageJunio C Hamano, Mar 28, 2016
  14. 05/11 rerere: allow multiple variants to existJunio C Hamano, Mar 28, 2016
  15. 06/11 t4200: rerere a merge with two identical conflictsJunio C Hamano, Mar 28, 2016
  16. 07/11 rerere: do use multiple variantsJunio C Hamano, Mar 28, 2016
  17. 08/11 rerere: gc and clearJunio C Hamano, Mar 28, 2016
  18. 09/11 rerere: move code related to "forget" togetherJunio C Hamano, Mar 28, 2016
  19. 10/11 rerere: split code to call ll_merge() furtherJunio C Hamano, Mar 28, 2016
  20. 11/11 rerere: adjust 'forget' to multi-variant world orderJunio C Hamano, Mar 28, 2016
  21. 00/11 saving and replaying multiple variants with rerereJunio C Hamano, Apr 6, 2016
  22. 01/11 rerere: split conflict ID furtherJunio C Hamano, Apr 6, 2016
  23. 02/11 rerere: scan $GIT_DIR/rr-cache/$ID when instantiating a rerere_idJunio C Hamano, Apr 6, 2016
  24. 03/11 rerere: handle leftover rr-cache/$ID directory and postimage filesJunio C Hamano, Apr 6, 2016
  25. 04/11 rerere: delay the recording of preimageJunio C Hamano, Apr 6, 2016
  26. 05/11 rerere: allow multiple variants to existJunio C Hamano, Apr 6, 2016
  27. 06/11 t4200: rerere a merge with two identical conflictsJunio C Hamano, Apr 6, 2016
  28. 07/11 rerere: do use multiple variantsJunio C Hamano, Apr 6, 2016
  29. 08/11 rerere: gc and clearJunio C Hamano, Apr 6, 2016
  30. 09/11 rerere: move code related to "forget" togetherJunio C Hamano, Apr 6, 2016
  31. 10/11 rerere: split code to call ll_merge() furtherJunio C Hamano, Apr 6, 2016
  32. 11/11 rerere: adjust 'forget' to multi-variant world orderJunio C Hamano, Apr 6, 2016

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.