如何将git存储库与相关分支合并

时间:2013-05-24 08:07:32

标签: git merge repository branch

由于历史原因,我目前有以下项目结构:

  • PART0:

    • branch0
    • BRANCH1
  • 1部分:

    • branch0
    • BRANCH1

项目的二进制文件是通过从两个存储库中检出同一日期的提交来构建的,因此我需要例如part0 - master(01.04.2013)和part1 - master(01.04.2013)。检查不同日期的部件无法正常工作。

我现在想要将这两个存储库合并为一个结构

  • 梳:
    • branch0
    • BRANCH1

其中master中的提交是按照part0 - master和part1-master的提交日期排序的。

如果我使用我发现的描述合并方案,我将获得

的历史记录
  

part0 - master(everything)+ part1 - master(everything)之后

因此,任何提交的结账都不会起作用,因为要么我只得到part0(在合并part1之前),要么我得到最新的part0 - master与过时的part1 - master。

1 个答案:

答案 0 :(得分:2)

我终于在上面发布的链接中解决了这个问题。首先是图片中的问题:

repo0: A -- B -- C -- D -- E
             \
              F -- G -- H

repo1: A' -- B' -- C' -- D' -- E'
              \
               F' -- G' -- H'

如果提交A和A'对应并且以正在运行的形式获得项目,则需要同时将A和A'签出到各自的目录中,例如proj0和proj1。

在存储库中,文件和目录放在/.

目标存储库应如下所示:

A -- A' -- B -- B' -- C -- C' -- D -- D' -- E -- E'
                 \
                  F -- F' -- G -- G' -- H -- H'

所以我首先将存储库的所有内容提交到最终目录中(当然是副本):

git clone --mirror path/repo0 repo0
git filter-branch --tree-filter "(mkdir -p proj0 ; find * -maxdepth 0 ! -iname proj0 -exec mv {} proj0/ \;)" -- --all

git clone --mirror path/repo1 repo1
git filter-branch --tree-filter "(mkdir -p proj1 ; find * -maxdepth 0 ! -iname proj1 -exec mv {} proj1/ \;)" -- --all

现在我可以合并这两个,首先我创建一个新的存储库,旧存储库作为遥控器:

git init new
git remote add proj0 path/repo0
git remote add proj1 path/repo1

git fetch --all

然后我按分支合并,我只将它们命名为BranchE和BranchH。由于它们从项目开始就存在,我必须得到第一次提交,这是通过虚拟分支完成的:

git checkout -b dummy remotes/proj0/BranchE
git checkout -b start `git log --topo-order --reverse | head -n 1 | sed s/"commit \(.*\)"/"\1"/`
git checkout -b merge start

git merge -m "merge" remotes/proj1/BranchE
git rebase --onto start start merge

git branch -D start
git branch -D dummy
git branch -m merge BranchE

我为BranchH做了同样的事情。直到现在的缺点是,histroy现在看起来像这样:

A -- A' -- B -- B' -- C -- C' -- D -- D' -- E -- E'
 \
  \
   \
    A' -- B -- B' -- F -- F' -- G -- G' -- H -- H'

最后要做的是将历史的相似部分组合在一起,这是通过以下命令完成的:

git checkout BranchE
git rebase `git log --oneline | grep "commit comment of last common commit B'" | sed -r s/"(^[a-f0-9]+) .*"/"\1"/` BranchH

Etvoilá,你得到了理想的结果。