Git 的远端操作及解析(含思维导图)
0. 前言
大家好,我是多选参数的程序锅,一个正在 neng 操作系统、学数据结构和算法以及 Java 的硬核菜鸡。Git 是 4 月份时候开的一个坑,一直没填完,所以今天我先来填一下 Git 的坑。最近正在学习的内容,有的已经挖了坑,有的正在挖坑中。首先依旧是先来一份本篇内容的提纲。
1. 远端仓库
git 中远端的定义较为广泛,任何其他位置,只要不是当前仓库,都可以算作远端。同一台机器上,只要不是当前仓库的位置也可以算作远端。另外,我们常见的 github、gitlab 也是远端仓库。那么本地仓库和远端仓库之间的传输协议有以下那么几种:
常用协议语法格式说明本地协议(1)/path/to/repo.git哑协议本地协议(2)file:///path/to/repo.git智能协议http/https 协议http://git-server.com:port/to/repo.git https://git-server.com:port/to/repo.git平时接触的都是智能协议ssh 协议user@git-server.com:path/to/repo.git工作中最常用的智能协议
本地协议是指同一台机器上,通过文件路径能访问到的
http/https 方式需要账号密码
ssh 协议是需要公私秘钥的
哑协议传输进度不可见,智能传输协议可见,另外智能协议比哑协议传输速度快
2. 远端操作
2.1. git remote
与远端仓库建立连接
在使用 git remote
命令之后,会多出一个远端分支。
2.2. git clone
将远端仓库 clone 下来
从远端上 clone 一个仓库的时候,那么 clone 下来的仓库已经和远端建立了连接,不需要再使用
git remote
命令
2.3. git push
将本地分支推到远端
git push
的意思是本地比较新,要把本地 push 到远端,对远端进行更新,其实也就是更新 origin/master 的指向。所以 git push origin master
, 其实就相当于把 origin/master 的指针移到 master 的位置,这样子 origin/master 就被更新了,然后将远端分支拷贝到远端,这样就相当于远端被更新了,但是在执行 push 的时候得要求远端仓库的 origin/master 是本地更新之后的 origin/master 的 fast-forward,也就相当于远端仓库的 origin/master 得在本地更新之后的 origin/master 的前面,其实也就是在一条线上。简单来说 git push
就是先将改变 origin/master ,然后将其复制到远端。(Hint:经过测试,本地仓库处于 master 分支,那么执行 git push origin temp
命令,操作的两个分支其实是 origin/temp 和 temp 分支)
在push的时候有时候会遇到
None fast-forward
问题,None fast-forward
是指:同分支情况下或者说两个相互绑定的远端分支和本地分支的情况下(通常origin/master
和master
属于同分支),远端分支不是本地分支的父亲上的,也就是远端分支跟本地分支不在同一个分支上也就是远端分支所指的 commit 不在本地分支最新的 commit 的前面。
2.4. git fetch
将远端分支 fetch 到本地
2.5. git pull
这个命令是 git fetch
和 git merge
的整合
git pull
的意思是远端比较新,要把本地分支进行更新。那么 git pull origin master
,是相当于先把远端的 origin/master fetch 到本地,然后让 master 移到 origin/master 的位置(这是本地所在分支为 master,并且是 fast-forward 的情况)。假如 master 和 origin/master 不是 fast-forward(但是本地所在分支是 master),那么 master 和 origin/master 会进行 merge。那么假如本地当前分支不是 master,而是 temp,并且 temp 分支跟 origin/master 也不是 fast-forward,那么 temp 分支会和 origin/master 分支进行 merge。所以简单来说 git pull
就是先把远端分支 fetch 下来,然后将本地分支更新为远端分支所指的地方,这跟 git push
正好是反操作。
多人开发的情况下,一定要先 git fetch 或者 git pull。
2.6. 远端操作总结---个人理解
刚开始的时候对 git 的远端概念不太懂,怎么一会儿远端分支 origin/master、一会儿本地分支 master的,为啥 push 了之后,远端仓库内容就被更新了呢,pull 之后本地仓库就被更新了呢。在接触之后,其实从 git 是分布式的角度可以理解一波,git 分布式也就意味着一份仓库的内容,同时在远端和本地都有备份。如下图所示
那么远端分支和本地分支都是这个仓库的分支,比如 origin/master 和 master 都是仓库的分支。只是本地仓库操作的分支是都是本地分支,而远端仓库只在远端分支上进行操作,远端仓库显示的内容是远端分支的内容。那么 push、pull 等操作其实就可以简单的当做对本地仓库分支的操作,比如 push 操作就是把本地仓库中的远端分支指向本地分支,然后把远端分支的情况同步到远端。pull 操作就是把远端仓库的远端分支同步下来,然后对将本地分支指向远端分支。
3. git 与 github 简单同步
上文提到了 github 也可以算是一个远端仓库,那么本地仓库与远端仓库之间通信的方式有四种。显然,假如把 github 当成远端仓库,本地协议不能用了,只能用 http/https 协议或者 SSH 协议。假如需要想用 SSH 协议的话,需要配置公私钥,但是这个步骤在这里省略,下面是已经配好公私钥的。
3.1. Github 上创建仓库
依次将所需填写的内容填写完成,之后点击 “Create repository” 即可创建相应的仓库,其中关于填写选项有以下几点说明:
Description:如果希望别人很容易搜到你的 repository 的话,那么需要在这块写具体一点
Public:repository 可以让所有看到,但是仅有只读权限。
Private:repository 并不是对外开放的,需要授权。
README:搜索 repository 的时候,会到 README 里面搜索关键字的。
Add .gitignore:有很多 .gitignore 的模板供你选择,可以根据仓库会使用的语言选择一个,也可不选。
Add a license:选择开源协议
创建完成之后,如下图所示:
3.2. 本地仓库同步到 Github 上
现在要将本地的这个仓库同步到 Github 上
首先与远端仓库进行关联
之后使用
git push
命令把本地库的内容推送到远程
由于远程库是空的,我们第一次推送时,加上了 -u
参数,Git不但会把本地的 master
分支内容推送到远程新的 master
分支,还会把本地的 master
分支和远程的 master
分支关联起来。此后,每次本地提交后,就可以使用命令 git push origin master
推送最新修改。上述提交完成之后,Github 上面的内容就和本地的一样了。
3.3. 本地仓库与远程仓库进行整合
上面所述的是在 Github 创建的是一个空仓库,假如Github上创建的仓库已经存在了东西,如下所示,仓库中已经还有了 LICENSE 文件,那么在 push 之前需要先 pull 或者 fetch && merge。
先使用
git remote
命令与远端仓库建立连接
之后先把远端的东西 fetch 下来
假如不把远端的仓库中的东西 fetch 下来的话,而是直接
push
的话会报fast-forward
错误。
使用
git merge
将两颗不相关的分支进行整合
最后再
git push
其他方法
其实针第二步开始可以使用
git pull
命令,因为git pull
命令就包含了 fetch 和 merge 两个命令。当然,我们可以不用 merge 的方式进行合并,还可以使用 rebase 的方式进行合并,使用
git rebase orgin/master
(假设本地仓库 HEAD 指向 master),那么就相当于把本地 master 中的 commit 以线性的方式依次合并到origin/master
中。甚至可以在
git pull
的时候直接使用git pull --rebase
。
版权声明: 本文为 InfoQ 作者【多选参数】的原创文章。
原文链接:【http://xie.infoq.cn/article/d136d329030f25444c2fdc99f】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论