查看历史记录

git log


其中,

  • 80555fa9114e1aa95eef4677fda4424829fd80a4de4a738faba2b6c27ef69cf9295df79a95a852e8是哈希值,表示索引。
  • (HEAD -> master)表示指针,指向当前的版本。
  • Author是作者签名,Date是提交时间。
  • second commit, modify 1.txtfirst commit new file 1.txt是我们自己写的提交注释。

多屏显示

为了讲解接下来的内容,不断给1.txt文档增加内容,多添加一些提交(我添加了8次的样子),然后使用git log可以看到:

可以看到一屏已经放不下了,并且左下角多了个:,说明后面还有内容。
在这里和Linux一样,可以按键盘的上下箭头来浏览,也可以空格向下翻页、B键向上翻页,Q键退出。

简要显示

直接用git log显示的内容比较多,浏览起来比较麻烦,所以当日志多的时候可以给此命令附加一些参数:

git log --pretty=oneline

这样一来每条日志只显示简要的一行:
(增加一行“3”写错了,应该是增加一行4,对不住了强迫症朋友)

还可以:

git log --oneline

这样一来哈希值只显示一部分:


版本穿梭

git reflog


相比于之前的git log,多了一些HEAD@{$}的信息,表示回到$版本需要移动$步。
这里的HEAD之前介绍过,表示指针,默认指向时间上离我们最近的版本,可以操控指针移动来实现版本回退。
有3种方式:

基于索引值操作(推荐)

命令:git reset --hard <局部索引值>

然后使用cat 1.txt查看1.txt的内容:

可以看到版本回退成功。
然后再使用git reflog来看:

可以看到指针指到了HEAD@{6}这条记录。
这种基于索引值的命令可以随意穿梭,前进后退都行。总之只要你知道你想去的那个版本,就可以穿梭到那。

插曲小tip
在git bash窗口中,选中即复制,什么键都不用按。也就是说选中后直接粘贴就行。
而在Windows的cmd窗口中,选中之后按一下鼠标右键是复制。

使用^符号,只能后退

命令:git reset --hard HEAD^
我们再回到最新的版本,然后用git log --oneline

然后使用git reset --hard HEAD^

可以看到它回退到了上一个版本。

HEAD后有几个^,就回退几个版本:

但这样有很大的限制,如果是要回退好几十个版本,那写好几十个^岂不是要累坏……
所以就可以用~符号。

使用~符号,只能后退

命令:git reset --hard HEAD~<回退步数>

使用^~,都需要数一下回退步数,如果是要回退几十次,很容易数错
所以还是推荐使用git reset --hard <局部索引值>

另外,使用git reset --hard HEAD,不加^~,就表示统一工作区、暂存区到本地库HEAD指针指向的位置。相关内容见下面。


reset命令的三个参数对比

解释

可以使用git help <命令名>查看帮助,比如输入git help reset就会在浏览器中弹出git-reset.html帮助文件,

在这里可以看到reset命令的3个参数解释:

–soft
Does not touch the index file or the working tree at all (but resets the head to <commit>, just like all modes do). This leaves all your changed files “Changes to be committed”, as git status would put it.

index file指的是暂存区,working tree指的是工作区。也就是说--soft不涉及到暂存区和工作区,仅仅在本地库中移动HEAD指针。

–mixed
Resets the index but not the working tree (i.e., the changed files are preserved but not marked for commit) and reports what has not been updated. This is the default action.
If -N is specified, removed paths are marked as intent-to-add (see git-add(1)).

重置暂存区,但不涉及工作区。也就是在本地库移动HEAD指针的同时重置暂存区。

–hard
Resets the index and working tree. Any changes to tracked files in the working tree since <commit> are discarded. Any untracked files or directories in the way of writing any tracked files are simply deleted.

在本地库移动HEAD指针的同时重置暂存区和工作区。可以感觉到“hard”的含义了,确实很hard。

演示

下面分别运行这3个参数体会一下。
先用git reflog查看一下当前HEAD指针的位置:

可以看到HEAD是指在“增加一行7”的版本。

--soft
使用git reset --soft 2a84e07把HEAD指针移动到“增加一行B”的版本,然后使用cat 1.txt查看一下1.txt文件:

可以看到1.txt并没有修改,也就是本地的工作区没被修改。
再用git status看一下暂存区:

字儿变成绿的了,提示modified 1.txt,这是因为本地库的版本变了,而暂存区的版本没变,导致暂存区和本地库不一致,所以它就提示“modified”。
也就是说不是因为我们修改而1.txt直接导致modified,而是因为本地库版本改变间接导致modified

--mixed
--soft上面一样的一套操作:

移动到“增加一行8”的版本,然后用cat 1.txt发现本地工作区没被改变。
而使用git status查看暂存区,发现字儿变成红的了,也就是暂存区被改变了。

--hard

可以看见本地工作区文件被修改,并且暂存区没什么提示。
也就是说工作区、暂存区、本地库三者同步了。

实际上--soft--mixed很少用到。