所以我的历史看起来像这样:
o---o---o---o master
\
o---o---o A
\
o B
所以,解释一下:
A
是从master
B
A
(只有1次提交)
我想要的是:
o---o---o---o master
\
o---o---o A
\
o B
我做的是:
1)。
git checkout A
git rebase master
这导致了很多冲突,经过一段时间的修复后,出现了以下历史:
o---o---o---o master
\
o---o---o A
这正是我想要的。
(我不知道B
现在在哪里)
2)。
在此之后我做了很多南瓜并改变了A
的提交顺序,使历史看起来像我想要的。
3)。
现在,我还想做的是:
git checkout B
git rebase A
然而,这似乎不起作用,我不知道为什么。如果我git log
,我会在执行第1步之前看到那些提交。
另外,我得到了我在第1步已经解决过的大量冲突。我花了很多时间做这件事,不想再这样做了。
This example建议使用--onto
,我这样做了:
git checkout B
git rebase --onto A
但是这会完全删除B
上的提交,并使A
和B
指向同一个提交,即A
上的最后一个提交。
我的问题是:如何才能有效地将B关闭A以使其看起来像B从A 开始? (这在开始时确实如此)。
我最好的猜测是我使用--onto
错了。或者我应该使用别的东西(比如cherry-pick
)。
答案 0 :(得分:31)
对的简短回答如何才能有效地将B关闭A以使其看起来像B从A开始? 假设您想要移动一个提交:
git rebase --onto A B~ B
如果你想移动多一个提交使用:
git rebase --onto A old_A B
答案的其余部分。
您的B分支仍然存在(您可以查看),但其父级仍然是A
之前的确切提交对象。
看到我使用的图形表示:
git log --graph --decorate --all
查看所有分支机构以及它们相互之间的位置。
你原来拥有的东西:
o---o---o---o master
\
o---o---o A
\
o B
你现在拥有什么:
o---o---o-----------o master
\ \
o---o---o(B~) o---o---o A
\
o B
在使用--onto
方面,您需要有一个起点和一个终点。
使用方法:
git rebase --onto [target] [rebasing stops] [rebasing head]
git rebase --onto A B~ B
你得到了什么:
o---o---o----------o master
\ \
o---o---o o---o---o A
(old_A) \
o B
[branch_name]~
表示分支的父提交。
B~
是您不想更改的分支。 (它恰好是旧的A
)
或者,如果B是唯一一个将A作为父级的提交,(即,B是从master分支的提交链的末尾),则可以执行
git checkout B
git rebase master
git checkout B~ # this is the commit before B (the A commit)
git branch -d A # remove the old A branch (it was rebased, and so is now invalid
git branch A # recreate the A branch on the commit that is based on the original A
答案 1 :(得分:5)
我在git flow中遇到了同样的问题,并且我找到了一种最快,最好的方法。
(1)开始时的项目历史记录:
master ---A---B---C
\
D---E---F feature1
\
G---H feature2
(2)将feature1重新设置为主节点并强制按下:
master ---A---B------------------------C
\ \
D---E---F feature1(old) D---E---F feature1
\
G---H feature2
(3)将feature2改编为featrue1(新的)
master ---A---B---C
\
D---E---F feature1
\
G---H feature2
最困惑的部分是如何做(3) ..但没有人对此有明确的答案。
我相信很多人都遇到了与我相同的问题,当我们尝试进行“重新设置基础”时,我们发现 feature1(old)实际上不存在!
git rebase --onto feature1 feature1(old) feature2
解决方案是改用下面的方法:
git rebase --onto feature1 feature1@{1} feature2
语法feature1 @ {1}表示“ rebase之前Feature1的最后一个已知状态”,答案可参考https://coderwall.com/p/xzsr9g/rebasing-dependent-branches-with-git
答案 2 :(得分:1)
如果你已经重新开始A.应该是B就在你离开的地方。 A的分支(指针)只是移动到它的新位置。
如果你建议的话,我建议有效地将B变为A的是使用'cherry-pick'。此命令尝试将提交中所做的更改应用于运行它的分支。
因此,如果B最初指向的提交的提交ID为“123456”,那么我建议将当前的“B”移动到与git branch -f B A
的新“A”相同的位置,然后运行{{ 1}}将更改应用到A。
我相信git cherry-pick 123456
标志用于设置应用提交的目标位置。默认为“上游”(来源:http://git-scm.com/docs/git-rebase)。
我喜欢考虑rebase命令的方式如下:
--onto
使用它,将B重新绑定到master上然后将A指向B之前的提交可能更简单。
git rebase --onto <Starting here> <Apply all commits from HERE> <TO HERE>
(因为起点( - 多)隐含'主')
然后使用git rebase master B
(^表示'父母')