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.
git diff -- '*AssemblyInfo.cs' to avoid the shell trying to expand.find or grep are slow, clunky, and liable to break for more complicated use cases.git diff -- '*.sql*' '*.ws'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
git diff, but leaves out the last file.git diff --name-only | grep AssemblyInfo.cs indeed gives the correct file names, as I would expect, but I need full diff output. Both find . -name AssemblyInfo.cs | xargs git diff -- and find . -name AssemblyInfo.cs | xargs git diff --name-status -- are giving files that are not "AssemblyInfo.cs" (such as .sql files).find . -name "AssemblyInfo.cs" -print0 | xargs -0 git diff --Probably the simplest option is to use:
git diff "*/*AssemlyInfo.cs"
works as of git 2.20.1
"**/*AssemblyInfo.cs" to search for files anywhere in the repository, and not under only 1 level nested directories. Once this correction done, it's the best answer to the question and should be the accepted answer.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.
$ git diff | wc -l 1110 $ find . -name AssemblyInfo.cs | git diff | wc -l 1110find . -name AssemblyInfo.cs?find . -name AssemblyInfo.cs is working correctly, giving the paths to all the "AssemblyInfo.cs" files.wc -l 1110, and what does 1110 means?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 ;-)