如何在git中的master分支上首次提交之前移动后创建分支?

时间:2017-04-13 11:04:25

标签: git git-rebase

我有我的主分支master和分支originalCodeoriginalCode分支的父级是master

                  F  originalCode
                 / 
A - B - C - D - E  master

现在我想在提交originalCode之前使用提交F移动A分支。 我已经尝试过变基和合并,但我无法让它工作,我找不到类似的问题。

目标是拥有一个共同的历史记录,以确切了解原始代码(某些脚本)的更改。当我开始使用签入时,我已经开始使用外部修改版本了。

2 个答案:

答案 0 :(得分:3)

我将如何做到这一点:

  1. 创建并切换到新分支reordered,该分支稍后将包含重新排序的提交,指向与F相同的提交(originalCode):

    $ git checkout -b reordered originalCode
    

    提交图现在看起来像这样:

                      F  originalCode, reordered
                     / 
    A - B - C - D - E  master
    

    这样masteroriginalCode保持不变。如果出现问题,您只需删除reordered并重新开始。

  2. reordered为基础,以F之前定位A互动地重新定位:

    由于A是根提交,因此您需要指定--root选项。

    $ git rebase -i --root reordered
    

    这将打开包含以下内容的文本编辑器:

    pick d14a5dd A
    pick 57b6bd9 B
    pick de4e672 C
    pick 6fc8c1f D
    pick 453da48 E
    pick d2443c0 F
    

    使用F剪切该行并将其粘贴到A的行上方。然后保存并退出编辑器继续。

    根据提交的实际内容,您可能需要在rebase期间解决合并冲突。

  3. 完成rebase后,提交图应如下所示:

                      F  originalCode
                     / 
    A - B - C - D - E  master
    
    F'- A'- B'- C'- D'- E'  reordered
    

    请注意,由于--root rebase,有两个系列的提交没有共同的祖先。

  4. 确保reorderedmaster之间的内容没有差异。

    $ git diff reordered master
    

    这不会产生任何输出。

    编辑:我怀疑您希望master的内容为“最新”版本,而不是originalCode的内容,因此我相应更改了diff。)

    如果存在差异,则在解决合并冲突时可能会出错。

    您还可以使用gitk等图形存储库浏览器检查各个提交。

  5. reordered分支的状态感到满意后,您可以删除originalCodemaster,然后将reordered重命名为{{1}或者,您可以将master移至与master相同的提交(E')并删除reorderedoriginalCode分支。

    reordered

    最终结果应该是这样的提交图:

    $ git checkout -B master reordered
    $ git branch -D reordered originalCode
    
  6. 解决一些评论者提出的问题:

    如果有其他人克隆了存储库并依赖于F'- A'- B'- C'- D'- E' master 分支,则不应删除或移动它,如上面的步骤5所示。

    相反(在第4步之后)我建议将新的master分支合并到reordered,以提供导致当前状态的替代历史,但同时保留原始历史记录:

    master

    结果:

    $ git checkout master
    $ git merge reordered
    $ git branch -d reordered
    

答案 1 :(得分:0)

您执行以下操作:

创建一个包含原始代码库的新根提交:

git checkout originalCode
git checkout --orphan originalCode2
git commit -m "Original code of project foo"

现在我们必须在这个新根的基础上移植导致master的历史记录。为此,我们在A

之上移植提交originalCode2
echo $(git rev-parse A originalCode2) >> .git/info/grafts

然后重写历史记录以使新的父母关系永久化:

git filter-branch master

现在你有了预期的历史。请注意,此会重写历史记录,并且有关已发布的重写历史记录的所有警告均适用。

最后,您应该删除.git/info/grafts的最后一行(已在上述步骤中编写)。它很可能是唯一的一行,然后您可以删除.git/info/grafts

有可能使用git rebase --root originalCode2 master或某些涉及--root而非filter-branch的变体,但我没有使用此rebase变体的经验。