🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
>[info] git pull 功能:抓取远程的新提交(并和本地版本库合并)。 你的小伙伴已经向`origin/dev`分支推送了他的提交,而碰巧你也对同样的文件作了修改,并试图推送: ~~~ $ git add hello.py $ git commit -m "add coding: utf-8" [dev bd6ae48] add coding: utf-8 1 file changed, 1 insertion(+) $ git push origin dev To git@github.com:michaelliao/learngit.git ! [rejected] dev -> dev (non-fast-forward) error: failed to push some refs to 'git@github.com:michaelliao/learngit.git' hint: Updates were rejected because the tip of your current branch is behind hint: its remote counterpart. Merge the remote changes (e.g. 'git pull') hint: before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details. ~~~ 推送失败,因为你的小伙伴的最新提交和你试图推送的提交有冲突,解决办法也很简单,Git已经提示我们,先用`git pull`把最新的提交从`origin/dev`抓下来,然后,在本地合并,解决冲突,再推送: ~~~ $ git pull remote: Counting objects: 5, done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 0), reused 3 (delta 0) Unpacking objects: 100% (3/3), done. From github.com:michaelliao/learngit fc38031..291bea8 dev -> origin/dev There is no tracking information for the current branch. Please specify which branch you want to merge with. See git-pull(1) for details git pull <remote> <branch> If you wish to set tracking information for this branch you can do so with: git branch --set-upstream dev origin/<branch> ~~~ `git pull`也失败了,原因是没有指定本地`dev`分支与远程`origin/dev`分支的链接,根据提示,设置`dev`和`origin/dev`的链接: ~~~ $ git branch --set-upstream dev origin/dev Branch dev set up to track remote branch dev from origin. ~~~ 再`pull`: ~~~ $ git pull Auto-merging hello.py CONFLICT (content): Merge conflict in hello.py Automatic merge failed; fix conflicts and then commit the result. ~~~ 这回`git pull`成功,但是合并有冲突,需要手动解决,解决的方法和分支管理中的解决冲突完全一样。解决后,提交,再`push`: ~~~ $ git commit -m "merge & fix hello.py" [dev adca45d] merge & fix hello.py $ git push origin dev Counting objects: 10, done. Delta compression using up to 4 threads. Compressing objects: 100% (5/5), done. Writing objects: 100% (6/6), 747 bytes, done. Total 6 (delta 0), reused 0 (delta 0) To git@github.com:michaelliao/learngit.git 291bea8..adca45d dev -> dev ~~~ 因此,多人协作的工作模式通常是这样: 首先,可以试图用`git push origin branch-name`推送自己的修改; 如果推送失败,则因为远程分支比你的本地更新,需要先用`git pull`试图合并; 如果合并有冲突,则解决冲突,并在本地提交; 没有冲突或者解决掉冲突后,再用`git push origin branch-name`推送就能成功! 如果`git pull`提示“no tracking information”,则说明本地分支和远程分支的链接关系没有创建,用命令`git branch --set-upstream branch-name origin/branch-name`。 这就是多人协作的工作模式,一旦熟悉了,就非常简单。 小结 查看远程库信息,使用`git remote -v`; 本地新建的分支如果不推送到远程,对其他人就是不可见的; 从本地推送分支,使用`git push origin branch-name`,如果推送失败,先用`git pull`抓取远程的新提交; 在本地创建和远程分支对应的分支,使用`git checkout -b branch-name origin/branch-name`,本地和远程分支的名称最好一致; 建立本地分支和远程分支的关联,使用`git branch --set-upstream branch-name origin/branch-name`; 从远程抓取分支,使用`git pull`,如果有冲突,要先处理冲突。 扩展知识: >[info] git pull = git fetch + git merge 但是合并操作并不总是会成功,如果自动合并失败,会在暂存区对合并前后文件进行标识,工作区进入冲突解决状态,在冲突解决完成之前不能提交。Git支持多种图形工具帮助完成冲突解决,执行如下命令,即可自动调用已安装的冲突解决工具。 注意理解这里的“工作区进入冲突解决状态”哦。试想一下,如果当前工作现场还在干活货怎么样呢? 答:实际上有个合并的操作你也知道了,所以同理,跟合并的情况一样,如果有“合并”操作,那么进入冲突前必须完成本地工作区未完成的工作,否则就拉失败了。 实际上不论是合并,还是拉,这与工作区的关系就是,只要发生冲突,就必须要求工作区是干净的,否则就可以进入“解决冲突状态”(满足快速合并的不需要解决冲突)。 实际上,pull只要有本地没有,远程有的新提交,哪怕是没有冲突(当前落后),也会要求本地工作区是干净的。(因为这会重置工作区,所以要保证你当前进行的工作啊。) 但是如果,这次没有拉到任何的新提交,则没有任何事。 注意这里的一个小细节,git的一般任何操作都不需要网络,也就是如果你不主动获取远程版本库信息的话,在看状态时,它是不知道远程领先于本地(远程有新的提交还没有拉到本地来),或者本地领先于远程(本地有新的提交还没有同步到远程),但是上面我们pull失败后明显看到了远程领先于本地的信息,我们也知道pull实际是两步,也就是说虽然pull失败了,但是fetch这个动作是完成了,只是merge失败了而已。不信我们撤销修改(不撤销修改的话还会报错和pull一样),直接merge试下,哈哈,也完成了合并吧。(这些细节都是git的许多小聪明之一。) 上面说得太乱了,其实可以总结下,只要是涉及到会改变工作区的操作,都会检查工作区是否是干净的。 注意快速合并(快进式合并)有两种情况哦,“当前领先”和“当前落后”,前者不会改变工作区,只是移动指针到当前而已,所以不要求工作区是干净的;而后者会改变工作区,并移动指针到最新的提交,所以会要求工作区是干净的(没有为添加到暂存区的修改,暂存区是干净的)。(注意快速合并没有一个提交哦,所以有时看不出来是合并过哦) 上面有个地方讲错了,不是所有需要改变工作区都会检查工作区是否干净,应该是检测我们的修改是否与拉取的新的提交是否有冲突。比如拉取得提交里面变动了test文件,但是我们本地只是修改test文件,就不会提示错误,不会强制需要我们完成工作。 合并操作也是这样的哦,很灵活的。也就是说之前都说错了,不一定要求工作区是干净的才能合并,只要和新的不产生冲突就不会影响,合并后工作区还可以继续工作。(或者说只要未完成的工作区文件名单中有本次合并变化/冲突的文件,那么则需要解决当前未完成的工作区问题) >[info] 总之情况很多,git很复杂,暂时没有时间去讨论所有的情况,我们唯一能做的就是遇到实际情况时根据命令提示去解决问题,现在没有时间去总结所有的情况。 所有的合并都是两个提交(对象)的合并。 什么时候需要解决冲突: 两次提交有共同的文件修改,且内容不同。 总之遇到问题时看提示解决。 ### 注意 单纯的看这个可能会以为3的父节点是2,实际上3和2的父节点都是1,4是3和2合并的结果。 commits图 ![](https://box.kancloud.cn/2f054101b7c99a55f4e153da60ae210e_917x757.jpg) Network图 ![](https://box.kancloud.cn/dce7d32f1f3b1c0c290fc219f32035b4_404x244.jpg) * * * * * Network图 ![](https://box.kancloud.cn/02299cf8572d0dc3d4c04750ef92d057_611x434.png) commit info图(第一个红框加载时:Loading branch information……)分支结构信息 ![](https://box.kancloud.cn/14d73bd510a8b2600cd40b5331564d6e_1738x327.png) 还可以看到`dev merge master`提交有两个父节点。 点击一个之后,显示可以和master快速合并。 ![](https://box.kancloud.cn/5405e62cf3772d3de248d81e7c6d56d5_1920x1051.jpg)