Skip to content

Commit 96352ef

Browse files
committed
Merge branch 'jc/cutoff-config'
"[gc] rerereResolved = 5.days" used to be invalid, as the variable is defined to take an integer counting the number of days. It now is allowed. * jc/cutoff-config: rerere: allow approxidate in gc.rerereResolved/gc.rerereUnresolved rerere: represent time duration in timestamp_t internally t4200: parameterize "rerere gc" custom expiry test t4200: gather "rerere gc" together t4200: make "rerere gc" test more robust t4200: give us a clean slate after "rerere gc" tests
2 parents 030faf2 + 6e96cb5 commit 96352ef

File tree

5 files changed

+79
-31
lines changed

5 files changed

+79
-31
lines changed

Documentation/config.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1564,11 +1564,13 @@ gc.<pattern>.reflogExpireUnreachable::
15641564
gc.rerereResolved::
15651565
Records of conflicted merge you resolved earlier are
15661566
kept for this many days when 'git rerere gc' is run.
1567+
You can also use more human-readable "1.month.ago", etc.
15671568
The default is 60 days. See linkgit:git-rerere[1].
15681569

15691570
gc.rerereUnresolved::
15701571
Records of conflicted merge you have not resolved are
15711572
kept for this many days when 'git rerere gc' is run.
1573+
You can also use more human-readable "1.month.ago", etc.
15721574
The default is 15 days. See linkgit:git-rerere[1].
15731575

15741576
gitcvs.commitMsgAnnotation::

config.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2094,6 +2094,28 @@ int git_config_get_expiry(const char *key, const char **output)
20942094
return ret;
20952095
}
20962096

2097+
int git_config_get_expiry_in_days(const char *key, timestamp_t *expiry, timestamp_t now)
2098+
{
2099+
char *expiry_string;
2100+
intmax_t days;
2101+
timestamp_t when;
2102+
2103+
if (git_config_get_string(key, &expiry_string))
2104+
return 1; /* no such thing */
2105+
2106+
if (git_parse_signed(expiry_string, &days, maximum_signed_value_of_type(int))) {
2107+
const int scale = 86400;
2108+
*expiry = now - days * scale;
2109+
return 0;
2110+
}
2111+
2112+
if (!parse_expiry_date(expiry_string, &when)) {
2113+
*expiry = when;
2114+
return 0;
2115+
}
2116+
return -1; /* thing exists but cannot be parsed */
2117+
}
2118+
20972119
int git_config_get_untracked_cache(void)
20982120
{
20992121
int val = -1;

config.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,9 @@ extern int git_config_get_max_percent_split_change(void);
215215
/* This dies if the configured or default date is in the future */
216216
extern int git_config_get_expiry(const char *key, const char **output);
217217

218+
/* parse either "this many days" integer, or "5.days.ago" approxidate */
219+
extern int git_config_get_expiry_in_days(const char *key, timestamp_t *, timestamp_t now);
220+
218221
struct key_value_info {
219222
const char *filename;
220223
int linenr;

rerere.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,14 +1133,14 @@ int rerere_forget(struct pathspec *pathspec)
11331133
* Garbage collection support
11341134
*/
11351135

1136-
static time_t rerere_created_at(struct rerere_id *id)
1136+
static timestamp_t rerere_created_at(struct rerere_id *id)
11371137
{
11381138
struct stat st;
11391139

11401140
return stat(rerere_path(id, "preimage"), &st) ? (time_t) 0 : st.st_mtime;
11411141
}
11421142

1143-
static time_t rerere_last_used_at(struct rerere_id *id)
1143+
static timestamp_t rerere_last_used_at(struct rerere_id *id)
11441144
{
11451145
struct stat st;
11461146

@@ -1157,11 +1157,11 @@ static void unlink_rr_item(struct rerere_id *id)
11571157
id->collection->status[id->variant] = 0;
11581158
}
11591159

1160-
static void prune_one(struct rerere_id *id, time_t now,
1161-
int cutoff_resolve, int cutoff_noresolve)
1160+
static void prune_one(struct rerere_id *id,
1161+
timestamp_t cutoff_resolve, timestamp_t cutoff_noresolve)
11621162
{
1163-
time_t then;
1164-
int cutoff;
1163+
timestamp_t then;
1164+
timestamp_t cutoff;
11651165

11661166
then = rerere_last_used_at(id);
11671167
if (then)
@@ -1172,7 +1172,7 @@ static void prune_one(struct rerere_id *id, time_t now,
11721172
return;
11731173
cutoff = cutoff_noresolve;
11741174
}
1175-
if (then < now - cutoff * 86400)
1175+
if (then < cutoff)
11761176
unlink_rr_item(id);
11771177
}
11781178

@@ -1182,15 +1182,15 @@ void rerere_gc(struct string_list *rr)
11821182
DIR *dir;
11831183
struct dirent *e;
11841184
int i;
1185-
time_t now = time(NULL);
1186-
int cutoff_noresolve = 15;
1187-
int cutoff_resolve = 60;
1185+
timestamp_t now = time(NULL);
1186+
timestamp_t cutoff_noresolve = now - 15 * 86400;
1187+
timestamp_t cutoff_resolve = now - 60 * 86400;
11881188

11891189
if (setup_rerere(rr, 0) < 0)
11901190
return;
11911191

1192-
git_config_get_int("gc.rerereresolved", &cutoff_resolve);
1193-
git_config_get_int("gc.rerereunresolved", &cutoff_noresolve);
1192+
git_config_get_expiry_in_days("gc.rerereresolved", &cutoff_resolve, now);
1193+
git_config_get_expiry_in_days("gc.rerereunresolved", &cutoff_noresolve, now);
11941194
git_config(git_default_config, NULL);
11951195
dir = opendir(git_path("rr-cache"));
11961196
if (!dir)
@@ -1211,7 +1211,7 @@ void rerere_gc(struct string_list *rr)
12111211
for (id.variant = 0, id.collection = rr_dir;
12121212
id.variant < id.collection->status_nr;
12131213
id.variant++) {
1214-
prune_one(&id, now, cutoff_resolve, cutoff_noresolve);
1214+
prune_one(&id, cutoff_resolve, cutoff_noresolve);
12151215
if (id.collection->status[id.variant])
12161216
now_empty = 0;
12171217
}

t/t4200-rerere.sh

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,43 @@ test_expect_success 'old records rest in peace' '
239239
! test -f $rr2/preimage
240240
'
241241

242+
rerere_gc_custom_expiry_test () {
243+
five_days="$1" right_now="$2"
244+
test_expect_success "rerere gc with custom expiry ($five_days, $right_now)" '
245+
rm -fr .git/rr-cache &&
246+
rr=.git/rr-cache/$_z40 &&
247+
mkdir -p "$rr" &&
248+
>"$rr/preimage" &&
249+
>"$rr/postimage" &&
250+
251+
two_days_ago=$((-2*86400)) &&
252+
test-chmtime =$two_days_ago "$rr/preimage" &&
253+
test-chmtime =$two_days_ago "$rr/postimage" &&
254+
255+
find .git/rr-cache -type f | sort >original &&
256+
257+
git -c "gc.rerereresolved=$five_days" \
258+
-c "gc.rerereunresolved=$five_days" rerere gc &&
259+
find .git/rr-cache -type f | sort >actual &&
260+
test_cmp original actual &&
261+
262+
git -c "gc.rerereresolved=$five_days" \
263+
-c "gc.rerereunresolved=$right_now" rerere gc &&
264+
find .git/rr-cache -type f | sort >actual &&
265+
test_cmp original actual &&
266+
267+
git -c "gc.rerereresolved=$right_now" \
268+
-c "gc.rerereunresolved=$right_now" rerere gc &&
269+
find .git/rr-cache -type f | sort >actual &&
270+
>expect &&
271+
test_cmp expect actual
272+
'
273+
}
274+
275+
rerere_gc_custom_expiry_test 5 0
276+
277+
rerere_gc_custom_expiry_test 5.days.ago now
278+
242279
test_expect_success 'setup: file2 added differently in two branches' '
243280
git reset --hard &&
244281
@@ -419,24 +456,6 @@ count_pre_post () {
419456
test_line_count = "$2" actual
420457
}
421458

422-
test_expect_success 'rerere gc' '
423-
find .git/rr-cache -type f >original &&
424-
xargs test-chmtime -172800 <original &&
425-
426-
git -c gc.rerereresolved=5 -c gc.rerereunresolved=5 rerere gc &&
427-
find .git/rr-cache -type f >actual &&
428-
test_cmp original actual &&
429-
430-
git -c gc.rerereresolved=5 -c gc.rerereunresolved=0 rerere gc &&
431-
find .git/rr-cache -type f >actual &&
432-
test_cmp original actual &&
433-
434-
git -c gc.rerereresolved=0 -c gc.rerereunresolved=0 rerere gc &&
435-
find .git/rr-cache -type f >actual &&
436-
>expect &&
437-
test_cmp expect actual
438-
'
439-
440459
merge_conflict_resolve () {
441460
git reset --hard &&
442461
test_must_fail git merge six.1 &&
@@ -446,6 +465,8 @@ merge_conflict_resolve () {
446465
}
447466

448467
test_expect_success 'multiple identical conflicts' '
468+
rm -fr .git/rr-cache &&
469+
mkdir .git/rr-cache &&
449470
git reset --hard &&
450471
451472
test_seq 1 6 >early &&

0 commit comments

Comments
 (0)