Merge branch 'rp/maintenance-qol'
'git maintenance register' is taught to write configuration to an arbitrary path, and 'git for-each-repo' is taught to expand tilde characters in paths. * rp/maintenance-qol: builtin/gc.c: fix use-after-free in maintenance_unregister() maintenance --unregister: fix uninit'd data use & -Wdeclaration-after-statement maintenance: add option to register in a specific config for-each-repo: interpolate repo path arguments
This commit is contained in:
commit
56a64fcdc3
@ -50,13 +50,13 @@ stop::
|
||||
the background maintenance is restarted later.
|
||||
|
||||
register::
|
||||
Initialize Git config values so any scheduled maintenance will
|
||||
start running on this repository. This adds the repository to the
|
||||
`maintenance.repo` config variable in the current user's global
|
||||
config and enables some recommended configuration values for
|
||||
`maintenance.<task>.schedule`. The tasks that are enabled are safe
|
||||
for running in the background without disrupting foreground
|
||||
processes.
|
||||
Initialize Git config values so any scheduled maintenance will start
|
||||
running on this repository. This adds the repository to the
|
||||
`maintenance.repo` config variable in the current user's global config,
|
||||
or the config specified by --config-file option, and enables some
|
||||
recommended configuration values for `maintenance.<task>.schedule`. The
|
||||
tasks that are enabled are safe for running in the background without
|
||||
disrupting foreground processes.
|
||||
+
|
||||
The `register` subcommand will also set the `maintenance.strategy` config
|
||||
value to `incremental`, if this value is not previously set. The
|
||||
|
@ -14,13 +14,16 @@ static int run_command_on_repo(const char *path, int argc, const char ** argv)
|
||||
{
|
||||
int i;
|
||||
struct child_process child = CHILD_PROCESS_INIT;
|
||||
char *abspath = interpolate_path(path, 0);
|
||||
|
||||
child.git_cmd = 1;
|
||||
strvec_pushl(&child.args, "-C", path, NULL);
|
||||
strvec_pushl(&child.args, "-C", abspath, NULL);
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
strvec_push(&child.args, argv[i]);
|
||||
|
||||
free(abspath);
|
||||
|
||||
return run_command(&child);
|
||||
}
|
||||
|
||||
|
45
builtin/gc.c
45
builtin/gc.c
@ -1480,13 +1480,15 @@ static char *get_maintpath(void)
|
||||
}
|
||||
|
||||
static char const * const builtin_maintenance_register_usage[] = {
|
||||
"git maintenance register",
|
||||
"git maintenance register [--config-file <path>]",
|
||||
NULL
|
||||
};
|
||||
|
||||
static int maintenance_register(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
char *config_file = NULL;
|
||||
struct option options[] = {
|
||||
OPT_STRING(0, "config-file", &config_file, N_("file"), N_("use given config file")),
|
||||
OPT_END(),
|
||||
};
|
||||
int found = 0;
|
||||
@ -1523,12 +1525,16 @@ static int maintenance_register(int argc, const char **argv, const char *prefix)
|
||||
|
||||
if (!found) {
|
||||
int rc;
|
||||
char *user_config, *xdg_config;
|
||||
git_global_config(&user_config, &xdg_config);
|
||||
if (!user_config)
|
||||
die(_("$HOME not set"));
|
||||
char *user_config = NULL, *xdg_config = NULL;
|
||||
|
||||
if (!config_file) {
|
||||
git_global_config(&user_config, &xdg_config);
|
||||
config_file = user_config;
|
||||
if (!user_config)
|
||||
die(_("$HOME not set"));
|
||||
}
|
||||
rc = git_config_set_multivar_in_file_gently(
|
||||
user_config, "maintenance.repo", maintpath,
|
||||
config_file, "maintenance.repo", maintpath,
|
||||
CONFIG_REGEX_NONE, 0);
|
||||
free(user_config);
|
||||
free(xdg_config);
|
||||
@ -1543,14 +1549,16 @@ static int maintenance_register(int argc, const char **argv, const char *prefix)
|
||||
}
|
||||
|
||||
static char const * const builtin_maintenance_unregister_usage[] = {
|
||||
"git maintenance unregister [--force]",
|
||||
"git maintenance unregister [--config-file <path>] [--force]",
|
||||
NULL
|
||||
};
|
||||
|
||||
static int maintenance_unregister(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
int force = 0;
|
||||
char *config_file = NULL;
|
||||
struct option options[] = {
|
||||
OPT_STRING(0, "config-file", &config_file, N_("file"), N_("use given config file")),
|
||||
OPT__FORCE(&force,
|
||||
N_("return success even if repository was not registered"),
|
||||
PARSE_OPT_NOCOMPLETE),
|
||||
@ -1561,6 +1569,7 @@ static int maintenance_unregister(int argc, const char **argv, const char *prefi
|
||||
int found = 0;
|
||||
struct string_list_item *item;
|
||||
const struct string_list *list;
|
||||
struct config_set cs = { { 0 } };
|
||||
|
||||
argc = parse_options(argc, argv, prefix, options,
|
||||
builtin_maintenance_unregister_usage, 0);
|
||||
@ -1568,7 +1577,13 @@ static int maintenance_unregister(int argc, const char **argv, const char *prefi
|
||||
usage_with_options(builtin_maintenance_unregister_usage,
|
||||
options);
|
||||
|
||||
list = git_config_get_value_multi(key);
|
||||
if (config_file) {
|
||||
git_configset_init(&cs);
|
||||
git_configset_add_file(&cs, config_file);
|
||||
list = git_configset_get_value_multi(&cs, key);
|
||||
} else {
|
||||
list = git_config_get_value_multi(key);
|
||||
}
|
||||
if (list) {
|
||||
for_each_string_list_item(item, list) {
|
||||
if (!strcmp(maintpath, item->string)) {
|
||||
@ -1580,12 +1595,15 @@ static int maintenance_unregister(int argc, const char **argv, const char *prefi
|
||||
|
||||
if (found) {
|
||||
int rc;
|
||||
char *user_config, *xdg_config;
|
||||
git_global_config(&user_config, &xdg_config);
|
||||
if (!user_config)
|
||||
die(_("$HOME not set"));
|
||||
char *user_config = NULL, *xdg_config = NULL;
|
||||
if (!config_file) {
|
||||
git_global_config(&user_config, &xdg_config);
|
||||
config_file = user_config;
|
||||
if (!user_config)
|
||||
die(_("$HOME not set"));
|
||||
}
|
||||
rc = git_config_set_multivar_in_file_gently(
|
||||
user_config, key, NULL, maintpath,
|
||||
config_file, key, NULL, maintpath,
|
||||
CONFIG_FLAGS_MULTI_REPLACE | CONFIG_FLAGS_FIXED_VALUE);
|
||||
free(user_config);
|
||||
free(xdg_config);
|
||||
@ -1598,6 +1616,7 @@ static int maintenance_unregister(int argc, const char **argv, const char *prefi
|
||||
die(_("repository '%s' is not registered"), maintpath);
|
||||
}
|
||||
|
||||
git_configset_clear(&cs);
|
||||
free(maintpath);
|
||||
return 0;
|
||||
}
|
||||
|
@ -8,9 +8,11 @@ test_expect_success 'run based on configured value' '
|
||||
git init one &&
|
||||
git init two &&
|
||||
git init three &&
|
||||
git init ~/four &&
|
||||
git -C two commit --allow-empty -m "DID NOT RUN" &&
|
||||
git config run.key "$TRASH_DIRECTORY/one" &&
|
||||
git config --add run.key "$TRASH_DIRECTORY/three" &&
|
||||
git config --add run.key "~/four" &&
|
||||
git for-each-repo --config=run.key commit --allow-empty -m "ran" &&
|
||||
git -C one log -1 --pretty=format:%s >message &&
|
||||
grep ran message &&
|
||||
@ -18,12 +20,16 @@ test_expect_success 'run based on configured value' '
|
||||
! grep ran message &&
|
||||
git -C three log -1 --pretty=format:%s >message &&
|
||||
grep ran message &&
|
||||
git -C ~/four log -1 --pretty=format:%s >message &&
|
||||
grep ran message &&
|
||||
git for-each-repo --config=run.key -- commit --allow-empty -m "ran again" &&
|
||||
git -C one log -1 --pretty=format:%s >message &&
|
||||
grep again message &&
|
||||
git -C two log -1 --pretty=format:%s >message &&
|
||||
! grep again message &&
|
||||
git -C three log -1 --pretty=format:%s >message &&
|
||||
grep again message &&
|
||||
git -C ~/four log -1 --pretty=format:%s >message &&
|
||||
grep again message
|
||||
'
|
||||
|
||||
|
@ -500,9 +500,28 @@ test_expect_success 'register and unregister' '
|
||||
git config --global --get-all maintenance.repo >actual &&
|
||||
test_cmp before actual &&
|
||||
|
||||
git config --file ./other --add maintenance.repo /existing1 &&
|
||||
git config --file ./other --add maintenance.repo /existing2 &&
|
||||
git config --file ./other --get-all maintenance.repo >before &&
|
||||
|
||||
git maintenance register --config-file ./other &&
|
||||
test_cmp_config false maintenance.auto &&
|
||||
git config --file ./other --get-all maintenance.repo >between &&
|
||||
cp before expect &&
|
||||
pwd >>expect &&
|
||||
test_cmp expect between &&
|
||||
|
||||
git maintenance unregister --config-file ./other &&
|
||||
git config --file ./other --get-all maintenance.repo >actual &&
|
||||
test_cmp before actual &&
|
||||
|
||||
test_must_fail git maintenance unregister 2>err &&
|
||||
grep "is not registered" err &&
|
||||
git maintenance unregister --force
|
||||
git maintenance unregister --force &&
|
||||
|
||||
test_must_fail git maintenance unregister --config-file ./other 2>err &&
|
||||
grep "is not registered" err &&
|
||||
git maintenance unregister --config-file ./other --force
|
||||
'
|
||||
|
||||
test_expect_success !MINGW 'register and unregister with regex metacharacters' '
|
||||
|
Loading…
Reference in New Issue
Block a user