зеркало из https://github.com/microsoft/git.git
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 <hsed@unimetic.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Родитель
89ea799ffc
Коммит
5f9674243d
|
@ -180,6 +180,11 @@ See also <<FILES>>.
|
|||
value (but you can use `git config section.variable ~/`
|
||||
from the command line to let your shell do the expansion).
|
||||
|
||||
--expiry-date::
|
||||
`git config` will ensure that the output is converted from
|
||||
a fixed or relative date-string to a timestamp. This option
|
||||
has no effect when setting the value.
|
||||
|
||||
-z::
|
||||
--null::
|
||||
For all options that output values and/or keys, always
|
||||
|
|
|
@ -52,6 +52,7 @@ static int show_origin;
|
|||
#define TYPE_INT (1<<1)
|
||||
#define TYPE_BOOL_OR_INT (1<<2)
|
||||
#define TYPE_PATH (1<<3)
|
||||
#define TYPE_EXPIRY_DATE (1<<4)
|
||||
|
||||
static struct option builtin_config_options[] = {
|
||||
OPT_GROUP(N_("Config file location")),
|
||||
|
@ -80,6 +81,7 @@ static struct option builtin_config_options[] = {
|
|||
OPT_BIT(0, "int", &types, N_("value is decimal number"), TYPE_INT),
|
||||
OPT_BIT(0, "bool-or-int", &types, N_("value is --bool or --int"), TYPE_BOOL_OR_INT),
|
||||
OPT_BIT(0, "path", &types, N_("value is a path (file or directory name)"), TYPE_PATH),
|
||||
OPT_BIT(0, "expiry-date", &types, N_("value is an expiry date"), TYPE_EXPIRY_DATE),
|
||||
OPT_GROUP(N_("Other")),
|
||||
OPT_BOOL('z', "null", &end_null, N_("terminate values with NUL byte")),
|
||||
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
|
|||
return -1;
|
||||
strbuf_addstr(buf, v);
|
||||
free((char *)v);
|
||||
} else if (types == TYPE_EXPIRY_DATE) {
|
||||
timestamp_t t;
|
||||
if (git_config_expiry_date(&t, key_, value_) < 0)
|
||||
return -1;
|
||||
strbuf_addf(buf, "%"PRItime, t);
|
||||
} else if (value_) {
|
||||
strbuf_addstr(buf, value_);
|
||||
} else {
|
||||
|
@ -273,12 +280,13 @@ static char *normalize_value(const char *key, const char *value)
|
|||
if (!value)
|
||||
return NULL;
|
||||
|
||||
if (types == 0 || types == TYPE_PATH)
|
||||
if (types == 0 || types == TYPE_PATH || types == TYPE_EXPIRY_DATE)
|
||||
/*
|
||||
* We don't do normalization for TYPE_PATH here: If
|
||||
* the path is like ~/foobar/, we prefer to store
|
||||
* "~/foobar/" in the config file, and to expand the ~
|
||||
* when retrieving the value.
|
||||
* Also don't do normalization for expiry dates.
|
||||
*/
|
||||
return xstrdup(value);
|
||||
if (types == TYPE_INT)
|
||||
|
|
|
@ -416,16 +416,6 @@ static struct reflog_expire_cfg *find_cfg_ent(const char *pattern, size_t len)
|
|||
return ent;
|
||||
}
|
||||
|
||||
static int parse_expire_cfg_value(const char *var, const char *value, timestamp_t *expire)
|
||||
{
|
||||
if (!value)
|
||||
return config_error_nonbool(var);
|
||||
if (parse_expiry_date(value, expire))
|
||||
return error(_("'%s' for '%s' is not a valid timestamp"),
|
||||
value, var);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* expiry timer slot */
|
||||
#define EXPIRE_TOTAL 01
|
||||
#define EXPIRE_UNREACH 02
|
||||
|
@ -443,11 +433,11 @@ static int reflog_expire_config(const char *var, const char *value, void *cb)
|
|||
|
||||
if (!strcmp(key, "reflogexpire")) {
|
||||
slot = EXPIRE_TOTAL;
|
||||
if (parse_expire_cfg_value(var, value, &expire))
|
||||
if (git_config_expiry_date(&expire, var, value))
|
||||
return -1;
|
||||
} else if (!strcmp(key, "reflogexpireunreachable")) {
|
||||
slot = EXPIRE_UNREACH;
|
||||
if (parse_expire_cfg_value(var, value, &expire))
|
||||
if (git_config_expiry_date(&expire, var, value))
|
||||
return -1;
|
||||
} else
|
||||
return git_default_config(var, value, cb);
|
||||
|
|
10
config.c
10
config.c
|
@ -990,6 +990,16 @@ int git_config_pathname(const char **dest, const char *var, const char *value)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int git_config_expiry_date(timestamp_t *timestamp, const char *var, const char *value)
|
||||
{
|
||||
if (!value)
|
||||
return config_error_nonbool(var);
|
||||
if (parse_expiry_date(value, timestamp))
|
||||
return error(_("'%s' for '%s' is not a valid timestamp"),
|
||||
value, var);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int git_default_core_config(const char *var, const char *value)
|
||||
{
|
||||
/* This needs a better name */
|
||||
|
|
1
config.h
1
config.h
|
@ -58,6 +58,7 @@ extern int git_config_bool_or_int(const char *, const char *, int *);
|
|||
extern int git_config_bool(const char *, const char *);
|
||||
extern int git_config_string(const char **, const char *, const char *);
|
||||
extern int git_config_pathname(const char **, const char *, const char *);
|
||||
extern int git_config_expiry_date(timestamp_t *, const char *, const char *);
|
||||
extern int git_config_set_in_file_gently(const char *, const char *, const char *);
|
||||
extern void git_config_set_in_file(const char *, const char *, const char *);
|
||||
extern int git_config_set_gently(const char *, const char *);
|
||||
|
|
|
@ -5,6 +5,7 @@ static const char *usage_msg = "\n"
|
|||
" test-date show:<format> [time_t]...\n"
|
||||
" test-date parse [date]...\n"
|
||||
" test-date approxidate [date]...\n"
|
||||
" test-date timestamp [date]...\n"
|
||||
" test-date is64bit\n"
|
||||
" test-date time_t-is64bit\n";
|
||||
|
||||
|
@ -71,6 +72,15 @@ static void parse_approxidate(const char **argv, struct timeval *now)
|
|||
}
|
||||
}
|
||||
|
||||
static void parse_approx_timestamp(const char **argv, struct timeval *now)
|
||||
{
|
||||
for (; *argv; argv++) {
|
||||
timestamp_t t;
|
||||
t = approxidate_relative(*argv, now);
|
||||
printf("%s -> %"PRItime"\n", *argv, t);
|
||||
}
|
||||
}
|
||||
|
||||
int cmd_main(int argc, const char **argv)
|
||||
{
|
||||
struct timeval now;
|
||||
|
@ -95,6 +105,8 @@ int cmd_main(int argc, const char **argv)
|
|||
parse_dates(argv+1, &now);
|
||||
else if (!strcmp(*argv, "approxidate"))
|
||||
parse_approxidate(argv+1, &now);
|
||||
else if (!strcmp(*argv, "timestamp"))
|
||||
parse_approx_timestamp(argv+1, &now);
|
||||
else if (!strcmp(*argv, "is64bit"))
|
||||
return sizeof(timestamp_t) == 8 ? 0 : 1;
|
||||
else if (!strcmp(*argv, "time_t-is64bit"))
|
||||
|
|
|
@ -901,6 +901,36 @@ test_expect_success 'get --path barfs on boolean variable' '
|
|||
test_must_fail git config --get --path path.bool
|
||||
'
|
||||
|
||||
test_expect_success 'get --expiry-date' '
|
||||
rel="3.weeks.5.days.00:00" &&
|
||||
rel_out="$rel ->" &&
|
||||
cat >.git/config <<-\EOF &&
|
||||
[date]
|
||||
valid1 = "3.weeks.5.days 00:00"
|
||||
valid2 = "Fri Jun 4 15:46:55 2010"
|
||||
valid3 = "2017/11/11 11:11:11PM"
|
||||
valid4 = "2017/11/10 09:08:07 PM"
|
||||
valid5 = "never"
|
||||
invalid1 = "abc"
|
||||
EOF
|
||||
cat >expect <<-EOF &&
|
||||
$(test-date timestamp $rel)
|
||||
1275666415
|
||||
1510441871
|
||||
1510348087
|
||||
0
|
||||
EOF
|
||||
{
|
||||
echo "$rel_out $(git config --expiry-date date.valid1)"
|
||||
git config --expiry-date date.valid2 &&
|
||||
git config --expiry-date date.valid3 &&
|
||||
git config --expiry-date date.valid4 &&
|
||||
git config --expiry-date date.valid5
|
||||
} >actual &&
|
||||
test_cmp expect actual &&
|
||||
test_must_fail git config --expiry-date date.invalid1
|
||||
'
|
||||
|
||||
cat > expect << EOF
|
||||
[quote]
|
||||
leading = " test"
|
||||
|
|
Загрузка…
Ссылка в новой задаче