On 2020-09-18 at 11:32:56, Thomas Guyot-Sionnest wrote: > diff --git a/diff-no-index.c b/diff-no-index.c > index 7814eabfe0..779c686d23 100644 > --- a/diff-no-index.c > +++ b/diff-no-index.c > @@ -41,6 +41,33 @@ static int read_directory_contents(const char *path, struct string_list *list) > */ > static const char file_from_standard_input[] = "-"; > > +/* Check that file is - (STDIN) or unnamed pipe - explicitly > + * avoid on-disk named pipes which could block > + */ > +static int ispipe(const char *name) > +{ > + struct stat st; > + > + if (name == file_from_standard_input) > + return 1; /* STDIN */ > + > + if (!lstat(name, &st)) { > + if (S_ISLNK(st.st_mode)) { > + /* symlink - read it and check it doesn't exists > + * as a file yet link to a pipe */ > + struct strbuf sb = STRBUF_INIT; > + strbuf_realpath(&sb, name, 0); > + /* We're abusing strbuf_realpath here, it may append > + * pipe:[NNNNNNNNN] to an abs path */ > + if (!stat(sb.buf, &st)) > + return 0; /* link target exists , not pipe */ > + if (!stat(name, &st)) > + return S_ISFIFO(st.st_mode); This makes a lot of assumptions about the implementation which are specific to Linux, namely that an anonymous pipe will be a symlink to a FIFO. That's not the case on macOS, where the /dev/fd entries are actually named pipes themselves. Granted, in that case, Git just chokes and fails instead of diffing the symlink values, but I suspect you'll want this to work on macOS as well. I don't use macOS that often, but I would appreciate it if it worked when I did, and I'm sure others will as well. I think we can probably get away with just doing a regular stat and seeing if S_ISFIFO is true, which is both simpler and cheaper. > diff --git a/t/t4053-diff-no-index.sh b/t/t4053-diff-no-index.sh > index 0168946b63..e49f773515 100755 > --- a/t/t4053-diff-no-index.sh > +++ b/t/t4053-diff-no-index.sh > @@ -144,4 +144,193 @@ test_expect_success 'diff --no-index allows external diff' ' > test_cmp expect actual > ' > > +test_expect_success 'diff --no-index can diff piped subshells' ' > + echo 1 >non/git/c && > + test_expect_code 0 git diff --no-index non/git/b <(cat non/git/c) && > + test_expect_code 0 git diff --no-index <(cat non/git/b) non/git/c && > + test_expect_code 0 git diff --no-index <(cat non/git/b) <(cat non/git/c) && > + test_expect_code 0 cat non/git/b | git diff --no-index - non/git/c && > + test_expect_code 0 cat non/git/c | git diff --no-index non/git/b - && > + test_expect_code 0 cat non/git/b | git diff --no-index - <(cat non/git/c) && > + test_expect_code 0 cat non/git/c | git diff --no-index <(cat non/git/b) - > +' As mentioned by others, this requires non-POSIX syntax. /bin/sh on my Debian system is dash, which doesn't support this. You can either use a prerequisite, or just test by piping from standard input and assume that Git can handle the rest. I would recommend at least adding some POSIX testcases that use only a pipe from standard input to avoid regressing this behavior on Debian and Ubuntu. -- brian m. carlson: Houston, Texas, US