Skip to content

Commit 5f96742

Browse files
Haaris Mehmoodgitster
authored andcommitted
config: add --expiry-date
Add --expiry-date as a data-type for config files when 'git config --get' is used. This will return any relative or fixed dates from config files as timestamps. This is useful for scripts (e.g. gc.reflogexpire) that work with timestamps so that '2.weeks' can be converted to a format acceptable by those scripts/functions. Following the convention of git_config_pathname(), move the helper function required for this feature from builtin/reflog.c to builtin/config.c where other similar functions exist (e.g. for --bool or --path), and match the order of parameters with other functions (i.e. output pointer as first parameter). Signed-off-by: Haaris Mehmood <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 89ea799 commit 5f96742

File tree

7 files changed

+69
-13
lines changed

7 files changed

+69
-13
lines changed

Documentation/git-config.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,11 @@ See also <<FILES>>.
180180
value (but you can use `git config section.variable ~/`
181181
from the command line to let your shell do the expansion).
182182

183+
--expiry-date::
184+
`git config` will ensure that the output is converted from
185+
a fixed or relative date-string to a timestamp. This option
186+
has no effect when setting the value.
187+
183188
-z::
184189
--null::
185190
For all options that output values and/or keys, always

builtin/config.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ static int show_origin;
5252
#define TYPE_INT (1<<1)
5353
#define TYPE_BOOL_OR_INT (1<<2)
5454
#define TYPE_PATH (1<<3)
55+
#define TYPE_EXPIRY_DATE (1<<4)
5556

5657
static struct option builtin_config_options[] = {
5758
OPT_GROUP(N_("Config file location")),
@@ -80,6 +81,7 @@ static struct option builtin_config_options[] = {
8081
OPT_BIT(0, "int", &types, N_("value is decimal number"), TYPE_INT),
8182
OPT_BIT(0, "bool-or-int", &types, N_("value is --bool or --int"), TYPE_BOOL_OR_INT),
8283
OPT_BIT(0, "path", &types, N_("value is a path (file or directory name)"), TYPE_PATH),
84+
OPT_BIT(0, "expiry-date", &types, N_("value is an expiry date"), TYPE_EXPIRY_DATE),
8385
OPT_GROUP(N_("Other")),
8486
OPT_BOOL('z', "null", &end_null, N_("terminate values with NUL byte")),
8587
OPT_BOOL(0, "name-only", &omit_values, N_("show variable names only")),
@@ -159,6 +161,11 @@ static int format_config(struct strbuf *buf, const char *key_, const char *value
159161
return -1;
160162
strbuf_addstr(buf, v);
161163
free((char *)v);
164+
} else if (types == TYPE_EXPIRY_DATE) {
165+
timestamp_t t;
166+
if (git_config_expiry_date(&t, key_, value_) < 0)
167+
return -1;
168+
strbuf_addf(buf, "%"PRItime, t);
162169
} else if (value_) {
163170
strbuf_addstr(buf, value_);
164171
} else {
@@ -273,12 +280,13 @@ static char *normalize_value(const char *key, const char *value)
273280
if (!value)
274281
return NULL;
275282

276-
if (types == 0 || types == TYPE_PATH)
283+
if (types == 0 || types == TYPE_PATH || types == TYPE_EXPIRY_DATE)
277284
/*
278285
* We don't do normalization for TYPE_PATH here: If
279286
* the path is like ~/foobar/, we prefer to store
280287
* "~/foobar/" in the config file, and to expand the ~
281288
* when retrieving the value.
289+
* Also don't do normalization for expiry dates.
282290
*/
283291
return xstrdup(value);
284292
if (types == TYPE_INT)

builtin/reflog.c

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -416,16 +416,6 @@ static struct reflog_expire_cfg *find_cfg_ent(const char *pattern, size_t len)
416416
return ent;
417417
}
418418

419-
static int parse_expire_cfg_value(const char *var, const char *value, timestamp_t *expire)
420-
{
421-
if (!value)
422-
return config_error_nonbool(var);
423-
if (parse_expiry_date(value, expire))
424-
return error(_("'%s' for '%s' is not a valid timestamp"),
425-
value, var);
426-
return 0;
427-
}
428-
429419
/* expiry timer slot */
430420
#define EXPIRE_TOTAL 01
431421
#define EXPIRE_UNREACH 02
@@ -443,11 +433,11 @@ static int reflog_expire_config(const char *var, const char *value, void *cb)
443433

444434
if (!strcmp(key, "reflogexpire")) {
445435
slot = EXPIRE_TOTAL;
446-
if (parse_expire_cfg_value(var, value, &expire))
436+
if (git_config_expiry_date(&expire, var, value))
447437
return -1;
448438
} else if (!strcmp(key, "reflogexpireunreachable")) {
449439
slot = EXPIRE_UNREACH;
450-
if (parse_expire_cfg_value(var, value, &expire))
440+
if (git_config_expiry_date(&expire, var, value))
451441
return -1;
452442
} else
453443
return git_default_config(var, value, cb);

config.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -990,6 +990,16 @@ int git_config_pathname(const char **dest, const char *var, const char *value)
990990
return 0;
991991
}
992992

993+
int git_config_expiry_date(timestamp_t *timestamp, const char *var, const char *value)
994+
{
995+
if (!value)
996+
return config_error_nonbool(var);
997+
if (parse_expiry_date(value, timestamp))
998+
return error(_("'%s' for '%s' is not a valid timestamp"),
999+
value, var);
1000+
return 0;
1001+
}
1002+
9931003
static int git_default_core_config(const char *var, const char *value)
9941004
{
9951005
/* This needs a better name */

config.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ extern int git_config_bool_or_int(const char *, const char *, int *);
5858
extern int git_config_bool(const char *, const char *);
5959
extern int git_config_string(const char **, const char *, const char *);
6060
extern int git_config_pathname(const char **, const char *, const char *);
61+
extern int git_config_expiry_date(timestamp_t *, const char *, const char *);
6162
extern int git_config_set_in_file_gently(const char *, const char *, const char *);
6263
extern void git_config_set_in_file(const char *, const char *, const char *);
6364
extern int git_config_set_gently(const char *, const char *);

t/helper/test-date.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ static const char *usage_msg = "\n"
55
" test-date show:<format> [time_t]...\n"
66
" test-date parse [date]...\n"
77
" test-date approxidate [date]...\n"
8+
" test-date timestamp [date]...\n"
89
" test-date is64bit\n"
910
" test-date time_t-is64bit\n";
1011

@@ -71,6 +72,15 @@ static void parse_approxidate(const char **argv, struct timeval *now)
7172
}
7273
}
7374

75+
static void parse_approx_timestamp(const char **argv, struct timeval *now)
76+
{
77+
for (; *argv; argv++) {
78+
timestamp_t t;
79+
t = approxidate_relative(*argv, now);
80+
printf("%s -> %"PRItime"\n", *argv, t);
81+
}
82+
}
83+
7484
int cmd_main(int argc, const char **argv)
7585
{
7686
struct timeval now;
@@ -95,6 +105,8 @@ int cmd_main(int argc, const char **argv)
95105
parse_dates(argv+1, &now);
96106
else if (!strcmp(*argv, "approxidate"))
97107
parse_approxidate(argv+1, &now);
108+
else if (!strcmp(*argv, "timestamp"))
109+
parse_approx_timestamp(argv+1, &now);
98110
else if (!strcmp(*argv, "is64bit"))
99111
return sizeof(timestamp_t) == 8 ? 0 : 1;
100112
else if (!strcmp(*argv, "time_t-is64bit"))

t/t1300-repo-config.sh

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -901,6 +901,36 @@ test_expect_success 'get --path barfs on boolean variable' '
901901
test_must_fail git config --get --path path.bool
902902
'
903903

904+
test_expect_success 'get --expiry-date' '
905+
rel="3.weeks.5.days.00:00" &&
906+
rel_out="$rel ->" &&
907+
cat >.git/config <<-\EOF &&
908+
[date]
909+
valid1 = "3.weeks.5.days 00:00"
910+
valid2 = "Fri Jun 4 15:46:55 2010"
911+
valid3 = "2017/11/11 11:11:11PM"
912+
valid4 = "2017/11/10 09:08:07 PM"
913+
valid5 = "never"
914+
invalid1 = "abc"
915+
EOF
916+
cat >expect <<-EOF &&
917+
$(test-date timestamp $rel)
918+
1275666415
919+
1510441871
920+
1510348087
921+
0
922+
EOF
923+
{
924+
echo "$rel_out $(git config --expiry-date date.valid1)"
925+
git config --expiry-date date.valid2 &&
926+
git config --expiry-date date.valid3 &&
927+
git config --expiry-date date.valid4 &&
928+
git config --expiry-date date.valid5
929+
} >actual &&
930+
test_cmp expect actual &&
931+
test_must_fail git config --expiry-date date.invalid1
932+
'
933+
904934
cat > expect << EOF
905935
[quote]
906936
leading = " test"

0 commit comments

Comments
 (0)