12

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

当然,我可以手动创建一个补丁并将其应用于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.

4

1 回答 1

10

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

假设像您描述的那样的历史:

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

为什么差异不为空:

这种情况是由您提到的命令产生的,即打开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_branch的确切位置my_branch

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


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

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

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

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

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

于 2013-05-11T07:18:06.573 回答