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.