当`git diff`显示更改但是`git merge`什么都不做时,合并分支的正确方法是什么

hob*_*obs 10 git git-diff git-merge

git diff other_branch表现出差异并且git merge other_branch什么都不做时,我感到难过.将"缺失"代码合并到什么位置的正确方法是my_branch什么?

这个SO答案描绘了一个类似于我的情况.

o---A---B---C-------G   my_branch
     \       \     /
      --*D*---E---F    other_branch
Run Code Online (Sandbox Code Playgroud)

令人惊讶的是,当我这样做时,D的变化不会自动合并my_branch

git checkout my_branch
git merge other_branch
Run Code Online (Sandbox Code Playgroud)

把在˚F

当然我可以手动创建补丁并将其应用到my_branch,如下所示:

git diff other_branch my_branch > patchfile
git checkout my_branch
patch -p1 < patchfile 
Run Code Online (Sandbox Code Playgroud)

但是我想要做到这一点,而不是弄乱git日志.使用补丁方法,git会将D和我最新补丁中的更改记录为彼此独立发生(代码流失).我想简化git log并确保其他人在他们这样做时不会发生意外的事情(悄悄地和阴险地)git merge my_branch.

Nev*_*nel 9

您似乎同时遇到两个问题。

假设有一段像您所描述的历史:

                my_branch
                    v
----A---B---C-------G   
     \       \     /
      --*D*---E---F
                  ^
             other_branch
Run Code Online (Sandbox Code Playgroud)

为什么 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-- 这是一个快进合并,因为G它是F
  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_branchmy_branch当前指向的位置

完成这些步骤之一my_branch,和都other_branch将指向G


为什么提交的更改D不在my_branch(G)

Git 合并历史,而不是更改。这通常意味着 Git 将获取合并的两侧(以及,如果可用,它们最年轻的共同祖先提交,也称为merge-base)并尝试将它们组合起来。由于 Git 提交是快照, not changesets/deltas/diffs, this no information of other commits or changes is used in the actual merge.

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

您的历史记录中可能发生的情况是,提交EF恢复(或覆盖)更改D- 这可能在合并期间发生,从而产生E或实际(手动)更改F

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