假设我有以下场景:
o (master)
/ o--o (WIP1)
/ /
o--o--o--o--o--o (WIP2)
(X) \
o--o (WIP3)有没有一个git命令可以创建一个新的分支,使其包含分支X之后的子树?我想执行一个“大型rebase",我想要基于master的三个WIP分支。
我知道我可以使用一些Bash脚本来做到这一点,但是我想知道如何使用git命令来做到这一点。
发布于 2013-01-25 00:14:17
没有单一的git命令可以做到这一点。你将不得不做一些体力劳动。在你的情况下:
o (master)
/ o--o (WIP1)
/ /
X--o--o--B--o--o (WIP2)
\
o--o (WIP3)首先将WIP1重新设置为master:
git rebase --onto master X WIP1这将导致以下结果:
o--o (WIP1)
(master) /
o--o--o--B’
/
/
X--o--o--B--o--o (WIP2)
\
o--o (WIP3)如果你现在运行git rebase --onto master X WIP2,你会得到这样的结构:
o--o (WIP1)
(master) /
o--o--o--B’
/ \
/ o--o--B’’--o--o (WIP2)
/
X--o--o--B--o--o (WIP3)这可能不是您想要的,所以现在您应该在B’上重新设置WIP2和WIP3的基础
git rebase --onto B’ B WIP2
git rebase --onto B’ B WIP3 这将导致以下结果:
o--o (WIP1)
(master) /
o--X--o--o--B’--o--o (WIP2)
\
o--o (WIP3)发布于 2017-08-24 20:13:51
我已将此问题标记为重复。我将使用您的示例编写我解释过的the other answer。
对于这种用例,我使用的方法是将所有要移动的分支合并到一个公共的人工节点中,然后使用带有--preserve-merges选项的rebase命令。合并所有分支将公开一个端点,该端点将用作rebase --onto的最终输入参数。起始点通常是显而易见的,子树的原点要移动。
在合并以获得子树端点时,应明确避免冲突。因此,应指示合并命令使用-Xours选项自动求解它们。合并结果并不重要,因为这些人工合并节点将在rebase之后被丢弃。
为了不丢失原始引用,建议创建一个新的分支包。在上面的示例中,将执行以下命令:
$ git checkout -b pack WIP1 # create new branch at 'WIP1'
$ git merge -s recursive -Xours WIP2 # merges WIP2 into pack (node p2)
$ git merge -s recursive -Xours WIP3 # merges WIP3 into pack下面可以看到这棵树会变成什么样子。通过合并创建了两个新的人工节点p2和pack。
o (master)
/
/ (WIP1) (p2)
/ o-----o-----o----o (pack)
/ / / /
o--o--o--o-----o-----o / (WIP2)
(X) \ /
o------------o (WIP3)现在是时候重新建立基础了。由于现在所有分支(pack)都有一个公共端点,因此很容易使用以下命令移动整个子树:
$ git rebase --preserve-merges --onto master X pack这会产生这样的结果:
(WIP1') (p2')
o-----o-----o----o (pack')
(master) / / /
o----o----o--o--o-----o-----o / (WIP2')
(X) \ /
o------------o (WIP3')现在是重新排列引用的时候了。我不知道为什么,在某些情况下,引用会移动,而在另一些情况下则不会。为每个引用WIP1、WIP2、WIP3或您需要的任何内容键入以下内容:
$ git checkout WIP1
$ git reset --hard <WIP1' hash>最后,去掉为生成公共子树端节点而创建的人工提交。
$ git branch -D pack
$ git branch -D p2 # if there is any所以最后的树应该是:
(WIP1')
o-----o
(master) /
o----o----o--o--o-----o-----o (WIP2')
(X) \
o------------o (WIP3')发布于 2013-01-24 23:29:57
o (master)
/ o--o (WIP1)
/ /
o--p--p--o--o--o (WIP2)
(X) (Y)
\
o--o (WIP3)这应该是一个rebase --onto (您可以在“How to move certain commits to another branch in git?”中看到一个示例):
git rebase --onto master X WIP1
git rebase --onto master X WIP2
git rebase --onto master X WIP3 p'--p'--o--o (WIP2)
/
o-----o-----p--p--o--o--o (WIP1)
(X) (master) (Y')
\
p''--p''--o--o (WIP3)因此,第一个rebase是可以的,但您需要获得Y SHA,并且:
git rebase --onto Y' Y WIP2
git rebase --onto Y' Y WIP3https://stackoverflow.com/questions/14504029
复制相似问题