builtin/maintenance: run maintenance tasks depending on type

We basically have three different ways to execute repository maintenance: 1. Manual maintenance via `git maintenance run`. 2. Automatic maintenance via `git maintenance run --auto`. 3. Scheduled maintenance via `git maintenance run --schedule=`. At the moment, maintenance strategies only have an effect for the last type of maintenance. This is about to change in subsequent commits, but to do so we need to be able to skip some tasks depending on how exactly maintenance was invoked. Introduce a new maintenance type that discern between manual (1 & 2) and scheduled (3) maintenance. Convert the `enabled` field into a bitset so that it becomes possible to specifiy which tasks exactly should run in a specific context. The types picked for existing strategies match the status quo: - The default strategy is only ever executed as part of a manual maintenance run. It is not possible to use it for scheduled maintenance. - The incremental strategy is only ever executed as part of a scheduled maintenance run. It is not possible to use it for manual maintenance. The strategies will be tweaked in subsequent commits to make use of this new infrastructure. Signed-off-by: Patrick Steinhardt <ps@pks.im> Acked-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Oct 24, 2025 at 08:57 UTC 6a7d3eeb4703ab27ec7520d6e7fa9145e66f43dc
1 file changed +19 -9
builtin/gc.c
+19 -9
@@ -1827,9 +1827,16 @@ static int maintenance_run_tasks(struct maintenance_run_opts *opts,
1827 return result;
1828 }
1829
1830 +enum maintenance_type {
1831 + /* As invoked via `git maintenance run --schedule=`. */
1832 + MAINTENANCE_TYPE_SCHEDULED = (1 << 0),
1833 + /* As invoked via `git maintenance run` and with `--auto`. */
1834 + MAINTENANCE_TYPE_MANUAL = (1 << 1),
1835 +};
1836 +
1837 struct maintenance_strategy {
1838 struct {
1832 - int enabled;
1839 + unsigned type;
1840 enum schedule_priority schedule;
1841 } tasks[TASK__COUNT];
1842 };
@@ -1839,7 +1846,7 @@ static const struct maintenance_strategy none_strategy = { 0 };
1846 static const struct maintenance_strategy default_strategy = {
1847 .tasks = {
1848 [TASK_GC] = {
1842 - .enabled = 1,
1849 + .type = MAINTENANCE_TYPE_MANUAL,
1850 },
1851 },
1852 };
@@ -1847,23 +1854,23 @@ static const struct maintenance_strategy default_strategy = {
1854 static const struct maintenance_strategy incremental_strategy = {
1855 .tasks = {
1856 [TASK_COMMIT_GRAPH] = {
1850 - .enabled = 1,
1857 + .type = MAINTENANCE_TYPE_SCHEDULED,
1858 .schedule = SCHEDULE_HOURLY,
1859 },
1860 [TASK_PREFETCH] = {
1854 - .enabled = 1,
1861 + .type = MAINTENANCE_TYPE_SCHEDULED,
1862 .schedule = SCHEDULE_HOURLY,
1863 },
1864 [TASK_INCREMENTAL_REPACK] = {
1858 - .enabled = 1,
1865 + .type = MAINTENANCE_TYPE_SCHEDULED,
1866 .schedule = SCHEDULE_DAILY,
1867 },
1868 [TASK_LOOSE_OBJECTS] = {
1862 - .enabled = 1,
1869 + .type = MAINTENANCE_TYPE_SCHEDULED,
1870 .schedule = SCHEDULE_DAILY,
1871 },
1872 [TASK_PACK_REFS] = {
1866 - .enabled = 1,
1873 + .type = MAINTENANCE_TYPE_SCHEDULED,
1874 .schedule = SCHEDULE_WEEKLY,
1875 },
1876 },
@@ -1881,6 +1888,7 @@ static void initialize_task_config(struct maintenance_run_opts *opts,
1888 {
1889 struct strbuf config_name = STRBUF_INIT;
1890 struct maintenance_strategy strategy;
1891 + enum maintenance_type type;
1892 const char *config_str;
1893
1894 /*
@@ -1915,8 +1923,10 @@ static void initialize_task_config(struct maintenance_run_opts *opts,
1923 strategy = parse_maintenance_strategy(config_str);
1924 else
1925 strategy = none_strategy;
1926 + type = MAINTENANCE_TYPE_SCHEDULED;
1927 } else {
1928 strategy = default_strategy;
1929 + type = MAINTENANCE_TYPE_MANUAL;
1930 }
1931
1932 for (size_t i = 0; i < TASK__COUNT; i++) {
@@ -1926,8 +1936,8 @@ static void initialize_task_config(struct maintenance_run_opts *opts,
1936 strbuf_addf(&config_name, "maintenance.%s.enabled",
1937 tasks[i].name);
1938 if (!repo_config_get_bool(the_repository, config_name.buf, &config_value))
1929 - strategy.tasks[i].enabled = config_value;
1930 - if (!strategy.tasks[i].enabled)
1939 + strategy.tasks[i].type = config_value ? type : 0;
1940 + if (!(strategy.tasks[i].type & type))
1941 continue;
1942
1943 if (opts->schedule) {