我有一个相当标准的用例,我将从我的主分支(主)创建一个主题分支,并且在未来的道路上,我希望更改我自创建以来引入master的主题分支主题分支,以确保我有最新的代码。我不喜欢我的主题分支中的合并提交,所以我更喜欢将master中的提交重新绑定到主题分支,而无需将主题分支的更改放入master。有没有办法从主服务器转换到主题分支与rebase,而不必将主题的提交应用于主服务器?或者合并我唯一的选择?
感谢。
答案 0 :(得分:1)
普通的rebase
可以做到这一点。如果您是主题分支的唯一开发人员,并且您只使用一个系统进行开发(以及用于备份的中央服务器),则可以轻松地强制推送您的重新定位的主题分支。
例如,昨天你有:
F - G <-- topic
/
... E - H - I <-- master
今天您确定master上的提交I
非常I
对您的主题非常重要,您希望topic
重新定位到master,所以(在分支topic
上)你运行:
git rebase master
这样做:
F - G [abandoned]
/
... E - H - I <-- master
\
F' - G' <-- topic
在您自己的存储库中。 (提交F'
和G'
是原始F
和G
的“副本”,这只会在下面的“叉点”内容中真正起作用。)您必须然后强制推送topic
,如果你在其他地方复制它,这会增加一些风险:
topic
?更糟糕的是,如果其他人也在做这个rebase并且有自己的额外提交J
并且已经进行了强制推送,那么集中式备份服务器具有:
... E - H - I <-- master
\
F' - G' - J <-- topic
嗯,如果没有“别人”,那么这些都不可能发生,你没事。
你需要另一种选择。你当然可以使用合并或挑选。但你仍然可以使用rebase,提供你和所有“别人”同意这可能发生。然后你需要(或者至少强烈要求)一些新的git工具:
--fork-point
--force-with-lease
--fork-point
做了什么聪明起来git rebase
,以便你可以采取一个移动的主题分支,并使用你自己的reflog来找出哪些提交被复制,这样你就可以自己修改你自己的工作而不是别人的。它并不完美,但这是一个很大的帮助。
--force-with-lease
所做的可能是最重要的。假设您正在执行上面的rebase
,而其他人已经完成了rebase并添加了新的提交J
。当你转到git push
重新定位的topic
时,你告诉你的git和中央服务器git,你想让topic
指向服务器上提交G'
,,但前提是它当前指向服务器上的G
。在这种情况下,“其他人”会将您击败为强制租用推送,因此在服务器上,topic
现在指向提交J
。这会使您的强制租赁推送失败,然后您可以运行git fetch
并找出发生的情况并相应地协调您自己的工作。
(请记住,每个单个大写字母代表一些独特的40个字符的SHA-1。如果您在复制的F'
和G'
上面有新的提交,您仍然可以认为该服务器使用你在提交G
中拥有的ID,它一切正常:服务器确实有这个ID,因为没有其他人推,或者没有,因为其他人推了。这是唯一的两个服务器端的可能性。但是,你必须非常小心,因为在git fetch
yor origin/topic
现在指向提交J
之后。)