summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar Rafael Silva <rafaeloliveira.cs@gmail.com>2020-11-26 20:41:41 +0000
committerLibravatar Junio C Hamano <gitster@pobox.com>2020-11-30 13:44:15 -0800
commite72f7defc4f454cc7ad512d9a16a78b83f2606d8 (patch)
treea7f4893c377b7de761dc369fe8c68100978e0465
parentEighth batch (diff)
downloadtgif-e72f7defc4f454cc7ad512d9a16a78b83f2606d8.tar.xz
maintenance: fix SEGFAULT when no repository
The "git maintenance run" and "git maintenance start/stop" commands holds a file-based lock at the .git/maintenance.lock and .git/schedule.lock respectively. These locks are used to ensure only one maintenance process is executed at the time as both operations involves writing data into the git repository. The path to the lock file is built using "the_repository->objects->odb->path" that results in SEGFAULT when we have no repository available as "the_repository->objects->odb" is set to NULL. Let's teach maintenance command to use RUN_SETUP option that will provide the validation and fail when running outside of a repository. Hence fixing the SEGFAULT for all three operations and making the behaviour consistent across all subcommands. Setting the RUN_SETUP also provides the same protection for all subcommands given that the "register" and "unregister" also requires to be executed inside a repository. Furthermore let's remove the local validation implemented by the "register" and "unregister" as this will not be required anymore with the new option. Signed-off-by: Rafael Silva <rafaeloliveira.cs@gmail.com> Reviewed-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--builtin/gc.c7
-rw-r--r--git.c2
-rwxr-xr-xt/t7900-maintenance.sh8
3 files changed, 9 insertions, 8 deletions
diff --git a/builtin/gc.c b/builtin/gc.c
index bc25ad52c7..ebb0158308 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -1446,10 +1446,6 @@ static int maintenance_register(void)
struct child_process config_set = CHILD_PROCESS_INIT;
struct child_process config_get = CHILD_PROCESS_INIT;
- /* There is no current repository, so skip registering it */
- if (!the_repository || !the_repository->gitdir)
- return 0;
-
/* Disable foreground maintenance */
git_config_set("maintenance.auto", "false");
@@ -1486,9 +1482,6 @@ static int maintenance_unregister(void)
{
struct child_process config_unset = CHILD_PROCESS_INIT;
- if (!the_repository || !the_repository->gitdir)
- return error(_("no current repository to unregister"));
-
config_unset.git_cmd = 1;
strvec_pushl(&config_unset.args, "config", "--global", "--unset",
"maintenance.repo",
diff --git a/git.c b/git.c
index 4b7bd77b80..a00a0a4d94 100644
--- a/git.c
+++ b/git.c
@@ -535,7 +535,7 @@ static struct cmd_struct commands[] = {
{ "ls-tree", cmd_ls_tree, RUN_SETUP },
{ "mailinfo", cmd_mailinfo, RUN_SETUP_GENTLY | NO_PARSEOPT },
{ "mailsplit", cmd_mailsplit, NO_PARSEOPT },
- { "maintenance", cmd_maintenance, RUN_SETUP_GENTLY | NO_PARSEOPT },
+ { "maintenance", cmd_maintenance, RUN_SETUP | NO_PARSEOPT },
{ "merge", cmd_merge, RUN_SETUP | NEED_WORK_TREE },
{ "merge-base", cmd_merge_base, RUN_SETUP },
{ "merge-file", cmd_merge_file, RUN_SETUP_GENTLY },
diff --git a/t/t7900-maintenance.sh b/t/t7900-maintenance.sh
index d9e68bb2bf..4ca3617173 100755
--- a/t/t7900-maintenance.sh
+++ b/t/t7900-maintenance.sh
@@ -441,4 +441,12 @@ test_expect_success 'register preserves existing strategy' '
test_config maintenance.strategy incremental
'
+test_execpt_success 'fails when running outside of a repository' '
+ nongit test_must_fail git maintenance run &&
+ nongit test_must_fail git maintenance stop &&
+ nongit test_must_fail git maintenance start &&
+ nongit test_must_fail git maintenance register &&
+ nongit test_must_fail git maintenance unregister
+'
+
test_done