# 第五讲:远程仓库Github与Git图形化界面

# 前言

这一节将会介绍本地仓库与远程仓库的一些简单互动以及几款常用的Git图形化界面,让你更加方便地使用git

# 一、Git裸库

简单来说git裸库就是没有工作区的git仓库。比如服务器,只起到代码托管的作用而不需要也不应该修改服务器上的代码。

可通过以下指令创建git裸库:

git init --bare
1

创建完成之后,查看当前文件目录:

image-20200329192222085

可以看到并不存在工作区目录,表明git裸库仅仅是用来存放和中转开发者提交的代码。

# 二、本地仓库与远程版本库

  • **本地仓库:**也就是之前所讲的git仓库,分为三个区:工作区,暂存区和版本库;
  • 远程版本库:与本地版本库相对应的远程在线版本库,属于裸库

我们一般会在本地git仓库的工作区和暂存区中对文件进行修改,然后提交到本地版本库,并最终推送到远程版本库进行托管。整个流程如下图所示:

image-20200415215625991

远程仓库的实质就是本地仓库中的版本库对应的远程版本库,通常直接叫做远程仓库

远程仓库(版本库)的存在作用为:供多台计算机间交换信息,相当于交换两个数过程中的第三方容器。

# 1.git pushgit pull

这两个命令是我们使用远程仓库时非常常用的命令,它们十分的重要:

  • git push:将本地仓库某分支上的代码推送到远程仓库的某分支上;注意了,推送操作是分支对分支的,而不是将本地仓库的所有分支都推送到远程仓库,如下图所示(假设推送到远程同名分支):

    image-20200415222039765

  • git pull:将远程仓库文件拉取到本地版本库,也就是将本地仓库中没有的文件都拉取到本地仓库的版本库中,所以进行拉取操作后,本地仓库的工作区是干净的:

    image-20200415222320473

    这里的ststatus的别名,有关别名的内容,后续会进行详细讲解。

push指令的完整写法:

git push origin srcBranch:destBranch
1

其中srcBranch表示的是本地分支destBranch表示的是远程分支

pull指令的完整写法:

git pull origin srcBranch:destBranch
1

其中srcBranch表示的是远程分支destBrach表示的是本地分支

不要混淆了,可以这样理解:srcBranch表示从哪里来destBranch表示到哪里去

# git push的三种情况

  • **情况一:**只有一个用户操作远程仓库时,由于本地仓库对所有的文件和操作都进行了追踪,所以即使本地仓库删除之前推送到远程仓库的文件,再次执行推送时也不需要执行git pull操作。

    例如,远程仓库有这么些文件:

    image-20200410204056615

    在对应的本地仓库中将其他文件删除,只留下README.md,此时再向该远程仓库推送。推送过程十分顺利,并不需要执行git pull操作拉取合并远程仓库中的文件。

  • **情况二:**也是只有一个用户操作远程仓库,但是不通过本地推送来更新远程仓库,而是直接为远程仓库添加文件,比如手动添加README.md

    这个时候,由于本地仓库并没有对远程仓库中新增的README.md进行追踪,所以再次推送时会出现如下错误:

    image-20200410205057781

    此时需要执行git pull操作对远程仓库中新增的文件进行拉取、合并与追踪,之后才能进行git push

  • **情况三:**多人共用同一远程仓库,比如用户AB,这个时候由于远程仓库上有A提交的而B没有的文件。所以B在执行git push前,要先执行git pull操作,将远程仓库中这些没有的文件进行拉取、合并与追踪。

# git pull实质

在进行拉取操作的过程中,会执行合并操作(merge),合并操作可能成功也可能失败:

  • 如果merge成功:说明两个人修改的不是一个文件,或者是一个文件的不同地方,这样git会直接使用Fast-forward方式自动合并;
  • 如果merge失败:说明两个人可能修改了同一文件同一行,这时候就需要进行手动合并,解决文件发生的冲突;

合并完成之后才能进行push操作,将本地仓库的代码推送到远程仓库;

pull操作其实是fetch操作和merge操作的合成:

  • fetch指令的作用为:将远程仓库中的所有文件拉取到本地仓库的版本库中;

  • merge指令的作用为:合并拉取到本地的文件;

# 2.GithubGitlab

  • 先有Github后有Gitlab
  • Gitlab为内网的Github,即Gitlab为内网的git远程服务器,代码不开源,仅供公司内网用户使用,并且可以设置管理权限。

# Github

不多介绍,世界上最大的开源及私有软件项目的托管和同性交友平台;

# Gitlab

Gitlab可作为内网的远程代码托管服务器,一般都是安装在Linux系统上:

image-20200330201124866

# 三、本地仓库 -> 远程版本库

# 1.建立联系

Github上克隆项目时,主要可以采用两种协议:HTTP/HTTPS协议和SSH协议:

image-20200415195835932

当使用HTTP/HTTPS协议建立本地仓库与远程仓库的联系时,不用进行任何配置,但是每次进行推送时都需要输入账号密码。而使用SSH协议,只需要进行一次配置,就可以实现免密推送。

# HTTP/HTTPS协议

  • 克隆Github上的项目时,可以采用该协议:

image-20200415195957464

  • 建立本地仓库与远程仓库连接时,也可以采用该协议:
git remote add origin https://github.com/AhuntSun/test.git
1

其中的origin表示远程仓库的意思,可以不叫这个名字,但是约定俗成叫origin。执行完这条命令之后,就可以采用origin来代表远程仓库的URL了。

但是,在进行推送时,由于Github上的项目有权限管理,除了远程仓库的创立者本人,其他用户都无权进行代码的推送。所以,每次将本地仓库的代码进行推送时,都需要输入账号密码验证推送者身份。

image-202020415195957464

# SSH协议

虽然公网上推荐使用HTTPS协议进行加密传输;但是,在公司内网中只有HTTP协议,每次推送代码都需要重复输入用户名和密码,比较不方便;因此,可以采用SSH协议进行身份验证,过程如下:

  • 首先,采用SSH地址关联远程仓库:

    image-20200415200040097

     git remote add origin git@github.com:AhuntSun/test.git
    
    1

    注意到,Github已经提示我们当前Github账号没有任何SSH公钥。

  • 添加之后,查看远程仓库地址:

     git remote show origin
    
    1

    image-20200415200521163

    如图所示,本地仓库没有远程仓库的访问权限。这是因为我们并没有将本地的SSH公钥部署到远程仓库上,为了解决这个问题,我们需要在本地生成秘钥对,并将其中的公钥部署到远程仓库上。

# 生成秘钥对

.ssh文件夹下有一个known_hosts的文件:

image-20200328152518312

打开该文件,可以看到远程仓库GithubIP地址已经添加到了本地信任地址中:

image-20200415200922784

接下来,使用以下命令生成本地计算机的公钥和私钥:

方法一:

ssh-keygen
1

image-20200328153029340

在生成过程中,可以选择公钥和私钥的保存地址,默认是保存在.ssh文件夹下的;还可以设置密码,也可以不设置,直接两次回车后成功生成公钥和私钥;

方法二:

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

image-20200419143846484

上述的邮箱作用为识别所用的key,当你创建ssh的时候:

  • 参数-t:表示密钥的类型;
  • 参数-C:用于识别这个密钥的注释;因此,这个注释可以输入任何内容,很多网站和软件用这个注释作为密钥的名字。

执行上述命令之后,可以在.ssh文件夹下查看生成的秘钥对:

image-20200328153154037

其中,id_rsa表示私钥,id_rsa.pub表示公钥,我们可以分别查看一下它们的内容:

  • 公钥:

image-20200328153258023

  • 私钥:

image-20200328153328042

# 部署公钥

接着我们要做的就是把生成的公钥部署到远程仓库Github上,如下图所示:

image-20200328153538328

在该界面中可以添加多个公钥,如果项目组会有多个成员,或者一个人使用多台电脑时可以设置多个公钥:

image-20200328154605789

如图所示,可以自定义公钥的名字。注意:一定要勾选Allow write access选项,否则无法将本地仓库代码推送到该远程仓库。并且,添加时需要输入Github账号密码进行确认:

image-20200328153903341

添加完成后,就可以在原来的界面看到新增的公钥了。这样使用该公钥的本地计算机就具有了读写这个远程仓库的权限了;

image-20200328154723134

完成公钥的部署后,就可以成功地查看远程仓库的地址了:

image-20200415204247670

实际开发中,通常会使用SSH协议进行本地仓库与远程仓库的连接。因为只需要配置一次公钥,就可以进行免密推送,十分方便;

# 添加账户SSH

之前在Github上的test仓库中添加了一把SSH公钥,但是该SSH KEY仅限于本地与test仓库的通信,不能在其他仓库中使用。

image-20200415204439936

如果我们想要让Github上的所有仓库都使用同一把SSH KEY,就需要配置针对账号的SSH KEY了。点击Github右上角的Settings

image-20200329193849833

在该界面可以新建全局的SSH KEY

image-20200329194410138

# 2.推送代码

建立了本地仓库与远程仓库的联系之后,就可以将本地仓库的文件推送到远程仓库了:

 git push -u origin master
1

上述指令表示将本地的master分支推送到远程仓库的master分支上,加上-u表示将本地的master分支与远程的master分支建立关联;再次推送时就可以直接通过git push进行推送了。

# 3.查看远程仓库地址

可以通过以下三种方法查看所有与本地仓库关联的远程仓库的地址:

git remote //只显示远程仓库地址名
git remote -v //显示远程仓库地址名和对应URL
git remote show origin//显示详细信息
1
2
3

image-20200407221734277

在通过git remote show origin显示的详细信息中:

  • Fetch URL:表示拉取文件到本地的远程仓库的URL

  • Push URL:表示推送时的远程仓库的URL

  • 可以看到进行git pullgit push操作时,本地与远程分支之间是一一对应的关系;

# 4.修改远程仓库地址

  • 方法一:删除原有地址,再添加新的URL
git remote rm origin
git remote add origin https://gitee.com/ahuntsun/gitTest.git
1
2
  • 方法二:修改原有的远程仓库URL
git remote set-url origin https://163.com
1
  • 方法三:直接修改.git仓库的config文件

image-20200328063634159

不建议使用这种方法,建议使用命令行修改。手动修改时,可能只是修改了一部分(不全)。这样可能会造成一些无法维护的情况;

**注意:**尽量避免直接手动操作文件,对于常见的,合理的操作git都提供了相应的指令,使用这些指令更加安全和高效。

对于git来说,默认情况下,它的远程仓库的地址都叫origin;当需要为本地仓库添加多个远程仓库地址时,可通过以下方式:

 git remote add newOrigin https://biliwa.com
1

image-20200328145720489

不过,在将本地仓库的文件推送到不同的远程仓库时,需要重新建立关联:

 git push -u newOrigin master
1

与远程仓库的相关分支建立关联后,可直接使用git push进行推送(简写的原理将在下一节进行讲解)。

# 四、Git图形化界面

Git图形化界面非常之多,各种图形化界面的操作不尽相同。但是,它们的实质都是一样的。都是通过执行一条条Git命令,来实现图形化界面中的各种操作。因此,在熟练掌握Git底层操作命令的前提下,再使用Git图形化界面会更加得心应手。因此,十分不建议初学者直接从Git图形化界面入门。

下面简单介绍比较常见的四种Git图形化界面,分别是:gitkGit GuiGithub DeskTopSourceTree

# 1.gitk

gitkgit自带的图形化界面,输入命令:gitk,就可以打开下图所示的图形化界面:

image-20200329103724204

gitk图形化界面中:

  • 左侧表示提交历史,从下往上,从旧到新;

  • 右边的两栏分别是每次提交对应的用户时间

image-20200329104548998

该界面很好地展示了**git合并的原则**:三方合并,如下图所示:

image-20200329104940260

append 1append 2两次提交的合并过程为:找到它们公共的父节点add a hello,然后在该节点的基础上合并两个节点,得到合并后的master节点。该节点有两个parent指针,分别指向append 1append 2

gitk界面的下半部分如下图所示:

image-20200329105310417

  • 上图的SHA1 ID表示每次提交的识别码,也就是commit_id
  • AuthorCommitter分别表示代码的作者和代码的提交者,一般情况下二者是同一人;但是在一些开源项目中,代码的作者是没有权力提交代码的(如Github)。只能提交一个补丁issue,待开源项目作者同意修改后,才会由项目作者代替代码作者提交代码;
  • 再下面的就是各个文件修改的详细信息;如下图所示,Parent表示的是上一次提交,Child表示的是下一次提交:

image-20200329105659158

image-20200329105824734

# 2.Git Gui

Git Gui同样也是git内置的图形化界面,输入git gui命令便可打开:

image-20200329110131346

在上图中:

  • Unstaged Changes:表示未添加到暂存区的文件或改动,即工作区文件;
  • Staged Changes:表示暂存区中的文件或改动,即将被提交;
  • Modified,not stage:表示文件已修改但未被纳入暂存区;

image-20200329110304513

通过git add .可将所有改动纳入暂存区:

image-20200329110610386

执行完上述指令后,再次查看Git Gui会发现,文件转移到了Stage Changes区域中。随后可以直接在Git Gui界面进行提交,如下图所示:

image-20200329110714387

Git Gui中的每一步操作,实际上都是通过命令行中的一条条指令实现的。除此之外,Git Gui的菜单栏还提供了很多功能:

image-20200329111217827

# 3.Github DeskTop

这是Github的客户端应用程序,同样属于Git图形化界面:

image-20200329111727510

在界面的File选项中可以添加一个本地仓库进行管理:

image-20200329111945655

image-20200329112002719

添加后可以查看该本地仓库的提交历史和其他相关信息:

image-20200329112057396

# 4.Sourcetree

这是一个比较受欢迎的Git图形化界面,官方网址为:https://www.sourcetreeapp.com/

image-20200415112533399

安装时需要注册一个账号:

image-20200415210504189

安装完成后,就可以使用了:

image-20200415232345617

功能十分强大,使用起来也十分地方便,这里就不详细介绍了,有兴趣的可以查阅网上的资料。

最后更新于: 2020年6月13日星期六晚上7点32分