黑帽联盟

标题: Git之旅(4):第一次亲密接触 [打印本页]

作者: 定位    时间: 2020-4-2 16:37
标题: Git之旅(4):第一次亲密接触
在git系列的第一篇文章中我们提到,如果我们需要手动的去管理版本,很有可能需要不停的创建"副本",通过"副本"的方式将各个"状态"保存下来,以便恢复到我们期望的某个"状态",其实,git的思路跟我们差不多,只不过实现方式比我们的笨办法先进太多了,不过,这并不影响我们通过笨办法的思路去学习git的使用。

所以,我们还是从笨办法的思路出发吧。

假设,我在写一个小项目,我的代码都放在一个名为project的目录中,为了保险起见,每过一会儿,我就会对project目录复制一个副本出来,然后在原目录中继续之前的工作,这样,我就能通过之前拷贝的副本,回到任意一个副本所在的状态了。

此处假设,我在2019年5月1日8点8分复制了第一个project目录的副本,为了方便描述,我们用一个圆球表示这个副本,如下图所示
1.png
也就是说,通过这个副本,我们能在之后的任何时候,回到2019年5月1日8点8分时的状态。

过了一会,我又复制出了一个副本,此时的时间是2019年5月1日8点15分,加上之前的副本,我们已经有两个副本了,也就是说,我们已经保存了两个状态,可供我们恢复,使用下图表示我们保存的两个副本:
2.png
由于201905010808这个副本是我们第一个保存的副本,所以,我们把它放在最下方,表示一切的起点,就像树根一样,树长高了一点,于是有了201905010815这个副本,但是201905010815这个副本是后来的,所以,我们可以理解成,201905010815这个副本是由201905010808这个副本演变出来的,因为保存201905010808这个副本以后,我们又修改了代码,然后再次创建副本,才有了201905010815,所以,我们可以这样认为,201905010808这个状态是201905010815这个状态的父状态。

过了5分钟,我又创建副本了,好吧,我也是一个不嫌麻烦的人,于是,我们有了三个副本,如下图所示
3.png
同理,201905010820这个状态的父状态是201905010815,换句话说就是,201905010808这个状态是201905010820这个状态的爷爷。

总是手动的创建副本,我真的受不了了,赶紧让git解救我吧。

上一篇文章中我们已经创建了git_test仓库,现在,我们就把这个git_test目录当作刚才提到的project目录,从而开始我们的git之旅吧。

首先,打开"git bash"或者资源管理器,进入git_test仓库,在仓库目录中随便添加一些文件,或者目录,我们用这些文件和目录模拟最开始我编写的一些代码文件和目录结构,以便进行版本管理的相关测试。

注:我的使用习惯是所有操作都在"git bash"中进行,习惯使用vim编辑器编辑文件,你可以按照你的使用习惯创建文件、删除文件、编辑文件,只有在执行相关的git命令时,在"git bash"中执行,以便更加舒适的按照本文使用git。

我在git_test仓库中创建的测试文件如下:
$ ls
dir1/  file1  file2

$ ls dir1
d1file1

$ cat file1
1

$ cat file2
2

$ cat dir1/d1file1
d1f1
如上述信息所示,仓库目录中有两个文件,file1和file2,还有一个目录,dir1,此目录中还有一个名为d1file1的文件,这些文件中分别有一些内容,这些内容只是用于测试,并没有什么实际意义。
$ cat file1
1

$ cat file2
2

$ cat dir1/d1file1
d1f1
好了,我的项目目录中已经有这些文件了,假设这些文件就是我的代码文件,现在,我想要把当前项目的状态保存下来,以便在以后的任何时候,恢复到当前状态,我该怎么办呢?之前说过,我们通过Git管理这些文件时,不用创建副本,但是总要有一种办法能够把当前状态保存下来吧,是的,如果我们想要将一个状态保存到git仓库中,则需要借助一些git命令才行,接下来的操作你可以先大致的看一遍,以便在心里有一个大概的了解,接下来的操作中并不会有太多详细的解释,只是为了让我们对git进行版本管理的大致过程有一个感观上的认识,以便结合之前描述的概念认识git,所以,先看完整个操作过程,我们再进行进一步的讨论。



为了保存项目当前的状态,我使用如下git命令,将当前状态提交到了版本库中。

首先确保你在仓库目录中,然后执行如下命令
$ git add .
$ git commit -m "First snapshot"
你不用在意上述命令的含义,只要知道,我们通过上述命令,将当前状态保存到了版本库中即可,你可以理解成,上述两条命令帮助我们创建了一个"副本",只不过这个副本是以git对象的方式保存在了git仓库中,而不是我们手动复制出的那种"副本",我们可以通过它回到当前"状态"。

什么?你问我怎样找到这个状态?怎样查看之前保存的状态?好吧,为了更加直观的展示,我先用图形化的界面查看一下我们刚才保存的状态吧,前文说过,默认安装后,会安装一个叫gitk的图形化工具,为了更加直观的展示,我们先用这个工具演示怎样查看之前保存的状态吧,有两种方式可以打开gitk,一种是纯图形化的方式打开gitk,一种是通过命令行打开gitk,我的使用习惯是使用命令行打开gitk,因为这样非常方便,操作如下:
首先,确保你的终端路径在git仓库目录中
$ pwd
/d/workspace/git/git_test
然后直接输入gitk命令,即可打开gitk图形化操作界面
$ gitk
打开gitk图形化以后,可以看到如下图所示的一个黄色的"圆球",看到这个"圆球",是不是感觉很亲切,没错,你可以把这个"圆球"理解成上文中我们描述的蓝色"圆球",这个"圆球"就是我们刚才通过命令保存的那个"状态",从下图蓝色底色的文字中可以看到这个状态的描述信息,"First snapshot",细心如你肯定已经发现了,这正是之前使用的git命令中的信息,这个信息是对这个状态的描述,方便我们在很久以后,也能知道这个状态的大致作用是什么,指向这个圆球的,还有一个名叫"master"的东西,我们暂且不用管它是什么,先忽略它,之后我们再去了解它。
4.png
注:当你从命令行中打开gitk以后,命令行会停留在gitk命令的位置,直到你关闭了gitk的图形化界面,如果你想要在执行git命令的同时查看gitk图形化的内容,你最好再打开一个新的"Git Bash",然后在新的"Git Bash"中执行命令。

好了,我们已经保存了第一个"状态",即使从现在开始我把代码改乱了,也能通过这个状态快速的恢复了(恢复操作是后话,不用纠结)。因为当前状态已经保存了,所以我们已经没有了后顾之忧,我们现在可以继续工作了,那么,我随便修改一个文件的内容,模拟一下我们继续工作的样子,假装我们又写了很多代码,操作如下:
$ cat file1
1

$ echo '11' >> file1

$ cat file1
1
11
我通过上述命令,在file1文件中多加入了一行文本,这行文本就是我新开发的代码,假设,我现在又想要将当前项目的状态保存下来,已被不时之需,我只需要执行如下git命令即可(你仍然不需要在意这些命令的含义,先有个大概印象即可):
$ git add .
$ git commit -m "Second snapshot"
好了,我们又保存了一个新的状态,那么我们再来通过gitk查看一下这些状态吧。
再次打开gitk界面(如果你没有关闭之前的gitk,可以按F5快捷键刷新),如下图所示
5.png
从上图可以看出,现在已经有两个"圆球"了,这两个圆球分别代表我们保存的两次状态,你可以把它们理解成我们手动创建的"副本",跟我们使用"笨办法"时的思路一样,"Second snapshot"这个状态其实是由 "First snapshot"这个状态演化而来的,所以,"First snapshot"状态是"Second snapshot"状态的父状态,我们为了方便理解,一直将这些"圆球"称之为"状态",在git中,它有另外一个名字,它在git中被称之为"commit",中文名叫"提交",也就是说,每一个这样的"圆球",都代表一次"提交",之所以被称之为提交,是因为如果想要将某个状态保存下来,就需要提交到版本库中,正如我们上文中使用的git commit命令,这个命令就是来负责将之前改动的内容提交到版本库的。

那么我们再来修改一些内容,然后尝试再次提交。
假装我们又在file1中写了一些代码,并且创建了新的文件,file3
$ echo 111 >> file1

$ echo 3 > file3

$ ls
dir1/  file1  file2  file3

$ cat file1
1
11
111

$ cat file3
3
好了,我们又写了一些"新代码",并且创建了一个新文件,也就是说,从上一次提交以后,我们又做了一些修改,如果我们想要将修改后的状态再次保存,就还需再次进行提交的操作,聪明如你一定想到了,其实我们每次提交,都是在保存上一次提交之后的"变更",或者称之为"变更集"更为合适,因为自从上次提交以后,我们可能已经进行了非常多的操作,我们可以将这些操作作为一个"变更集合",一次性的提交到仓库中,就像我刚才所做的那样,我修改了file1,创建了file3,这些操作都是所谓的变更,你可以认为这是两个变更,如果我再次进行提交,可以将这"两个变更"作为一个"变更集合",一次性提交到git仓库中,好了,说了这么多,我们还没有进行第三次提交,我们赶紧行动吧,执行如下命令,将上述两个变更作为一个变更集,提交到仓库中。
$ git add -A
$ git commit -m "modified file1 and add new file: file3"
你可能会问,为什么每次执行"git commit"命令之前都要执行一个"git add"命令呢?其实,"git add"命令就是用来操作变更集的,当存在多个变更时,我们可以利用"git add"命令,选择将哪些变更加入到本次提交的变更集合中,也就是说,并不是每次提交都要将所有的变更都提交,而是可以有选择性的,只有被加入到变更集中的变更才会被提交, 只不过,上例中的"git add -A"命令并没有进行选择,而是将所有变更作为了一个变更集合,当"git add"命令创建出这个变更集以后,"git commit"命令将这个变更集合提交到了git仓库中。

关于"git add"命令和"git commit"命令我们还有很多话题可以聊,所以不要着急,我们只要对它们有一个初步印象即可。

完成上述步骤后,我们已经有了3个提交,打开gitk,如下图所示
6.png
如果以后,我想要回到这三个版本中的任何一个,就靠它们了!不过,关于版本回退的话题,我们之后再聊吧。

我觉得我应该休息一会儿了,我们就在之后的文章中再见吧。













欢迎光临 黑帽联盟 (https://bbs.cnblackhat.com/) Powered by Discuz! X2.5