更新:我写完这个答案后,发帖人改变了问题。此更新回答了其余答案未涵盖的问题之一。
好的..现在,奇怪的是;现在我称之为“git status”;它说我在远程分支之前提交了 4 次。这是怎么回事?我不应该只有一个承诺吗?
在合并 ( --no-ff
) 提交A
和D
intoE
之后,本地分支比远程分支早 4 次提交(我想远程分支仍然指向A
)。这是对的。
让我们计算一下本地分支上的提交(现在指向E
)而不是远程分支上的提交(指向A
)。E
显然是其中之一。E
,作为合并提交,有两个父级:(A
存在于远程分支上)和D
(不存在于远程分支上)。当git
推E
送到远程服务器时,它需要同时推送它的父母(否则E
在远程服务器上无效)。
D
requires C
(其父级) that requires B
that requires A
。A
远程服务器上已经存在,链到此结束。B
, C
,D
并且E
在远程服务器上不存在。必须全部推送,以保持远程服务器上数据的一致性。
其余的回复处理了定义不是很明确的原始问题。海报提到git log --graph
和(可能)Atlassian Stash。这两个工具(以及git
我知道的所有其他界面)都首先在提交历史中显示最近的提交。这个答案使用相同的约定。
git merge --no-ff
对您描述的情况没有任何影响。
拥有br1
作为当前分支,git merge br2
将引入由可访问和不可访问br1
的提交引入的更改。根据 about 的相对位置,可以创建一个新的提交(包含由无法访问的提交引入的所有更改),或者它可以只是将分支头移动到一个新位置(并且不创建任何新的提交)。br2
br1
br1
br2
git merge
br1
br1
在您的情况下,br2
落后br1
于 1 次提交,并且因为A
是合并提交,所有可访问的提交br2
也可以从br1
.
无论如何,git merge --no-ff
是在不同的情况下使用的。
假设我们有这张图:
B <-- br2
|
C
|
D
|
E <-- br1
|
...
该分支br2
是从分支创建的br1
(当时两者都在提交E
),然后br2
被签出并添加了三个新的提交(D
和C
)B
。
在这种情况下,命令:
git checkout br1
git merge br2
不要创建新分支。分支br1
被移动到提交B
(在哪里br2
),仅此而已。现在所有可以访问的提交br2
也可以从br1
. br2
已成功合并到br1
.
这是图表的样子:
br1 --> B <-- br2
|
C
|
D
|
E
|
...
之所以调用这种合并,是fast-forward
因为分支br1
从其先前位置“快进”移动到新位置(可能与一次b2
从一个提交移动E
到B
一个提交的分支相反)。只有当br2
是唯一的一个子路径时才有可能br1
(从 开始E
,每个提交都有一个子提交并且路径到达B
)。
这里就派上用场--no-ff
了。如果您希望此合并创建包含由 commits 引入的所有更改的合并提交,D
然后C
运行B
:
git checkout br1
git merge --no-ff br2
选项的存在--no-ff
禁止分支的快速转发b1
并强制创建新的合并提交。该图将如下所示:
A <-- br1
|\
| B <-- br2
| |
| C
| |
| D
|/
E
|
...