问题描述
我想做一些 Gitk 已经做过的事情,除了在命令行中。我想显示来自一个分支的所有提交,以及来自另一个分支的所有提交,但没有其他历史记录。让我们更具体一点:我说的是一个功能分支加上主分支,但没有其他东西(不管还有多少)。如何实现这一目标?
“从分支提交”是指在分支上明确提交(并推送)的提交,而不是由合并带来的提交。对我来说,看到提交实际上是合并就足够了,正如我希望在提交消息中看到这是与哪个其他分支合并的,这告诉我这里就足够了。
为了在 Gitk 中实现这一点:我创建了一个视图,在其中列出了我想要查看的分支,并选中了“Limit to first parent”。
一个例子。
L-M : other stuff
\
A-B-C-I : feature
/
... -D-E-F-J : main
/ /
/ G-H-K : more other stuff
/
... potentially even more stuff contributing to main via merges (not explicitly kNown)
C
是 B
和 F
合并的结果。
E
是 D
和 H
合并的结果。
B
是 A
和 M
合并的结果。
我想看A
、B
、C
、I
、D
、E
、F
和{ {1}},但不是 J
、G
、H
、K
和 L
。
M
奖励:也看不到 A-B-C-I - feature
/
D-E-F-J - main
...
奖金:...但不知何故知道 J
曾经是 F
并将其标记为这样。
main
编辑:如果我使用 A-B-C-I - feature
/
D-E-F - was main
我几乎得到了我想要的,除了没有显示第二个父合并关系(即使它们存在,Gitk 也会显示它们)。现在怎么办?
解决方法
没有办法 100% 可靠地满足您的所有要求。 LeGEC 的回答解决了您最初问题中的具体示例,但我认为您对此的后续行动不会让人感到意外。
对于您的基本要求,您可以尝试类似
git log --graph --oneilne --first-parent main feature
如果您遵循典型的惯例,那么这可能会给您带来您想要的。但在某些情况下它不会。我会回到那个。
对于你的“奖金”,你可以做一些类似的事情
git log --graph --oneline --first-parent $(git merge-base main feature) feature
因此,您不是说 main
而是希望历史记录可以从两个分支都可以访问到的最后一次提交。
我不知道在日志中动态标记合并基础提交的方法(额外奖励)。我猜你可以标记你的合并基础。
git tag was_on_master $(git merge-base main feature)
git log --graph --oneline --first-parent feature was_on_master
git tag -d waS_on_master
那么现在......什么时候它不起作用,为什么会这样?
在 git 中,提交不“属于”分支。没有历史可以告诉您提交“是在哪个分支上创建的”。分支和提交之间的唯一关系是提交是否可以从给定的分支到达。在合并提交的情况下,您还可以使用父指针的顺序来区分合并可能发生在哪个“方向”。
如果您在 branch_A
上并说 git merge branch_B
,那么您所在的提交(历史记录“来自”branch_A
)将成为合并的第一个父级。这就是 --first-parent
稍后将遵循的内容。并且,如果当您给出合并命令时,您实际上已经签出了 branch_A
(而不是在分离的 HEAD 状态下签出相同的提交),branch_A
会自动移动到合并;所以假设通常“第一个父级意味着这个分支的历史”。
但在某些情况下,有人可能会做一些将事情搞砸的事情。假设你有
... A <--(branch_A)
... B <--(branch_B)
然后你说
git checkout branch_A
git merge branch_B
git checkout branch_B
git merge branch_A
除非您的配置阻止它,否则第二次合并将作为快进处理,导致
... A -- M <--(branch_A)(branch_B)
/
... B
现在无论签出哪个分支,git log --first-parent
都会转到A
。
一个应该符合你在图表上描述的答案:
git log --oneline --graph main feature ^K ^M
要排除 J
,请不要列出 main
:
git log --oneline --graph feature ^K ^M
在 git log
参数中,^xxx
(注意 ^
位于 之前 commit-ish,而不是之后)表示“从列表中排除提交 xxx
及其所有祖先"