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
This commit is contained in:
Junio C Hamano 2017-08-26 22:55:08 -07:00
commit 96352ef9b4
5 changed files with 79 additions and 31 deletions

View file

@ -1564,11 +1564,13 @@ gc.<pattern>.reflogExpireUnreachable::
gc.rerereResolved::
Records of conflicted merge you resolved earlier are
kept for this many days when 'git rerere gc' is run.
You can also use more human-readable "1.month.ago", etc.
The default is 60 days. See linkgit:git-rerere[1].
gc.rerereUnresolved::
Records of conflicted merge you have not resolved are
kept for this many days when 'git rerere gc' is run.
You can also use more human-readable "1.month.ago", etc.
The default is 15 days. See linkgit:git-rerere[1].
gitcvs.commitMsgAnnotation::

View file

@ -2094,6 +2094,28 @@ int git_config_get_expiry(const char *key, const char **output)
return ret;
}
int git_config_get_expiry_in_days(const char *key, timestamp_t *expiry, timestamp_t now)
{
char *expiry_string;
intmax_t days;
timestamp_t when;
if (git_config_get_string(key, &expiry_string))
return 1; /* no such thing */
if (git_parse_signed(expiry_string, &days, maximum_signed_value_of_type(int))) {
const int scale = 86400;
*expiry = now - days * scale;
return 0;
}
if (!parse_expiry_date(expiry_string, &when)) {
*expiry = when;
return 0;
}
return -1; /* thing exists but cannot be parsed */
}
int git_config_get_untracked_cache(void)
{
int val = -1;

View file

@ -215,6 +215,9 @@ extern int git_config_get_max_percent_split_change(void);
/* This dies if the configured or default date is in the future */
extern int git_config_get_expiry(const char *key, const char **output);
/* parse either "this many days" integer, or "5.days.ago" approxidate */
extern int git_config_get_expiry_in_days(const char *key, timestamp_t *, timestamp_t now);
struct key_value_info {
const char *filename;
int linenr;

View file

@ -1133,14 +1133,14 @@ int rerere_forget(struct pathspec *pathspec)
* Garbage collection support
*/
static time_t rerere_created_at(struct rerere_id *id)
static timestamp_t rerere_created_at(struct rerere_id *id)
{
struct stat st;
return stat(rerere_path(id, "preimage"), &st) ? (time_t) 0 : st.st_mtime;
}
static time_t rerere_last_used_at(struct rerere_id *id)
static timestamp_t rerere_last_used_at(struct rerere_id *id)
{
struct stat st;
@ -1157,11 +1157,11 @@ static void unlink_rr_item(struct rerere_id *id)
id->collection->status[id->variant] = 0;
}
static void prune_one(struct rerere_id *id, time_t now,
int cutoff_resolve, int cutoff_noresolve)
static void prune_one(struct rerere_id *id,
timestamp_t cutoff_resolve, timestamp_t cutoff_noresolve)
{
time_t then;
int cutoff;
timestamp_t then;
timestamp_t cutoff;
then = rerere_last_used_at(id);
if (then)
@ -1172,7 +1172,7 @@ static void prune_one(struct rerere_id *id, time_t now,
return;
cutoff = cutoff_noresolve;
}
if (then < now - cutoff * 86400)
if (then < cutoff)
unlink_rr_item(id);
}
@ -1182,15 +1182,15 @@ void rerere_gc(struct string_list *rr)
DIR *dir;
struct dirent *e;
int i;
time_t now = time(NULL);
int cutoff_noresolve = 15;
int cutoff_resolve = 60;
timestamp_t now = time(NULL);
timestamp_t cutoff_noresolve = now - 15 * 86400;
timestamp_t cutoff_resolve = now - 60 * 86400;
if (setup_rerere(rr, 0) < 0)
return;
git_config_get_int("gc.rerereresolved", &cutoff_resolve);
git_config_get_int("gc.rerereunresolved", &cutoff_noresolve);
git_config_get_expiry_in_days("gc.rerereresolved", &cutoff_resolve, now);
git_config_get_expiry_in_days("gc.rerereunresolved", &cutoff_noresolve, now);
git_config(git_default_config, NULL);
dir = opendir(git_path("rr-cache"));
if (!dir)
@ -1211,7 +1211,7 @@ void rerere_gc(struct string_list *rr)
for (id.variant = 0, id.collection = rr_dir;
id.variant < id.collection->status_nr;
id.variant++) {
prune_one(&id, now, cutoff_resolve, cutoff_noresolve);
prune_one(&id, cutoff_resolve, cutoff_noresolve);
if (id.collection->status[id.variant])
now_empty = 0;
}

View file

@ -239,6 +239,43 @@ test_expect_success 'old records rest in peace' '
! test -f $rr2/preimage
'
rerere_gc_custom_expiry_test () {
five_days="$1" right_now="$2"
test_expect_success "rerere gc with custom expiry ($five_days, $right_now)" '
rm -fr .git/rr-cache &&
rr=.git/rr-cache/$_z40 &&
mkdir -p "$rr" &&
>"$rr/preimage" &&
>"$rr/postimage" &&
two_days_ago=$((-2*86400)) &&
test-chmtime =$two_days_ago "$rr/preimage" &&
test-chmtime =$two_days_ago "$rr/postimage" &&
find .git/rr-cache -type f | sort >original &&
git -c "gc.rerereresolved=$five_days" \
-c "gc.rerereunresolved=$five_days" rerere gc &&
find .git/rr-cache -type f | sort >actual &&
test_cmp original actual &&
git -c "gc.rerereresolved=$five_days" \
-c "gc.rerereunresolved=$right_now" rerere gc &&
find .git/rr-cache -type f | sort >actual &&
test_cmp original actual &&
git -c "gc.rerereresolved=$right_now" \
-c "gc.rerereunresolved=$right_now" rerere gc &&
find .git/rr-cache -type f | sort >actual &&
>expect &&
test_cmp expect actual
'
}
rerere_gc_custom_expiry_test 5 0
rerere_gc_custom_expiry_test 5.days.ago now
test_expect_success 'setup: file2 added differently in two branches' '
git reset --hard &&
@ -419,24 +456,6 @@ count_pre_post () {
test_line_count = "$2" actual
}
test_expect_success 'rerere gc' '
find .git/rr-cache -type f >original &&
xargs test-chmtime -172800 <original &&
git -c gc.rerereresolved=5 -c gc.rerereunresolved=5 rerere gc &&
find .git/rr-cache -type f >actual &&
test_cmp original actual &&
git -c gc.rerereresolved=5 -c gc.rerereunresolved=0 rerere gc &&
find .git/rr-cache -type f >actual &&
test_cmp original actual &&
git -c gc.rerereresolved=0 -c gc.rerereunresolved=0 rerere gc &&
find .git/rr-cache -type f >actual &&
>expect &&
test_cmp expect actual
'
merge_conflict_resolve () {
git reset --hard &&
test_must_fail git merge six.1 &&
@ -446,6 +465,8 @@ merge_conflict_resolve () {
}
test_expect_success 'multiple identical conflicts' '
rm -fr .git/rr-cache &&
mkdir .git/rr-cache &&
git reset --hard &&
test_seq 1 6 >early &&