特性分支合并删除后,如何筛选release与指定分支的Git日志?
问题
我们有一个名为release的主分支,每个功能对应不同的特性分支,最终会合并至release分支。我希望git log仅列出release主分支与我关注的某一特性分支的提交,忽略其他特性分支的提交,该如何操作?
更复杂的是,特性分支合并到release后会被手动删除。例如如下提交历史:
1---2---4------+7--8------+11----+13----> # release branch \ \ / \ / / \ 5--6 9--10 / # feature-bar1 and feature-bar2 branches \ / 3-------------------12 # feature-foo --> time # 1 - 13 are commits # 1, 2, 4, 7, 8, 11, 13 are the main branch "release" # + shows a merge # 4, 5, 6, 7 is a feature branch 'bar1' merged into "release" # 8, 9, 10, 11 is another feature branch 'bar2' merged into "release" # 2, 3, 12, 13 is the feature branch "foo" merged into "release"
我可通过git log 13..1 --oneline --graph查看完整历史,但我想生成仅包含release和foo分支的变更日志,排除bar1、bar2等其他分支,即便这些分支已被删除,是否仍能实现?
解决方案
当然可以实现,Git的提交筛选机制能精准定位目标提交,哪怕特性分支已被删除(只要提交未被垃圾回收)。以下是几种实用方法:
方法1:直接排除已知的其他分支
如果记得已删除分支的名称(比如bar1、bar2),用^符号排除这些分支的所有提交:
git log --oneline --graph release ^bar1 ^bar2
这个命令会展示release分支的所有提交,同时剔除bar1、bar2分支引入的所有提交(包括它们的特性提交和合并提交)。
方法2:通过提交范围精准筛选
如果不记得其他分支名称,或者分支数量太多,先定位目标特性分支foo的提交范围:
- 找到
foo分支的起始提交(示例中是2)和最后一个提交(示例中是12) - 用以下命令筛选
release主线+foo分支的提交:
git log --oneline --graph release --not $(git rev-list release --not 2..12)
解释:git rev-list release --not 2..12会找出release上不属于foo分支的提交,再用--not排除这些提交,剩下的就是release主线和foo分支的内容。
方法3:结合--first-parent简化主线展示
如果release分支的合并都使用--no-ff(保留合并提交),可以用--first-parent只显示release的主提交链,再加上foo分支的提交范围:
git log --oneline --graph --first-parent release 2..12
--first-parent会跳过其他分支的合并提交细节,只展示release主线上的线性提交,再加上2..12这个foo分支的提交链,就能得到干净的目标日志。
关键提示
- 已删除分支的提交不会立刻消失,Git会保留这些对象直到执行
git gc且提交超过默认过期时间(通常是90天),只要提交还在仓库中,就能通过哈希或历史引用筛选。 - 如果找不到
foo分支的提交范围,可以用git log --merges release找出所有合并到release的提交,再用git show <合并提交哈希>查看它的父提交,其中非release主线的父提交就是特性分支的最后一个提交(比如示例中合并foo的提交是13,git show 13会显示父提交是11和12,12就是foo的最后一个提交)。
内容的提问来源于stack exchange,提问作者athos

