Git 从分支 A 合并到分支 B 也更新了分支 A 中的代码
Git merging from Branch A to Branch B has updated the code in Branch A too
我有两个分支(分支 A 和 B),每个分支都有不同的文件。
我创建了新的拉取请求以将代码从分支 A 合并到 B。
我预计分支 B 中不存在但分支 A 中存在的那些更改将被合并,并且只有分支 B 将更新所有代码。
但我观察到合并请求甚至 更新了分支 A,其中的代码仅存在于分支 B。
因此,两者现在都持有所有代码。如何避免这种情况?
我希望保留分支 B 中的所有代码,但分支 A 应该保持原样。
这在 Git 中可能吗?
这只会发生在拉取请求以某种方式从 B 到 A(而不是 A 到 B)的情况下
这意味着 PR 的基本分支不正确。
如您在“About pull request merges”中所见,只有目标分支受到影响。
重要的是要认识到,在 Git 中,分支 在某种程度上是一种幻觉。 Git 与 分支机构 无关。 Git 大约 提交 .
当您使用 git merge
或 GitHub 的点击按钮来实现合并时,您得到的通常是 新提交 。这个新的提交不会——字面上 can 不会——改变任何现有的提交。1 这是一个新的提交,所以它有一个新的,前所未见的哈希 ID。
与此同时,分支名称 本身只是提交对象哈希 ID。更准确地说,每个名字都有一个哈希ID。此提交是被视为“在分支上”的 last 提交。其他更早的提交也可以在同一个分支上,并且任何一个提交都可以——而且很多是——同时在许多分支上。
在 Git 中进行新提交的过程是在“分支上”完成的——在特殊名称 HEAD
包含分支名称的情况下——或者在“分离的 HEAD 模式”,其中特殊名称 HEAD
包含原始哈希 ID。如果“在分支上”完成,创建新提交的最后一步是 Git 将新提交的哈希 ID 写入当前分支名称,以便该分支名称现在标识新提交。由于此时没有更新其他分支名称,因此新提交在该分支上 仅。
这也适用于 git merge
。2 所以如果你在分支 B
和 运行 git merge A
,新提交的哈希 ID 被写入名称 B
。这意味着分支 B
将新提交作为其最终提交。但是,新提交不仅有通常的一个父项,而且有两个:第一个父项是通常的第一个父项,而第二个父项是分支 A
的尖端提交。所以现在,所有以前只在分支 A
上的提交,现在都在两个分支上了。但是 name A
没有更新,所以新的合并提交还没有出现在分支 A
.
上
现在可以移动名称 A
,以便在两个分支上进行合并 — 但如果您想这样做,则必须作为一个单独的步骤进行。
1这是由于所有 Git 对象的基本 属性:一个 Git 对象的 ID 是它的加密散列内容。如果您从某个现有对象中取出内容,对其进行更改,然后将其放回 Git,您将得到一个 新的和不同的对象 ,带有 新的和不同的哈希 ID。旧对象仍然存在,在其旧哈希 ID 下,未更改。
2本段描述了由 git merge --no-ff
或 git merge
执行的需要真正合并的真正合并。使用命令行 Git、git merge --ff-only
或 git merge
否则允许快进操作毕竟不会进行新的提交。
当使用 GitHub 进行合并时(但不是用于“rebase and merge”或“squash and merge”),GitHub 接口会进行真正的合并,即使快进可以操作。
我有两个分支(分支 A 和 B),每个分支都有不同的文件。
我创建了新的拉取请求以将代码从分支 A 合并到 B。
我预计分支 B 中不存在但分支 A 中存在的那些更改将被合并,并且只有分支 B 将更新所有代码。
但我观察到合并请求甚至 更新了分支 A,其中的代码仅存在于分支 B。
因此,两者现在都持有所有代码。如何避免这种情况?
我希望保留分支 B 中的所有代码,但分支 A 应该保持原样。
这在 Git 中可能吗?
这只会发生在拉取请求以某种方式从 B 到 A(而不是 A 到 B)的情况下
这意味着 PR 的基本分支不正确。
如您在“About pull request merges”中所见,只有目标分支受到影响。
重要的是要认识到,在 Git 中,分支 在某种程度上是一种幻觉。 Git 与 分支机构 无关。 Git 大约 提交 .
当您使用 git merge
或 GitHub 的点击按钮来实现合并时,您得到的通常是 新提交 。这个新的提交不会——字面上 can 不会——改变任何现有的提交。1 这是一个新的提交,所以它有一个新的,前所未见的哈希 ID。
与此同时,分支名称 本身只是提交对象哈希 ID。更准确地说,每个名字都有一个哈希ID。此提交是被视为“在分支上”的 last 提交。其他更早的提交也可以在同一个分支上,并且任何一个提交都可以——而且很多是——同时在许多分支上。
在 Git 中进行新提交的过程是在“分支上”完成的——在特殊名称 HEAD
包含分支名称的情况下——或者在“分离的 HEAD 模式”,其中特殊名称 HEAD
包含原始哈希 ID。如果“在分支上”完成,创建新提交的最后一步是 Git 将新提交的哈希 ID 写入当前分支名称,以便该分支名称现在标识新提交。由于此时没有更新其他分支名称,因此新提交在该分支上 仅。
这也适用于 git merge
。2 所以如果你在分支 B
和 运行 git merge A
,新提交的哈希 ID 被写入名称 B
。这意味着分支 B
将新提交作为其最终提交。但是,新提交不仅有通常的一个父项,而且有两个:第一个父项是通常的第一个父项,而第二个父项是分支 A
的尖端提交。所以现在,所有以前只在分支 A
上的提交,现在都在两个分支上了。但是 name A
没有更新,所以新的合并提交还没有出现在分支 A
.
现在可以移动名称 A
,以便在两个分支上进行合并 — 但如果您想这样做,则必须作为一个单独的步骤进行。
1这是由于所有 Git 对象的基本 属性:一个 Git 对象的 ID 是它的加密散列内容。如果您从某个现有对象中取出内容,对其进行更改,然后将其放回 Git,您将得到一个 新的和不同的对象 ,带有 新的和不同的哈希 ID。旧对象仍然存在,在其旧哈希 ID 下,未更改。
2本段描述了由 git merge --no-ff
或 git merge
执行的需要真正合并的真正合并。使用命令行 Git、git merge --ff-only
或 git merge
否则允许快进操作毕竟不会进行新的提交。
当使用 GitHub 进行合并时(但不是用于“rebase and merge”或“squash and merge”),GitHub 接口会进行真正的合并,即使快进可以操作。