更新:在我写完这个答案后,发帖者改变了问题。此更新回答了其余答案未涵盖的问题之一。
好的.. 现在,奇怪的是;现在我称之为“git status”;它说我在远程分支之前提交了 4 次。这是怎么回事?我不应该只有一个提交吗?
在您合并 (--no-ff) 提交 A 和 D 到 E 之后,本地分支比远程分支提前 4 次提交(我想远程分支仍然指向 A)。这是正确的。
让我们计算本地分支上的提交(现在指向E)和不在远程分支上(指向A)的提交。 E 显然是其中之一。 E,作为一个合并提交,有两个父级:A(存在于远程分支上)和D(不存在于远程分支上)。当git 将E 推送到远程服务器时,它需要同时推送其父服务器(否则E 在远程服务器上无效)。
D 需要C(它的父级),需要B,需要A。 A 已经存在于远程服务器上,链到此结束。远程服务器上不存在B、C、D 和 E。必须全部推送,以保持远程服务器上数据的一致性。
回复的其余部分处理了未明确定义的原始问题。海报提到了git log --graph 和(可能)Atlassian Stash。这两个工具(以及我知道的所有其他git 接口)都首先在提交历史中显示最近的提交。这个答案使用相同的约定。
git merge --no-ff在你描述的情况下没有任何作用。
将br1 作为当前分支,git merge br2 将提交引入的更改引入br1,这些更改可以从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从其先前位置“快进”移动到新位置(可能与从E移动到B的分支b2相反一次提交一个)。只有当br2 是br1 的唯一一个子路径时才有可能(从E 开始,每个提交都有一个子提交并且路径到达B)。
--no-ff 开始发挥作用了。如果您希望此合并创建一个合并提交,其中包含提交 D、C 和 B 引入的所有更改,那么您运行:
git checkout br1
git merge --no-ff br2
--no-ff 选项的存在禁止分支b1 的快速转发,并强制创建新的合并提交。图表将如下所示:
A <-- br1
|\
| B <-- br2
| |
| C
| |
| D
|/
E
|
...