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

p0l*_*ard 6 git

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

目前它看起来像这样:

Master: A - B - C - D - E - F - - - - - - - - - L
                             \                 /
Release:                      \           J - K
                               \         /     \
Development:                    G - H - I       M
Run Code Online (Sandbox Code Playgroud)

我希望它看起来像这样:

Master:  A - - - - - - - - - - - - - - - - - - - L
          \                                     /
Release:   \                               J - K
            \                             /     \
Development: B - C - D - E - F - G - H - I       M
Run Code Online (Sandbox Code Playgroud)

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

提前谢谢了.

jub*_*0bs 10

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

例如,它可能是真实的,在过去,承诺G,H以及I是该家系的一部分development唯一分支机构.然而,在你的回购的当前状态,它们属于所有三个部门的祖先(master,development,和release).

认为那三个提交(G,HI)在某种程度上仍然与development分支相关而不是master或者release不再有任何意义,仅仅因为你的repo不记得过去分支引用指向的位置(虽然该信息存储在本地存储在称为reflog的东西中.你的Git repo只知道分支引用在当前指向的位置.

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

原始状态

A - B - C - D - E - F - - - - - - - - - L [master]
                     \                 /
                      G - H - I - J - K [release]
                                       \
                                        M [development]
Run Code Online (Sandbox Code Playgroud)

期望的状态

A - - - - - - - - - - - - - - - - - - - L' [master]
 \                                     /
  B - C - D - E - F - G - H - I - J - K [release]
                                       \
                                        M [development]
Run Code Online (Sandbox Code Playgroud)

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

程序

1 - 检查你的master分支机构

git checkout master
Run Code Online (Sandbox Code Playgroud)

之后,HEAD指向master:

A - B - C - D - E - F - - - - - - - - - L [HEAD -> master]
                     \                 /
                      G - H - I - J - K [release]
                                       \
                                        M [development]
Run Code Online (Sandbox Code Playgroud)

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

git reset --hard <commit_ID_of_A>
Run Code Online (Sandbox Code Playgroud)

因为L您的仓库中的任何引用都无法再访问它,它会从历史图表中"消失",而您只是留下了

A [HEAD -> master]
 \
  B - C - D - E - F - G - H - I - J - K [release]
                                       \
                                        M [development]
Run Code Online (Sandbox Code Playgroud)

3 - 真正release融入master

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

git merge release
Run Code Online (Sandbox Code Playgroud)

因为尖端master是尖端的祖先,所以release会发生快进合并,你最终会得到

A - B - C - D - E - F - G - H - I - J - K [HEAD -> master,release]
                                         \
                                          M [development]
Run Code Online (Sandbox Code Playgroud)

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

git merge --no-ff release
Run Code Online (Sandbox Code Playgroud)

在最后一个命令之后,您的repo应该处于所需的状态:

A - - - - - - - - - - - - - - - - - - - L' [HEAD -> master]
 \                                     /
  B - C - D - E - F - G - H - I - J - K [release]
                                       \
                                        M [development]
Run Code Online (Sandbox Code Playgroud)

请注意,我绰号新的提交L',而不是L因为这两个提交有不同的父母:父母LFK,而新的父母承诺,L'AK.