技术背景
在使用Git进行版本控制时,我们经常需要查看两次提交之间哪些文件发生了更改。这在代码审查、故障排查、持续集成等场景中非常有用。
实现步骤
列出文件名
使用 git diff --name-only 命令可以列出两次提交之间更改的文件名:
git diff --name-only SHA1 SHA2
其中,SHA1 和 SHA2 是提交的哈希值,只需包含足够的哈希值来唯一标识提交即可,且顺序无关紧要。输出包含文件的相对路径。
例如,查看第十个最新提交和第五个最新提交之间的差异:
git diff --name-only HEAD~10 HEAD~5
显示文件状态
使用 git diff --name-status 命令除了列出文件名,还会显示文件的状态:
git diff --name-status [SHA1 [SHA2]]
文件状态标志如下:
标志 | 名称 | 含义 |
M | modified | 文件已修改 |
C | copy-edit | 文件已复制并修改 |
R | rename-edit | 文件已重命名并修改 |
A | added | 文件已添加 |
D | deleted | 文件已删除 |
U | unmerged | 文件在合并后有冲突 |
结合提交日志查看
使用 git log --name-status --oneline 命令可以在提交消息后列出文件状态,方便查看文件更改的时间:
git log --name-status --oneline [SHA1..SHA2]
如果只关心某些文件或文件夹的更改,可以在 git log 命令后追加 -- <filename> [<filename>...]。如果想查看单个提交的文件更改,可使用:
git log --name-status --oneline [SHA1^..SHA1]
其他统计选项
- --stat:显示文件更改的统计信息,包括插入和删除的行数:
git diff --stat HEAD~5 HEAD
- --numstat:以数字形式显示每个文件的插入和删除行数:
git diff --numstat HEAD~5 HEAD
- --shortstat:只显示更改的文件数量、插入和删除的总行数:
git diff --shortstat HEAD~5 HEAD
比较分支
查看当前分支与另一个分支(如 origin/master)的共同祖先之后的文件更改:
git diff --name-only `git merge-base origin/master HEAD`
避免分页显示
使用 --no-pager 选项可以避免结果进入分页器:
git --no-pager diff --name-only sha1 sha2
比较两个分支
比较两个分支之间的文件更改:
git diff --name-status mybranch..myotherbranch
注意分支顺序,较新的分支在前会显示文件为删除而不是添加。可以结合 grep 进一步筛选:
git diff --name-status mybranch..myotherbranch | grep "A\t"
查看最后两次提交的更改
查看最后一次提交和前一次提交之间的更改文件:
git show --name-only
设置别名
在 ~/.bash_profile 文件中添加以下别名,然后运行 source ~/.bash_profile,之后在Git仓库中运行 showfiles 即可查看最后一次提交的更改文件:
alias showfiles='git show --pretty="format:" --name-only'
处理单个或多个提交
使用 git show --name-only --format=tformat: 命令可以处理单个或多个提交:
git show --name-only --format=tformat: SHA1..SHA2
git show --name-only --format=tformat: SHA1
显示文件内容更改
使用 --word-diff 选项可以显示文件内容的更改:
git diff --word-diff SHA1 SHA2
筛选特定文件类型
如果只关注Java文件,可以使用 grep 筛选:
git diff --name-status SHA1 SHA2 | grep '\.java#39;
包含暂存文件
查看包括暂存文件在内的更改文件列表:
git diff HEAD --name-only --relative --diff-filter=AMCR
git diff HEAD --name-only --relative --diff-filter=AMCR sha-1 sha-2
如果需要绝对路径,可移除 --relative 选项。
日志输出到文件
将更改文件的单行日志输出到文件:
git log --pretty=oneline > C:\filename.log
使用扩展工具
基于 git diff --name-status 开发的 git-diffview 扩展可以以层次树视图显示两次提交之间的更改。
核心代码
# 列出文件名
git diff --name-only SHA1 SHA2
# 显示文件状态
git diff --name-status [SHA1 [SHA2]]
# 结合提交日志查看
git log --name-status --oneline [SHA1..SHA2]
# 其他统计选项
git diff --stat HEAD~5 HEAD
git diff --numstat HEAD~5 HEAD
git diff --shortstat HEAD~5 HEAD
# 比较分支
git diff --name-only `git merge-base origin/master HEAD`
# 避免分页显示
git --no-pager diff --name-only sha1 sha2
# 比较两个分支
git diff --name-status mybranch..myotherbranch
git diff --name-status mybranch..myotherbranch | grep "A\t"
# 查看最后两次提交的更改
git show --name-only
# 设置别名
alias showfiles='git show --pretty="format:" --name-only'
# 处理单个或多个提交
git show --name-only --format=tformat: SHA1..SHA2
git show --name-only --format=tformat: SHA1
# 显示文件内容更改
git diff --word-diff SHA1 SHA2
# 筛选特定文件类型
git diff --name-status SHA1 SHA2 | grep '\.java#39;
# 包含暂存文件
git diff HEAD --name-only --relative --diff-filter=AMCR
git diff HEAD --name-only --relative --diff-filter=AMCR sha-1 sha-2
# 日志输出到文件
git log --pretty=oneline > C:\filename.log
最佳实践
- 当需要快速查看更改的文件名时,使用 git diff --name-only 命令。
- 如果想了解文件的具体状态(如修改、添加、删除等),使用 git diff --name-status 命令。
- 结合 grep 命令可以筛选出特定类型的文件更改。
- 设置别名可以提高工作效率,避免重复输入长命令。
常见问题
- 分页显示问题:如果结果进入分页器,可使用 --no-pager 选项避免。
- 分支顺序问题:在比较两个分支时,注意分支顺序,否则可能会得到意外的文件状态显示。