0

I have a script which sets useful git settings and aliases, and I want to end by printing the difference between git config --global --list before and after. I'd like to show the diff in the same format as git diff. I can use diff -u to get almost the same thing without colors, but besides making the diff easier to parse, the colors also render the diff visually familiar to git users.

For other bash commands that take files as inputs, I can use variables instead.

diff -u a.txt b.txt
diff -u <(printf "%s\n" "$x") <(printf "%s\n" "$y")

I should then be able to save the git output to variables before and after, and compare the variables: BEFORE=$(git config --global --list) etc. But git diff does not accept variables as inputs:

git diff --no-index a.txt b.txt # ok
git diff --no-index <(printf "%s\n" "$x") <(printf "%s\n" "$y") # error: Could not access '/proc/2219/fd/63'

Why can't I use variables as inputs here? Is there some way to get git diff to do what I want, or some other command with the same diff format?

9
  • git diff is ment to show diffs in your git project, but 2 outputs of git config isn't ment to be used with git diff. You could write both to temp files but then they'll still not be part of the working tree and thus will git diff not work as expected. Commented Aug 14 at 13:17
  • 1
    Did you try diff --color -u <(printf "%s\n" "$x") <(printf "%s\n" "$y") ? Commented Aug 14 at 13:18
  • @0stone0 diff --color -u does it, thanks! I looked up this diff man page and I figured color wasn't available since ctrl+f didn't show anything about that. git diff --no-index does work on files even if untracked. Commented Aug 14 at 13:23
  • 3
    @phd See unix.stackexchange.com/questions/65803/… Commented Aug 14 at 15:33
  • 2
    @phd, also see Bash Pitfalls #14 (echo $foo). Commented Aug 14 at 16:28

2 Answers 2

4

I've been under the impression that Windows simply can't be bludgeoned into properly supporting process substitution.

As a smoke test, I tried your command on Git bash and on my Linux system.

On my Linux system your command works.

On Git Bash under Windows, it doesn't, and it shows a basically-identical error.

Google results are telling me things that don't match my memory or the evidence I'm looking at.

Running

x='Kilroy was here'
y='Kilroy was here too'
strace diff -u <(printf %s\\n "$x") <(printf %s\\n "$y")
strace git diff --no-index <(printf %s\\n "$x") <(printf %s\\n "$y")

on both windows and linux will show you what I saw. Whatever the mingw diff is doing to get results on Windows is awe-inspiring but I can kinda see why the git team don't want to go there, it's well over a thousand extra syscalls.

Sign up to request clarification or add additional context in comments.

2 Comments

For the Windows part: you tested the command with git-bash, I imagine the subsctitution would work correctly using WSL ?
@LeGEC WSL I think is always WSL2 now, that's actual Linux run as sibling under a hypervisor, with some tunnel drivers to windows, yeah, it'll work.
0

One-liner Bash function to compare the content of two variables like git diff

The issue is that git diff --no-index has sometimes problems with substitution.
Try something like this function. Still can slip as 'alias' function since it is one-liner:

gdiffvars() { diff --color -u <(printf "%s\n" "$1") <(printf "%s\n" "$2"); }

So it would work like this:

BEFORE="$(git config --global --list)"
# ...run your git commands here...
AFTER="$(git config --global --list)"
gdiffvars "$BEFORE" "$AFTER"

- gdiffvars uses diff --color -u to show differences between two variables in a unified, color-highlighted format similar to Git.

- The vars are safely passed using process substitution with printf, so multiline data is compared correctly

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.