All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Johannes Schindelin <johannes.schindelin@gmx.de>,
	Johannes Schindelin <johannes.schindelin@gmx.de>
Subject: [PATCH 1/2] for-each-repo: optionally keep going on an error
Date: Wed, 17 Apr 2024 08:28:54 +0000	[thread overview]
Message-ID: <6721e3ada5d125bd6c33561c694acb986b17b38f.1713342535.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.1719.git.1713342535.gitgitgadget@gmail.com>

From: Johannes Schindelin <johannes.schindelin@gmx.de>

In https://github.com/microsoft/git/issues/623, it was reported that
the regularly scheduled maintenance stops if one repo in the middle of
the list was found to be missing.

This is undesirable, and points out a gap in the design of `git
for-each-repo`: We need a mode where that command does not stop on an
error, but continues to try the running the specified command with the
other repositories.

Imitating the `--keep-going` option of GNU make, this commit teaches
`for-each-repo` the same trick: to continue with the operation on all
the remaining repositories in case there was a problem with one
repository, still setting the exit code to indicate an error occurred.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 Documentation/git-for-each-repo.txt |  4 ++++
 builtin/for-each-repo.c             |  8 ++++++--
 t/t0068-for-each-repo.sh            | 16 ++++++++++++++++
 3 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/Documentation/git-for-each-repo.txt b/Documentation/git-for-each-repo.txt
index 94bd19da263..8c18001d825 100644
--- a/Documentation/git-for-each-repo.txt
+++ b/Documentation/git-for-each-repo.txt
@@ -42,6 +42,10 @@ These config values are loaded from system, global, and local Git config,
 as available. If `git for-each-repo` is run in a directory that is not a
 Git repository, then only the system and global config is used.
 
+--keep-going::
+	Continue with the remaining repositories if the command failed
+	on a repository. The exit code will still indicate that the
+	overall operation was not successful.
 
 SUBPROCESS BEHAVIOR
 -------------------
diff --git a/builtin/for-each-repo.c b/builtin/for-each-repo.c
index 28186b30f54..74498539e9c 100644
--- a/builtin/for-each-repo.c
+++ b/builtin/for-each-repo.c
@@ -32,6 +32,7 @@ static int run_command_on_repo(const char *path, int argc, const char ** argv)
 int cmd_for_each_repo(int argc, const char **argv, const char *prefix)
 {
 	static const char *config_key = NULL;
+	int keep_going = 0;
 	int i, result = 0;
 	const struct string_list *values;
 	int err;
@@ -39,6 +40,8 @@ int cmd_for_each_repo(int argc, const char **argv, const char *prefix)
 	const struct option options[] = {
 		OPT_STRING(0, "config", &config_key, N_("config"),
 			   N_("config key storing a list of repository paths")),
+		OPT_BOOL(0, "keep-going", &keep_going,
+			 N_("stop at the first repository where the operation failed")),
 		OPT_END()
 	};
 
@@ -55,8 +58,9 @@ int cmd_for_each_repo(int argc, const char **argv, const char *prefix)
 	else if (err)
 		return 0;
 
-	for (i = 0; !result && i < values->nr; i++)
-		result = run_command_on_repo(values->items[i].string, argc, argv);
+	for (i = 0; (keep_going || !result) && i < values->nr; i++)
+		if (run_command_on_repo(values->items[i].string, argc, argv))
+			result = 1;
 
 	return result;
 }
diff --git a/t/t0068-for-each-repo.sh b/t/t0068-for-each-repo.sh
index 4b90b74d5d5..95019e01ed3 100755
--- a/t/t0068-for-each-repo.sh
+++ b/t/t0068-for-each-repo.sh
@@ -59,4 +59,20 @@ test_expect_success 'error on NULL value for config keys' '
 	test_cmp expect actual
 '
 
+test_expect_success '--keep-going' '
+	git config keep.going non-existing &&
+	git config --add keep.going . &&
+
+	test_must_fail git for-each-repo --config=keep.going \
+		-- branch >out 2>err &&
+	test_grep "cannot change to .*non-existing" err &&
+	test_must_be_empty out &&
+
+	test_must_fail git for-each-repo --config=keep.going --keep-going \
+		-- branch >out 2>err &&
+	test_grep "cannot change to .*non-existing" err &&
+	git branch >expect &&
+	test_cmp expect out
+'
+
 test_done
-- 
gitgitgadget


  reply	other threads:[~2024-04-17  8:29 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-17  8:28 [PATCH 0/2] Use a "best effort" strategy in scheduled maintenance Johannes Schindelin via GitGitGadget
2024-04-17  8:28 ` Johannes Schindelin via GitGitGadget [this message]
2024-04-17  8:36   ` [PATCH 1/2] for-each-repo: optionally keep going on an error Eric Sunshine
2024-04-17 15:38     ` Junio C Hamano
2024-04-17  8:28 ` [PATCH 2/2] maintenance: running maintenance should not stop on errors Johannes Schindelin via GitGitGadget
2024-04-17 15:41   ` Junio C Hamano
2024-04-17 15:36 ` [PATCH 0/2] Use a "best effort" strategy in scheduled maintenance Junio C Hamano
2024-04-18 12:53 ` [PATCH v2 " Johannes Schindelin via GitGitGadget
2024-04-18 12:53   ` [PATCH v2 1/2] for-each-repo: optionally keep going on an error Johannes Schindelin via GitGitGadget
2024-04-19  4:24     ` Patrick Steinhardt
2024-04-19 16:03       ` Junio C Hamano
2024-04-19 17:56         ` Jeff King
2024-04-22 21:39           ` Junio C Hamano
2024-04-18 12:53   ` [PATCH v2 2/2] maintenance: running maintenance should not stop on errors Johannes Schindelin via GitGitGadget
2024-04-24 16:14   ` [PATCH v3 0/2] Use a "best effort" strategy in scheduled maintenance Johannes Schindelin via GitGitGadget
2024-04-24 16:14     ` [PATCH v3 1/2] for-each-repo: optionally keep going on an error Johannes Schindelin via GitGitGadget
2024-04-24 17:02       ` Junio C Hamano
2024-04-24 16:14     ` [PATCH v3 2/2] maintenance: running maintenance should not stop on errors Johannes Schindelin via GitGitGadget
2024-04-25  6:36     ` [PATCH v3 0/2] Use a "best effort" strategy in scheduled maintenance Patrick Steinhardt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=6721e3ada5d125bd6c33561c694acb986b17b38f.1713342535.git.gitgitgadget@gmail.com \
    --to=gitgitgadget@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=johannes.schindelin@gmx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.