查看历史记录
git log
其中,
80555fa9114e1aa95eef4677fda4424829fd80a4
和de4a738faba2b6c27ef69cf9295df79a95a852e8
是哈希值,表示索引。(HEAD -> master)
表示指针,指向当前的版本。Author
是作者签名,Date
是提交时间。second commit, modify 1.txt
和first 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
很少用到。