diff options
Diffstat (limited to 'builtin/gc.c')
-rw-r--r-- | builtin/gc.c | 66 |
1 files changed, 63 insertions, 3 deletions
diff --git a/builtin/gc.c b/builtin/gc.c index 86b807a008..00fff59bdb 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -701,7 +701,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix) } static const char * const builtin_maintenance_run_usage[] = { - N_("git maintenance run [--auto] [--[no-]quiet]"), + N_("git maintenance run [--auto] [--[no-]quiet] [--task=<task>]"), NULL }; @@ -759,6 +759,9 @@ struct maintenance_task { const char *name; maintenance_task_fn *fn; unsigned enabled:1; + + /* -1 if not selected. */ + int selected_order; }; enum maintenance_task_label { @@ -781,13 +784,32 @@ static struct maintenance_task tasks[] = { }, }; +static int compare_tasks_by_selection(const void *a_, const void *b_) +{ + const struct maintenance_task *a, *b; + + a = (const struct maintenance_task *)&a_; + b = (const struct maintenance_task *)&b_; + + return b->selected_order - a->selected_order; +} + static int maintenance_run_tasks(struct maintenance_run_opts *opts) { - int i; + int i, found_selected = 0; int result = 0; + for (i = 0; !found_selected && i < TASK__COUNT; i++) + found_selected = tasks[i].selected_order >= 0; + + if (found_selected) + QSORT(tasks, TASK__COUNT, compare_tasks_by_selection); + for (i = 0; i < TASK__COUNT; i++) { - if (!tasks[i].enabled) + if (found_selected && tasks[i].selected_order < 0) + continue; + + if (!found_selected && !tasks[i].enabled) continue; if (tasks[i].fn(opts)) { @@ -799,20 +821,58 @@ static int maintenance_run_tasks(struct maintenance_run_opts *opts) return result; } +static int task_option_parse(const struct option *opt, + const char *arg, int unset) +{ + int i, num_selected = 0; + struct maintenance_task *task = NULL; + + BUG_ON_OPT_NEG(unset); + + for (i = 0; i < TASK__COUNT; i++) { + if (tasks[i].selected_order >= 0) + num_selected++; + if (!strcasecmp(tasks[i].name, arg)) { + task = &tasks[i]; + } + } + + if (!task) { + error(_("'%s' is not a valid task"), arg); + return 1; + } + + if (task->selected_order >= 0) { + error(_("task '%s' cannot be selected multiple times"), arg); + return 1; + } + + task->selected_order = num_selected + 1; + + return 0; +} + static int maintenance_run(int argc, const char **argv, const char *prefix) { + int i; struct maintenance_run_opts opts; struct option builtin_maintenance_run_options[] = { OPT_BOOL(0, "auto", &opts.auto_flag, N_("run tasks based on the state of the repository")), OPT_BOOL(0, "quiet", &opts.quiet, N_("do not report progress or other information over stderr")), + OPT_CALLBACK_F(0, "task", NULL, N_("task"), + N_("run a specific task"), + PARSE_OPT_NONEG, task_option_parse), OPT_END() }; memset(&opts, 0, sizeof(opts)); opts.quiet = !isatty(2); + for (i = 0; i < TASK__COUNT; i++) + tasks[i].selected_order = -1; + argc = parse_options(argc, argv, prefix, builtin_maintenance_run_options, builtin_maintenance_run_usage, |