Git学习记录--git仓库

    Git是一款强大的版本控制工具,与svn相比git的分布式提交,本地仓库等在使用时确实比较方便。当然两者之间各有优劣,我在这里不多做比较。由于之前少有接触git,只是零星大致地了解一点,所以找时间系统地看了下廖老师的git入门教程。廖老师git入门教程:https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000。

作为学习记录,我会跳过git的安装介绍等,也不会系统地挨个介绍使用的git命令。以下主要包括:

  * git仓库(Git仓库的介绍)

    * git本地仓库操作的执行过程(add,commit, diff,reset)

  * 总结

一、Git的仓库(版本库)

  1. Git的本地仓库

  其实就是版本库(repository),直观了解就是自己文件系统中的一个目录,这个目录里的文件可以被git工具管理,目录里文件的增删改都能被Git追踪到。

以下就是在git_learn目录下使用init命令创建的一个本地Git仓库,初始创建时,仓库是空的,需要add并commit才能让Git追踪仓库目录下的文件。

 

  2. Git本地仓库的构成

  当上面在空文件夹下执行 git init 命令后,我们说在当前目录下的Git仓库就创建好了,那创建好的Git仓库到底是什么样呢,除了多了一个隐藏的.git 文件目录,似乎什么也没有。其实,初始化成功后我们的当前目录已经被分成了两个部分,一个是工作区,另一个就是版本库。所谓工作区就是我们能在这个目录下操作文件,进行工作,比如写代码啊T_T。版本库就是那个生成的.git目录了,里面主要包括暂存区(index指向)和版本区(HEAD指向,这个“”版本区“”只是我个人的叫法)。版本区就是放分支的地方,里面会有Git为我们创建的第一个分支,名为master。这里的index和head可以理解为指针的作用。下图就是仓库创建后的样子。

 

 二、Git本地仓库的操作流程

  1. 操作流程

  工作区的文件我们是可以任意添加修改的,修改的文件需要从工作区通过add命令添加到暂存区,再从暂存区commit到版本区。我们也可以从从仓库checkout文件到工作区,操作关系如下图:

  2 .Git的add与commit

  在工作区创建文件file.txt并将改文件提交到Git本地仓库,整个过程执行如下:

 

两步,add 和commit就将file.txt文件的第一个版本加入了git仓库,看看其过程:

工作区创建file.txt第一个版本,这时git仓库并没有追踪到这个文件。

将file.txt添加到暂存区(index指向),这时暂存区的文件和工作区同步。

最后将暂存区的提交到版本区(HEAD指向),这时版本区会自动生成此次提交的版本号,这时file文件已经被git仓库追踪到。

 以上操作都是在初始生成的master分支上完成,每次提交成功后HEAD都会指向版本区中当前分支的最新版本,这里使用master分支提交,所以HEAD指向master分支的当前最新版本,目前只有一个版本(master分支只有一个提交,每次提交形成一个版本,并生成唯一版本号),如果存在多个分支,切换分支时,HEAD就会指向切换到的分支的最新版本。存在分支存在多个版本(多次提交)会形成类似链表的结构。所以在当前仓库版本区(只有master分支,且只有一个提交)具体来说应该是这样的:

 现在编辑file.txt文件,添加一行,形成v2版本(v1是新建的空文件),再执行add和commit,我们依然是在master分支上提交的,这时候file.txt就应该有两个版本了,且是在master分支上,HEAD应该指向的是master的最新分支。

git仓库中的版本区,master分支上存在两个版本,HEAD指向master分支的最新版本:

  3. Git的版本重置 reset

  git的版本可以向前向后移动,如同指向双向链表中的某个节点的指针一样。这里的指针其实就是HEAD,执行reset命令其实就是移动HEAD指向分支上的另一个版本(每一次提交都会形成一个版本)。

例如,我在file.txt中又有修改并且形成了v3版本,现在我想要将file.txt文件回退到上一次提交(v2版本),可以使用  git reset HEAD~1 ,前面说过,每次提交都有版本号,可以通过log和reflog查看提交的版本号,使用git reset 9e5e6a4,来将HEAD重新指向到v2版本。版本号挺长的,但不用写完一般写前面几个就够了。但这是分支上的v3版本依然存在(如同移动指向链表节点的指针,链表节点依然在).

在master分支上回退一次的操作应该是这样:

可以看到,在版本区,HEAD的指向已经指向了master分支的v2版本上,前面说到,git仓库里除了版本区还有暂存区(index指向)和工作区(我们能看到的并工作的目录中)是什么样子呢?

这里reset 有三个可选参数:git reset [--soft | mixed | hard]

git reset --soft HEAD~1:

        soft参数,由于提交了v3版本,在执行reset命令之前,暂存区(index)和工作区应该都是v3版本,执行git reset --soft HEAD~1 之后,暂存区和工作区依然是v3版本,简单来说我们再工作目录看到的依然是v3的内容,只是仓库里的版本区当前版本已经指向了v2.

git reset --mixed HEAD~1:

  mixed参数,这个参数是默认参数。分成两个步骤,首先将HEAD指向改变,再将暂存区(index)与HEAD指向的当前版本同步(到v2版本),工作区依然不变(保留v3版本)。

git reset --hard HEAD~1:

  hard参数,改变HEAD指向,并且将暂存区与工作区全部同步到v2版本,这个时候我们我们可以通过文件直接看到v3版本新添加的内容不见了,回到了v2版本。

当然,我们虽然到了v2版本,那我们依然可以通过reset命令到v3版本,同样的道理。

这里关于reset命令的操作过程我只是简要描述了一下,这里有一篇非常好的讲解,很详细:https://www.cnblogs.com/kidsitcn/p/4513297.html

  4.git 的diff命令

  比较区别,弄清楚git仓库的组成部分就很容易想到比较啦。反正就是这样:

 git diff  :  工作区与暂存区比较

  git diff --cached    : 暂存区与HEAD指向版本比较

git diff HEAD  :  工作区与HEAD指向版本直接比较

git diff 版本号1 版本号2   :     比较两个版本号对应版本版本的不同

 三、总结

  Git仓库主要包括三部分:工作区,暂存区,版本区。 我们对文件的操作是在工作区进行,完成修改后先要将修改内容添加到暂存区,然后再提交到版本区形成一个版本。至于为什么git要设置一个暂存区这样一个中间层,想到一句话调侃的话:没有什么问题是添加一个中间层解决不了的,若有,那就添加两层。想想,如果我们一次要修改的东西太多,我想每写一点东西就先存起来但是又不想让它形成一个版本提交(因为没写完啊,提交的时候需要些commit comment的),那就写一点就提交到暂存区诺,写完后再一次commit。或者正在开心的写着代码,写着一半突然需要切换到另一个分支去修复bug,那就将当前工作内容放到暂存区,然后利用stash功能将暂存区内容打包存起来,等修复完bug再回来恢复继续。另外就是git的status功能,这个功能比较简单,主要显示就是当前仓库的状态,是否有内容需要add到暂存区,是都有暂存的内容需要commit到版本区等等。

原文地址:https://www.cnblogs.com/gonjan-blog/p/8146421.html