Why does `git diff` not work with process substitution?

梦想与她 提交于 2019-12-06 17:15:47

问题


Why does git diff not work with process substitution?

$ echo hallo > hallo
$ echo holla > holla

$ git diff hallo holla  # works

$ git diff hallo <(cat holla)  # works not

diff --git a/hallo b/hallo
deleted file mode 100644
index 4cf5aa5..0000000
--- a/hallo
+++ /dev/null
@@ -1 +0,0 @@
-hallo
diff --git a/dev/fd/63 b/dev/fd/63
new file mode 120000
index 0000000..864a6ca`

Same with git diff --no-index.

It works with plain diff. cat is only a trivial example, can be replaced by a non-trivial sed expression.

Workaround:

$ cat holla | git diff hallo -  # works

But it will not work if both arguments should be affected by process substitution, like described in many examples for diff and process substitution.


回答1:


git diff does not work with process substitution because a patch that added handling of process substitution was ignored.




回答2:


git diff cannot be used as a substitute for diff. It does not diff between two arbitrary files on disk EXCEPT when you're outside of a Git repository or you pass in the --no-index flag.

$ git diff --no-index holla hallo
diff --git a/holla b/hallo
index 5cf9d44..ba1a6c1 100644
--- a/holla
+++ b/hallo
@@ -1 +1,2 @@
-holla
+hallo
+new line

$ cat hallo | git diff --no-index holla -
diff --git a/holla b/-
index 5cf9d44..0000000 100644
--- a/holla
+++ b/-
@@ -1 +1,2 @@
-holla
+hallo
+new line

This all works because git diff is just reading from STDIN, and that's so standard they'd have to work hard to make it not work.

As for process substitution...

$ git diff --no-index holla <(cat hallo)
error: /dev/fd/63: unsupported file type
fatal: cannot hash /dev/fd/63

What I can interpret from that is Git is trying to run its hash algorithm on the named pipe, without which Git cannot operate, and refusing because it's not a file, it's a pipe. There's no reason to have a pipe in a Git repository, so there's no reason for git diff to support them.

It's a bad idea to use git diff as replacement for diff. Git is a content tracker which works on files, not a general purpose diff tool. This "I'm going to silently sort of work like diff outside a Git repository" is one of those overly flexible design choices that just confuses users.



来源:https://stackoverflow.com/questions/22706714/why-does-git-diff-not-work-with-process-substitution

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!