Skip to content

Commit e72f7de

Browse files
raffsgitster
authored andcommitted
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 <[email protected]> Reviewed-by: Derrick Stolee <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent e67fbf9 commit e72f7de

File tree

3 files changed

+9
-8
lines changed

3 files changed

+9
-8
lines changed

builtin/gc.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1446,10 +1446,6 @@ static int maintenance_register(void)
14461446
struct child_process config_set = CHILD_PROCESS_INIT;
14471447
struct child_process config_get = CHILD_PROCESS_INIT;
14481448

1449-
/* There is no current repository, so skip registering it */
1450-
if (!the_repository || !the_repository->gitdir)
1451-
return 0;
1452-
14531449
/* Disable foreground maintenance */
14541450
git_config_set("maintenance.auto", "false");
14551451

@@ -1486,9 +1482,6 @@ static int maintenance_unregister(void)
14861482
{
14871483
struct child_process config_unset = CHILD_PROCESS_INIT;
14881484

1489-
if (!the_repository || !the_repository->gitdir)
1490-
return error(_("no current repository to unregister"));
1491-
14921485
config_unset.git_cmd = 1;
14931486
strvec_pushl(&config_unset.args, "config", "--global", "--unset",
14941487
"maintenance.repo",

git.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,7 @@ static struct cmd_struct commands[] = {
535535
{ "ls-tree", cmd_ls_tree, RUN_SETUP },
536536
{ "mailinfo", cmd_mailinfo, RUN_SETUP_GENTLY | NO_PARSEOPT },
537537
{ "mailsplit", cmd_mailsplit, NO_PARSEOPT },
538-
{ "maintenance", cmd_maintenance, RUN_SETUP_GENTLY | NO_PARSEOPT },
538+
{ "maintenance", cmd_maintenance, RUN_SETUP | NO_PARSEOPT },
539539
{ "merge", cmd_merge, RUN_SETUP | NEED_WORK_TREE },
540540
{ "merge-base", cmd_merge_base, RUN_SETUP },
541541
{ "merge-file", cmd_merge_file, RUN_SETUP_GENTLY },

t/t7900-maintenance.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,4 +441,12 @@ test_expect_success 'register preserves existing strategy' '
441441
test_config maintenance.strategy incremental
442442
'
443443

444+
test_execpt_success 'fails when running outside of a repository' '
445+
nongit test_must_fail git maintenance run &&
446+
nongit test_must_fail git maintenance stop &&
447+
nongit test_must_fail git maintenance start &&
448+
nongit test_must_fail git maintenance register &&
449+
nongit test_must_fail git maintenance unregister
450+
'
451+
444452
test_done

0 commit comments

Comments
 (0)