scalar reconfigure -a: remove stale `scalar.repo` entries

Every once in a while, a Git for Windows installation fails because the attempt to reconfigure a Scalar enlistment failed because it was deleted manually without removing the corresponding entries in the global Git config. In f5f0842d0b5 (scalar: let 'unregister' handle a deleted enlistment directory gracefully, 2021-12-03), we already taught `scalar delete` to handle the case of a manually deleted enlistment gracefully. This patch adds the same graceful handling to `scalar reconfigure --all`. This patch is best viewed with `--color-moved`. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Taylor Blau <me@ttaylorr.com>

Johannes Schindelin committed Nov 7, 2022 at 18:25 UTC c90db53d203d7ade1dc7abe63857cfb5616fe34f
2 files changed +45 -20
scalar.c
+34 -20
@@ -599,6 +599,24 @@ static int get_scalar_repos(const char *key, const char *value, void *data)
599 return 0;
600 }
601
602 +static int remove_deleted_enlistment(struct strbuf *path)
603 +{
604 + int res = 0;
605 + strbuf_realpath_forgiving(path, path->buf, 1);
606 +
607 + if (run_git("config", "--global",
608 + "--unset", "--fixed-value",
609 + "scalar.repo", path->buf, NULL) < 0)
610 + res = -1;
611 +
612 + if (run_git("config", "--global",
613 + "--unset", "--fixed-value",
614 + "maintenance.repo", path->buf, NULL) < 0)
615 + res = -1;
616 +
617 + return res;
618 +}
619 +
620 static int cmd_reconfigure(int argc, const char **argv)
621 {
622 int all = 0;
@@ -638,8 +656,22 @@ static int cmd_reconfigure(int argc, const char **argv)
656 strbuf_reset(&gitdir);
657
658 if (chdir(dir) < 0) {
641 - warning_errno(_("could not switch to '%s'"), dir);
642 - res = -1;
659 + struct strbuf buf = STRBUF_INIT;
660 +
661 + if (errno != ENOENT) {
662 + warning_errno(_("could not switch to '%s'"), dir);
663 + res = -1;
664 + continue;
665 + }
666 +
667 + strbuf_addstr(&buf, dir);
668 + if (remove_deleted_enlistment(&buf))
669 + res = error(_("could not remove stale "
670 + "scalar.repo '%s'"), dir);
671 + else
672 + warning(_("removing stale scalar.repo '%s'"),
673 + dir);
674 + strbuf_release(&buf);
675 } else if (discover_git_directory(&commondir, &gitdir) < 0) {
676 warning_errno(_("git repository gone in '%s'"), dir);
677 res = -1;
@@ -725,24 +757,6 @@ static int cmd_run(int argc, const char **argv)
757 return 0;
758 }
759
728 -static int remove_deleted_enlistment(struct strbuf *path)
729 -{
730 - int res = 0;
731 - strbuf_realpath_forgiving(path, path->buf, 1);
732 -
733 - if (run_git("config", "--global",
734 - "--unset", "--fixed-value",
735 - "scalar.repo", path->buf, NULL) < 0)
736 - res = -1;
737 -
738 - if (run_git("config", "--global",
739 - "--unset", "--fixed-value",
740 - "maintenance.repo", path->buf, NULL) < 0)
741 - res = -1;
742 -
743 - return res;
744 -}
745 -
760 static int cmd_unregister(int argc, const char **argv)
761 {
762 struct option options[] = {
t/t9210-scalar.sh
+11
@@ -166,6 +166,17 @@ test_expect_success 'scalar reconfigure' '
166 test true = "$(git -C one/src config core.preloadIndex)"
167 '
168
169 +test_expect_success '`reconfigure -a` removes stale config entries' '
170 + git init stale/src &&
171 + scalar register stale &&
172 + scalar list >scalar.repos &&
173 + grep stale scalar.repos &&
174 + rm -rf stale &&
175 + scalar reconfigure -a &&
176 + scalar list >scalar.repos &&
177 + ! grep stale scalar.repos
178 +'
179 +
180 test_expect_success 'scalar delete without enlistment shows a usage' '
181 test_expect_code 129 scalar delete
182 '