git rebase并保留所有子分支

时间:2013-09-25 19:22:52

标签: git

我正在尝试将CVS存储库导入git。不幸的是,我们一直在使用一种从CVS仓库创建版本的非常古老的方法,它不涉及任何实际的CVS分支或标记,而是将这些信息保存在单独的系统中。因此,几乎所有的开发都发生在CVS主干上。因此,可以在历史的早期添加一个文件,但不会在6个月内成为发布的一部分。

我想做的是将这个CVS repo导入git,并使用rebasing将这些提交移动到开发分支。我确实有一些来自CVS的分支,所以我真的想移动所有分支。

说我有这个:

                  F---G---H topic
                 /
A---B---C---D---E---I---J master

B是我想要移动到自己的分支的提交。我希望结果看起来像这样:

                F`---G`---H` topic
               /
A---C`---D`---E`---I`---J` master
 \
  B some_unfinished_feature

但仅限master的结果会导致:

git checkout -b some_unfinished_feature B
git rebase --onto A B master

A---C`---D`---E`---I`---J` master
 \
  \               F---G---H topic
   \             /
    B---C---D---E
     \-some_unfinished_feature

我可以在一个rebase命令中使用git将topic重新绑定到E'吗?我可能有很多分支,我想转移到相应的新提交。或者我有办法在EE'之间建立映射吗?

4 个答案:

答案 0 :(得分:2)

               F---G---H topic
              /
 A---B---C---D---E---I---J master

 git checkout B
 git branch BRANCH-B
 git checkout master
 git rebase -i  HEAD~6

(删除提交B)

 git rebase --onto D' D topic

这应该假设没有冲突;)

答案 1 :(得分:0)

移动topic的命令是:

git rebase --onto E' E topic

不幸的是,没有办法自动为一堆不同的分支做这个,这是设计的。每个rebase都可能引入必须手动解决的冲突。

或者,您可以将git filter-branch与配置管理软件一起使用来编写所需的更改,但这可能会带来很多工作。将master保留为开发分支可能更有意义,并使用filter-branch创建发布分支,而不是相反。

答案 2 :(得分:0)

首先,提出建议:在重新布线时,使用临时分支:

git branch wip_topic
git checkout wip_topic

成功完成rebase(并检查它是否有效......)后,您可以将原始头部移动到工作提交中:

git checkout topic
git reset --hard wip_topic
git branch -d wip_topic

(如果你没有,而且发生了一些不好的事情,git reflog仍可以保存你的培根......)


当进行rebase时,git会跳过commit的文本diff与目标分支上的现有提交匹配的提交。

如果您的master rebase未引入太多冲突,请应用:

git rebase --onto A B wip_topic

应该给你想要的结果。

通常,大多数冲突都会出现在已重新定位的提交列表的“开头”附近(< - 捏盐)。 假设您在构建提交C'时遇到了冲突,但之后没有冲突,您可以重新定义C..topic部分:

git rebase --onto C' C wip_topic

无论如何:尝试一下,看看git的黑魔法是什么。

答案 3 :(得分:0)

在您的问题中,您希望从C提交开始。 B保留为基于A的分支。

首先我们应该给它起名字:

git branch -b some_unfinished_feature <B-ish>

此命令将从some_unfinished_feature提交开始创建<B-ish>分支。

<C-ish>位于上游。您可以查看所有要重新提交的提交:

git log <C-ish>..topic

您可以注意到IJ不会被重新定位,因为它们是不同的分支。你应该稍后再单独重新定位。

现在从topic开始将您的<A-ish>改为<C-ish>

git rebase -p --onto <A-ish> <C-ish> topic

-p标记将保留从<C-ish>topic

的任何合并

完成此命令后,您将获得:

       some_unfinished_feature
     /
A---B---C---D---E---I---J master
  \
   C`---D`---E`
              \   
                F`---G`---H` topic

现在您应该从master

<E-ish>重新加入<I-ish>
git rebase -p --onto <E-ish> <I-ish> master

瞧:

A---B some_unfinished_feature
  \
   C`---D`---E`--I`---J` master
              \   
                F`---G`---H` topic