目录
一、在 Linux 环境中安装 Git
1. 先检查当前服务器中是否有 Git(如果有显示如下图)
2. 安装Git
3. 然后重复第一步:查看 Git 的版本信息即可
二、Git 的初始化及配置
1. 创建目录
2. 对仓库进行初始化
3. 新增两个配置项(git cofig)
三、 Git 的使用
1. 在仓库中创建一个文件(touch ReadMe)编辑
四、Git 场景操作
1. 分多次 add 和 commit
2. 查看修改的是哪一个文件(显示暂存区和工作区文件的差异)
3. 查看文件修改的内容
4. Git 的版本回退 (reset)
5. 撤销工作区的文件到上一个版本(chechout)
6. 删除文件
前言
假设有这样一个场景,老板让员工做一个档案,员工这个档案做好了之后交给老板看,此时老板不满意,又让回去改,改完给老板看,但是老板又不是很满意,就这样改了又改,给老板看过之后,老板此时说第一版是最符合预期的,这个时候员工就..........
然后就演化出了 Git(就是一个很主流的版本控制器),简单来说它就是一个文件版本管理系统,可以记录各种文件的版本信息,就像上述的设计文档,改过一次就是一个版本,这样就产生了很多个版本,那这个版本维护的工作其实是很困难的,那如何才能清楚的记录每一个版本的改动的信息呢,这个时候 Git 就出现了。它可以帮助我们做一个版本的维护,而且不仅仅局限于文档的形式,它可以维护各种文件,包括二进制文件。
对于开发人员来说,最重要的就是可以管理项目中的源代码文档,对于文本文件来说,如下图所示:
可以很清晰的看到新增的信息,但是 Git 不仅仅文本,还有二进制文件(图片,视频),对于这种文件 Git 无法知道而每个版本修改的内容是什么,如图片,原来是 100Kb 大小的图片,现在变成 200Kb,这个 Git 是可以知道的。
首先在 Git 中存储各种版本的各种文件时,也不是直接就可以将修改过的文件放在服务器的任意位置的,此时 Git 是无法进行追踪管理的,所以要使用 Git 存储一些文件时,需要把文件存放在 Git 仓库中,这个仓库是在目录中创建的,所以首先要创建一个目录:
之后需要进行初始化(git init),之后用 tree 命令,这个.git/ 就是追踪管理我们的仓库的,但是不要修改这个文件中的内容,就可以看到这个仓库中有各种初始化的文件了:
第一个配置项就是 name,第二个就是 Email,如果不进行这两个配置项,以后再使用 Git 管理文件的时候就会出错,配置如下:
git config user.name "用户名"
git config user.email "邮箱地址"
git config -l (列出git中的配置项有哪些)
(还可以对配置项进行删除)(git config --unset 要删除的配置项)
通过上述命令就可以对 git 的配置文件进行简单的操作了,还有一个重要的配置项:
(git config --global)
在一台服务器中,可以创建很多个本地仓库,上述 加了 --gloabl 参数的目的就说明在当前服务器的所有仓库这个配置都是生效的,可以看到上图中执行结果,但是如果要删除这个配置选项,刚才的删除方式就不可行了,如下图:
可以看到,如果配置的是全局配置项,在删除的时候也需要加上 --gloabl 这个参数。
但是这个ReadMe 文件也是不能托管给 Git 管理的,因为只有 .git 文件才是版本库,但是也不能 cd 到 .git 创建一个文件,上述已经说过,.git 文件是不能做出任何修改的,否则本地仓库就不能使用了,所以只能将 ReadMe 文件写在 gitcide 目录下,.git 就是版本库,此时 ReadMe 文件所在的就是工作区,此时有了 版本库(对应着上图中.git文件的树状结构)和工作区两个概念,如下图:
左半部分就对应着工作区(ReadMe文件),右边就是版本库,其中有两个区域,stage(暂存区 / 索引),master(分支),如果要将各种文件托管给 Git,就需要上图的流程:
1. 将工作区中的修改(修改包含:新增 / 删除 / 修改)的内容 add 到版本库中的 暂存区(stage) |
2. 将 暂存区的文件 commit 到 master 分支,在 master 中的文件才能真正的被管理维护。(master 分支才算是真正意义的本地仓库) |
那是如何做到对文件的版本信息的维护呢? 在版本库中其实还维护着一个对象库(objects)
这个里面存储的就是一个个的 Git 对象,当工作区的文件修改之后,会将修改i的内容存储其中的一个 Git 对象中,Git 对象会被维护到 Git 对象库中,每 add 一次,这个对象库中就会存一份修改的内容,这个 stage(暂存区)存储的就是一个个修改后的对象的索引,所以暂存区也是很轻量的,没有存储很多的对象。
commit 操作就是将暂存区的这个树状结构写到 master 分支下,这个分支存储的也不是 Git 对象,存储的也是一个目录树,这个树中存储的也是 Git 对象库的索引。
上图中还有一个 Head,它就是一个指针,有了 Head就可以拿到master分支中的索引,之后就可以拿到每一次修改的文件内容。
通过上述的种种流程,就是 Git 如何来管理维护一个文件。可以通过下图来对照看:
如上图所示:如果在 add 其中一个文件之后,又创建了一个文件,没有 add 之前是不能进行 commit 的,但是可以分多次 add,分多次 进行 commit。
(git status)
(git diff ReadMe)
(git reset [-- soft | --mixed | --hard] [HEAD])
版本回退本质就是上述老板让做的设计文档,改了又改之后,老板决定要第一个版本,此时如果将文档交给 Git 后,Git 也是有这个能力还原出第一个版本的,如下图所示:
Git 的版本回退一般都会在版本库中回退,如果要在工作区和暂存区也回退,需要设置上述命令的参数。
--soft :只会在版本库中回退 |
--mixed : 会在暂存区和版本库中都会回退 |
--hard : 工作区,暂存区,版本库中全部回退(慎用!) |
可以以 --hard 参数为例,可以先打印一下看 gitCode 目录中有哪些文件:
如上图所示;就使用 --hard 参数回退到第一次提交的 ReadMe 文件(只有hello git),使用
git reset --hard [ID] 命令进行回退:
上图执行结果中就只有 ReadMe 一个文件了,其实现在再回退回去也是可以的可以用下边这个命令: git refflog ,来查看 Git 中的每一次操作,我们可以看到如下图所示:
然后再使用 reset 命令:git reset --hard [ID],之后就又回退到原来的版本了。这个回退的前提就是需要找到某一次的 commit ID,但是在开发的时候可能会 commit 很多次操作,此时是不太容易找到 commit ID(就是一个 Git 对象)的,所以 --hard 参数要慎用。
版本回退这个操作是很快很轻量的,因为在回退的时候本质上就是将 master 中的指针进行修改,如下图所示:
(git checkout --)
有了版本回退操作之后,为啥还要有这个,如果写了很多代码,但是发现写的代码质量很差,此时就想将新写的代码进行删除操作,如果要进行手动删除,这个操作很耗时,所以要将工作区的文件回退到上一个版本,就可以使用 checkout 命令来撤销。
如上图所示:存在工作区中的修改后的文件,如果要撤销到上一个版本,使用以下命令:
git checkout -- [filename],(注意 -- 两边都是有空格的,而且必须加上 -- 和文件名,否则 checkout 是另一个含义)如在 ReadMe 文件中新增内容:
此时修改后的 ReadMe 文件只存在于工作区中,但是现在想要回退到上一个版本,可以使用下图命令:
上个表格中的第二种第三种情况都是可以使用 reset 命令来进行撤销操作的,但是需要注意以下两点:
(1)撤销和版本回退的区别:版本回退都是回退到某个 commit,修改的是 master 分支中的指针的指向,不会改变提交历史记录,但是撤销主要是帮助我们修复错误,并回到之前的状态。 |
(2)上述撤销操作都是在 本地仓库中的代码文件没有推送到远程仓库中之前,才可以进行撤销。 |
删除Git 中的文件有两种方式:
(1)rm [filename] git add [filename] git commit -m "细节描述" |
(2)git rm file [filename] git commit -m "细节描述" |
第一种方式分三个步骤,先删除文件,但是这一步只是将工作区中的文件进行了删除,暂存区和版本库中的文件并没有被删除,所以还要进行 add 和 commit。
第二种方式只需两个步骤:git rm 这个命令做了两个工作,第一步就是将工作区和暂存区的文件都进行了删除,但是版本库中的文件还是存在的,所以还需要进行 commit 即可。