Re: [PATCH 2/2] Allow passing pipes for input pipes to diff --no-index
- From
Taylor Blau <me@ttaylorr.com>
- Date
- Sep 18, 2020, 14:36 UTC
- Message-ID
- <20200918143647.GB1606445@nand.local>
- In-Reply-To
- <20200918113256.8699-3-tguyot@gmail.com>
Hi Thomas,
On Fri, Sep 18, 2020 at 07:32:56AM -0400, Thomas Guyot-Sionnest wrote:
Show 5 quoted lines
> A very handy way to pass data to applications is to use the <() process > substitution syntax in bash variants. It allow comparing files streamed > from a remote server or doing on-the-fly stream processing to alter the > diff. These are usually implemented as a symlink that points to a bogus > name (ex "pipe:[209326419]") but opens as a pipe.
This is true in bash, but sh does not support process substitution with <().
Show 30 quoted lines
> Git normally tracks symlinks targets. This patch makes it detect such
> pipes in --no-index mode and read the file normally like it would do for
> stdin ("-"), so they can be compared directly.
>
> Signed-off-by: Thomas Guyot-Sionnest <tguyot@gmail.com>
> ---
> diff-no-index.c | 56 ++++++++++--
> t/t4053-diff-no-index.sh | 189 +++++++++++++++++++++++++++++++++++++++
> 2 files changed, 238 insertions(+), 7 deletions(-)
>
> 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)) {I had to read this a few times to make sure that I got it; you want to stat the link itself, and then check that it links to a pipe.
I'm not sure why, though. Do you want to avoid handling named FIFOs in the code below? Your comment that they "could block" makes me think you do, but I don't know why that would be a problem.
Show 7 quoted lines
> + /* 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))
Statting sb.buf is confusing to me (especially when followed up by another stat right below. Could you explain?
Show 10 quoted lines
> +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) - > +'
Indeed this test fails (Git thinks that the HERE-DOC is broken, but I suspect it's just getting confused by the '<()'). This test (like almost all other tests in Git) use /bin/sh as its shebang. Does your /bin/sh actually point to bash?
If you did want to test something like this, you'd need to source t/lib-bash.sh instead of t/test-lib.sh.
Unrelated to the above comment, but there are a few small style nits that I notice:
- There is no need to run with 'test_expect_code 0' since the test is
marked as 'test_expect_success' and the commands are all in an '&&'
chain. (This does appear to be common style for others in t4053, so
you may just be matching it--which is fine--but an additional
clean-up on top to modernize would be appreciated, too). - The cat pipe is unnecessary, and is also violating a rule that we
don't place 'git' on the right-hand side of a pipe (can you redirect
the file at the end instead?).Documentation/CodingGuidelines is a great place to look if you are ever curious about whether something is in good style.
> +test_expect_success 'diff --no-index finds diff in piped subshells' ' > + ( > + set -- <(cat /dev/null) <(cat /dev/null)
Why is this necessary?
Show 13 quoted lines
> + cat <<-EOF >expect > + diff --git a$1 b$2 > + --- a$1 > + +++ b$2 > + @@ -1 +1 @@ > + -1 > + +2 > + EOF > + ) && > + test_expect_code 1 \ > + git diff --no-index <(cat non/git/b) <(sed s/1/2/ non/git/c) >actual && > + test_cmp expect actual > +'
Thanks, Taylor