【问题标题】:What is the right way to merge branches when `git diff` shows changes but `git merge` does nothing当`git diff`显示更改但`git merge`什么都不做时合并分支的正确方法是什么
【发布时间】:2013-05-05 15:03:18
【问题描述】:

git diff other_branch 显示差异而git merge other_branch 什么都不做时,我感到很困惑。将“缺失”代码合并到 my_branch 中的正确方法是什么?

这个SO answer 描绘了一个与我类似的情况。

o---A---B---C-------G   my_branch
     \       \     /
      --*D*---E---F    other_branch

令人惊讶的是,D 中的更改不会自动合并到 my_branch

git checkout my_branch
git merge other_branch

F引入G

我当然可以manually create a patch 并将其应用到my_branch,如下所示:

git diff other_branch my_branch > patchfile
git checkout my_branch
patch -p1 < patchfile 

但我想正确地做到这一点,而不会弄乱 git 日志。使用补丁方法,git 将记录 D 和我的最新补丁中的更改,因为它们彼此独立发生(代码搅动)。我想简化git log 并确保其他人在执行git merge my_branch 时不会发生意外的事情(悄悄地和隐蔽地)。

【问题讨论】:

  • 您是否尝试将my_branch 合并到other_branch 中?可能这可以解决分歧。如果某些提交在 my_branch 而不是在 other_branch 中被还原,你最终会遇到这样的情况。
  • @iltempo,我在您发表评论后尝试了合并,是的,它确实解决了差异,git diff 现在很干净。我只需要相信它会适当地合并。
  • @iltempo,我并没有故意恢复 my_branch 中的任何更改,但很可能有——通过在结帐和编辑之间摇摆后在 sublime(文本编辑器)中保存并穿插提交。我需要对这一切更加小心。

标签: git git-merge git-diff


【解决方案1】:

您似乎同时在这里遇到了两个问题。

假设你所描述的历史:

                my_branch
                    v
----A---B---C-------G   
     \       \     /
      --*D*---E---F
                  ^
             other_branch

为什么 diff 不为空:

这种情况是由您提到的命令产生的,即my_branch上然后在git merge other_branch上执行。此操作产生了合并提交 G 并将当前分支 (my_branch) 向前移动,但将 other_branch 留在原处。这就是合并始终起作用的方式!当然,此时my_branch (G) 和other_branch (F) 之间仍然存在差异——毕竟它们指向不同的提交。

如果希望两个分支相同,可以通过以下方式向上移动other_branch

  1. git checkout other_branch; git merge my_branch -- 这是一个 快进 合并,因为 GF 的后代
  2. [虽然不在 other_branch!] git branch -D other_branch; git branch other_branch my_branch -- 这将删除 other_branch 然后在 my_branch 当前所在的相同位置重新创建它
  3. git checkout other_branch; git reset --hard my_branch -- 这将移动 other_branch 精确指向my_branch 当前指向的位置

在完成上述一个步骤后,my_branchother_branch 都将指向 G


为什么commit D的变化不在my_branch(G)

Git 合并历史,而不是更改。这通常意味着 Git 将采用合并的两侧(如果可用,它们最年轻的共同祖先提交,也就是 merge-base)并尝试将它们组合起来。由于 Git 提交是快照,而不是变更集/增量/差异,因此在实际合并中不会使用其他提交或更改的信息。

使用合并基础,Git 进行了所谓的三向合并,使用共同祖先来尝试巧妙地解决双方的变化。如果不能,它将中断合并并要求用户解决冲突。

可能发生的事情在你的历史中是提交 EF 恢复(或覆盖)D 的更改 - 这可能发生在产生 @ 的合并期间987654353@ 或F 中的实际(手动)更改。

正如您自己在评论中提到的,您经常在提交和编辑之间切换。因此,您将大量浮动更改(Git 在结帐期间携带未提交的更改),这很可能使您很难判断更改应该去哪里以及它们实际去哪里。尝试通过在更改分支之前提交任何更改或使用git stash 来缓冲它们来避免这种情况。

【讨论】:

  • 这非常有帮助!
猜你喜欢
  • 2011-04-04
  • 1970-01-01
  • 1970-01-01
  • 2014-03-05
  • 2013-12-21
  • 2015-06-08
  • 2013-05-20
  • 2012-04-23
  • 1970-01-01
相关资源
最近更新 更多