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

[PATCH 2/2] rerere: fix overeager gc

From
SZEDER Gábor <szeder@ira.uka.de>
Date
Jul 12, 2010, 23:42 UTC
Message-ID
<1278978124-3035-2-git-send-email-szeder@ira.uka.de>
In-Reply-To
<7vlj9lo6w6.fsf@alter.siamese.dyndns.org>

'rerere gc' prunes resolutions of conflicted merges that occurred long time ago, and when doing so it takes the creation time of the conflicted automerge results into account. This can cause the loss of frequently used conflict resolutions (e.g. long-living topic branches are merged into a regularly rebuilt integration branch (think of git's pu)) when they become old enough to exceed 'rerere gc's threshold.

To prevent the loss of valuable merge resolutions 'rerere' will (1) update the timestamp of the recorded conflict resolution (i.e. 'postimage') each time when encountering and resolving the same merge conflict, and (2) take this timestamp, i.e. the time of the last usage into account when gc'ing.

Signed-off-by: SZEDER Gábor <szeder@ira.uka.de>
---
On Thu, Jul 08, 2010 at 05:06:49PM -0700, Junio C Hamano wrote:
Show 12 quoted lines
> Johannes Sixt <j.sixt@viscovery.net> writes:
> 
> > Am 7/2/2010 19:25, schrieb Junio C Hamano:
> >
> >> I'd rather see "preimage"
> >> timestamp to keep track of the time when we _first_ encountered the
> >> particular conflict, and "postimage" used for recording the time when we
> >> saw the conflict most recently.
> >
> > That would be fine, too.
> 
> Ok, then let's make it so ;-)
Here it is.  Now you have it all, take your pick (;
 builtin/rerere.c  |   15 +++++++++++++--
 rerere.c          |    8 +++++++-
 t/t4200-rerere.sh |   14 +++++++++++---
 3 files changed, 31 insertions(+), 6 deletions(-)
diff --git a/builtin/rerere.c b/builtin/rerere.c
index 980d542..52e4b64 100644
--- a/builtin/rerere.c
+++ b/builtin/rerere.c
@@ -19,6 +19,12 @@ static time_t rerere_created_at(const char *name)
 	return stat(rerere_path(name, "preimage"), &st) ? (time_t) 0 : st.st_mtime;
 }
 
+static time_t rerere_last_used_at(const char *name)
+{
+	struct stat st;
+	return stat(rerere_path(name, "postimage"), &st) ? (time_t) 0 : st.st_mtime;
+}
+
 static void unlink_rr_item(const char *name)
 {
 	unlink(rerere_path(name, "thisimage"));
@@ -56,8 +62,13 @@ static void garbage_collect(struct string_list *rr)
 		then = rerere_created_at(e->d_name);
 		if (!then)
 			continue;
-		cutoff = (has_rerere_resolution(e->d_name)
-			  ? cutoff_resolve : cutoff_noresolve);
+		if (has_rerere_resolution(e->d_name)) {
+			then = rerere_last_used_at(e->d_name);
+			if (!then)
+				continue;
+			cutoff = cutoff_resolve;
+		} else
+			cutoff = cutoff_noresolve;
 		if (then < now - cutoff * 86400)
 			string_list_append(&to_remove, e->d_name);
 	}
diff --git a/rerere.c b/rerere.c
index d03a696..1d95161 100644
--- a/rerere.c
+++ b/rerere.c
@@ -378,7 +378,13 @@ static int merge(const char *name, const char *path)
 	}
 	ret = ll_merge(&result, path, &base, NULL, &cur, "", &other, "", 0);
 	if (!ret) {
-		FILE *f = fopen(path, "w");
+		FILE *f;
+
+		if (utime(rerere_path(name, "postimage"), NULL) < 0)
+			warning("failed utime() on %s: %s",
+					rerere_path(name, "postimage"),
+					strerror(errno));
+		f = fopen(path, "w");
 		if (!f)
 			return error("Could not open %s: %s", path,
 				     strerror(errno));
diff --git a/t/t4200-rerere.sh b/t/t4200-rerere.sh
index 70856d0..093b138 100755
--- a/t/t4200-rerere.sh
+++ b/t/t4200-rerere.sh
@@ -132,6 +132,8 @@ test_expect_success 'commit succeeds' \
 
 test_expect_success 'recorded postimage' "test -f $rr/postimage"
 
+oldmtimepost=$(test-chmtime -v -60 $rr/postimage |cut -f 1)
+
 test_expect_success 'another conflicting merge' '
 	git checkout -b third master &&
 	git show second^:a1 | sed "s/To die: t/To die! T/" > a1 &&
@@ -144,6 +146,11 @@ test_expect_success 'rerere kicked in' "! grep ^=======$ a1"
 
 test_expect_success 'rerere prefers first change' 'test_cmp a1 expect'
 
+test_expect_success 'rerere updates postimage timestamp' '
+	newmtimepost=$(test-chmtime -v +0 $rr/postimage |cut -f 1) &&
+	test $oldmtimepost -lt $newmtimepost
+'
+
 rm $rr/postimage
 echo "$sha1	a1" | perl -pe 'y/\012/\000/' > .git/MERGE_RR
 
@@ -165,15 +172,16 @@ just_over_15_days_ago=$((-1-15*86400))
 almost_60_days_ago=$((60-60*86400))
 just_over_60_days_ago=$((-1-60*86400))
 
-test-chmtime =$almost_60_days_ago $rr/preimage
+test-chmtime =$just_over_60_days_ago $rr/preimage
+test-chmtime =$almost_60_days_ago $rr/postimage
 test-chmtime =$almost_15_days_ago $rr2/preimage
 
 test_expect_success 'garbage collection (part1)' 'git rerere gc'
 
-test_expect_success 'young records still live' \
+test_expect_success 'young or recently used records still live' \
 	"test -f $rr/preimage && test -f $rr2/preimage"
 
-test-chmtime =$just_over_60_days_ago $rr/preimage
+test-chmtime =$just_over_60_days_ago $rr/postimage
 test-chmtime =$just_over_15_days_ago $rr2/preimage
 
 test_expect_success 'garbage collection (part2)' 'git rerere gc'
-- 
1.7.2.rc2.37.g5e8ef
Previous: SZEDER GáborNext: Junio C Hamano
Message 19 of 24 in “rerere: fix overeager gc”
  1. rerere: fix overeager gcSZEDER Gábor, Jun 29, 2010
  2. Junio C HamanoJun 29, 2010
  3. Johannes SixtJun 30, 2010
  4. SZEDER GáborJun 30, 2010
  5. Junio C HamanoJun 30, 2010
  6. Johannes SixtJun 30, 2010
  7. rerere: fix overeager gcSZEDER Gábor, Jul 1, 2010
  8. Johannes SixtJul 1, 2010
  9. 1/2 mingw: utime() handles NULL times parameterSZEDER Gábor, Jul 1, 2010
  10. 1/2 mingw_utime(): handle NULL times parameterJohannes Sixt, Jul 1, 2010
  11. 2/2 rerere: fix overeager gcSZEDER Gábor, Jul 1, 2010
  12. Junio C HamanoJul 1, 2010
  13. Johannes SixtJul 2, 2010
  14. Junio C HamanoJul 2, 2010
  15. Johannes SixtJul 5, 2010
  16. rerere: fix overeager gcSZEDER Gábor, Jul 8, 2010
  17. Junio C HamanoJul 9, 2010
  18. 1/2 mingw_utime(): handle NULL times parameterSZEDER Gábor, Jul 12, 2010
  19. 2/2 rerere: fix overeager gcSZEDER Gábor, Jul 12, 2010
  20. Junio C HamanoJul 13, 2010
  21. SZEDER GáborJul 14, 2010
  22. Junio C HamanoJul 14, 2010
  23. SZEDER GáborJul 14, 2010
  24. Johannes SixtJul 8, 2010

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.