I would like the results of git diff to be filtered by the file name.
In particular, I want a diff for all of the files named "AssemblyInfo.cs", but located anywhere within the git repository.
I am using git on Cygwin, if that makes a difference.
The simplest method is to simply use a wildcard:
git diff -- '*AssemblyInfo.cs'
At least this works on my Git v1.8.4, bash 3.2, and zsh 5.7.
File arguments to git diff need to be delimited by -- - try this:
find . -name <pattern> | xargs git diff --
xargs makes sure spaces, tabs, newlines, etc are handled correctly.
You could debug it with the --name-status argument to git diff. You could also try:
git diff --name-only | grep <pattern>
[edit] Try:
git diff --name-status -- `find . -name '<pattern>'`
ebg@taiyo(98)$ git diff --name-status -- `find . -name '*.scm'`
M scheme/base/boolean.scm
M surf/compiler/common.scm
M surf/compiler/compile.scm
M surf/compiler/expand.scm
Probably the simplest option is to use:
git diff "*/*AssemlyInfo.cs"
works as of git 2.20.1
You can use pipeline
find . -name AssemblyInfo.cs | git diff
Use find to filter all the files named "AssemblyInfo.cs", then use the output as the parameter of git diff.
While the answer given by GoZoner works for some (hundred?) files, it executes git diff multiple times (in the case of xargs) or fails (in the case of git diff … -- `find …`) if there is a large number of files to diff. This might be a problem or not, depending on your use case.
A possible solution is to create a commit containing only changes to files of interest and diff the commits. Based on an answer on unstaging files matching some pattern I came up with this solution:
git co <new_branch> --detach
git reset --soft <old_branch>
Now git status --porcelain | grep <pattern> shows all files that should be compared. All other files can be listed by passing -v to grep, i.e. git status --porcelain | grep -v <pattern>. This files need to be reset to the state of <old_branch>:
# Remove the destination of renamed and copied files not matching <pattern>
git status --porcelain | grep -v <pattern> | grep '^R \|^C ' | sed 's/.* -> //' | xargs git rm -f --
# Remove added files not matching <pattern>
git status --porcelain | grep -v <pattern> | grep '^A ' | cut -c 4- | xargs git rm -f --
# Restore deleted files not matching <pattern>
git status --porcelain | grep -v <pattern> | grep '^M \|^D ' | cut -c 4- | xargs git checkout HEAD --
(Note that using xargs is not a problem in this case, as calling git rm and git checkout multiple times is ok.)
Now the index (and working copy) only contains changes to the files matched by <pattern>. The next thing to do is to commit this changes:
git commit -m "Changes between <old_branch> and <new_branch> in files matching <pattern>"
That's it! Now we can use git diff as usual:
git diff HEAD^..HEAD
You can use all options or arguments you like.
Note: This solution is not tested extensively and may fail e.g. on files with special characters or other special cases… Suggestions to improve the solution are welcome ;-)
find . -iregex AssemblyInfo\.cs -exec git diff {} +
you can replace the AssemblyInfo\.cs with your regex.