首页 > 解决方案 > 用重写提交历史的分支强制更新“main”的正确方法是什么?

问题描述

编辑:谢谢大家的回答。只是强制覆盖远程文件是我知道会发生的事情,git push --force但我更关注保留提交历史记录main(再次,我希望重写提交历史记录 - 不一定有新文件覆盖远程文件) - 但在阅读之后通过答案,我意识到我忘记了强制推送如何用我的本地分支覆盖远程,包括提交历史

这一切都始于我注意到有人在历史记录中进行了合并提交,而不是像他们应该做的那样进行变基

我按照这个先前回答的问题来解决这个问题,也就是说,以一种重新设置基准而不是合并提交的方式重写提交历史。这种重写只是在本地分支上完成的,我确认代码仍然按预期构建/工作,并且HEAD我的分支和main匹配项都是。唯一的区别是从提交c开始的实际提交对象(见下图) - 但我理解为什么这会产生问题,我现在在我的分支上有一个完全不同的历史

问题是:我现在想做什么?由于我重写了提交历史,我的本地分支已经偏离了origin/main预期。在我的脑海中,我只想拿起我的分支并强制推送到main具有main我在此分支上编写的新历史的内容

main我理解以这种方式重写历史可能是非常不鼓励的——但是如果想要清理没有任何合并提交的历史,是否有适当的方法来处理这样的事情?

我采取的步骤:

  1. 本地存储库的main分支的历史记录如下所示:
a   b   d   e   f   g   h   i   j   k
o---o---o---o---o---o---o---o---o---o
  \---o---/
      c

HEAD在哪里k和合并提交是e- 目标是重新定位 c并完全d删除e

  1. 从中签出一个本地分支main,使其反映上述提交历史
  2. 在我的本地分支上,重新定位到a因为那是发生分歧的地方
$ git rebase -i <sha of a>
  1. 在交互式变基中,选择c进行编辑并e完全删除
  2. 解决了合并冲突并逐步执行git rebase --continue命令,直到我的本地分支如下所示,我又回到了HEAD. 由于变基重写了历史,因此之后的提交c是完全不同的对象,但实际上与远程存储库中的内容没有任何不同的内容
a   b   d   c   l   m   n   o   p   q
o---o---o---o---o---o---o---o---o---o
  1. 观察以下内容git status
$ git status
On branch cleanup
Your branch and 'origin/main' have diverged,
and have 6 and 7 different commits each, respectively.
  (use "git pull" to merge the remote branch into yours)

nothing to commit, working tree clean

这又是预期的。我关心的是如何继续,也就是说,强制更新main分支以获得我现在在本地分支上拥有的更清晰的历史记录

标签: gitbitbucketdevopspull-request

解决方案


如果您想强制在遥控器上重写您的历史记录,您将不得不强制推送您的更改。

  1. 在您的本地结帐时,您清理了主要的
  2. 做一个git push -f origin main。这将用您在本地创建的远程主目录重写

陷阱:

  1. 任何克隆或更新了 repo 的人都会有不同的历史记录。他们将不得不获取并硬重置他们的本地 main 到一个新的 origin/main。您必须确保发生这种情况。否则,如果其他人强行推动,那么您的历史就会一团糟。
  2. 当你用力推。如果在您上次进行更新后有任何更改被推送到远程。他们会迷路的。

个人经验:在过去,甚至我都沉迷于没有合并提交和重新定位所有内容。随着时间的推移,我意识到它被高估了。这不是我们应该花时间担心的事情。合并提交也很好(而且很漂亮)。


推荐阅读