如果按一个提交到服务器,然后重写在本地提交(有git reset
,git rebase
,git filter-branch
,或其他任何历史操作),然后推说改写提交备份到服务器上,你会搞砸了谁比谁已经退出。这是一个例子。说您已提交A,并将其推送到服务器。
-*-*-A <-主
-*-*-A <-起源/母版
现在,您决定以您提到的方式重写A,然后重新设置并重新提交。请注意,这留下了一个悬空的提交A,由于无法到达,最终将对其进行垃圾回收。
-*-*-一个
\
A'<-大师
-*-*-A <-起源/母版
假设弗雷德master
在执行此操作时从服务器中拉出其他人,他们将获得对A的引用,他们可能从以下地方开始工作:
-*-*-A'<-主
-*-*-A <-起源/母版
-*-*-AB <-弗雷德/大师
现在,如果您能够将A'推送到原点/主节点,这将创建非快进,则其历史记录中就不会包含A。因此,如果弗雷德试图再次拉,他将突然不得不合并,并重新引入A提交:
-*-*-A'<-主
-*-*-A <-起源/母版
-*-*-AB- \
\ * <-弗雷德/大师
一个' - /
如果Fred恰好注意到这一点,那么他可以进行重新设置基准,这将阻止提交A再次出现。但是他必须注意到这一点,并记住要这样做。如果您有多个人将A拉倒,则他们都必须重新设置基准,以避免在树中获得额外的A提交。
因此,通常不要在其他人提供的回购中更改历史记录。但是,如果您碰巧知道没有其他人正在从该存储库中提取信息(例如,这是您自己的私人存储库,或者只有一个其他开发人员可以轻松地与该项目进行协作),那么您可以强制执行通过运行更新:
git push -f
要么
git push origin +master
这些都将忽略对非快进推送的检查,并将服务器上的内容更新为新的A'版本,放弃A版本,以便最终对其进行垃圾回收。
receive.denyNonFastForwards
config选项可能会完全禁用强制推送。默认情况下,此选项在共享存储库上启用。在这种情况下,如果您确实要强制执行推送,则最好的选择是使用删除分支并重新创建分支git push origin :master; git push origin master:master
。但是,由于denyNonFastForwards
上述原因而启用了该选项。在共享存储库上,这意味着现在使用它的每个人都需要确保他们基于新的历史记录。
在共享存储库上,通常最好将新的提交放在最上面,以解决您遇到的任何问题;您可以git revert
用来生成将撤消先前提交的更改的提交。