如何在最新合并后仅修改提交?

时间:2013-09-24 10:02:19

标签: git git-rebase git-pull

请考虑以下情况:

  1. 我检查了一个主人的分支
  2. 我做了一些提交
  3. 我合并了更新后的主人
  4. 我做了更多提交
  5. 现在我想从第4点开始提交rebase,这样第2点的提交就不会受到影响。
  6. 所以,如果我最初:

         (1)         (2)
    x--x--x--x--x--x--x         master
           \     \
            y--y--Y--y--y       dev
              (2)(3)   (4)
    

    我想得到:

         (1)         (2)
    x--x--x--x--x--x--x             master
           \           \
            y--y--------Y'--y'--y'  dev
              (2)      (5)     (5)
    

    如果我只做git rebase master,它将从2和4重新提交提交并从3删除合并。这不是我想要的。

    还可以选择在3合并提交之前执行git merge master,然后执行git rebase -i -p,并在合并之后从3移动最后一次合并,然后将修复/压缩到3中的合并中。 strong>更新:它不那么容易。 Git拒绝压制两个合并。这个问题:git rebase interactive: squash merge commits together

3 个答案:

答案 0 :(得分:2)

你从:

开始
     (1)
x--x--x--x--x--x--x         master
       \     \
        y--y--Y--y--y       dev
          (2)(3)   (4)

执行git rebase --onto

git branch dev1 Y^
git rebase --onto master Y^ dev

Y^引用合并提交的第一个父级Y:此处为“y”,而不是“x”。
请参阅“Ancestry References”:

  

第一个父项是您合并时所在的分支,第二个是您合并的分支上的提交。

你最终会得到:

     (1)
x--x--x--x--x--x--x             master
       \           \
        y--y        Y'--y'--y'  dev
          (2)      (5)
        (dev1)

这会将您的初始dev分支分成两部分,并仅在dev之上仅应用最后master次提交,同时保持第一次dev次提交不变,由分支dev1引用。

您可以尝试:

git rebase -p --onto master `Y^` dev

查看是否保留y(即Y^)与新重新定位的Y'之间的关系。但我怀疑这是可能的。

-p适用于--preserve-merge

答案 1 :(得分:2)

使用my和VonC的答案提供了更多自动化解决方案:

git checkout -b tmp Y
git merge master 
git reset --soft HEAD^^ 
git rev-parse master > .git/MERGE_HEAD 
git commit -C Y
git checkout -
git rebase --onto tmp Y
git branch -d tmp

Y - 是要扩展的合并提交。

它的工作原理如下:

x--x--x--x--x--x--x         master
       \     \
        y--y--Y--y--y       dev

x--x--x--x--x--x--x         master
      |      \
       \      Y             tmp
        \    / \
         y--y   y--y        dev

x--x--x--x--x--x--x         master
      |      \     \
       \      Y-----Y'      tmp
        \    / \
         y--y   y--y        dev

x--x--x--x--x--x--x         master
      |            \
      |      -------Y'      tmp
       \    /
        y--y--Y--y--y       dev

x--x--x--x--x--x--x         master
      |            \
      |      -------Y'      tmp
       \    /        \
        y--y          y--y  dev

x--x--x--x--x--x--x           master
       \           \
        y--y--------Y'--y--y  dev

答案 2 :(得分:1)

我最终做了以下事情:

git rebase -i -p Y^

在文件中,在合并行之后添加以下行(可能在第一行之后):

exec sh -c "git merge master; git reset --soft HEAD^^; git rev-parse master > .git/MERGE_HEAD; git commit -C `git rev-parse HEAD`"