当我将它合并到另一个分支时,master 分支会被修改吗?

Does the master branch gets modified when I merge it into another branch?

简单问题:

我最近发现您可以将 master 合并到派生功能 branches 中(用最新的 master 更改更新您的功能分支)。

通过这样做,我是否以任何方式修改了 master?或者它完全没有被那个操作改变?

在这种情况下,您在 master 分支中修改 nothing。您只需将更改从它更改到您的功能分支。 "master" 不是某种 "special" 分支。它只是具有相同规则的普通分支。它的广泛传播是因为每个新的 git 存储库都以一个名为 "master"

的分支开始

简短的回答是 "no",但这不仅仅是一个简短的回答。

如果您从 提交 而不是 分支的角度考虑,您会发现您和 Git 相处得更好。好吧,更准确地说,重要的是要记住哪个分支是 当前分支 ——或者使用 git status 看看它是 on branch master 还是 on branch develop 或者不管怎样——但是 在那之后,考虑提交。

每个分支名称都指向一个(单个)提交。根据定义,该提交是分支的 tip 提交。短语 指向 在这里意味着分支名称字面上包含该提交的原始哈希 ID。每个提交都有自己唯一的哈希 ID:没有其他提交可以拥有该哈希 ID。该哈希 ID 意味着 提交,现在和永远。

特名HEAD指的是一个分支名。1HEAD记住一个分支名,一个分支名记住一个提交。

当你这样做时:

git checkout develop

(假设它成功了),Git 通过让 HEAD 记住名字 develop 来让你 "on" 你的 develop。您当前的 提交 现在是 develop 命名的那个。

当您随后 运行:

git merge master

(假设它成功),Git 已经完成了所有合并工作——无论是什么工作,这可能会变得复杂——然后可能进行了新的提交。2 如果 did 进行了新的提交,name develop 现在标识新的提交。名称 master 仍然标识名称 master 一直标识的同一个提交。

同时,每个提交都通过哈希 ID 引用一定数量的 parent 提交。大多数提交只持有一个 parent 哈希 ID,因此大多数提交都指向它们的 parent。这一系列 backwards-pointing 箭头形成一条链。例如,名称 master 可能包含哈希 ID H。同时,hash ID H 的 commit 持有 hash ID G,commit G 持有 hash ID F,依此类推:

... <-F <-G <-H   <-- master

Git 可以从名称 master 到提交 H,然后返回到 G,再到 F,等等,通过提交链向后。

没有提交可以永远改变——一点也没有——所以一旦一个提交存在并且有一些parents,那个提交总是向后指向那些parent秒。 (您不能更改提交。最多,您可以 Git 停止查看提交。如果您和 Git 都不能 找到 提交,则commit 最终从存储库中掉出并被垃圾收集。)Git 主要只是不断添加 new 提交到链中。

所以我们从这样的事情开始:

...--F--G--H   <-- master
         \
          I--J   <-- develop

git checkout 发展到 select 提交 J。 (在名字 develop 旁边画上单词 HEAD,这样你就可以记住你在 develop。)

现在你 运行 git merge master 和 Git 启动合并机器。这会进行大量计算,找出正确的合并结果,并构建一个新的提交。由于新提交是合并提交,它像往常一样指向 J,但 指向 H:

...--F--G-----H   <-- master
         \     \
          I--J--K

作为写出合并提交 K 的结果,Git 将其哈希 ID(无论它是什么)写入 HEAD 所附加的名称,现在 develop 指向提交 K:

...--F--G-----H   <-- master
         \     \
          I--J--K   <-- develop (HEAD)

提交 H 未更改——不能 更改——并且名称 master 未移动,因此 master 是不受影响。


1名称HEAD可以包含哈希ID而不是分支名称。在这种情况下,Git 表示您处于 "detached HEAD" 模式。更新——例如创建新的提交——只需将新的提交哈希 ID 直接写入 HEAD,以便 HEAD 继续分离。使用带有分支名称的 git checkout 到 re-attach HEAD 到该分支名称。

2在某些情况下,git merge 实际上根本不进行合并,而是进行 fast-forward操作。当不需要合并时会发生这种情况。例如,如果您在 master 上并且有这个:

...--G--H   <-- master (HEAD)
         \
          I--J  <-- dev

并询问 git merge dev,如果要进行真正的合并,Git 必须合并的更改将是从提交 H 到提交 Hmaster 上的 "what you changed")以及从提交 H 到提交 Jdev 上的"what they changed")的任何更改。但很明显,commit H 中的内容与 commit H 中的内容相同。实际上不需要进行任何合并!如果允许,git merge根本不会去合并,直接check out commitJand把名字master往前拖匹配,给出:

...--G--H
         \
          I--J  <-- dev, master (HEAD)

请注意,这是针对 git checkout master; git merge dev 的,而不是相反。执行 git checkout dev; git merge master 会得到一条 "already up to date" 消息,其他任何内容都没有改变。