Skip to content

Commit 26c7974

Browse files
sunshinecogitster
authored andcommitted
maintenance: fix incorrect maintenance.repo path with bare repository
The periodic maintenance tasks configured by `git maintenance start` invoke `git for-each-repo` to run `git maintenance run` on each path specified by the multi-value global configuration variable `maintenance.repo`. Because `git for-each-repo` will likely be run outside of the repositories which require periodic maintenance, it is mandatory that the repository paths specified by `maintenance.repo` are absolute. Unfortunately, however, `git maintenance register` does nothing to ensure that the paths it assigns to `maintenance.repo` are indeed absolute, and may in fact -- especially in the case of a bare repository -- assign a relative path to `maintenance.repo` instead. Fix this problem by converting all paths to absolute before assigning them to `maintenance.repo`. While at it, also fix `git maintenance unregister` to convert paths to absolute, as well, in order to ensure that it can correctly remove from `maintenance.repo` a path assigned via `git maintenance register`. Reported-by: Clement Moyroud <[email protected]> Signed-off-by: Eric Sunshine <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 966e671 commit 26c7974

File tree

2 files changed

+46
-17
lines changed

2 files changed

+46
-17
lines changed

builtin/gc.c

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1461,11 +1461,23 @@ static int maintenance_run(int argc, const char **argv, const char *prefix)
14611461
return maintenance_run_tasks(&opts);
14621462
}
14631463

1464+
static char *get_maintpath(void)
1465+
{
1466+
struct strbuf sb = STRBUF_INIT;
1467+
const char *p = the_repository->worktree ?
1468+
the_repository->worktree : the_repository->gitdir;
1469+
1470+
strbuf_realpath(&sb, p, 1);
1471+
return strbuf_detach(&sb, NULL);
1472+
}
1473+
14641474
static int maintenance_register(void)
14651475
{
1476+
int rc;
14661477
char *config_value;
14671478
struct child_process config_set = CHILD_PROCESS_INIT;
14681479
struct child_process config_get = CHILD_PROCESS_INIT;
1480+
char *maintpath = get_maintpath();
14691481

14701482
/* Disable foreground maintenance */
14711483
git_config_set("maintenance.auto", "false");
@@ -1478,40 +1490,44 @@ static int maintenance_register(void)
14781490

14791491
config_get.git_cmd = 1;
14801492
strvec_pushl(&config_get.args, "config", "--global", "--get",
1481-
"--fixed-value", "maintenance.repo",
1482-
the_repository->worktree ? the_repository->worktree
1483-
: the_repository->gitdir,
1484-
NULL);
1493+
"--fixed-value", "maintenance.repo", maintpath, NULL);
14851494
config_get.out = -1;
14861495

1487-
if (start_command(&config_get))
1488-
return error(_("failed to run 'git config'"));
1496+
if (start_command(&config_get)) {
1497+
rc = error(_("failed to run 'git config'"));
1498+
goto done;
1499+
}
14891500

14901501
/* We already have this value in our config! */
1491-
if (!finish_command(&config_get))
1492-
return 0;
1502+
if (!finish_command(&config_get)) {
1503+
rc = 0;
1504+
goto done;
1505+
}
14931506

14941507
config_set.git_cmd = 1;
14951508
strvec_pushl(&config_set.args, "config", "--add", "--global", "maintenance.repo",
1496-
the_repository->worktree ? the_repository->worktree
1497-
: the_repository->gitdir,
1498-
NULL);
1509+
maintpath, NULL);
1510+
1511+
rc = run_command(&config_set);
14991512

1500-
return run_command(&config_set);
1513+
done:
1514+
free(maintpath);
1515+
return rc;
15011516
}
15021517

15031518
static int maintenance_unregister(void)
15041519
{
1520+
int rc;
15051521
struct child_process config_unset = CHILD_PROCESS_INIT;
1522+
char *maintpath = get_maintpath();
15061523

15071524
config_unset.git_cmd = 1;
15081525
strvec_pushl(&config_unset.args, "config", "--global", "--unset",
1509-
"--fixed-value", "maintenance.repo",
1510-
the_repository->worktree ? the_repository->worktree
1511-
: the_repository->gitdir,
1512-
NULL);
1526+
"--fixed-value", "maintenance.repo", maintpath, NULL);
15131527

1514-
return run_command(&config_unset);
1528+
rc = run_command(&config_unset);
1529+
free(maintpath);
1530+
return rc;
15151531
}
15161532

15171533
static const char *get_frequency(enum schedule_priority schedule)

t/t7900-maintenance.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,4 +632,17 @@ test_expect_success 'fails when running outside of a repository' '
632632
nongit test_must_fail git maintenance unregister
633633
'
634634

635+
test_expect_success 'register and unregister bare repo' '
636+
test_when_finished "git config --global --unset-all maintenance.repo || :" &&
637+
test_might_fail git config --global --unset-all maintenance.repo &&
638+
git init --bare barerepo &&
639+
(
640+
cd barerepo &&
641+
git maintenance register &&
642+
git config --get --global --fixed-value maintenance.repo "$(pwd)" &&
643+
git maintenance unregister &&
644+
test_must_fail git config --global --get-all maintenance.repo
645+
)
646+
'
647+
635648
test_done

0 commit comments

Comments
 (0)