我希望git diff
按文件名过滤结果。
特别是,我想要所有名为“AssemblyInfo.cs”但位于 git 存储库中任何位置的文件的差异。
我在 Cygwin 上使用 git,如果这有什么不同的话。
最简单的方法是简单地使用通配符:
git diff -- '*AssemblyInfo.cs'
至少这适用于我的 Git v1.8.4、bash 3.2 和 zsh 5.7。
文件参数git diff
需要被分隔--
- 试试这个:
find . -name <pattern> | xargs git diff --
xargs 确保正确处理空格、制表符、换行符等。
您可以--name-status
使用git diff
. 你也可以试试:
git diff --name-only | grep <pattern>
[编辑] 尝试:
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 "*/*AssemlyInfo.cs"
从 git 2.20.1 开始工作
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 ;-)
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
.
find . -iregex AssemblyInfo\.cs -exec git diff {} +
你可以AssemblyInfo\.cs
用你的正则表达式替换。