From c5dbfd44398e41c26e98990e25dfd6e4c1b147ae Mon Sep 17 00:00:00 2001 From: Phillip Wood Date: Thu, 19 Sep 2024 19:48:04 +0100 Subject: [PATCH] submodule status: propagate SIGPIPE It has been reported than running git submodule status --recurse | grep -q ^+ results in an unexpected error message fatal: failed to recurse into submodule $submodule When "git submodule--helper" recurses into a submodule it creates a child process. If that process fails then the error message above is displayed by the parent. In the case above the child in killed by SIGPIPE as grep exits as soon as it sees the first match. Fix this by propagating SIGPIPE so that it is visible to the process running git. We could propagate other signals but I'm not sure there is much value in doing that. In the common case of the user pressing Ctrl-C or Ctrl-\ then SIGINT or SIGQUIT will be sent to the foreground process group and so the parent process will receive the same signal as the child. Reported-by: Matt Liberty Signed-off-by: Phillip Wood --- builtin/submodule--helper.c | 7 ++++++- t/t7422-submodule-output.sh | 7 +++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index a46ffd49b34458..a8e497ef3c66aa 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -30,6 +30,7 @@ #include "advice.h" #include "branch.h" #include "list-objects-filter-options.h" +#include #define OPT_QUIET (1 << 0) #define OPT_CACHED (1 << 1) @@ -695,6 +696,7 @@ static void status_submodule(const char *path, const struct object_id *ce_oid, if (flags & OPT_RECURSIVE) { struct child_process cpr = CHILD_PROCESS_INIT; + int res; cpr.git_cmd = 1; cpr.dir = path; @@ -710,7 +712,10 @@ static void status_submodule(const char *path, const struct object_id *ce_oid, if (flags & OPT_QUIET) strvec_push(&cpr.args, "--quiet"); - if (run_command(&cpr)) + res = run_command(&cpr); + if (res == SIGPIPE + 128) + raise(SIGPIPE); + else if (res) die(_("failed to recurse into submodule '%s'"), path); } diff --git a/t/t7422-submodule-output.sh b/t/t7422-submodule-output.sh index ab946ec9405deb..c1686d6bb5f6f0 100755 --- a/t/t7422-submodule-output.sh +++ b/t/t7422-submodule-output.sh @@ -167,4 +167,11 @@ do ' done +test_expect_success !MINGW 'git submodule status --recursive propagates SIGPIPE' ' + { git submodule status --recursive 2>err; echo $?>status; } | + grep -q X/S && + test_must_be_empty err && + test_match_signal 13 "$(cat status)" +' + test_done