我们先来说一下,Git的当前是在哪个版本,在Git中我们用HEAD表示当前版本,也就是我们最新提交的”749f84ccb87……ff2q6ad“,上一个版本就应该这么表示”HEAD^“,再上一个版本就这样表示”HEAD^^“,当然如果有几十个版本或者1000个版本,我们还要写1000个^,这是不可能的,所以哟。我们写成这样HEAD~1000。好了,现在我们就用git
reset命令,将我们的版本回退到”add readme.txt“中吧,如下图:
大家可以看到,我们回到了”add readme.txt“版本中了,下面我们再来查看一下git
log,如下图:
有个问题哦,有没有发现我们最后提交的那个版本不见了,如上图。现在只有三个版本了,这说明什么问题呢?举个简单的例子说明一下,就好比你从现在回到了18世界,想再回到21世界已经回不去了,那应该怎么办呢?只要我们找到最新版本的commit
id,我这里新版本的commit id是”749f84ccb87……ff2q6ad“,于是就可以回到未来的某个版本,就好比我们知道现在的时间,就能回到现在。下面我们来演示一下(如下图):
好了,大家可以看到我们又回到最新版本,嘿嘿。现在你回退到某个版本中,已经关掉了Git
bash。但是呢,你又后悔了,想恢复到新版本中,但是呢?你又找不到commit id了,那又该怎么办呢?在Git中,我们当时用$
git reset --hard HEAD^^^,回退到“add readme.txt”版本时,再想恢复到最新版的
“add a line distributed” 中,必须有commit id才行,这时我们已经关闭了Git
bash。在Git中提供了一个git reflog命令,是用来记录你每一次执行的命令,下面我们来演示一下(如下图):
嘿嘿,现在我们又可以回去最新版了。好了,到这里我们的回滚版本就讲解完成了。下面我们来说一下,工作区、提交区/暂存区(stage/index)、版本库。
3.工作区、提交区/暂存区(stage/index)、版本库
其实呢,工作区、提交区/暂存区(stage/index)、版本库的概念问题,从上图中就能看的很清楚,本来不想细讲的,但想想还是说一下。Git与其他版本版本控制器其中之一的不同之处就在于有提交区/暂存区(stage/index)的概念。下面我们先来看一下工作区:
其实呢,工作区就是我们开发目录了,在电脑中是可能看到的,比如我们这里的pro目录,就是一个工作区。大家再来看一下,下面的两张图:
大家可以看到,工作区中有个隐藏的目录“.git”,这个不是工作区哦,这个就是Git的版本库。大家再看下面两张图:
大家可以看到,在“.git”目录中有很多文件,其中一个重要的文件index,就是我们说的提交区/暂存区(stage/index)。暂存区(stage,
index)是 Git 最重要的概念之一,理解了这个概念很多 Git 命令就不再那么神秘了。对于 Git
暂存区(stage) ,不知道您的感想如何?
“被眼花缭乱的 Git 魔法彻底搞糊涂了?”
“Git 为什么这么折磨人,修改的文件直接提交不就完了么?”
“看不出 Git 这么做有什么好处?”
我认为 Git 暂存区(stage或称为 index)的设计是 Git
最成功的设计之一,也是最难理解的一个设计。 在版本库(.git)目录下,有一个 index 文件,相信大家在上图中已经看到了。下面我们好好说一说他们之间关系,同样的我们先看一张图:
在上图中,我们可以看到部分 Git 命令是如何影响工作区和暂存区(stage/index)的。
图中左侧为工作区,右侧为版本库。在版本库中标记为 "index"
的区域是暂存区(stage/index),标记为 "master" 的是 master
分支所代表的目录树(关于分支问题在下面的文章中会详解)。
图中我们可以看出此时 "HEAD" 实际是指向 master
分支的一个“指针”。所以,图示的命令中出现 HEAD 的地方可以用 master 来替换(HEAD的概念我们在后面的文章中也会详解)。
图中的 objects 标识的区域为 Git 的对象库,实际位于 ".git/objects"
目录下,我们会在后面的文章中将重点介绍,嘿嘿!
当对工作区新增或修改的文件执行 "git add"
命令时,暂存区的目录树被更新,同时工作区新增或修改的文件内容被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中。(如上图)
当执行提交操作 "git commit" 时,暂存区的目录树写到版本库的对象库(objects)中,master
分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。(如上图)
当执行 "git reset HEAD" 命令时,暂存区的目录树会被重写,被
master 分支指向的目录树所替换,但是工作区不受影响。 当执行 "git rm --cached
<file>" 命令时,会直接从暂存区删除文件,工作区则不做出改变。
当执行 "git checkout ." 或者 "git
checkout -- <file>" 命令时,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区的改动。
当执行 "git checkout HEAD ."
或者 "git checkout HEAD <file>" 命令时,会用
HEAD 指向的 master 分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。
好了,到这里我们的工作区、暂存区、版本库就讲解到这里了,由于本人能力有限有什么不正确的地方欢迎大家指出。好了,下面我们继续讲解……
4.修改管理
1).关于修改
在上面的文章中我们讲解了工作区、暂存区和版本库的概念,有了这些概念有理解。下面我们说一说为什么Git比其它版本控制软件优秀?嘿嘿,是因为Git跟踪管理的是我们每一次的修改(或操作),而不是文件。比如你新增了一行,这就是一个修改,删除了一行,也是一个修改,更改了某些字符,也是一个修改,删了一些又加了一些,也是一个修改,甚至创建一个新文件,也算一个修改。下面我们来简单演示一下:我们先查看一下readme.txt文件,如下图:
下面我们修改一下readme.txt内容,增加一行:Git rest 1.如下图:
下面我们用 git add 命令提交一下,如下图:
下面我们再修改一下readme.txt文件,如下图:
我们又增加一行 Git test 2. 如下图:
下面我们提交一下,如下图:
下面我们再查看一下状态,如下图:
大家可以看到我们第二次没有被提交,怎么会这样呢?细心的博友可以看到我们第二次修改后,直接执行
git commit了。没有执行 git add 命令,前面我们说了,当你用“git add”命令后,在工作区的第一次修改被放入暂存区,准备提交。但是,在工作区的第二次修改并没有放入暂存区,所以,“git
commit”只负责把暂存区的修改提交了,也就是第一次的修改被提交了,第二次的修改不会被提交。下面我们用
git diff 命令查看一下工作区与版本库里面的区别:
大家可以从图上看到,我们增加 Git test 2. 还没有提交,嘿嘿!那么第二次修改怎么提交呢?其实我们再add再commit,就可以了。如下图:
好了,现在,你又理解了Git是如何跟踪修改的,每次修改,如果不add到暂存区,那就不会加入到commit中。那么我们想取消修改的版本,又该怎么取消呢?下面我们继续……
2).取消(撤消)修改
下面我们来讲解怎么撤消修改,一般情况下我们是不会出错的,但是项目比较紧,老是有人在催你(这个你懂的),突然出错了,我们想取消修改那又怎么办呢?如下图:
在你要提交之前,你发现在有错误了,应该是101。既然错误发现得很及时,就可以很容易地纠正它。你可以删掉最后一行,手动把文件恢复到上一个版本的状态。我信先用git
status查看一下,如下图:
如上图,Git会告诉你有你个文件被修改,你有两个选择,一个用 git add
提交到暂存区,另一个是用git checkout可以丢弃工作区的修改。命令git checkout --
readme.txt意思就是,把readme.txt文件在工作区的修改全部撤销,这里有两种情况:
一种是readme.txt自修改后还没有被放到暂存区,现在撤销修改就回到和版本库一模一样的状态;
另一种是readme.txt已经添加到暂存区后,又作了修改,现在撤销修改就回到添加到暂存区后的状态。
总之,就是让这个文件回到最近一次git commit或git add时的状态。下面我们来演示一下,如下图:
大家可以看一下 readme.txt 文件果然还原到上一个版本了,嘿嘿!大家注意哦,git
checkout -- file命令中的“--”很重要,没有“--”,就变成了“创建一个新分支”的命令,我们在后面的文章中将详细讲解分支管理。真是祸不单行啊,我们不但程序写错了,还
git add 到暂存区了,如下图:
不管怎么样,我们先查看一下状态吧,如下图:
大家可以看到Git告诉我们,用 git reset HEAD file
可以把暂存区中的修改撤消掉,重新放回工作区,如下图:
git reset命令既可以回退版本,也可以把工作区的某些文件替换为版本库中的文件。当我们用HEAD时,表示最新的版本。我们再用
git status 查看一下发现,现在的暂存区是干净的,工作区有修改。
那说明我们撤消成功,嘿嘿!下面我们再执行 git checkout命令撤消工作区修改,如下图:
好了,到这里我们终于撤消回来了,嘿嘿。现在,假设你不但改错了东西,还从暂存区提交到了版本库,怎么办呢?还记得版本回退一节吗?可以回退到上一个版本。不过,这是有条件的,就是你还没有把自己的本地版本库推送到远程。还记得Git是分布式版本控制系统吗?我们后面会讲到远程版本库,一旦你把错误提交推送到远程版本库,你就真的惨了……大家小心就好,哈哈……好了,下面我们来总结一下:
当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git
checkout -- file。
当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git
reset HEAD file,就回到了第1步,第二步按第1步进行操作,就是执行一下git checkout
-- file。
已经提交了不合适的修改到版本库时,想要撤销本次提交,参考我们前面讲解的版本回退,不过前提是没有推送到远程库。嘿嘿,祝你回退成功。
好了,撤消管理我们已经讲了很多了,下面我们来说一下文件删除的问题,终于快通关了。嘿嘿……
5.文件删除
删除文件就比较简单了,我们快速的过一下了,嘿嘿!下面我们新增加一个文件并提交到Git版本库中,如下图:
一般我们直接在目录中把没用的文件删了,或者用rm命令删了,下面我们来演示一下:
大家可以看到,我们用 git status 查看一下状态,现在我们有两个选择,一个是从版本库中删除该文件,就
git rm 命令删除掉并用 git commit提交,另一种情况删错了,因为版本库里还有所以可以很容易的恢复。下面我们来演示一下情况1:
好了,下面我们来看一下情况2:
git rm 命令用于删除一个文件。如果一个文件已经被提交到版本库,那么你永远不用担心误删,但是要小心,你只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容。好了,到这里我们删除文件就讲解完成,嘿嘿。
六、总结
在一篇博客中我们讲解了Git 本地版本库的讲解,在下一篇博客中我们主要讲解Git
远程仓库详解,好了到这里这篇博客到这里就全部完成。本人能力有限,有任何问题欢迎大家提出并讨论。最后,希望大家有所收获^_^……
Git 本地仓库(Repository)详解(一)
|