Could not find a difference filtering certain file types? I just want to compare .js files for example between branch a and b?
-
1What output do you expect here? Are you asking for a combined diff of several JS files? – Tim Biegeleisen Dec 18 '18 at 05:54
-
I want to see differences but i am only interested in the *.js files. – bier hier Dec 18 '18 at 05:55
-
Possible duplicate of [How to filter git diff based on file extensions?](https://stackoverflow.com/questions/8554776/how-to-filter-git-diff-based-on-file-extensions) – phd Dec 18 '18 at 13:53
-
https://stackoverflow.com/search?q=%5Bgit%5D+diff+file+extension – phd Dec 18 '18 at 13:54
-
Does the answer no longer apply? – iBug Jan 18 '19 at 06:59
1 Answers
Does this simply work?
git diff branch-a branch-b -- '*.js'
If you want to have a more complete view:
git diff branch-a branch-b -- $(cat <(git ls-tree --name-only -r branch-a) <(git ls-tree --name-only -r branch-b) | sort | uniq | grep '\.js$')
What does this super-long command do?
This part should be obvious, the --
at the end of this part means all subsequent arguments are file paths, not options
git diff branch-a branch-b --
Let's take a look at this giant command:
$(cat <(git ls-tree --name-only -r branch-a) <(git ls-tree --name-only -r branch-b) | sort | uniq | grep '\.js$')
The first thing is this:
cat <(git ls-tree --name-only -r branch-a) <(git ls-tree --name-only -r branch-b)
This uses git ls-tree
to list all files in commits, and use cat
to collect the output of files in the two branches. <()
is a shell substitution, which is replaced by the name of a pipe. The other side of the pipe is apparently the output of git ls-tree
.
| sort | uniq | grep '\.js$'
Sort and filter the combined files - in practice there are likely may duplicates, so uniq
takes duplicated stuff out. grep '\.js$'
at the end filters to show only files whose path ends in .js
.
The result of the long command in $()
is the combined .js
files in both branches, which is then passed to git diff
to filter diff files. This is exactly what you want, if I correctly understand.
What about packing this into a convenient shell script for later use?
#!/bin/sh
SOURCE=${1:-master}
TARGET=${2:-HEAD}
FILTER=${3:-.*}
exec git diff $SOURCE $TARGET -- $(cat <(git ls-tree --name-only -r $SOURCE) <(git ls-tree --name-only -r $TARGET) | sort | uniq | grep "$FILTER")
Usage:
./diff-all.sh branch-a branch-b '\.js$'

- 35,554
- 7
- 89
- 134
-
Actually, you can just quote the `*.js` part to get Git to do the same thing: `git diff branch-a branch-b -- '*.js'`. The arguments after `--` are pathspec arguments, which can be more than just file names. You just need to be sure the shell doesn't eat the `*` by expanding `*.js` to all the top level `*.js` files, before Git gets hold of it. – torek Dec 18 '18 at 06:08
-
-
@iBug Good one, how can I do this for multiple file types filter, something like this `git diff branch-a branch-b -- $(cat <(git ls-tree --name-only -r branch-a) <(git ls-tree --name-only -r branch-b) | sort | uniq | grep '(\.js|\.vue|\.php)$')` is possible ? – Vicky Dev Sep 01 '22 at 15:07