Git 我可以快进合并整个分支链到主节点吗?
如果我有一个分支链 master->branchA->branchB->branchC->branchDGit 我可以快进合并整个分支链到主节点吗?,git,Git,如果我有一个分支链 master->branchA->branchB->branchC->branchD 是否可以在一个git命令中将分支D以及它与master(A、B和C)之间的链中的所有分支快速合并到master中?答案是一种临时的是 这里的诀窍是认识到Git并不真正关心分支。Git非常关心提交。当你谈论“分支链”时,你谈论的是一种视错觉:你看到的是Git没有看到的东西 为了准确起见,我们必须定义分支这个术语。当我们尝试时,我们发现这是一个大问题。不同的人使用这个词的方式不同,一个人甚至会以
是否可以在一个git命令中将分支D以及它与master(A、B和C)之间的链中的所有分支快速合并到master中?答案是一种临时的是 这里的诀窍是认识到Git并不真正关心分支。Git非常关心提交。当你谈论“分支链”时,你谈论的是一种视错觉:你看到的是Git没有看到的东西 为了准确起见,我们必须定义分支这个术语。当我们尝试时,我们发现这是一个大问题。不同的人使用这个词的方式不同,一个人甚至会以多种方式使用这个词,也许是在同一个句子中。(请参阅)但如果我们有意识地退一步,尽量避免使用“分支”这个词,看看提交工作的方式,这一切就开始有意义了 每个提交都有一个数字。但是,这些数字不是很好的1、2、3样式的序列号:它们是随机的散列ID,比如
AE46588BE0CD730430DDED4491246DFB4EAC55557
。(它们显然不是随机的:它们是每个提交内容的校验和,因此每个Git都将为相同的提交位计算相同的哈希ID。这是Git的关键魔法,真的。)没有简单的方法从ID中知道哪个提交是哪个
因此,Git所做的是:无论何时进行新的提交,都是从某个现有的提交中进行的。1因此,现有的提交是新提交的父级。Git在提交的元数据中存储新提交父级的哈希ID。这意味着我们始终可以从最后一次提交开始,并向后工作:
... <-F <-G <-H
as在一行中提交所有内容,假设名称master
指向提交C
,名称功能指向提交F
,名称hack
指向提交H
,名称last
指向提交L
:
__feature
.
A--B--C--D--E--F--G--H--I--J--K--L <-- last
. .
---master --hack
(通过使用分支名称签出提交会将特殊名称HEAD
附加到分支名称,这就是我在上面添加HEAD
的原因。)
回到你最初的问题,我们现在需要定义“快进”一词。在Git中,快进操作意味着我们有一些现有的提交链,使用任何名称都可以使用的名称,尽管分支名称是这里讨论的通常类型的名称,指向其中一个,但是在该名称之后还有一些提交,如下所示:
V <-- option1
/
...--T--U <-- name
\
W--X--Y--Z <-- option2
现在我们已经这样做了,但是,如果我们要求Git移动name
,使它指向W
、X
、Y
、或Z
,Git必须首先从V
向后移动到U
,然后再向前移动。这意味着这项行动不是快进的
快进不仅仅来自合并
虽然git merge
命令可以执行快进操作,并且在可以的时候会自动执行,但这并不是git中寻找快进操作的唯一部分。特别是,git fetch
和git push
都可以调整名称。名称git fetch
adjusts通常是远程跟踪名称,而不是分支名称,但是与git push
一起使用的名称通常会告诉其他一些git存储库调整其分支名称,这些名称也会首先检查快进性
结论
最后,这一切都归结于您的提交链,以及您所说的“分支”的确切含义。如果您可以按照我们使用上面的master
、feature
、hack
和last
绘制分支,那么您可以要求Git向前移动名称master
:
A--B--C <-- master (HEAD)
\
D--E--F <-- feature
\
G--H <-- hack
\
I--J--K--L <-- last
这确实会失败。但是--ff only
在这里并不完美。例如,考虑一下
如果我们有:
A--B--C <-- master (HEAD)
\
D--E--F--NEW <-- feature
\
G--H <-- hack
\
I--J--K--L <-- last
但是feature
在master
之前仍然有一个commit,因为commitNEW
-指向F
-只有从feature
开始并向后操作才能使用。答案是一种临时的肯定
这里的诀窍是认识到Git并不真正关心分支。Git非常关心提交。当你谈论“分支链”时,你谈论的是一种视错觉:你看到的是Git没有看到的东西
为了准确起见,我们必须定义分支这个术语。当我们尝试时,我们发现这是一个大问题。不同的人使用这个词的方式不同,一个人甚至会以多种方式使用这个词,也许是在同一个句子中。(请参阅)但如果我们有意识地退一步,尽量避免使用“分支”这个词,看看提交工作的方式,这一切就开始有意义了
每个提交都有一个数字。但是,这些数字不是很好的1、2、3样式的序列号:它们是随机的散列ID,比如AE46588BE0CD730430DDED4491246DFB4EAC55557
。(它们显然不是随机的:它们是每个提交内容的校验和,因此每个Git都将为相同的提交位计算相同的哈希ID。这是Git的关键魔法,真的。)没有简单的方法从ID中知道哪个提交是哪个
因此,Git所做的是:无论何时进行新的提交,都是从某个现有的提交中进行的。1因此,现有的提交是新提交的父级。Git在提交的元数据中存储新提交父级的哈希ID。这意味着我们始终可以从最后一次提交开始,并向后工作:
... <-F <-G <-H
as在一行中提交所有内容,假设名称master
指向提交C
,名称功能指向提交F
,名称hack
指向提交H
,名称last
指向提交
V <-- name, option1
/
...--T--U
\
W--X--Y--Z <-- option2
A--B--C <-- master (HEAD)
\
D--E--F <-- feature
\
G--H <-- hack
\
I--J--K--L <-- last
A--B--C--D--NEW <-- master
\
E--...--L <-- last
A--B--C <-- master (HEAD)
\
D--E--F--NEW <-- feature
\
G--H <-- hack
\
I--J--K--L <-- last
A--B--C--D--E--F--NEW <-- feature
\
G--H <-- hack
\
I--J--K--L <-- last, master (HEAD)