maintenance: update schedule before config
When running 'git maintenance start', the current pattern is to configure global config settings to enable maintenance on the current repository and set 'maintenance.auto' to false and _then_ to set up the schedule with the system scheduler. This has a problematic error condition: if the scheduler fails to initialize, the repository still will not use automatic maintenance due to the 'maintenance.auto' setting. Fix this gap by swapping the order of operations. If Git fails to initialize maintenance, then the config changes should never happen. Reported-by: Phillip Wood <phillip.wood123@gmail.com> Signed-off-by: Derrick Stolee <derrickstolee@github.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Derrick Stolee committed
Aug 10, 2023 at 20:39 UTC
69ecfcacfd136810f2343b548174efe9ae3fdead
2 files changed
+17
-1
builtin/gc.c
+4
-1
@@ -2728,9 +2728,12 @@ static int maintenance_start(int argc, const char **argv, const char *prefix)
2728
opts.scheduler = resolve_scheduler(opts.scheduler);
2729
validate_scheduler(opts.scheduler);
2730
2731
+ if (update_background_schedule(&opts, 1))
2732
+ die(_("failed to set up maintenance schedule"));
2733
+
2734
if (maintenance_register(ARRAY_SIZE(register_args)-1, register_args, NULL))
2735
warning(_("failed to add repo to global config"));
2733
- return update_background_schedule(&opts, 1);
2736
+ return 0;
2737
}
2738
2739
static const char *const builtin_maintenance_stop_usage[] = {
t/t7900-maintenance.sh
+13
@@ -849,4 +849,17 @@ test_expect_success 'register and unregister bare repo' '
849
)
850
'
851
852
+test_expect_success 'failed schedule prevents config change' '
853
+ git init --bare failcase &&
854
+
855
+ for scheduler in crontab launchctl schtasks systemctl
856
+ do
857
+ GIT_TEST_MAINT_SCHEDULER="$scheduler:false" &&
858
+ export GIT_TEST_MAINT_SCHEDULER &&
859
+ test_must_fail \
860
+ git -C failcase maintenance start &&
861
+ test_must_fail git -C failcase config maintenance.auto || return 1
862
+ done
863
+'
864
+
865
test_done