三,快进式推送(FastForwards)与非快进式推送(NonFastForwards)

xiaoxiao2021-02-27  462

本篇博客介绍git push的快进式推送和非快进式推送,也可以在此处访问。首先记住,快进式推送是合理地,非快进式推送时不合理的。所谓的快进式推送(FastForwards),指的是git push时,远程版本库的最新提交是本地版本库的祖先提交,此时,git push是可以顺利进行的,push之后远程版本库的提交状况与本地版本库是一致的。而如果执行git push时,远程版本库的最新提交不是本地版本库的祖先提交,那么push是会被拒绝的,因为如果可以顺利将本地的提交push到远程版本库,那远程版本库的最新提交该何去何从?总不能就直接无视它,往上堆吧。此时也不是不可以push,执行git push -f就可以强制推送,这就是所谓的非快进式推送(NonFastForwards)。

一起来看一个例子,该例子展示了这两种推送的区别:

Step1:首先先来检查一下上游版本库rere.git,两个本地版本库user1,user2的提交状况: 可见当前远程版本库和两个本地版本库的提交状况是一致的,最新提交都是fa7fe。

Step2:我们在user2版本库中创建一个pushfirst.txt文件。本地提交以后,使用git push将其推送到上游版本库中: 可以看到推送过程很顺利,因为上游版本库的最新提交fa7fe,是user2版本库最新提交4188af的父提交,故推送为快进式推送,没有阻碍。

Step3:我们切换到user1版本库,像user2一样创建一个pushsecond.txt文件。本地提交以后执行git push: 此时遇到了麻烦,rejected说明git push被拒绝了。原因是远程版本库有user1还未获取的工作,也就是说远程版本库的最新提交并不是user1版本库的祖先提交。这两句话是等价的(如果远程版本库有很多新提交user1都没有,那么远程版本库最新的提交user1肯定也没有,自然不是user1的祖先提交,相反,如果远程版本库的最新提交是本地提交的祖先提交,那么远程版本库肯定不存在user1没有的work)。

Step4:检查一下rere.git与user1的提交状况吧: Step5:如果user1非要提交,可以加上-f参数(git push -f): 推送自然是成功了,但是从rere.git的提交日志可以看出,4188af不见了,那是user2推送的提交,它被user1的非快进式提交覆盖了。非快进式提交的方法是,寻找远程版本库与本地版本库的最新的共同祖先,假设为Root,然后将远程版本库Root以上的所有提交全部删除,并将本地版本库Root以上的所有提交全部堆积上去。这就导致别人的提交成果被舍弃了,这显然不能作为一个常规做法,只能在某些特定情况下使用。

Step6:我们再进入user2,因为他的成果被抛弃了,所以还想push到远程版本库: 这和一开始user1的情况相同,push被拒绝。此时user1可以选择非快进式推送,但这又会舍弃user1的劳动成果。

Step7:为了防止此事一再发生,我们进入远程版本库修改一个配置项: 我们执行git config receive.denyNonFastForwards true,将该配置项置为true。它可以拒绝下游版本库的非快进式推送。

Step8:user2试一下非快进式推送: 了,被拒绝了。

Step9:user2想要推送的通常做法是,先git pull(拉回上有版本库的新提交(fetch),与本地提交进行合并(merge)),然后在push: 这样,本地进行了merge,远程版本库的最新提交成了本地提交的父提交,此时执行push便顺利无阻了。

Step10:进入远程版本库查看下提交日志: 版本库已经获取了user2的提交内容。

OK,这就是git的快进式推送与非快进式推送。 转载原文地址

转载请注明原文地址: https://www.6miu.com/read-240.html

最新回复(0)