代码之家  ›  专栏  ›  技术社区  ›  Priyank Bolia

如何将一个分支合并到Git中的另一个分支?

  •  6
  • Priyank Bolia  · 技术社区  · 15 年前

    让我详细解释一下这个问题。

    我有一个主Git分支,在它上面我创建了一个新的分支Bug10101010,现在我不想将Bug10101010合并到主。到目前为止一切都很好。 现在我有了相同产品的另一个分支,名为Legacy。我不想把bug10101010合并到Git的遗留分支。

    有什么想法吗?

    我不能直接合并它,因为分支bug1010110是从主分支分离出来的,在遗留的分支中,我只需要分支bug1010101和其父分支之间的差异。

    3 回复  |  直到 15 年前
        1
  •  2
  •   Mizipzor    15 年前

    这很难做到。Git保存合并历史记录,如果您“cherrypick”并在bug10101010中指向一个提交作为父级(指示您已经完成了合并),那么Git将假定在此之前的所有提交(返回到它们拆分的点)都已合并。当你想做一个“真正的”合并时给你问题。

    另一方面,您只需从特定的提交(并且仅此)手动生成一个补丁。但当您稍后进行“真正的”合并时,这也会给您带来问题,因为它会尝试应用手工处理的提交两次。

    但是,再一次,因为有一个分支被命名为“遗产”,我怀疑你无论如何都不打算进行真正的合并,在这种情况下,你可以自由地做任何你想做的事情。

    黑斯安 interesting blog post on the topic .

        2
  •  6
  •   VonC    15 年前

    你应该使用 git rebase --onto 在这里,并指定一个范围。
    (见 git rebase man page :

    将基于一个分支的主题分支移植到另一个分支,以假装您从后一个分支分叉了主题分支,使用 rebase --onto .

    )

    当然,这会让你 bug10 分支位于 legacy 分支,这不是您想要/需要的。

    所以,一个解决办法是 在克隆的repo中进行重新平衡,然后合并“增强”的repo 遗产 分支 (克隆报告中的一个,带有 错误10 上面的修改) 到本地和当前 遗产 分支 (离开时要修改的那个 错误10 独自一人。

    现在:

    • 这涉及额外的回购(可能导致磁盘空间限制)
    • 总之,这相当于定义一个补丁并将其应用于 遗产 分支,因此其他答案(补丁)是有效的(并且更简单)。
    • 我在这个方法中看到的唯一优势是有机会定义一个遗留环境,在这个环境中您可以重新设置所需的内容(如 BUG10 提交),然后只推该分支 遗产 到原始回购(你不会推 BUG10 因为它的历史会被完全改写!)

    我只是想看看它是否有效,所以…让我们测试一下这种方法。
    (在旧的xp sp2上为git1.6.5.1,因为 Start-Transcript command )


    PS D:\> mkdir git
    PS D:\> cd git
    PS D:\git> mkdir tests
    PS D:\git> cd tests
    PS D:\git\tests> git init mainRepo
    

    我喜欢我不再需要的方法,首先创建git repo目录,然后输入它。 git init 你说什么? Since 1.6.5 :

    初始化 学会了 mkdir / chdir 当给定一个额外的参数(即 git init this “”。

    这太棒了!

    让我们创建3个文件,用于3个不同的目的。
    (例如,我将把每个分支的文件修改分开:在这里合并或重新平衡期间没有冲突。)

    PS D:\git\tests> cd mainRepo
    PS D:\git\tests\mainRepo> echo mainFile > mainFile.txt
    PS D:\git\tests\mainRepo> echo contentToBeFixed > toBeFixedFile.txt
    PS D:\git\tests\mainRepo> echo legacyContent > legacy.txt
    PS D:\git\tests\mainRepo> git add -A
    PS D:\git\tests\mainRepo> git ci -m "first commit"
    PS D:\git\tests\mainRepo> echo firstMainEvol >> mainFile.txt
    PS D:\git\tests\mainRepo> git ci -a -m "first evol, for making 1.0"
    PS D:\git\tests\mainRepo> git tag -m "1.0 legacy content" 1.0
    

    此时,A git log --graph --oneline --branches 返回:

    * b68c1f5 first evol, for making 1.0
    * 93f9f7c first commit
    

    让我们建立一个 遗产 分支

    PS D:\git\tests\mainRepo> git co -b legacy
    PS D:\git\tests\mainRepo> echo aFirstLegacyEvol >> legacy.txt
    PS D:\git\tests\mainRepo> git ci -a -m "a first legacy evolution"
    

    我们返回master,再提交一次,我们将标记“2.0”(一个需要修复bug的版本!)

    PS D:\git\tests\mainRepo> git co -b master
    PS D:\git\tests\mainRepo> git co master
    PS D:\git\tests\mainRepo> echo aMainEvol >> mainFile.txt
    PS D:\git\tests\mainRepo> git ci -a -m "a main evol"
    PS D:\git\tests\mainRepo> echo aSecondMainEvolFor2.0 >> mainFile.txt
    PS D:\git\tests\mainRepo> git ci -a -m "a second evol for 2.0"
    PS D:\git\tests\mainRepo> git tag -m "main 2.0 before bugfix" 2.0
    

    我们有:

    * e727105 a second evol for 2.0
    * 473d44e a main evol
    | * dbcc7aa a first legacy evolution
    |/
    * b68c1f5 first evol, for making 1.0
    * 93f9f7c first commit
    

    现在我们做一个 BUG10 错误修复分支:

    PS D:\git\tests\mainRepo> git co -b bug10
    PS D:\git\tests\mainRepo> echo aFirstBug10Fix >> toBeFixedFile.txt
    PS D:\git\tests\mainRepo> git ci -a -m "a first bug10 fix"
    PS D:\git\tests\mainRepo> echo aSecondBug10Fix >> toBeFixedFile.txt
    PS D:\git\tests\mainRepo> git ci -a -m "a second bug10 fix"
    

    让我们在主分支上添加最后一个提交

    PS D:\git\tests\mainRepo> git co master
    PS D:\git\tests\mainRepo> echo anotherMainEvol >> mainFile.txt
    PS D:\git\tests\mainRepo> git ci -a -m "another main evol"
    

    主要回购的最终状态:

    * 55aac85 another main evol
    | * 47e6ee1 a second bug10 fix
    | * 8183707 a first bug10 fix
    |/
    * e727105 a second evol for 2.0
    * 473d44e a main evol
    | * dbcc7aa a first legacy evolution
    |/
    * b68c1f5 first evol, for making 1.0
    * 93f9f7c first commit
    

    在这个阶段,我不会在Mainrepo做任何进一步的操作。我只克隆它来做一些测试。如果这些失败了,我总是可以回到这个回购并再次克隆它。

    第一个克隆实际上是强制的,以便执行 Git-Rebase--到

    PS D:\git\tests\mainRepo> cd ..
    PS D:\git\tests> git clone mainRepo rebaseRepo
    PS D:\git\tests> cd rebaseRepo
    

    我们需要克隆的repo中的两个mainrepo分支:

    PS D:\git\tests\rebaseRepo> git co -b bug10 origin/bug10
    PS D:\git\tests\rebaseRepo> git co -b legacy origin/legacy
    

    让我们只重新设置bug10(这是之后的所有提交 2.0 标记为 HEAD 属于 BUG10 分支机构) :

    PS D:\git\tests\rebaseRepo> git co bug10
    PS D:\git\tests\rebaseRepo> git rebase --onto legacy 2.0
    First, rewinding head to replay your work on top of it...
    Applying: a first bug10 fix
    Applying: a second bug10 fix
    

    在这一点上 BUG10 已在 遗产 没有所有其他中间承诺 .
    我们现在可以快进了 属于 遗产 到重播的顶部 BUG10 分支机构。

    PS D:\git\tests\rebaseRepo> git co legacy
    Switched to branch 'legacy'
    PS D:\git\tests\rebaseRepo> git merge bug10
    Updating dbcc7aa..cf02bfc
    Fast forward
     toBeFixedFile.txt |  Bin 38 -> 104 bytes
     1 files changed, 0 insertions(+), 0 deletions(-)
    

    内容遵循我们需要的:

    • 我们拥有所有的传统内容:

    PS D:\git\tests\rebaseRepo> type legacy.txt
    legacyContent
    aFirstLegacyEvol
    

    • 的内容 main 分支机构最多只有 1.0 标签(根目录) 遗产 分支) 不再进一步 .

    PS D:\git\tests\rebaseRepo> type mainFile.txt
    mainFile
    firstMainEvol
    

    • 以及 BUG10 修正如下:

    PS D:\git\tests\rebaseRepo> type toBeFixedFile.txt
    contentToBeFixed
    aFirstBug10Fix
    aSecondBug10Fix
    

    就是这样。
    我们的想法是把它“增强” 遗产 原始回购中的分支机构,仍将拥有 BUG10 不变(即仍然从 标记,而不是像我们在 rebaseRepo .
    在这个克隆的repo中,我跟踪 origin/legacy 分支,以便在其上合并 遗产 分支 另一个 远程来源: 低音提琴 .

    PS D:\git\tests\rebaseRepo> cd ..
    PS D:\git\tests> git clone mainRepo finalRepo
    PS D:\git\tests> cd finalRepo
    
    PS D:\git\tests\finalRepo> git co -b legacy origin/legacy
    

    在这个原始的repo中(我克隆它只是为了不干扰mainrepo的状态,以防我有其他实验要做),我将声明 低音提琴 作为一个遥控器,并获取它的分支。

    PS D:\git\tests\finalRepo> git remote add rebasedRepo D:/git/tests/rebaseRepo
    PS D:\git\tests\finalRepo> type D:\git\tests\finalRepo\.git\config
    [remote "origin"]
        fetch = +refs/heads/*:refs/remotes/origin/*
        url = D:/git/tests/mainRepo
    [branch "master"]
        remote = origin
        merge = refs/heads/master
    [branch "legacy"]
        remote = origin
        merge = refs/heads/legacy
    [remote "rebasedRepo"]
        url = D:/git/tests/rebaseRepo
        fetch = +refs/heads/*:refs/remotes/rebasedRepo/*
    
    PS D:\git\tests\finalRepo> git fetch rebasedRepo
    remote: Counting objects: 8, done.
    remote: Compressing objects: 100% (6/6), done.
    remote: Total 6 (delta 3), reused 0 (delta 0)
    Unpacking objects: 100% (6/6), done.
    From D:/git/tests/rebaseRepo
     * [new branch]      bug10      -> rebasedRepo/bug10
     * [new branch]      legacy     -> rebasedRepo/legacy
     * [new branch]      master     -> rebasedRepo/master
    

    我们现在可以更新 遗产 不接触 BUG10 以下内容:

    PS D:\git\tests\finalRepo> git merge rebasedRepo/legacy
    Updating dbcc7aa..4919b68
    Fast forward
     toBeFixedFile.txt |  Bin 38 -> 104 bytes
     1 files changed, 0 insertions(+), 0 deletions(-)
    

    您可以根据需要随时重复该过程 错误10 提交需要在旧的 遗产 分支,不包括所有中间提交。

        3
  •  1
  •   Amber    15 年前

    使用 git-diff 然后 git-apply ?