]> git.ipfire.org Git - thirdparty/git.git/commitdiff
submodule status: propagate SIGPIPE
authorPhillip Wood <phillip.wood@dunelm.org.uk>
Fri, 20 Sep 2024 13:07:22 +0000 (13:07 +0000)
committerJunio C Hamano <gitster@pobox.com>
Fri, 20 Sep 2024 20:07:03 +0000 (13:07 -0700)
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 is killed by
SIGPIPE as "grep -q" 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 <mliberty@precisioninno.com>
Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/submodule--helper.c
t/t7422-submodule-output.sh

index f1218a19957aa526c20065e23076711183510b07..68da50e297cb201244125f6a45070efbaf8fba3a 100644 (file)
@@ -694,6 +694,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;
@@ -709,7 +710,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);
        }
 
index ab946ec9405deb536ffd7c6fa350bcc8abf3544c..c1686d6bb5f6f01a30dd277e79833375781148bb 100755 (executable)
@@ -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