Git 使用指南之远程仓库

上一篇博文我们已经掌握了 Git 版本库管理日常操作指令,已经初步达成了简单管理日常项目的目标,再也不用担心文件备份或者丢失的问题了。有用过集中式版本控制系统 SVN 的童鞋会说,这些功能在 SVN 里早就有了,没看出 Git 有什么特别的地方。

确实没错,如果只是作为仓库管理文件历史,Git 和 SVN 还真没啥区别,但项目开发不仅仅是管理文件历史。为了体现 Git 作为分布式版本控制系统较于 SVN 的优势(不做“杠精”哈~),本篇我们将介绍 Git 的杀手锏功能之一:Git 远程仓库,这也是 Git 迅速流行的主要原因。

版权说明: 本文思路以及内容主要来自廖雪峰老师的 Git 教程 (强烈推荐膜拜原文),并结合个人使用所作,只作为学习记录使用。如内容有侵权请联系删除,禁止转载!

更多 Git 相关内容,请关注博主 Git 博文系列:

之一 >>> Git 使用指南之初识

之二 >>> Git 使用指南之时光穿梭机

之三 >>> Git 使用指南之远程仓库

之四 >>> Git 使用指南之分支管理

之五 >>> Git 使用指南之 WorkFlow (工作流)

之六 >>> Git 使用指南之 Git 自定义

之七 >>> Git 使用指南之 HEAD 指针

之八 >>> Git 使用指南之 Git 中的黑魔法


Git 分布式版本控制策略

Git 是分布式版本控制系统,意味着同一个 Git 仓库,可以分布到不同的机器上。

怎么分布呢?

起初肯定只有一台机器有一个原始版本库,此后别的机器可以 克隆 这个原始版本库,而且每台机器的版本库其实都是一样的,并且没有主次之分。

那么 如何保证所有分布式节点版本库数据同步呢? 考虑以下场景:

  • 某个项目由多人负责开发,想要实现所有人项目版本库数据同步
  • 多地点不同机器进行项目开发(公司,家等),难道每天需要将项目拷贝过来拷贝过去?

我们在介绍版本控制系统的集中式和分布式区别时,我们提到过:分布式不像集中式一样有中央服务器,但它会选用一台服务器充当“中央服务器”的角色。

实际使用情况确实如此,找一台电脑充当服务器的角色,每天24小时开机,分布式系统中其它每个用户都从这个 “中央服务器” 仓库克隆一份到自己的电脑上,并且各自把各自的最新提交推送到服务器仓库里,也从服务器仓库中拉取别人的提交。

在公司局域网内进行项目开发时,完全可以搭建一台运行 Git 的 “中央服务器” 进行项目开发。不过为了学习 Git,先搭个服务器绝对是小题大作(看官老爷也要骂街了~)。不知道你还记不记得之前我们提过的 GitHub —> 提供了远程 Git 仓库托管服务的,只要注册一个 GitHub 账号,就可以免费获得 Git 远程仓库,然后就可以将其作为 “中央服务器” 使用了。

P.S. 如果你想要尝试一下个人搭建 Git 服务器,可以了解一下 GitLab

后续我们将以 GitHub 作为远程仓库(中央仓库)进行继续学习,阅读后续内容前,请自行注册 GitHub 账号。


Github

首先我们给出 GitHub 登陆界面:

SSH Reff

我们需要知道:本地 Git 仓库和远程 GitHub 仓库之间的传输是通过 SSH 加密的,所以首先我们需要设置 Git 和 GitHub 之间的 SSH,只有配置了 SSH,Git 才可以和 GitHub 远程仓库进行同步通信(SSH 保证了 Git 与 Github 之间的通信安全,防止其它人恶意操作你的 Github 仓库)。

SSH 是一种通讯协议,是用于实现 远程安全登录 的。有使用过在 Windows 下远程登录 Linux 服务器进行文件互传的看官,相信会对 SSH 有初步的了解,你可以直接跳过下面关于 SSH 安全机制的说明。

|—————————— SSH 安全机制 ——————————|

SSH 之所以能够保证安全,原因在于它采用了非对称加密技术(RSA)的安全机制,提供两种级别的验证方法:

第一种级别(基于口令的安全验证):只要你知道自己帐号和口令,就可以登录到远程主机。所有传输的数据都会被加密,但是不能保证你正在连接的服务器就是你想连接的服务器。可能会有别的服务器在冒充真正的服务器,这是危险的。

第二种级别(基于密钥的安全验证):必须为自己创建一对密钥,并把公钥放在需要访问的服务器上。如果你要连接到 SSH 服务器上,客户端软件就会向服务器发出请求,请求用你的密钥进行安全验证。服务器收到请求之后,先在该服务器上你的主目录下寻找你的公钥,然后把它和你发送过来的公钥进行比较。如果两个密钥一致,服务器就用公钥加密 “质询”(challenge)并把它发送给客户端软件。客户端软件收到 “质询” 之后就可以用你的私钥在本地解密再把它发送给服务器完成登录。


Config SSH Key For Git

下面来看如如何为 GiHub 配置本地 Git 仓库机器的 SSH:

1 –> 本地 Git 创建 SSH Key

检查用户主目录(~)下是否有 .ssh 目录,以及 .ssh 目录下是否有 id_rsaid_rsa.pub 这两个文件。如果都存在,可以跳过当前步骤,否则通过 Shell( Windows 下打开 Git Bash),使用邮箱创建 SSH Key:

1
$ ssh-keygen -t rsa -C "youremail@example.com"

youremail@example.com 换成可用的邮件地址,然后一路回车,使用默认值即可。

如果创建成功的话,可以在用户目录下找到 .ssh 目录,并且 .ssh 目录中还有 id_rsaid_rsa.pub 两个文件(SSH Key 的秘钥对)。其中 id_rsa 是私钥,id_rsa.pub 是公钥。


2 –> GitHub Settings

登陆 GitHub,打开 “Settings” –> “SSH and GPG keys” 页面:

然后点击 “Add SSH Key”,填任意 Title,在 Key 文本框里粘贴本地 Git 节点中 id_rsa.pub 文件的内容,点击下方 “Add SSH Key” 即可查看到添加好的 SSH Key 了:

|—————————————————————–

内容补充:

为什么 GitHub 需要 SSH Key 呢?因为 GitHub 需要识别出推送的提交确实是你推送的,而不是别人冒充的,而 Git 支持 SSH 协议,所以 GitHub 只要知道了你的公钥,就可以确认只有你自己才能推送。

当然,GitHub 允许用户添加多个 SSH Key。假定你有若干台设备时,只要把每台设备的 Key 都添加到 GitHub,就可以在每台设备上往 GitHub 进行推送了(是不实现了版本库的数据同步了)。

注意:GitHub 上免费托管的 Git 仓库,任何人都可以看到(但只有你自己才能改)。所以,不要把敏感信息放进去。当然你可以使用 GitHub 创建私有仓库。

—————————————————————–|

SSH Key 添加成功之后,我们可以在 Git bash 中进行测试:

1
2
3
$ ssh -T git@github.com
Warning: Permanently added the RSA host key for IP address 'X.X.X.X' to the list of known hosts.
Hi TheNightIsYoung! You've successfully authenticated, but GitHub does not provide shell access.

返回 “Hi username !You’ve successfully ……” 说明你已经成功啦!


Add Repo For Local Git

当前的场景是:我们的本地机器已经拥有了一个本地 Git 仓库,想将 GitHub 作为本地 Git 某个仓库(GitTestProject)的远程仓库(“中央仓库”)。这样 GitHub 上的仓库既可以作为备份,又可以让其他人通过该仓库来协作,真是一举多得。

1 –> GitHub 上创建一个新仓库,作为中央仓库(备份、同步仓库)

这里我们还是以 GitTestProject 作为项目名称。创建好后,GitHub 上的这个 GitTestProject 仓库还是空的。

可以看到,GitHub 告诉我们:可以从这个仓库克隆出新的仓库;也可以把一个已有的本地仓库与之关联,然后把本地仓库的内容推送到 GitHub 仓库;还可以从其它仓库导入代码。

这里我们只关注本地 Git 仓库与其进行关联。


2 –> 本地 Git 仓库关联 GitHub 远程仓库

根据你自己的 …or push an existing repository from the command line 中关联命令在 GitTestProject 目录下进行关联操作:

CMD 9 –>>> git remote add <repo name> <repo addr>

1
2
# 将地址为:git@github.com:TheNightIsYoung/GitTestProject.git 的远程仓库 origin(别名)链接到当前本地 Git 仓库
$ git remote add origin git@github.com:TheNightIsYoung/GitTestProject.git

注意:TheNightIsYoung 应该是你 GitHub 的用户名。如果使用成我的,关联没问题,但你无法推送(未添加你设备的 SSH Key)。

添加后,远程库的名字就是 origin,这是 Git 默认的叫法(比较形象),当然也可以改成别的。

修改本地映射的远程库的名字:git remote rename


3 –> 推送本地 Git 所有内容到 GitHub

把本地库的内容推送到远程,用 git push 命令,实际上是把当前分支 master 推送到远程。

CMD 10 –>>> git push && git pull

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ git push -u origin master
The authenticity of host 'github.com (127.8.0.1)' can't be established.
RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'github.com' (RSA) to the list of known hosts.
Enumerating objects: 29, done.
Counting objects: 100% (29/29), done.
Delta compression using up to 8 threads
Compressing objects: 100% (19/19), done.
Writing objects: 100% (29/29), 2.32 KiB | 395.00 KiB/s, done.
Total 29 (delta 5), reused 0 (delta 0)
remote: Resolving deltas: 100% (5/5), done.
To github.com:TheNightIsYoung/GitTestProject.git
* [new branch] master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.

|—————————————————————–

SSH 连接警告

当你第一次使用 Git 的 clone 或者 push 命令连接 GitHub 时,会得到一个警告:

1
2
3
The authenticity of host 'github.com (xx.xx.xx.xx)' can't be established.
RSA key fingerprint is xx.xx.xx.xx.xx.
Are you sure you want to continue connecting (yes/no)?

这是因为 Git 首次使用 SSH 连接,而 SSH 连接在第一次验证 GitHub 服务器的 Key 时,需要你确认 GitHub 的 Key 的指纹信息是否真的来自 GitHub 的服务器,输入 yes 回车即可。

后续,Git 会输出一个警告,告诉你已经把 GitHub 的 Key 添加到本机的一个信任列表里了:

1
Warning: Permanently added 'github.com' (RSA) to the list of known hosts.

这个警告只会出现一次,后面的操作就不会有任何警告了。

如果你实在担心有人冒充 GitHub 服务器,输入 yes 前可以对照 GitHub 的 RSA Key 的指纹信息 是否与 SSH 连接给出的一致。

参数说明

由于远程库是空的,我们第一次推送 master 分支时,加上了 -u 参数,Git 不但会把本地的 master 分支内容推送的远程新的 master 分支,还会把本地的 master 分支和远程的 master 分支关联起来,在以后的推送或者拉取时就可以简化命令(直接使用 git pull or git push)。

—————————————————————–|


4 –> 查看 GitHub GitTestProject 仓库

推送成功后,可以立刻在 GitHub 页面中看到远程库的内容已经和本地一模一样:

从现在起,只要本地作了提交,就可以通过命令:

1
$ git push origin master

把本地 master 分支的最新修改推送至 GitHub(origin)。到这里你就拥有了真正的分布式版本库!


Remove Repo For Local Git

如果添加的时候地址写错了,或者就是想删除远程库,可以用如下命令删除远程仓库的关联:

CMD 11 –>>> git remote rm <repo name>

建议先用 git remote -v 查看远程库信息:

1
2
3
$ git remote -v
origin git@github.com:TheNightIsYoung/GitTestProject.git (fetch)
origin git@github.com:TheNightIsYoung/GitTestProject.git (push)

然后,根据名字删除,比如删除 origin

1
$ git remote rm origin

注意:此处的 “删除” 其实是 解除了本地和远程的绑定关系,并不是物理上删除了远程库。远程库本身并没有任何改动。要真正删除远程库,需要登录到 GitHub,在后台页面找到删除按钮再删除。


Clone Repo From Github

之前我已经创建好了一个 GitTestProject 远程库,并且关联到了我自己的本地测试项目仓库。

多个人协作开发时,其他人要想获取我的版本库的话,可以直接使用 git clone 从我的 GitHub 克隆一个 GitTestProject 本地库:

CMD 12 –>>> git clone <repo addr>

1
2
3
4
5
$ git clone git@github.com:TheNightIsYoung/GitTestProject.git
Cloning into 'gitskills'...
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 3
Receiving objects: 100% (3/3), done.

GitHub 给出的地址不止一个,还可以用 https://github.com/TheNightIsYoung/GitTestProject.git 这样的地址。实际上 Git 支持多种协议,默认使用 SSH 协议,即 git://xxxxx ,但也可以使用 https 等其他协议。

使用 https 除了速度慢以外,还有个最大的麻烦是每次推送都必须输入口令,但是在某些只开放 http 端口的公司内部就无法使用 ssh 协议而只能用 https。


Git Clone 仓库中的单个目录

很多时候,由于项目较大,我们只想 git clone 仓库的某单个或多个文件夹,而不是全部的仓库内容。

Git1.7.0 以前,这无法实现。但是幸运的是,在 Git1.7.0 以后加入了 Sparse Checkout 模式,这使得 CheckOut 指定文件或者文件夹成为可能。

假设我们有一个 Github 仓库:https://github.com/yourgithub/Demo,我们想要 git clone Demo 里面的 childDir 子目录:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
###注意: 'childDir' 需要替换为自己想要下载的目录名称:

# 初始化本地仓库:
$ git init Demo && cd Demo

# 设置允许进行子目录克隆:
$ git config core.sparsecheckout true

$ 设置目标子目录名称(假设我的 childDir 位于 https://github.com/yourgithub/Demo/code 下):
echo 'code/childDir*' >> .git/info/sparse-checkout

$ 映射:
git remote add origin https://github.com/yourgithub/Demo.git

# 拉取:
$ git pull origin master
remote: Enumerating objects: 2750, done.
remote: Total 2750 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (2750/2750), 36.41 MiB | 10.38 MiB/s, done.
Resolving deltas: 100% (542/542), done.
From e.coding.net:xdzsoft/mashangwuyou
* branch master -> FETCH_HEAD
* [new branch] master -> origin/master

OK!!!


配置多个 SSH Key

事实上,除了 Github 提供远程 Git 仓库托管服务,国内也有一些优秀的远程 Git 仓库托管服务平台(GiteeCoding …),只要注册相关平台账号,就可以免费使用 Git 远程仓库,而且由于这些平台在国内,所以可以为我们提供更快的访问速度。

随着工作与学习的不断深入,你会拥有多个 Git 账户。比如公司 Gitlab 一个工作账号,Github 和 Gitee 一个个人学习账号,Coding 一个个人项目账号。而平时我们又会通过配置 SSH 公私钥认证的方式省去繁琐的登录远程仓库的操作,不同的 Git 账户一般都是不同的邮箱,而 SSH Key 又通过邮箱生成,那么就会涉及到为不同 Git Host 配置多对 ssh key 的问题。

详细步骤如下(以 Gitlab && Gitee 为例):

1 –> 为公司账号生成一对密钥(Gitlab)

通过 -f 参数指定生成的密钥文件的名称

1
$ ssh-keygen -t rsa -C "yourEmail1@xx.com" -f ~/.ssh/gitlab_id_rsa

执行后,生成公私钥文件如下:

1
2
your identification has been saved in /home/xx_usr/.ssh/gitlab_id_rsa. ==> 私钥
your public key has been saved in /home/xx_usr/.ssh/gitlab_id_rsa_pub. ==> 公钥

2 –> 为个人账号生成一对密钥(Gitee)

通过 -f 参数指定生成的密钥文件的名称

1
$ ssh-keygen -t rsa -C "yourEmail2@xx.com" -f ~/.ssh/gitee_id_rsa

执行后,生成公私钥文件如下:

1
2
your identification has been saved in /home/xx_usr/.ssh/gitee_id_rsa. ==> 私钥
your public key has been saved in /home/xx_usr/.ssh/gitee_id_rsa_pub. ==> 公钥

3 –> 配置不同 SSH Key 使用规则

~/.ssh 目录下新建名为 config 的文件(无后缀),config 文件用于配置多个不同的 Git Host 使用不同的 ssh key :

1
2
3
4
5
6
7
8
9
10
11
# gitee
Host gitee.com
HostName gitee.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/gitee_id_rsa

# gitlab
Host gitlab.com
HostName gitlab.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/gitlab_id_rsa

配置文件参数说明:

  • Host:用于区别不同平台的识别模式,名字随意;
  • HostName:登录服务器的域名地址或者 ip 地址;
  • PreferredAuthentications:配置登录时用什么权限认证 –> 可设置 publickeypassword publickey
  • IdentityFile:私钥路径。

4 –> 配置平台的 SSH

将上面生成的公钥文件 gitlab_id_rsa_pub && gitee_id_rsa_pub 中的内容,分别添加到 Gitlab 和 Gitee 平台的 SSH 中,添加过程类似于 Github。

5 –> 连接测试

配置完成之后测试一下,成功显示如下:

1
2
3
4
$ ssh -T git@gitee.com
Hi TheNightIsYoung! You've successfully authenticated, but GITEE.COM does not provide shell access.
Jie Guo Desktop $ ssh -T git@github.com
Hi TheNightIsYoung! You've successfully authenticated, but GitHub does not provide shell access.

================================== Permission denied (publickey) ==================================

这里有可能产生异常:git@gitee.com: Permission denied (publickey).,可以尝试如下操作:

删除掉 config 配置文件中相关条目的 PreferredAuthentications 项目。

==============================================================================================

至此,你可以像使用 Github 平台一样使用其它平台提供的 Git 仓库托管服务了~~~


Author

Waldeinsamkeit

Posted on

2017-07-03

Updated on

2022-03-11

Licensed under

You need to set install_url to use ShareThis. Please set it in _config.yml.

Comments

You forgot to set the shortname for Disqus. Please set it in _config.yml.