使用rebase

时间:2016-06-23 15:12:01

标签: git git-rebase

让我们考虑以下场景

    m1-m2------m3-------m4--------m5 (master)
        \                \
         \                \
          \                \---f1-f2-f3(feature)
           \                \
            \                \-P1-P2-P3(patch)
             \
              \
               r1-r2-r3-r4 (release)

Masterm5提交,因为人们正在做出贡献,releaser4完成某个版本后才会提交。

现在我在应用程序中发现了一个适用于所有版本的错误。出于某种原因,我从m4分叉了一个分支(为什么不m5?现在说m5尚未提交,这是现实的)并用P1修复问题..P3。

对完成的工作表示满意我将补丁合并到m5但我被要求将补丁向后移植到release并生成更新。

    m1-m2------m3-------m4--------m5-----------m6 (master)
        \                \                    /
         \                \                  /
          \                \-P1-P2-P3(patch)/
           \                \
            \                \                  
             \                \---f1-f2-f3(feature)
              \
               r1-r2-r3-r4 (release)

如果patch是单一提交,我会很容易做到

git checkout release
git cherry-pick patch

好的,但patch是一系列提交。我想我应该改变。

问题在于,将patch重新定位到release涉及提交m3,该提交不得是release分支的一部分。它可能是一系列提交。

所以场景如下。我知道feature来自特定提交(通常是我们工作流中的标记)生成,因此我想将所有提交从m4(已排除)重新绑定到{{已添加1}},将patch指向新的release

我曾尝试滥用 P3' rebase命令选项,所以我在这里提出建议,因为我可能对rebase命令的理解不够

onto

预期结果

git checkout release #pick r4
git branch experiment #destructive actions will try not to destroy precious branches
git checkout experiment
git rebase --onto experiment m4 patch # detaches head, but I don't want that!

问题是:如何将这些补丁提交反向移植到较早的分支而不进行交互式操作?

互动(实际上这是一个答案),我可以执行以下操作,尤其是如果我按问题ID跟踪提交:

    m1-m2------m3-------m4--------m5-----------m6 (master)
        \                \                    /
         \                \                  /
          \                \-P1-P2-P3(patch)/
           \                \
            \                \                  
             \                \---f1-f2-f3(feature)
              \
               r1-r2-r3-r4-P1'-P2'-P3' (release)

但是你可以看到我的问题是要求自动化方式

3 个答案:

答案 0 :(得分:2)

您想要的是在版本m5m6之间应用差异。在git cherry-pick选项的帮助下,-m可以做到这一点:

  

-m 父母编号 - 主线 父母编号

     

通常你不能挑选合并,因为你不知道哪一方   合并应被视为主线。此选项指定父级   主线的数字(从1开始)并允许樱桃选择重播   相对于指定的父级更改。

因此步骤如下:

  1. 运行git show m6并在m5行注明Merge:的基于(从1开始)索引 k

  2. git cherry-pick -m k m6

答案 1 :(得分:1)

#create a new branch, based on `patch` and switch to it
git checkout -b backported-patch patch
#rebase this new `backported-patch` branch onto release:
git rebase --onto release m4 backported-patch
# now we have backported patch branch, merge it into release:
git checkout release
git merge backported-patch
顺便说一下,我认为最好重新绑定到分支的合并基础,即git rebase --onto m2 m4 backported-patch,在这种情况下,后端移植补丁将合并到它们两者,提供更清晰的历史记录。

因此,最终结果将是:

m1-m2------m3-------m4--------m5-----------m6 (master)
    \                \                    /
     \                \                  /
      \                \-P1-P2-P3(patch)/
       \                \
        \                \                  
         \                \---f1-f2-f3(feature)
          \--P1'-P2'-P3'(backported-patch)
           \           \
            r1-r2-r3-r4-M (release)

此外,将未合并的发布分支更改,即r1-r4提交应合并到主分支,使历史更清晰。

它给你:

m1-m2------m3-------m4--------m5-----------m6-----m7 (master)
    \                \                    /      /
     \                \                  /       |
      \                \-P1-P2-P3(patch)/        |
       \                \                        |
        \                \                       |
         \                \---f1-f2-f3(feature)  |
          \--P1'-P2'-P3'  ----------------------/
           \           \ /
            r1-r2-r3-r4-M (release)

答案 2 :(得分:-2)

git rebase --onto experiment m4 patch之后,你几乎就在那里。 git checkout release;git reset P3' --hardgit branch -D release;git branch release P3'

相关问题