summaryrefslogtreecommitdiff
path: root/builtin/gc.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/gc.c')
-rw-r--r--builtin/gc.c66
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,