我已经创建了一个项目的分支,并为我们的master
添加了~40次提交。在某些时候,我不假思索地用强制推动重写了历史,因为我无法“毫无理由地”推动,有时你只是想看到世界燃烧。
现在一切都很好,但是upstream
的最后约100次提交也在我的回购中不再被认为是相同的:我看到“提前240次提交”而不是“提前40次提交”。
是否有可能获取上游主服务器并重新设置我们的主服务器上的提交,并强制将其推回到我们的主服务器上,以便我们和他们的所有以前的提交同步,除了我的?如果是这样,怎么样?请具体说明。
我假设你有一个干净的沙箱,origin
指向你的分叉,你可以通过不同的URL访问上游仓库。我还假设沙箱中的origin/master
和master
是同步的。
有了这些假设,这应该有效:
git remote add upstream <upstream_url>
git fetch upstream
git checkout master
git rebase upstream/master
希望rebase可以工作,不会引入任何重复的提交。如果没有,它甚至可能会突出显示为什么你必须首先强行推动。
在开始使用rebase之前,git log --graph --decorate --all
(或gitk -all
或任何其他显示完整图形的可视Git日志替换)可能会显示您遇到问题的原因。
编辑:另一种更保守的方法是使用git cherry-pick
。 rebase解决方案依赖于Git认识到应该共同的历史包括upstream/master
上已经存在的提交。但是,您可以确定要保留的第一个提交的父级,而不是重新定位,如果您确实要保留40个提交,请使用origin/master~40
,并在upstream/master
末尾添加这些提交:
git remote add upstream <upstream_url>
git fetch upstream
git checkout master
git reset --hard upstream/master
git cherry-pick origin/master~40..origin/master
这将为您提供一个新的master
,它明确地从upstream/master
开始,并添加您想要的新历史记录。
请注意--hard
中的git reset --hard upstream/master
:正如OP在评论中指出的那样,这需要确保在采摘樱桃之前从一个干净的状态开始。但首先要确保你没有任何你想保存的未提交的内容。
理智检查:在挑选樱桃(或者变种)之后,git diff master origin/master
应该什么也不返回,或者再次指出你需要处理的其他问题。结束编辑
一旦完成变基或挑选,你已经完全确信自己这个新的历史是你想要保留的:
git push -f origin master
应该把你的前叉带回到upstream
之前只有40次提交。
警告:我没有测试rebase解决方案,但我相信它应该可以工作,基于你对情况的描述。然而,我使用樱桃挑选解决方案是成功的类似情况。如果你尝试任何一种方法,请报告你的成功或需要调整的任何错误。