今天我有一个好奇的git行为,我想问这是否正常。现在,情况就是这样(新提交被添加到底部):
br1 br2
A
\
B
C
D
现在,当我做
时git checkout br1
git merge --no-ff br2
它变成这样(至少是git log --graph告诉我的):
br1 br2
A
| \
| B
| C
| D
| /
E
好的..现在,奇怪的是;现在我打电话给#34; git status&#34 ;;它说我在远程分支之前提交了4个提交。这是怎么回事?难道我不能只提前一次提交吗?
奇怪的是,当我从Stash(Git Web UI,基本上)检查时,它确认了这个" 4提交"状态,我看到" br1"下的相同提交(B C和D);和" br2"两个......
当我使用" - no-ff"参数,提交在" br2" (B C D)不会被复制到" br1"并且只创建合并提交。我错了吗?
答案 0 :(得分:2)
我认为你误解了分支机构在Git中的运作方式。 Branches are lightweight,这意味着当您创建新分支或将一个分支合并到另一个分支时,不会复制任何内容。
分支是指向到提交的引用。由于每个提交都与其先前的提交相关联,因此当您指向一个提交时,您实际上指向该提交的历史。
在您的示例中,E
是一个合并提交,将两个分支组合在一起,创建单个历史记录。这意味着在将br2
合并到br1
后,br1
(现在对E
的引用)将了解{br2
的历史记录1}}(仍然对D
的引用),因为D
,C
和B
是{{{}的历史记录的一部分1}}。
您的本地E
是对br1
的引用,而您的远程E
仍然是对br1
的引用。因此,A
的历史记录中有四个提交(B
,C
,D
和E
) new
答案 1 :(得分:2)
更新:在我写完这个答案后,海报改变了问题。此更新回答了其余答案未涵盖的其中一个问题。
好的..现在,奇怪的是;现在我打电话给#34; git status&#34 ;;它说我在远程分支之前提交了4个提交。这是怎么回事?难道我不能只提前一次提交吗?
将提交--no-ff
和A
合并到D
之后,本地分支是远程分支之前的4次提交(我想远程分支)仍然指向E
)。这是正确的。
让我们计算本地分支上的提交(现在指向A
)并且不在远程分支上(指向E
)。 A
显然是其中之一。作为合并提交的E
有两个父项:E
(存在于远程分支上)和A
(不存在于远程分支上)。当D
将git
推送到远程服务器时,它需要推送其父服务器(否则E
在远程服务器上无效)。
E
要求D
(其父级)需要C
,需要B
。 A
已存在于远程服务器上,链在此处结束。远程服务器上不存在A
,B
,C
和D
。必须推送所有这些以保持远程服务器上数据的一致性。
其余的回复会对原始问题进行处理。该海报引用了E
和(可能)Atlassian Stash。这两个工具(以及我所知道的所有其他git log --graph
接口)都首先在提交历史记录中提供最新的提交。这个答案使用相同的约定。
git merge --no-ff
对您描述的情况没有任何影响。
将git
作为当前分支,br1
将git merge br2
提交的更改引入br1
,但br2
无法访问这些更改。根据{{1}}关于br1
的相对位置,br1
可以创建一个新提交(包含由br2
无法访问的提交所引入的所有更改)或者它可以只是将git merge
分支头移动到新位置(并且不会创建任何新提交)。
在您的情况下,br1
落后br1
,提交1次,因为br2
是合并提交,所有可从br1
访问的提交也可以从A
访问{1}}。
无论如何,br2
用于不同的情况。
我们假设我们有这张图:
br1
分支git merge --no-ff
是从分支 B <-- br2
|
C
|
D
|
E <-- br1
|
...
创建的(当时两者都在提交br2
)然后检出br1
并提交了三个新提交({{1} }},E
和br2
)已添加。
在这种情况下,命令:
D
不要创建新分支。分支C
被移动到提交B
(其中git checkout br1
git merge br2
是)并且全部都是。现在,br1
可以访问的所有提交也可以从B
访问。 br2
已成功合并到br2
。
这就是图表的样子:
br1
这种合并称为br2
,因为分支br1
已被移动&#34;快进&#34;从其先前的位置到新的位置(可能与分支br1 --> B <-- br2
|
C
|
D
|
E
|
...
相反,一次从fast-forward
移动到br1
一个提交。仅当b2
是E
的唯一子路径时才有可能(从B
开始,每个提交都有一个子提交,路径到达br2
)。< / p>
这里有br1
。如果您希望此合并创建包含提交E
,B
和--no-ff
引入的所有更改的合并提交,那么您运行:
D
C
选项的存在禁止快速转发分支B
并强制创建新的合并提交。该图表如下所示:
git checkout br1
git merge --no-ff br2
答案 2 :(得分:1)
从技术上讲,4次提交实际上是br1
的一部分。如果您删除br2
,则提交仍将是br1
的一部分。重置合并提交时会出现差异。如果您执行硬重置,您将返回到合并提交之前的提交,即E
。当您想要回滚时,这尤其有用。所以,是的,你提前四次提交,但只要你没有重置br1
,你应该没问题。
-no-ff
也不是要阻止git复制提交。这是为了使提交与br1
的树分开。这样,您可以维护分支的历史记录和提交的上下文,而不是大量的提交都与不同的功能相关