git push :推送本地更改到远程仓库的三种模式

时间:2020-12-09 08:25:18

摘要:由于在git push过程中,no-fast-forward 的push会被拒绝,如何解决git push失败的问题?这里面有三种方法,分别会形成merge形式的提交历史,线性形式的提交历史,覆盖原来的提交历史。

本文来源:git push 的三种模式

地址:http://blog.csdn.net/trochiluses/article/details/14517379

1.git push产生冲突的形成过程

现在,服务器端最新版本是x;用户甲和用户已分别clone代码,然后进行开发;用户甲完成版本A,并提交,此时服务器端版本历史变成:

X------A

用户已机器上的版本提交历史是X--------B

而git push的结果说明是这样的: Update remote refs along with associated objects

其中远程和本地的refs都保存在本地的.git目录之下,而且都只有一个refs:

远程refs:

hyk@hyk-linux:~/xfstests/.git (master) 
$ cat refs/remotes/origin/master 
56a3959a96f1b5e046b3760778fd34b4911d0516

本地refs:

hyk@hyk-linux:~/xfstests/.git (master) 
$ cat refs/heads/master 
2c13da0b38b794581790ed0122a674d6ad6113ba

回顾我们原来学习过的分支创建的存储模型,push的实质是进行commit对象在远程的创建和指针的更新问题。也就是说,如果用户乙在此时push,那么X后代会指向B,B的parent也指向X,然后此时我们的X后代已经指向了A,所以会失败

2.方案一:强制覆盖

在某些情况下,你需要对别人的提交(也可能是你自己的),进行强制覆盖。例如,下面这种情况:

There is another common situation where you may encounter non-fast-forward rejection when you try to push, and  it is possible even when you are pushing into a repository nobody else pushes into. After you push commit A yourself (in the first picture in this div), replace it with "git commit --amend" to produce commit B, and you try to push it out, because forgot that you have pushed A out already.

此时,我们只需要执行命令;git push --force

3.方案二:形成merge形式的提交历史

这是最常见的一种情况,如果你不想丢失自己的工作,也不想丢失别人的工作(你需要同时保存从X到A和B和提交历史)在每次push之前,我们先从服务器上pull最新版本(这样,就更新了本地存储的 refs/remotes/origin/master ),处理冲突,然后进行push,就不会产生问题了。此时,形成的提交历史如下:

B---C
                /     /
            ---X---A

4.方案三:形成线性的提交历史

很多情况下,为了保持提交历史的整洁,我们需要形成线性的提交历史。仍然以这个例子说明:我们可以提取X和B之间的diff,把这个diff应用给A,形成如下的提交历史:

------X-------A--------D(the diff of X and B)

此时,需要的命令是:git push --rebase