maintenance: add 'unregister --force'

The 'git maintenance unregister' subcommand has a step that removes the current repository from the multi-valued maitenance.repo config key. This fails if the repository is not listed in that key. This makes running 'git maintenance unregister' twice result in a failure in the second instance. This failure exit code is helpful, but its message is not. Add a new die() message that explicitly calls out the failure due to the repository not being registered. In some cases, users may want to run 'git maintenance unregister' just to make sure that background jobs will not start on this repository, but they do not want to check to see if it is registered first. Add a new '--force' option that will siltently succeed if the repository is not already registered. Also add an extra test of 'git maintenance unregister' at a point where there are no registered repositories. This should fail without --force. Signed-off-by: Derrick Stolee <derrickstolee@github.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Derrick Stolee committed Sep 27, 2022 at 13:56 UTC 1ebe6b029703e4bebf413ec052918a81390797ac
3 files changed +44 -8
Documentation/git-maintenance.txt
+5 -1
@@ -11,7 +11,7 @@ SYNOPSIS
11 [verse]
12 'git maintenance' run [<options>]
13 'git maintenance' start [--scheduler=<scheduler>]
14 -'git maintenance' (stop|register|unregister)
14 +'git maintenance' (stop|register|unregister) [<options>]
15
16
17 DESCRIPTION
@@ -79,6 +79,10 @@ unregister::
79 Remove the current repository from background maintenance. This
80 only removes the repository from the configured list. It does not
81 stop the background maintenance processes from running.
82 ++
83 +The `unregister` subcommand will report an error if the current repository
84 +is not already registered. Use the `--force` option to return success even
85 +when the current repository is not registered.
86
87 TASKS
88 -----
builtin/gc.c
+29 -6
@@ -1519,18 +1519,26 @@ done:
1519 }
1520
1521 static char const * const builtin_maintenance_unregister_usage[] = {
1522 - "git maintenance unregister",
1522 + "git maintenance unregister [--force]",
1523 NULL
1524 };
1525
1526 static int maintenance_unregister(int argc, const char **argv, const char *prefix)
1527 {
1528 + int force = 0;
1529 struct option options[] = {
1530 + OPT__FORCE(&force,
1531 + N_("return success even if repository was not registered"),
1532 + PARSE_OPT_NOCOMPLETE),
1533 OPT_END(),
1534 };
1531 - int rc;
1535 + const char *key = "maintenance.repo";
1536 + int rc = 0;
1537 struct child_process config_unset = CHILD_PROCESS_INIT;
1538 char *maintpath = get_maintpath();
1539 + int found = 0;
1540 + struct string_list_item *item;
1541 + const struct string_list *list;
1542
1543 argc = parse_options(argc, argv, prefix, options,
1544 builtin_maintenance_unregister_usage, 0);
@@ -1538,11 +1546,26 @@ static int maintenance_unregister(int argc, const char **argv, const char *prefi
1546 usage_with_options(builtin_maintenance_unregister_usage,
1547 options);
1548
1541 - config_unset.git_cmd = 1;
1542 - strvec_pushl(&config_unset.args, "config", "--global", "--unset",
1543 - "--fixed-value", "maintenance.repo", maintpath, NULL);
1549 + list = git_config_get_value_multi(key);
1550 + if (list) {
1551 + for_each_string_list_item(item, list) {
1552 + if (!strcmp(maintpath, item->string)) {
1553 + found = 1;
1554 + break;
1555 + }
1556 + }
1557 + }
1558 +
1559 + if (found) {
1560 + config_unset.git_cmd = 1;
1561 + strvec_pushl(&config_unset.args, "config", "--global", "--unset",
1562 + "--fixed-value", key, maintpath, NULL);
1563 +
1564 + rc = run_command(&config_unset);
1565 + } else if (!force) {
1566 + die(_("repository '%s' is not registered"), maintpath);
1567 + }
1568
1545 - rc = run_command(&config_unset);
1569 free(maintpath);
1570 return rc;
1571 }
t/t7900-maintenance.sh
+10 -1
@@ -480,6 +480,11 @@ test_expect_success 'maintenance.strategy inheritance' '
480
481 test_expect_success 'register and unregister' '
482 test_when_finished git config --global --unset-all maintenance.repo &&
483 +
484 + test_must_fail git maintenance unregister 2>err &&
485 + grep "is not registered" err &&
486 + git maintenance unregister --force &&
487 +
488 git config --global --add maintenance.repo /existing1 &&
489 git config --global --add maintenance.repo /existing2 &&
490 git config --global --get-all maintenance.repo >before &&
@@ -493,7 +498,11 @@ test_expect_success 'register and unregister' '
498
499 git maintenance unregister &&
500 git config --global --get-all maintenance.repo >actual &&
496 - test_cmp before actual
501 + test_cmp before actual &&
502 +
503 + test_must_fail git maintenance unregister 2>err &&
504 + grep "is not registered" err &&
505 + git maintenance unregister --force
506 '
507
508 test_expect_success !MINGW 'register and unregister with regex metacharacters' '