Git 入门指南-协议
前言
讲到Git协议,通常情况下我们需要与其他人的git仓库进行推送或拉取资料,与别人通信是需要使用到协议。
最佳协作实践
建立一个你与合作者们都有权利访问,且可从那里推送和拉取资料的共用仓库。
注意:使用git,技术上是可以实现,从个人仓库进行推送(push)和拉取(pull)来修改内容,但不方便。
Git中的四种主要协议
- 本地协议(Local)
- HTTP 协议
- SSH(Secure Shell)协议
- Git 协议。
在此,我们将会讨论那些协议及哪些情形应该使用(或避免使用)他们。
本地协议
版本库就是硬盘内的另一个目录。
你可以像下面这样:
git clone /git/project.git # clone一个本地项目到新的目录。
git remote add local_proj /git/project.git # 添加project为当前库的远程库(本地引用local_proj)
优点
简单,直接使用现有的文件权限,速度快(不进行远程操作的话,就是磁盘的读写速度),
缺点
建立版本库协作需要共享文件系统,不方便从多个物理位置访问(家,公司,出差点等)。
值得一提的是,如果你使用的是类似于共享挂载的文件系统进行远程协作时,这个方法不一定是最快的。 访问本地版本库的速度与你访问数据的速度是一样的。 在同一个服务器上,如果允许 Git 访问本地硬盘,一般的通过 NFS 访问版本库要比通过 SSH 访问慢。
最终,这个协议并不保护仓库避免意外的损坏。 每一个用户都有“远程”目录的完整 shell 权限,没有方法可以阻止他们修改或删除 Git 内部文件和损坏仓库。
HTTP协议
Git 通过 HTTP 通信有两种模式。 在 Git 1.6.6 版本之前只有一个方式可用,十分简单并且通常是只读模式的。 Git 1.6.6 版本引入了一种新的、更智能的协议,让 Git 可以像通过 SSH 那样智能的协商和传输数据。新版本的 HTTP 协议一般被称为“智能” HTTP 协议,旧版本的一般被称为“哑” HTTP 协议。
智能(Smart) HTTP 协议
“智能” HTTP 协议运行在标准的 HTTP/S 端口上并且可以使用各种 HTTP 验证机制,这意味着使用起来会比 SSH 协议简单的多,比如可以使用 HTTP 协议的用户名/密码的基础授权,免去设置 SSH 公钥。
智能 HTTP 协议即支持像 git://
协议一样设置匿名服务,也可以像 SSH 协议一样提供传输时的授权和加密。 而且只用一个 URL 就可以都做到,省去了为不同的需求设置不同的 URL。 如果你要推送到一个需要授权的服务器上(一般来讲都需要),服务器会提示你输入用户名和密码。 从服务器获取数据时也一样。
事实上,类似 GitHub 的服务,你在网页上看到的 URL (比如, https://github.com/schacon/simple.git
),和你在克隆、推送(如果你有权限)时使用的是一样的。
哑(Dumb) HTTP 协议
SSH 协议
架设 Git 服务器时常用 SSH 协议作为传输协议。 因为大多数环境下已经支持通过 SSH 访问 —— 即使没有也比较容易架设。 SSH 协议也是一个验证授权的网络协议;并且,因为其普遍性,架设和使用都很容易。
通过 SSH 协议克隆版本库,你可以指定一个 ssh://
的 URL:
$ git clone ssh://user@server/project.git
你也可以不指定用户,Git 会使用当前登录的用户名。
优势
SSH 架设相对简单,使用广泛,多数操作系统都包含了它及相关的管理工具,安全,会压缩数据。
缺点
不能匿名只读访问。
所以,即便只要读取数据,使用者也要有通过 SSH 访问你的主机的权限,这使得 SSH 协议不利于开源的项目。 如果你只在公司网络使用,SSH 协议可能是你唯一要用到的协议。 如果你要同时提供匿名只读访问和 SSH 协议,那么你除了为自己推送架设 SSH 服务以外,还得架设一个可以让其他人访问的服务。
Git 协议
Git 里的一个特殊的守护进程;它监听端口(9418),类似于 SSH 服务,但是访问无需任何授权。 要让版本库支持 Git 协议,需要先创建一个 git-daemon-export-ok
文件 —— 它是 Git 协议守护进程为这个版本库提供服务的必要条件 —— 但是除此之外没有任何安全措施。 要么谁都可以克隆这个版本库,要么谁也不能。 这意味着,通常不能通过 Git 协议推送。 由于没有授权机制,一旦你开放推送操作,意味着网络上知道这个项目 URL 的人都可以向项目推送数据。 不用说,极少会有人这么做。
优点
目前,Git 协议是 Git 使用的网络传输协议里最快的。 如果你的项目有很大的访问量,或者你的项目很庞大并且不需要为写进行用户授权,架设 Git 守护进程来提供服务是不错的选择。 它使用与 SSH 相同的数据传输机制,但是省去了加密和授权的开销。
缺点
Git 协议缺点是缺乏授权机制。 把 Git 协议作为访问项目版本库的唯一手段是不可取的。 一般的做法里,会同时提供 SSH 或者 HTTPS 协议的访问服务,只让少数几个开发者有推送(写)权限,其他人通过 git://
访问只有读权限。 Git 协议也许也是最难架设的。 它要求有自己的守护进程,这就要配置 xinetd
或者其他的程序,这些工作并不简单。 它还要求防火墙开放 9418 端口,但是企业防火墙一般不会开放这个非标准端口。 而大型的企业防火墙通常会封锁这个端口。
在代码托管服务使用SSH协议协作
使用SSH协议,你可以连接和验证远程服务器和服务。使用SSH秘钥,你可以在每次连接GitHub或者Gitlab时,不需要用户名和密码。
检查是否已经存在SSH秘钥?
在生成新的SSH秘钥对之前我们应该检查一下我们的系统中是否已经有生成过秘钥,因为没有特别用途我们没有必要使用多对秘钥,如果没有找到秘钥对,那就需要新生成秘钥。
cd ~/.ssh/
目录我们可以查看到已经生成过的秘钥对。
Note: 公钥可能被命名为以.pub为扩展的文件名,如下:id_dsa.pub
id_ecdsa.pub
id_ed25519.pub
新生成秘钥
使用你的邮箱生成一个新的秘钥。
ssh-keygen -t rsa -C "your.email@example.com" -b 4096
这里会有几个提问:
- Enter file in which to save the key (/Users/rs/.ssh/id_rsa)?
键入你想把秘钥保存在哪(/Users/rs/.ssh/id_rsa)?
解释:括号中是一个默认路径/Users/rs/.ssh/和文件名id_rsa, 键入enter就会使用默认,这里需要注意,如果使用建议路径,SSH客户端将自动找到配置文件,否则可能需要自己调整配置。
另外,如果你建议路径已经有秘钥对,你将需要键入一个新的秘钥路径,并在./ssh/config文件中配置哪一个SSH秘钥对用在那个host上, 比如下面配置。
# GitLab.com server
Host gitlab.com
RSAAuthentication yes
IdentityFile ~/.ssh/config/private-key-filename-01
# Private GitLab server
Host gitlab.company.com
RSAAuthentication yes
IdentityFile ~/.ssh/config/private-key-filename
- Enter passphrase (empty for no passphrase)?
键入访问私钥需要的密码,留空代表不需要密码,一般情况我们秘钥都在自己个人电脑上,无需加密,省去加密过程,留空,键入enter。
这样我们就在~/.ssh目录下生成了id_rsa私钥和id_rsa.pub公钥这样一对秘钥,我们复制id_rsa.pub的文件内容到剪贴板。
打开公司的gitlab网站,输入自己的用户名和密码,进入自己的账号页面,找到账号的配置页面,找到SSH Keys标签页,将我们复制的内容粘贴到Key下面的输入框中, 如下图,注意请用自己的邮箱生成秘钥,我这里使用的是示例邮箱。
image-20181015173217998.png
这样我们就配置完成了SSHkey了
该如何使用SSH来推送更新呢
当我们配置好SSH后,我们找到我们的项目,比如这里我以git项目为例,选择SSH,然后我们就可以获取到一个SSH协议的git仓库地址,点击地址后面的复制按钮,将仓库地址复制到剪贴板中。
将项目克隆到本地
在电脑本地的一个目录中
git clone ssh://git@git.xes.com/courseware/share-plane/git.git
然后第一次连接会出现让确认主机:
大概意思是,无法确认host主机的真实性,只知道它的公钥指纹,问你还想继续连接吗?
所谓"公钥指纹",是指公钥长度较长(这里采用RSA算法,长达1024位),很难比对,所以对其进行SHA256计算,将它变成一个256位的指纹。上例中是SHA256:wixrNcpES0GdcUsWCvjbYYuanhmaMvgvmDSHZA9u+dA,再进行比较,就容易多了。
很自然的一个问题就是,用户怎么知道远程主机的公钥指纹应该是多少?回答是没有好办法,远程主机必须在自己的网站上贴出公钥指纹,以便用户自行核对。
没有找到我们公司公布的git.xes.com这个域名下的SSH指纹信息,但是类似的比如GitHub我们可以找到公布的指纹信息如下图:
我们接受这个指纹(一般情况内网没有坏人)继续向下走.
系统会出现一句提示,表示host主机已经得到认可。
Warning: Permanently added 'host,12.18.429.21' (RSA) to the list of known hosts.
然后,会要求输入密码,如果你在生成秘钥对的时候对私钥进行加密了,就需要输入密码。
Password: (enter password)
如果密码正确,就可以登录了。
当远程主机的公钥被接受以后,它就会被保存在文件$HOME/.ssh/known_hosts之中。下次再连接这台主机,系统就会认出它的公钥已经保存在本地了,从而跳过警告部分,直接提示输入密码。
这样配置之后,我们便可以在本地进行ssh连接仓库, 这也是大多数开发者会使用的最通用最普遍的方式,也是github和gitlab推荐的方式。
其他的连接方案
url带授权信息
当然更简单的方式,使用智能HTTP的方式进行登录和推送内容:
比如: https://username:password@git.xes.com/courseware/share-plane/git.git
这样做的唯一的缺点就是,别人通过你本地电脑可能不小心看到你的密码哦。
git config配置缓存认证信息
git config --global credential.helper store
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。