我们经常需要把某个提交传给 Git:
git show <commit>
git revert <commit>
git commit --fixup <commit>
最常见的做法是复制提交的 SHA:
git show 8f3a2c1
或者使用相对位置:
git show HEAD~3
这两种方式都没问题,但通常需要先执行一次 git log,找到目标提交,再把 SHA 或位置复制到下一个命令里。其实,Git 还支持直接根据提交信息中的文本查找提交。Git 官方文档把它归在 revision 的文本匹配语法中。
使用 :/ 按提交信息查找
假设最近的提交记录如下:
a8f31de Add login page
7c2b910 Fix typo in README
d4e8a11 Update dependencies
现在想查看修复 README 拼写错误的提交,可以直接运行:
git show ':/Fix typo'
Git 会查找提交信息中匹配 Fix typo 的最近提交。这里的 Fix typo 不是提交 SHA,而是一个用于匹配提交信息的正则表达式。
所以,下面的命令也可以工作:
git show ':/typo'
它会匹配提交信息中包含 typo 的提交。
命令中的引号不能省。提交信息通常包含空格,如果不加引号,Shell 可能会把它拆成多个参数。
它不只适用于 git show
只要命令接受 revision 参数,就可以尝试使用这种写法:
查看提交:
git show ':/Add login page'
撤销提交:
git revert ':/Remove deprecated API'
创建 fixup 提交:
git commit --fixup ':/Add login page'
这种方式比复制一串难以记忆的 SHA 更直观。尤其是在刚刚提交过某个改动、还记得提交内容,但不记得具体 SHA 时,很方便。
限制搜索范围
:/text 会从所有可达引用中查找匹配的提交。如果仓库中有多个分支,可能会匹配到另一个分支上的提交。
可以把搜索范围限制在 HEAD 的历史中:
git show 'HEAD^{/Fix typo}'
它只会查找从 HEAD 可达的历史,并返回最近匹配的提交。也可以从某个分支开始搜索:
git show 'main^{/Add login}'
这样就不会意外找到其它分支中的同名提交。
提交信息越清楚,这个技巧越有用
如果提交信息都是下面这样:
update
fix
changes
wip
按文本查找自然很难发挥作用。
相反,下面这种提交信息更容易定位:
Add email validation
Fix broken mobile navigation
Remove unused cache layer
Update PostgreSQL connection settings
提交信息不仅是给代码审查看的,也是未来和 Git 历史交互时使用的索引。
什么时候仍然应该使用 SHA?
按文本查找适合交互式操作和临时查询,但在脚本、文档或需要精确复现的操作中,完整 SHA 通常更可靠:
git show 8f3a2c1
如果可能存在多个匹配结果,也应该先确认 Git 找到的到底是哪一个:
git show ':/Fix typo'
git log --oneline --all --grep='Fix typo'
前者适合直接引用最近的匹配提交,后者适合先列出候选提交,再做决定。
Git 的 revision 语法非常强大:除了 SHA 和 HEAD~3,它还支持分支、标签、日期、父提交,以及按提交信息匹配。很多时候,最方便的命令并不是 Git 新增的功能,而是藏在文档里很久、只是我们还没用过的功能。
参考:Find Git Commits by Commit Message Text、Git revisions 官方文档。