了解Git Merges

时间:2017-07-15 14:45:06

标签: git

我知道这个解决方案已经存在,但我无法理解git。

我是一名开发人员,在使用git时,其他分支通常没有变化。

这通常是我做的事情:

git branch changes
git checkout -b changes
/* changes occur */
git commit -m "Changes Occured"
/* Changes occur */
git commit -m "More Changes"

在此之后,我脑子里有了以下可视化:

  :
  | c2
  | |
  | c1
  | /
master

然而,git gui展示了这种可视化

    :
    c2 changes
    |
    c1
    |
  master

然后我将我的更改与master合并:

git checkout -b master
git merge changes

我有以下可视化:

:
| master, changes
|
| \
| c2
| |
| c1
| /

然而,git gui表示:

:
| master, changes
c2
|
c1
|

这是预期的行为吗?或者我做错了什么?

3 个答案:

答案 0 :(得分:4)

您的可视化预先假定分支master上有更多提交:

c3 (master)
|
| c2 (changes)
| |
| c1
| /
c0
:

或者,相当于,分支名称具有某种永久意义(它们不在Git中:在Git中,只有提交重要;分支名称在很大程度上仅仅是为了容纳人类而愚蠢的东西,除了他们在保持提交存活并帮助在不同的Gits之间来回发送一些特殊角色之外。

另请注意,我还将分支标签移至指向最新提交(仅限)。这就是分支标签在Git中的工作方式:它们指向单个提交,因此识别分支的提示提交

如果尚不存在提交c3,Git会注意到您有这种安排:

c2 (changes)
|
c1
|
c0 (master)
:

其中c0的提示是master的提示,可以从c2到达,这是changes的提示。这意味着提交c0位于两个分支上(请注意,即使master指向某个提交c3,这仍然是可达性的事情,如顶部图)。由于你有这种安排,Git可以“以快进方式向前滑动名称master”,向上链接从c2到{{1然后回到c1。这个 - 实际上根本不是合并的东西 - 是c0的默认操作。如果git merge已经指向新提交master,那将是不可能的,并且Git必须做,并且做出“真正的合并”(做合并操作,并进行合并提交{{ 1}})。

要强制Git进行合并提交 - 动作,合并为动词仍然完全没必要,Git不会打扰你可以使用c3。这将生成一个新的合并提交c4并将git merge --no-ff标签向上移动以指向该合并提交:

c3

请注意,只有当前分支名称(即标签master)会移动。要记下哪个标签是最新的,我们会添加c3 (HEAD -> master) |\ | c2 (changes) | | | c1 | / c0 : 名称。

答案 1 :(得分:1)

如果主分支上没有其他提交,git将选择快进而不是进行合并提交。如果你不喜欢这种行为(许多人,比如我,不要)并希望保留分支历史记录,你可以与git merge _branch_ --no-ff合并以强制git进行合并提交。

答案 2 :(得分:1)

git中的分支只不过是他们提交的历史。它们不是自己记录的,而只是指向那些提交中最新的一个。

这就是为什么

    :
    c2 changes
    |
    c1
    |
  master

查看其显示方式。只有两个提交,c1和c2,changes指向第二个提交,而master没有记录历史。

合并后,master也记录了提交c1c2。由于在合并发生之前没有专门在master上提交,masterchanges实际上并不相同,即记录提交的历史相同,因为从两个角度来看,相同的提交都发生在同样的顺序。那是(c1c2),因为合并是由快进完成的。