为什么将主分支合并到功能分支会从 GIT 中的功能分支中删除文件?

时间:2021-07-17 16:22:16

标签: git github merge version-control

我有一个功能分支 A 并且我在功能分支中做了很少的提交。我的主分支在我的功能分支之前。当我尝试将我的主分支合并到功能分支时,我提交并推送到我的功能分支远程的功能分支文件被删除。在将 master 合并到 feature 分支时,我没有遇到合并冲突。当我删除本地功能分支并从功能分支的远程再次签出时,那些已删除的文件会重新出现,但是一旦我合并更新的主分支(没有从此功能分支 A 进行更改),这些文件就会被删除。有人可以帮助我了解正在发生的事情吗?

2 个答案:

答案 0 :(得分:1)

git merge 命令通过以下方式执行“真正的合并”:

  1. 定位合并基础提交。如果你现在在分支 B 上,并且正在运行 git merge M,你可以自己找到这个提交的哈希 ID:

    git merge-base --all B M
    

    理想情况下,这只会打印一个提交哈希 ID;如果它打印两个或多个哈希 ID,则您的合并特别复杂,必须转向更详细的答案。

  2. 使用相当于 git diff --find-renames 两次。其中一个 diff 命令用于确定 you 在分支 B 上的更改。另一个差异计算他们在分支M上的变化。

  3. 结合这些变化。

合并这些更改的结果包括删除一些文件。您会看到,在第 2 步生成的两个 diff 中,这两个 diff 之一表示要删除某个文件,而两个 diff 中的另一个在所有关于那个文件。将 delete file xyz 指令与 do nothing 指令组合的结果是 delete file xyz,因此 Git 遵循该(组合)指令并删除文件。

如果您不想删除文件,请不要删除它。 ? 找出为什么这两个差异之一显示文件已删除。您可以自己运行这两个差异;您可能希望使用 --name-status 来减少输出量。 (您可以使用 --diff-filter 进一步减少它,但仅从 --name-status 开始。)例如,假设 git merge-base 打印 12604a8d0c0a7d706c7be7be607a584260042ca9。你会跑:

git diff --find-renames --name-status 12604a8d0c0a7d706c7be7be607a584260042ca9 HEAD

看看 Git 认为改变了什么(如果你愿意,你可以输入 B 的分支名称而不是 HEAD),以及:

git diff --find-renames --name-status 12604a8d0c0a7d706c7be7be607a584260042ca9 M

(替换为实际的分支名称)以了解 Git 认为他们改变了什么。

如果你不喜欢 Git 的合并结果:

  • 在合并之前进行更改(通过向一个或两个分支添加提交);或
  • 在合并之后进行更改(通过添加新提交);或
  • 使用 git merge --no-commit 并生成 evil merge。阅读链接的问题,并在进行合并之前仔细考虑为什么要进行邪恶合并,因为如果您稍后使用 Git 的一些更高级的选项来重新执行此合并,Git 将进行非-下次邪恶合并,除非您仔细安排进行相同的邪恶合并。这往往需要大量了解自己在做什么。

请注意,git merge 有时根本不执行任何合并,并且某些结果来自 git merge(例如,使用 --squash)不是 合并提交,即使他们可能已经使用合并机制来产生合并结果。名词短语merge commit与动词to merge完全不同。

答案 1 :(得分:0)

我找到了这个问题的原因。这些文件过去被添加到 master 并被删除,因此当我尝试将 master 合并到 feature 分支时,GIT 过去常常忽略这些文件。我按照以下步骤解决了这个问题:

  1. 对这些文件进行一些更改。
  2. Git 提交这些文件。
  3. 将 master 合并到功能分支。
相关问题