如何在不使主分支中的主题提交的情况下重新定位到主题分支

时间:2015-10-22 21:26:49

标签: git git-rebase

我有一个相当标准的用例,我将从我的主分支(主)创建一个主题分支,并且在未来的道路上,我希望更改我自创建以来引入master的主题分支主题分支,以确保我有最新的代码。我不喜欢我的主题分支中的合并提交,所以我更喜欢将master中的提交重新绑定到主题分支,而无需将主题分支的更改放入master。有没有办法从主服务器转换到主题分支与rebase,而不必将主题的提交应用于主服务器?或者合并我唯一的选择?

感谢。

1 个答案:

答案 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'是原始FG的“副本”,这只会在下面的“叉点”内容中真正起作用。)您必须然后强制推送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之后。)