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" testsmaint
commit
96352ef9b4
|
@ -1564,11 +1564,13 @@ gc.<pattern>.reflogExpireUnreachable::
|
||||||
gc.rerereResolved::
|
gc.rerereResolved::
|
||||||
Records of conflicted merge you resolved earlier are
|
Records of conflicted merge you resolved earlier are
|
||||||
kept for this many days when 'git rerere gc' is run.
|
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].
|
The default is 60 days. See linkgit:git-rerere[1].
|
||||||
|
|
||||||
gc.rerereUnresolved::
|
gc.rerereUnresolved::
|
||||||
Records of conflicted merge you have not resolved are
|
Records of conflicted merge you have not resolved are
|
||||||
kept for this many days when 'git rerere gc' is run.
|
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].
|
The default is 15 days. See linkgit:git-rerere[1].
|
||||||
|
|
||||||
gitcvs.commitMsgAnnotation::
|
gitcvs.commitMsgAnnotation::
|
||||||
|
|
22
config.c
22
config.c
|
@ -2094,6 +2094,28 @@ int git_config_get_expiry(const char *key, const char **output)
|
||||||
return ret;
|
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 git_config_get_untracked_cache(void)
|
||||||
{
|
{
|
||||||
int val = -1;
|
int val = -1;
|
||||||
|
|
3
config.h
3
config.h
|
@ -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 */
|
/* This dies if the configured or default date is in the future */
|
||||||
extern int git_config_get_expiry(const char *key, const char **output);
|
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 {
|
struct key_value_info {
|
||||||
const char *filename;
|
const char *filename;
|
||||||
int linenr;
|
int linenr;
|
||||||
|
|
26
rerere.c
26
rerere.c
|
@ -1133,14 +1133,14 @@ int rerere_forget(struct pathspec *pathspec)
|
||||||
* Garbage collection support
|
* 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;
|
struct stat st;
|
||||||
|
|
||||||
return stat(rerere_path(id, "preimage"), &st) ? (time_t) 0 : st.st_mtime;
|
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;
|
struct stat st;
|
||||||
|
|
||||||
|
@ -1157,11 +1157,11 @@ static void unlink_rr_item(struct rerere_id *id)
|
||||||
id->collection->status[id->variant] = 0;
|
id->collection->status[id->variant] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void prune_one(struct rerere_id *id, time_t now,
|
static void prune_one(struct rerere_id *id,
|
||||||
int cutoff_resolve, int cutoff_noresolve)
|
timestamp_t cutoff_resolve, timestamp_t cutoff_noresolve)
|
||||||
{
|
{
|
||||||
time_t then;
|
timestamp_t then;
|
||||||
int cutoff;
|
timestamp_t cutoff;
|
||||||
|
|
||||||
then = rerere_last_used_at(id);
|
then = rerere_last_used_at(id);
|
||||||
if (then)
|
if (then)
|
||||||
|
@ -1172,7 +1172,7 @@ static void prune_one(struct rerere_id *id, time_t now,
|
||||||
return;
|
return;
|
||||||
cutoff = cutoff_noresolve;
|
cutoff = cutoff_noresolve;
|
||||||
}
|
}
|
||||||
if (then < now - cutoff * 86400)
|
if (then < cutoff)
|
||||||
unlink_rr_item(id);
|
unlink_rr_item(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1182,15 +1182,15 @@ void rerere_gc(struct string_list *rr)
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
struct dirent *e;
|
struct dirent *e;
|
||||||
int i;
|
int i;
|
||||||
time_t now = time(NULL);
|
timestamp_t now = time(NULL);
|
||||||
int cutoff_noresolve = 15;
|
timestamp_t cutoff_noresolve = now - 15 * 86400;
|
||||||
int cutoff_resolve = 60;
|
timestamp_t cutoff_resolve = now - 60 * 86400;
|
||||||
|
|
||||||
if (setup_rerere(rr, 0) < 0)
|
if (setup_rerere(rr, 0) < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
git_config_get_int("gc.rerereresolved", &cutoff_resolve);
|
git_config_get_expiry_in_days("gc.rerereresolved", &cutoff_resolve, now);
|
||||||
git_config_get_int("gc.rerereunresolved", &cutoff_noresolve);
|
git_config_get_expiry_in_days("gc.rerereunresolved", &cutoff_noresolve, now);
|
||||||
git_config(git_default_config, NULL);
|
git_config(git_default_config, NULL);
|
||||||
dir = opendir(git_path("rr-cache"));
|
dir = opendir(git_path("rr-cache"));
|
||||||
if (!dir)
|
if (!dir)
|
||||||
|
@ -1211,7 +1211,7 @@ void rerere_gc(struct string_list *rr)
|
||||||
for (id.variant = 0, id.collection = rr_dir;
|
for (id.variant = 0, id.collection = rr_dir;
|
||||||
id.variant < id.collection->status_nr;
|
id.variant < id.collection->status_nr;
|
||||||
id.variant++) {
|
id.variant++) {
|
||||||
prune_one(&id, now, cutoff_resolve, cutoff_noresolve);
|
prune_one(&id, cutoff_resolve, cutoff_noresolve);
|
||||||
if (id.collection->status[id.variant])
|
if (id.collection->status[id.variant])
|
||||||
now_empty = 0;
|
now_empty = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -239,6 +239,43 @@ test_expect_success 'old records rest in peace' '
|
||||||
! test -f $rr2/preimage
|
! 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' '
|
test_expect_success 'setup: file2 added differently in two branches' '
|
||||||
git reset --hard &&
|
git reset --hard &&
|
||||||
|
|
||||||
|
@ -419,24 +456,6 @@ count_pre_post () {
|
||||||
test_line_count = "$2" actual
|
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 () {
|
merge_conflict_resolve () {
|
||||||
git reset --hard &&
|
git reset --hard &&
|
||||||
test_must_fail git merge six.1 &&
|
test_must_fail git merge six.1 &&
|
||||||
|
@ -446,6 +465,8 @@ merge_conflict_resolve () {
|
||||||
}
|
}
|
||||||
|
|
||||||
test_expect_success 'multiple identical conflicts' '
|
test_expect_success 'multiple identical conflicts' '
|
||||||
|
rm -fr .git/rr-cache &&
|
||||||
|
mkdir .git/rr-cache &&
|
||||||
git reset --hard &&
|
git reset --hard &&
|
||||||
|
|
||||||
test_seq 1 6 >early &&
|
test_seq 1 6 >early &&
|
||||||
|
|
Loading…
Reference in New Issue