将主要的初始提交移到Git中的另一个分支

时间:2014-08-25 14:26:14

标签: git

我正在尝试迁移到GitFlow工作流程,我想重写存储库的历史记录,以便所有存储库都符合新的存储库。

目前它看起来像这样:

Master: A - B - C - D - E - F - - - - - - - - - L
                             \                 /
Release:                      \           J - K
                               \         /     \
Development:                    G - H - I       M

我希望它看起来像这样:

Master:  A - - - - - - - - - - - - - - - - - - - L
          \                                     /
Release:   \                               J - K
            \                             /     \
Development: B - C - D - E - F - G - H - I       M

我已经尝试在这里搜索答案了,我找到了answer,但是如果你要创建新的分支,而不是使用已经存在的分支,它似乎才有效。

非常感谢提前。

2 个答案:

答案 0 :(得分:10)

在Git中,正如his comment中的larsmans所指出的,分支只是指向特定提交的指针/引用。像在图表左侧那样使用分支名称标记代码行可能会造成混淆。

例如,在过去,提交GHI只是development分支的祖先的一部分可能是真的。 。但是,在您的仓库的当前状态下,它们属于所有三个分支(masterdevelopmentrelease)的祖先。

认为这三个提交(GHI)在某种程度上仍然与development分支相关,而不是{master分支。 1}}或release不再有任何意义,只是因为你的回购不记得过去分支引用指向的位置(尽管该信息存储在本地存储在名为 reflog的东西中)。你的Git repo只知道分支引用在当前指向的位置。

因此,当您绘制图形来描述您的repo所处的状态时,如果分支指向提交,则使用相应的分支名称标记提交本身更有意义。我在下面的所有图表中都这样做了。

原始状态

A - B - C - D - E - F - - - - - - - - - L [master]
                     \                 /
                      G - H - I - J - K [release]
                                       \
                                        M [development]

期望状态

A - - - - - - - - - - - - - - - - - - - L' [master]
 \                                     /
  B - C - D - E - F - G - H - I - J - K [release]
                                       \
                                        M [development]

要结束此状态,您应该执行以下三个步骤。

程序

1 - 查看您的master分支

git checkout master

之后,HEAD指向master

A - B - C - D - E - F - - - - - - - - - L [HEAD -> master]
                     \                 /
                      G - H - I - J - K [release]
                                       \
                                        M [development]

2 - 执行master的硬重置以提交A

git reset --hard <commit_ID_of_A>

由于您的回购邮件中的任何引用都无法再访问L,因此它会消失&#34;从历史图表中,您只需要留下

A [HEAD -> master]
 \
  B - C - D - E - F - G - H - I - J - K [release]
                                       \
                                        M [development]

3 - 将release真正合并到master

在这个阶段,如果你只是简单地运行

git merge release

因为master的提示是release提示的祖先,所以会发生快进合并,而您最终会以

结尾
A - B - C - D - E - F - G - H - I - J - K [HEAD -> master,release]
                                         \
                                          M [development]

这不是你想要的。因此,需要--no-ff选项来强制执行真正的合并:

git merge --no-ff release

在最后一个命令之后,你的回购应该处于所需的状态:

A - - - - - - - - - - - - - - - - - - - L' [HEAD -> master]
 \                                     /
  B - C - D - E - F - G - H - I - J - K [release]
                                       \
                                        M [development]

请注意,我昵称新提交L'而不是L,因为这两个提交有不同的父母:L的父母是FK ,而新提交的父母L'AK

答案 1 :(得分:1)

这应该做你想要的,(虽然我不确定你的发布分支)

git checkout master
git reset --hard commit_A # the commit id for A

git merge --no-ff release