git merge 时候如何处理已经cherry-pick 过的记录呢

dev 分支上有一大堆的 commit 记录,其中部分记录已经 cherry-pick 到了 master 分支,现在如果将整体的 dev 分支 merge 到 master 分支,那么之前已经 cherry-pick 过的记录会怎样?

注意: cherry-pick 的过程了相应的在 master 分支上生成了对应的 commit 记录

csdn 上找到了想问的问题,但是感觉不太详细,希望大佬能有相关资料分享下或解答下。

阅读 6k
1 个回答

假设你是这样的情况:

A - B - C  (master)
         \
          E - F  (dev)

现在我们在 mastercherry-pick E,然后得到:

A - B - C - E' (master)
         \
          E - F  (dev)

这时候如果我们在 mastermerge dev,则会得到:

A - B - C - E' - G (master)
         \      /
          E - F  (dev)

其中,GE'F 的 merge commit。如果我们在 mastergit log,看起来当然好像是 E 被 commit 了两次。原因有两点:

  1. 在一个 repo 中,commit hash 不能重复,因此 git cherry-pick 后的 E'E 的 commit hash 是不同的
  2. 产生这种现象的根源在于,这里的 git merge 执行的其实是 --no-ff,因为 cherry-pick 之后,masterdev 的历史线对不上。具体来说,相对于 cherry-pick 之前,现在在 C 出现了 diverge,master 多了个 E'dev 并没有这个 E'。请注意,E'E 在 git 看来,是两个不同的 commit。别忘了,git 不是存储 diff,而是存储 snapshot

因此,解决方案也不难想象,我们只要想办法让 devmaster 历史线对上就好了。这可以通过在 devrebase master 来实现。这是 cherry-pick 之后的样子:

A - B - C - E' (master)
         \
          E - F  (dev)

然后,我们在 devrebase master,就会得到:

A - B - C - E' (master)
             \
              F  (dev)

这时候,历史线对的上,git merge 会按照 fast forward 的方式进行,我们会在 merge 后得到:

A - B - C - E' - F (master)
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进