使用 Git,我如何显示所有共享一个共同祖先的提交树?
Posted
技术标签:
【中文标题】使用 Git,我如何显示所有共享一个共同祖先的提交树?【英文标题】:With Git, how can I show the tree of commits that all share a common ancestor? 【发布时间】:2015-11-03 21:46:27 【问题描述】:假设我有一个“master”分支,一个为我的团队审查和批准更改的分支(称为“stage”),以及一堆基于 stage 分支的功能分支。 (这个想法是将更改分组为从阶段到主的公共拉取请求。)
如何根据阶段分支的“根”显示所有更改的日志?我希望能够看到该团队/主题正在进行的所有功能。用普通的 Git 术语来说,我怎样才能获得可以到达给定(根)提交的所有提交的日志?对于我的生活,我找不到办法做到这一点。我可以对具有共同祖先的两个分支执行此操作,但不适用于从共同祖先派生的 N 个分支。
【问题讨论】:
听起来你想要git merge-base --octopus
(找到一个 N 分支合并基础,类似于通常的两个分支合并基础),然后是 git log <list of heads> ^<base>
。
但这是相当递归的。要获取包含给定提交的所有更改的列表,我需要提供包含该提交的所有提示的列表。如果我能做到这一点,我就快完成了。但我们可以从那里开始。所以我的推论问题是,给定一个提交,我怎样才能找到可以到达该提交的所有提示?
git branch --contains <id>
将打印所有本地分支标签的列表,这些标签将该提交作为其分支提示的祖先。如果需要(可能不需要),添加-r
以包括远程跟踪分支。 (我从你的问题中得到的印象是你已经有了分支提示标签的列表。)
【参考方案1】:
我认为这可以通过结合使用git branch --contains <id>
(正如torek 在对该问题的评论中所建议的那样)和git rev-list
的组合来完成。
具体来说,假设您对所有感兴趣的分支都有本地分支(如果没有,请尝试将-r
或-a
添加到git branches
命令),那么以下应该做我认为你追求的是:
$ git rev-list $(git branches --contains <ancestor>) --not <ancestor> --pretty=oneline
git
rev-list
是一个命令,它会列出一些父母可以访问但其他人不能访问的所有修订的列表。
在上述调用中,我们使用包含给定祖先的所有分支列表作为起点,然后排除该祖先之前的所有历史记录。
添加--pretty=oneline
告诉命令包含提交的简要描述;它通常只会每行输出一个修订 ID。
请记住,这可能并不完全符合您的要求,因为我认为提交是按时间顺序排列的,而不是按提交的拓扑图排序的。
git rev-list
有很多选项大量,所以可能有一个可以控制排序。
如果您真的只想列出 所有 具有给定祖先的提交,那么有一种更暴力的方法可以做到这一点(尽管它会包括其他无法访问的提交和存储)。
我们再次使用rev-list
,虽然我们没有传递有趣的分支列表,而是指定--all
:
$ git rev-list --all --not <ancestor> --pretty=oneline
【讨论】:
什么是git branches
?我似乎在 git 2.25.1 上没有那个命令,而且表面的谷歌搜索也没有打开它……也许这曾经是一个命令的名称?【参考方案2】:
如何获取可以到达给定(根)提交的所有提交的日志?
git log --ancestry-path --all --not $given
具有您想要的任何显示选项。 --graph --decorate --oneline
是通常的起点,--simplify-by-decoration
显示尽可能少的未修饰提交,同时仍显示分支结构。
【讨论】:
【参考方案3】:我被同样的问题困住了。 谷歌搜索没有带来合适的东西,所以我决定写一个脚本。 https://gist.github.com/lvitya/66a9f519d30b7fd2c90d8f95a0b3a1a1 它有助于可视化您的提交树。
这里是脚本的内容 git_show_graph_from_ancestor.sh
#!/bin/bash -x
# $1 == ancestor
BR_LIST=$(git for-each-ref --contains "$1" --format="%(refname)")
git log "$1"^! $BR_LIST --oneline --decorate --graph
这会生成从给定祖先开始的所有提交的图表。即你可以看到所有基于公共主分支的特性分支。
$ ~/scripts/git_show_graph_from_ancestor.sh master
* feature2
* commit
* commit
| * feature1
| * commit
|/
* master
【讨论】:
请不要只发布一些工具或库作为答案。至少在答案本身中展示how it solves the problem。 好的,所以我不得不发布 bash 脚本的内容。 这(即使用git for-each-ref
)产生了我正在寻找的答案:有问题的分支以及植根于那里的所有其他分支。以上是关于使用 Git,我如何显示所有共享一个共同祖先的提交树?的主要内容,如果未能解决你的问题,请参考以下文章
git bisect 如何选择一个没有第一个好的提交作为祖先的提交? (使用--first-parent)