Git rebase并发症

时间:2014-04-15 23:28:32

标签: git

在我们准备发布之前,我们的离岸开发人员意外地将发布分支合并为主。这使我们没有主分支,也没有释放修补程序的能力。我试图通过一个改变来解决这个问题,但是我不太明白发生了什么,我希望有人可以解释它。 (如果有更好的方法可以做到这一点)

发布分支是从master(在A点)创建的,
几个特征分支合并到它(创建点B)。 - 到目前为止一切顺利 发布分支合并为主(坏!)快进主站到点B.
在master(hotfixes,correct)上完成的工作将master带到C点(从B开始) 在Release上完成的工作(错误修正,正确)将Release发布到D点(来自B)。

我想要实现的是将B的变化带到A点,这样A到B的变化就不再包含在C点(但D点保持不变)。

我从A点(new_Master)创建了一个新分支,并且这样做了:
git rebase --onto new_Master Release master

这就是我想要的,即在new_Master上的A点之后创建了一些新的变更集(将它带到E点),但是它将new_Master分支留在A点,我无法弄清楚如何移动标签到新的HEAD。它还将主分支留在旧点C,但我期望它至少回滚到B点,因为这些变化根本不应该在那里。所以我最终得到了两个代表相同变化的签到,一个是A的孩子,另一个是B的孩子。

问题: 1)如何将new_Master标签移动到E点。
2)如何提交和推动这些更改以将其交给团队的其他成员? 3)为什么大师仍然坐在C点? (为什么C点仍然存在?)
4)如何让主标签移动到E点(如果可能) - 现在位于不同的分支上?
5)这显然不是应该如何完成的 - 那么解决将Release合并到master中所犯错误的正确方法是什么?

原图
C D(Master C,Release D)
3 |
| 2
B /
1

最终图表
E
3
| C D(Master C,Release D)
| 3 |
| | 2
| B /
| 1
| /
A(new_Master)

我想去的地方:

E(大师,理想情况下,我很高兴new_Master指向这里))
3
| D(释放)
| 2
|乙
| 1
A /

3 个答案:

答案 0 :(得分:2)

1)git checkout new_Master后跟git reset --hard <sha1 of E>

2)取决于您想与团队分享的内容。如果您只想分享新的new_Master,那么您显然可以执行类似git push origin new_Master的操作,但我猜测您对将master更加感兴趣怎么应该在主要回购?如果是这样,您可以执行以下操作(包含有关公布可见分支的所有常规警告)

使用新的,正确的master强行覆盖主回购中的损失new_Master(再次,请务必确定您知道此处发生了什么)

git push origin new_Master:master -f

然后,让每个人使用回购在家里做以下事情:

git checkout master
git reset --hard <sha1 of A>
git pull origin master

这将为他们留下一个看起来像你的新new_Master分支的主分支。

3)git rebase --onto new_Master release master应该master更改为E。我不确定这里发生了什么。

4)git reset --hard <sha1 of E>在主人身上。请注意,由于历史记录不同,您无法将本地仓库中的主人推送到您的共享仓库中(参见2)

5)是的。我们走了:

掌握主人,以便我们可以从中分支

git checkout master 

C创建分支,以便我们在下一步中不会丢失对它的引用

git branch master_backup 

master移回A.由于最后一步,我们不会失去C

git reset --hard <sha1 for A>

然后将BC的更改添加到master。这里release master_backup指定&#34;找到releasemaster_backupB)的共同祖先,并从那里获取所有提交,直到master_backup为止指向(C)&#34;

git rebase --onto master release master_backup
git checkout master
get merge master_backup

master现在包含A之前的所有内容,以及BC之间的提交。据我所知,release应该仍然准确无误,无需更改。

答案 1 :(得分:1)

听起来,老实说,你想要办理revert的办理登机手续。重新定位将重写提交的历史记录,使其“从未发生过”#34; - 但是在清理提交时让你有点头疼。

git revert允许您执行的操作是撤消合并(或可能是任何其他提交)引入的更改。如果您以后决定要进行这些更改,则必须还原还原(实际上,还原还原SHA)。

答案 2 :(得分:1)

1)如何将new_Master标签移动到E点。

git checkout new_Master
git reset --hard <sha1 of E>

这会将new_Master移动到与E相同的位置。您之前的命令git rebase --onto new_Master Release master移动了主分支上的提交,但不移动Release(即,我读取时提交3) new_Master。

2)如何提交并推送这些更改以将其发送给团队的其他成员?

git push <remote>

3)为什么大师仍然坐在C点? (为什么C点仍然存在?)

master只是一个指针,就像new_Master一样。您可以将指针移动到任何您喜欢的位置,甚至可以及时移动。当你改变时,它不会自动完成;只是移动了你重新定位的点。要更改分支指向的位置,请检查分支,然后使用git reset

4)如何让主标签移动到E点(如果可能) - 现在位于不同的分支上?

假设您想要移动new_Master,最简单的选项是

git checkout new_Master
git branch -d master
git reset --hard <sha1 of E>
git branch master

这将删除master,将new_Master移动到你想要的位置,然后从new_Master创建一个新的master分支。

5)这显然不是应该如何完成的 - 那么解决将Release合并到master中所犯错误的正确方法是什么?

很多方法。我可能不会像其他人所建议的那样恢复;不是因为它错了(它没有错),仅仅是因为我对这个名字并没有任何强烈的依恋&#34; master&#34;。我认为你的方法对我来说已经足够了,我只是按照我认为的更多&#34; seft documenting&#34;方式。

  1. Checkout master。
  2. 创建一个新分支,可能是bad-merge
  3. 将master重置为A.
  4. git rebase --onto master Release bad-merge
  5. 注意sha-1。
  6. git checkout master
  7. 将master重置为新sha-1。
  8. 如果我遇到这种情况,这会让我想要它的方式。