跳转至

Git入门-01

参考视频:https://www.bilibili.com/video/BV1vy4y1s7k6/

1.Git概述

Git是一个免费的,开源的分布式版本控制系统,可以快速高效地处理从小型到大型的各种项目。

Git易于学习,占地面积小,性能极快。它具有廉价的本地库,方便的暂存区域和多个工作流分支等特性。其性能优于Subversion,CVS,Perforce 和 ClearCase 等版本控制工具。

1.1何为版本控制

在学习Git之前,我们需要先明白一个概念:版本控制。

版本控制是一种记录文件内容变化,一边将来查阅特定版本修订情况的系统。

版本控制其实最重要的是可以记录文件修改历史记录,从而让用户能够查看历史版本,方便版本切换。

image-20221209001918788

  • 为什么需要版本控制?

从个人开发过渡到团体协作。

1.2版本控制工具

1.2.1集中式版本控制工具

CVS,SVN(Subversion),VSS……

集中化的版本控制系统(Centralized Version Control Systems,简称 CVCS),诸如CVS,SVN等,都有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连接到这台服务器,取出最新的文件或者提交更新。多年以来,这已成为版本控制系统的标准做法。

这种做法带来了许多好处,每个人都可以在一定程度上看到项目中的其他人正在做什么,而管理员也可以轻松掌控每个开发者的权限,并且管理一个集中化的版本控制系统,要远比在每个客户端上维护本地数据库来得轻松容易。

事分两面,有好有坏,这么做显而易见的缺点是中央服务器的单点故障。如果服务器宕机一小时,那么在这一小时内,谁都无法提交更新,也就无法协同工作。

image-20221209003803838

1.2.2分布式版本控制工具

于是分布式版本控制系统(Distributed Version Control System,简称 DVCS)面世了。

在这类系统中,像Git、Mercurial、Bazaar 以及 Darcs 等,客户端并不只提取最新版本的文件快照, 而是把代码仓库完整地镜像下来,包括完整的历史记录。 这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。 因为每一次的克隆操作,实际上都是一次对代码仓库的完整备份。

分布式的版本控制系统出现之后,解决了集中式版本控制系统的缺陷:

  1. 服务器断网的情况下也可以进行开发,因为版本控制系统是在本地进行的
  2. 每个客户端保存的都是整个完整的项目,包含历史记录,更加安全

image-20221209003903055

1.3Git发展历史

image-20221209215608236

1.4Git工作机制

image-20221209215634523

工作区:指的是你代码存放的磁盘目录位置

除此之外可以通过pull,将代码推送到远程库中

1.5Git和代码托管中心

代码托管中心是基于网络服务器的远程代码仓库,一般我们简单称为远程库。

局域网:GitLab

互联网:GitHub,Gitee

2.Git安装

关于Git的详细介绍:Git - Book (git-scm.com)

Git下载地址:Git - Downloads (git-scm.com)

Git安装教程:Git-详细安装教程

3.Git常用命令

命令名称 作用
git config --global user.name 用户名 设置用户签名
git config --global user.email 邮箱 设置用户签名
git init 初始化本地库
git status 查看本地库状态
git add 文件名 添加到暂存区
git commit -m "日志信息" 文件名 提交到本地库
git reflog 查看历史记录
git reset --hard 版本号 版本穿梭

3.1设置用户签名

命令:

git config --global user.name 你的用户名
git config --global user.email 你的邮箱

image-20221209224428028

用户名和邮箱可以多次设置

可以在c盘的用户home目录下的.gitconfig文件中查看修改内容:

image-20221209225222338

说明:签名的作用是区分不同操作者身份。用户的签名信息在每一个版本的提交信息中能够看到,以此确认本次提交是谁做的。Git 首次安装必须设置一下用户签名,否则无法提交代码。 ※注意:这里设置用户签名和将来登录 GitHub(或其他代码托管中心)的账号没有任何关系。

3.2初始化本地库

使用git init命令初始化本地仓库

1.创建一个项目文件夹,在文件夹下面右键,点击Git Bash Here,就可以将当前的路径赋给git命令行,即进入到当前目录。使用git init命令初始化当前目录:

image-20221209225620534

2.初始化成功之后可以在当前目录下看到.git文件(隐藏文件):

image-20221209230419104

3.3查看本地库状态

使用git status命令来查看本地库状态

image-20221209230657136

3.4添加暂存区

使用git add 文件名 命令将工作区的文件添加到暂存区

image-20221209231331429

1.添加过后,Git就可以追踪到该文件:

image-20221209231541310

2.如果在暂存区将该文件的cached删除(不是删除工作区的文件),删除后工作区的该文件又会变回未追踪状态

image-20221209231800416

image-20221209232019992

3.5提交本地库

使用git commit -m "日志信息" 文件名命令将暂存区的缓存文件提交到本地仓库

日志信息必须填写

image-20221209232730387

1.这时如果查看状态,可以看到如下状态,说明已经提交过文件,并且在提交过后文件既没有新增,也没有修改,工作树是干净的

image-20221209232934074

2.也可以通过git reflog命令来查看引用日志信息:下图说明指针head指向了master分支第一次提交的版本

image-20221209233253426

3.还可以使用git log命令来查看详细的日志:不仅可以看到提交的版本号,还可以看到提交者信息和提交时间

image-20221209233611342

3.6修改文件

1.如果我们将**追踪过(创建过快照)**的文件再次进行修改,那么此时该文件的状态将是modified,且是红色的。代表已追踪过的文件又修改了,但是没有提交到暂存区。

image-20221209234419006

2.这时,只要将修改过的文件再次添加到暂存区,文件的状态仍是modified,但是已经变为了绿色。代表已追踪过文件又修改了,并且已经提交到了暂存区。

image-20221209235150197

3.将该文件提交commit后,再次查看本地库的状态,就可以看到工作树清空了

image-20221209235534925

4.查看日志,可以看到本地仓库中有两个代码版本,head指针指向了master分支的第二个版本

image-20221209235822216

3.7历史版本

3.7.1查看历史版本信息

git reflog 查看版本信息

git log 查看版本详细信息

git reflog 和 git log 的区别:

git log是显示当前的HEAD和它的祖先的,递归是沿着当前指针的父亲,父亲的父亲,……,这样的原则。

git reflog根本不遍历HEAD的祖先。它是HEAD所指向的一个顺序的提交列表:它的undo历史。reflog并不是repo(仓库)的一部分,它单独存储,而且不包含在pushesfetches或者clones里面,它纯属是本地的。 reflog可以很好地帮助你恢复你误操作的数据,例如你错误地reset了一个旧的提交,或者rebase,……,这个时候你可以使用reflog去查看在误操作之前的信息,并且使用git reset --hard 去恢复之前的状态。

git-reflog的用法总结

image-20221210000943339

image-20221210001013923

3.7.2版本穿梭

git reset 命令 | 菜鸟教程 (runoob.com)

命令:git reset [--soft|--mixed |--hard] [HEAD|版本号]

版本号可以通过 git reflog 命令查看

1.如下,通过命令可以穿梭回第二个版本。

通过git reflog命令查看日志,可以发现head指针已经指向第二个版本了

image-20221210001534395

这时查看文件,可以发现文件的内容变成了第二个版本commit时的内容。

2.通过上述过程,可以将提交过的文件变为任意版本

image-20221210002428435

progit:在 Git中,每当你提交更新或保存项目状态时,它基本上就会对当时的全部文件创建一个快照并保存这个快照的索引。为了效率,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件。 Git对待数据更像是一个快照流。

4.Git分支操作

image-20221210004730687

4.1什么是分支

在版本控制过程中,同时推进多个任务,为每个任务,我们就可以创建每个任务的单独分支。使用分支意味着程序员可以把自己的工作从开发主线上分离开来,开发自己分支的时候,不会影响主线分支的运行。对于初学者而言,分支可以简单理解为副本,一个分支就是一个单独的副本。(分支底层其实也是指针的引用)

image-20221211000615923

4.2分支的好处

同时并行推进多个功能的开发,提高开发效率。各个分支在开发过程中,如果某一个分支开发失败,不会对其他分支有任何影响。失败的分支删除重新开始即可。

4.3分支的操作

分支命令 作用
git branch 分支名 创建分支
git branch -v 查看分支
git checkout 分支名 切换分支(事实上是切换HEAD指针的指向)
git merge 分支名 把指定的分支合并到当前分支上

4.3.1查看分支

git branch -v 查看分支

image-20221211001748269

*代表当前所在的分支

4.3.2创建分支

git branch 分支名 创建分支

image-20221211002144858

git checkout -d 分支名创建分支并切换到该分支上

4.3.3切换分支

git checkout 分支名 切换分支

image-20221211002419771

可以看到当前分支已经切换到hot-fix分支

master、hot-fix 其实都是指向具体版本记录的指针。当前所在的分支,其实是由 HEAD 决定的。所以创建分支的本质就是多创建一个指针。 HEAD 如果指向 master,那么我们现在就在 master 分支上。 HEAD 如果执行 hotfix,那么我们现在就在 hotfix 分支上。 所以切换分支的本质就是**移动 HEAD 指针**。

4.3.4修改分支

分支的版本控制和主分支完全一致

比如现在修改hot-fix分支的hello.txt文件,查看该文件状态:

image-20221211003437436

将其添加到暂存区并提交:

image-20221211003543855

查看历史版本记录:

image-20221211003639625

image-20221211003714457

注:这里查看hot-fix分支可以看到之前在master分支上的提交记录,是因为分支的底层仍然是指针,它在创建的时候把复制分支当做父记录。这也是为什么创建一个新分支消耗的内存非常小。

4.3.5删除分支

删除本地分支

git branch -d 分支名

删除远程分支

git push remote_name -d remote_branch_name

4.3.6合并分支-正常合并

git merge 分支名:把指定的分支合并到当前分支上

案例演示:在master分支上合并hot-fix分支(正常合并)

image-20221211004458756

4.3.7合并分支-冲突合并

冲突产生的原因:合并分支时,**两个分支在同一个文件的同一个位置**有两套完全不同的修改,Git无法替我们确定使用哪一个,必须**人为决定**新代码内容。

案例演示:合并冲突分支

我们分别在master分支和hot-fix分支的同一个文件上的同一行进行修改,并分别commit

image-20221211005355223

image-20221211005548285

现在我们切换回master分支,在master分支上进行分支合并

系统提示:有文件合并冲突,修改冲突然后才能提交结果

image-20221211010437064

这时的本地库状态为:

image-20221211011220009

用vim打开冲突的文件:可以看到产生冲突的地方已经用符号标注出来了,下图中的标注解释为:

<<<<<<< HEAD 
当前分支的代码 
=======
合并过来的代码 
>>>>>>> hot-fix

image-20221211011935638

手动修改文件,并删除特殊符号,保存文件:

image-20221211012539662

保存完文件之后,还要把修改后的文件再添加到暂存区:

image-20221211012817643

然后提交保存:

注意此时commit不能带文件名,否则会提示错误。因为两个分支上的hello.txt都进行了修改,在合并冲突的情况下,git不知道提交的是哪一个文件

合并成功,右上角的MERGING标识消失:

image-20221211013143720

注意:这里的合并只会修改master分支的文件,hot-fix分支的文件没有被修改

4.3.8Git以分支的方式同时管理多个项目

https://www.shuzhiduo.com/A/mo5kLl7Kdw/

5.Git团队协作机制

5.1团队内协作

image-20221211014417956

5.2跨团队协作

image-20221211014505535

6.GitHub操作

github网址:GitHub

6.1创建远程库

  1. 注册登录账号,点击账号页面

image-20221130184900892

  1. 点击页面右上方的+号,选择new repository,创建新项目

image-20221130203615053

  1. 在repository name中填写你的仓库名

注意:仓库名不支持中文,所有的中文符号会被自动识别为-符号。

  1. 填写项目简介,简介支持中文

image-20221130204103838

  1. 点击add a readme file选项,项目会自动创建一个readme文件

image-20221130204415065

  1. 其他的选项默认即可

  2. 最后点击按钮创建

image-20221130204525444

6.2远程仓库操作

命令名称 作用
git remote -v 查看当前所有远程地址别名
git remote add 别名 远程地址 起别名
git push 别名 分支 推送本地分支上的内容到远程仓库
git clone 远程地址 将远程仓库的内容克隆到本地
git pull 远程库地址别名 远程分支名 将远程仓库对于分支最新内容拉下来后与当前本地分支直接合并

6.2.1创建远程仓库别名

git remote -v 查看当前所有远程地址别名

git remote add 别名 远程地址 给远程仓库起别名

这里使用ssh链接,使用ssh链接前请看6.4SSH免密登录

image-20221211234051674

image-20221211234403603

可以看到拉取远程仓库和推送都可以使用该别名

6.2.2推送本地分支到远程仓库

git push 别名 分支 推送本地分支上的内容到远程仓库,如果没有起别名,使用远程地址代替也可以

现在将本地仓库上的master分支推动到远程仓库上:

image-20221211234239729

在远程仓库上查看,已经成功推送文件:

image-20221211234655576

2021年8月13日起,Github不再支持使用密码push,即不再接受帐户密码登录,下面这个push方法过时了:

image-20221211233106729

6.2.3拉取远程库到本地库

git pull 远程库地址别名 远程分支名 将远程仓库对于分支最新内容拉下来后与当前本地分支**直接合并**

有时候远程仓库上的代码进行了更新,我们需要将新的代码下载到本地仓库里:

可以使用别名或者直接使用远程仓库进行拉取

image-20221211235731470

这时查看本地文件的状态,发现工作树干净的,说明拉取动作会自动帮你提交本地库:

image-20221212000107413

6.2.4克隆远程仓库到本地

git clone 远程地址 将远程仓库的内容克隆到本地

在远程仓库上复制链接:

image-20221212001026285

在本地新建一个空白文件夹git-demo-second,在该文件夹中右键点击git bash here,打开git命令面板,使用克隆命令将远程仓库克隆到本地:

克隆公共仓库的代码不需要登录

image-20221212001206908

克隆成功之后可以发现在git-demo-second目录下,已经成功下载了git-demo仓库的代码:

image-20221212001439777

打开文件夹,不仅可以看到代码文件,还能看到.git隐藏文件:

image-20221212001608421

这说明克隆clone会做如下操作:

  1. 拉取代码
  2. 初始化本地仓库
  3. 创建别名(创建的别名默认为origin,如下:)

image-20221212001854036

6.3团队内协作

6.3.1选择邀请合作者

如果他人想要推送代码到你的仓库,获取你想要推送代码到他人的仓库,必须得到仓库所有者的许可权限,即仓库所有者拉取他人才能进入团队协作。

仓库拥有者操作:

仓库settings--Collaborators--Add people

image-20221212003542826

输入拉取者的账户名称,选择后点击下方按钮:

image-20221212004208595

复制邀请链接Pending Invite,发送给被邀请者:

image-20221212004259379

被邀请者登录自己的github账号,登录后在浏览器地址栏中粘贴邀请链接,回车:

如下所示,被邀请者点击Accept invitation即可加入团队。

image-20221212004813866

点击Accept invitation后会自动跳转到加入的仓库界面:

image-20221212005037737

加入的合作者可以在自己的本地上直接推送代码到远程仓库中。

6.3.2跨团队协作

非团队内的人可以点击fork,将他人的仓库复制到自己的账户下,之后就可以对代码进行修改了。

image-20221212010135282

修改完之后如果要把代码提交到他人的仓库下,要到别人的仓库下点击new pull request:

image-20221212010627051

点击完之后会自动将你修改的代码展示出来,与作者的代码进行对比:

image-20221212010809078

点击上一步的Create pull request后会创建一个拉取请求,可以在这里填写你的提交留言,点击提交,等待作者审批。

image-20221212011152845


仓库所有者可以在仓库的Pull request界面看到别人提交的pull request

image-20221212011646407

点击上一步的pull request标题即可查看提交详情:

image-20221212011826713

点击留言下方的链接可查看别人提交的代码:

image-20221212011946432

也可以给提交者留言(Write):

image-20221212012319262

或者合并别人提交的代码(Merge pull request):

image-20221212012727389

image-20221212012808702

image-20221212012901910

6.4SSH免密登录

想要使用ssh免密登录,首先要添加秘钥。

在本地电脑的用户目录下有一个.ssh目录(第一次安装git的用户可能没有该目录,或者打开该目录是空的)

image-20221212013250386 image-20221212013346468

在git命令窗口中,运行命令生成.ssh 秘钥目录:ssh-keygen -t rsa -C 你的邮箱

这里的邮箱是你注册github账号的邮箱

连续三次回车即可:

image-20221212013936873

这时再次打开.ssh目录,可以发现该目录下已经创建了两个文件:

打开id_rsa.pub,全选复制里面的内容

image-20221212014130291

打开之前邮箱对应的账号:点击账号头像--下拉点击Settings--在设置页面选择SSH and GPG keys

image-20221212014832102

点击右上方的New SSH key,将之前复制的内容粘贴到框中,添加title,点击Add SSH key即可添加成功:

image-20221212015225672

image-20221212015309531


SSH的使用1:

之后就可以在本地使用SSH链接拉取仓库

image-20221212015603581

第一次使用ssh的时候会提示是否继续链接,填写yes,回车:

显示成功拉取远程仓库代码

image-20221212015736835

使用2:可以使用ssh免密推送代码到远程仓库

image-20221212020808323