说我有两个分支,A& B.我跑的时候
git cherry -v A B
我将获得分支B中存在但在分支A中不存在的提交列表。在这个例子中,假设列出了50个提交:
+ 53458a1a commit 1
+ de6e9b10 commit 2
+ 683f3ef2 commit 3
+ a9e8e23d commit 4
...
+ 127197fb commit 50
有没有办法只将前面列出的四个提交合并到分支A中,而不进行挑选或重新定位?
在分支A上,我尝试过:
git merge a9e8e23d
但这只能让我获得第四次提交,并且它不包括提交1-3。
我也尝试在commit 4创建一个本地分支:
git branch tmp a9e8e23d
但是分支tmp不包含提交1-3。
我通过运行验证分支是否包含提交:
git branch --contains de6e9b10
提前感谢您的帮助。
答案 0 :(得分:0)
有没有办法只将前面列出的四个提交合并到分支A中,而不进行挑选或重新定位?
如果您想在合并中进行特定提交,则必须使用cherry-pick
,但cherry-pick
的优点是您可以提供范围以便获取多个提交。
例如,获取前4个提交
# The .. marks the commits range.
git cherry-pick 53458a1a..a9e8e23d
答案 1 :(得分:0)
TL; DR:"是的,如果满足某些非常常见的约束条件。"
......当我跑步时
git cherry -v A B
我将获得分支
B
中存在但在分支A
中不存在的提交列表。
不完全:您在B
中获得所有非合并提交的列表,这些提交不在A
中,以标记为前缀。如果+
中的提交在B
中没有相应的提交,则标记为B..A
,如果-
中的提交,则B
>在B..A
中有相应的提交(由git patch-id
确定)。
如果您只想要B
中不在A
中的提交列表,无论修补程序ID是否等效,您都可以使用以下命令:
git rev-list A..B
这些都是没有前缀的,而做包括合并提交(尽管您可以在内部添加--max-parents=1
或--no-merges
,以排除合并)。
有没有办法只将前面列出的四个提交合并到分支A中,而不进行挑选或重新定位?
有时,但并非总是如此。
请注意,您已经明确询问了合并这些提交。你还说前四个。这里有许多潜在的问题,但让我们先来看一下合并提交和/或分支的含义。
要做的第一件事是绘制(部分)提交图:
git cherry
这里我们有两个分支名称 A1--A2--A3 <-- A
/
...--o--*
\
B1--B2--B3--B4 <-- B
和A
,其中三个提交在分支B
上不在A
上,四个提交在B
上那些不在B
中。 两个分支上至少有两个提交,以标记为A
的提交结束,并包括所有早期提交。
使用*
,您会看到这四个git cherry -v A B
提交(包含缩短的哈希值和主题行),前缀为B
或+
。
要将整个分支-
合并到分支B
,您可以执行以下操作:
A
在找到合并基础提交git checkout A; git merge B
之后,尝试将所有*
提交中的所有更改与来自所有A
提交的所有更改组合在一起,并创建一个B
上的新合并提交:
A
请注意,这已经合并了提交 A1--A2--A3------M <-- A
/ /
...--o--* /
\ /
B1--B2--B3--B4 <-- B
(分支A3
的提示,您在A
之后)提交git checkout A
(分支的提示{{1} }})。这是B4
的工作方式,当给出一个名称时:它找到分支提示提交,并与当前提交合并 - 无论你已经签出了什么
从那里提交的提交。例如,要合并提交B
,您将:
git merge
,并提供:
B4
甚至可以合并B3
(包括git checkout B; git merge <hash-id-of-B3>
),或仅 A1--A2--A3--M <-- A
/ /
...--o--* /
\ /
B1--B2--B3--B4 <-- B
(因为分支在B2
加入, 仅包括B1
),例如:
B1
可以合并*
而不包括B1
和 A1--A2--A3--M <-- A
/ /
...--o--* /
\ /
----B1--B2--B3--B4 <-- B
,或B3
与B1
合并例如,但不是B2
。一旦您进行合并,该图本身就会自动包含所有之前的提交。 (这是因为图形实际上是通过读取每个提交来构建的。读取合并提交B3
告诉Git将B1
视为第一个父级,以及B2
提交它作为第二个然后,它会自行提交M
和A3
来回顾B
和之前的A3
提交,依此类推。
现在,因为Bn
省略了合并提交,如果我们刚刚绘制的图表过于简单,我们就会遇到麻烦。例如,假设图形实际上如下所示:
A2
如果我们运行A
,我们会再次看到四次git cherry
次提交。我们没有看到提交 A1--A2--A3 <-- A
/
...--o--* B2
\ / \
B1 B4--B5 <-- B
\ /
B3
,因为它是git cherry -v A B
和B
的合并。我们做看到一些顺序;我们也会回复此问题 - B4
,B3
,B2
和B1
。
我们假设您选择B2
进行合并。除非我将图形的下半部分颠倒过来,否则这很难画出来,所以我会这样做:
B3
查看结果:我们已合并B5
和B3
,但未合并 A1--A2--A3--M <-- A
/ /
...--o--* B3
\ / \
-------B1 B4--B5 <-- B
\ /
B2
。这可能不是你想要的。我们可以合并B1
,或者我们可以合并B3
以获得B2
的合并结果(这是B2
中合并的内容)以引入所有内容B4
。但B2+B3
输出中甚至没有列出B4
!
现在我们遇到另一个问题。显示的B1-B2-B3
,B4
,git cherry
和B1
的顺序是什么? 应该显示的顺序是什么?如果Git向您显示B2
然后B3
然后B5
以及B1
B3
,您就会得到您期望的结果。但是,如果它显示B2
然后git merge
然后B3
以及B1
,则会得到您 期望的内容:{ {1}}似乎不见了!
B2
未指定显示这些提交的实际顺序。如果您使用B3
代替git merge B3
,则可以使用B2
,git cherry
或git rev-list
来控制订单(实际上您只需要git cherry
})。您仍然会遇到合并的潜在问题,因此您可能希望检查(例如,使用--topo-order
,是否已备份任何合并,或--date-order
,--author-date-order
中是否存在任何合并1}}(无论你是否计划在该点之前或之后合并)。
--topo-order
限制确保子提交在父提交之前提交,即列表以git rev-list --count
顺序进行。添加git rev-list --merges --count
会颠倒此顺序,如果没有合并 - 就像上面的四个commit-long变体一样 - 以从左到右的顺序获取提交,这样您就可以确定哪些修订提供了哪些历史。
在我的测试中,A..B
似乎以反向拓扑顺序列出 - 但文档中没有任何内容可以保证这一点,并且快速查看源代码,也没有任何来源。如上所述,您还可以获得一个标记,其中“提交”位于上游,由相同的修补程序ID&#34;确定,但这应该是无害的。所以唯一真正的限制是图表强加的是什么,即你的&#34;前N是否提交&#34;确实是第一次 N提交:没有排序问题,没有后续合并的分支没有重新组合它们。
如果您的--topo-order
输出(跳过合并)首先没有合并要跳过,和输出以反向拓扑顺序出现,然后你一定很好。两者通常都是正确的 - 通常你会在一个简单的分支B&#34;上运行它。没有合并,通常没有问题,提交以错误的顺序显示。
在Git的其他版本中,我看到提交以不同的顺序出现,并且在当前(Git 2.10 / 2.11)文档中没有描述为&#34;总是以反向拓扑顺序和&#34; #34 ;.当然,您可能正在运行包含内部分支的分支上。所以在这种情况下,答案是否定的。