likes
comments
collection
share

git-理解git-reset-HEAD命令

作者站长头像
站长
· 阅读数 3

git-理解git-reset-HEAD命令

理解git reset hard HEAD^ 的使用场景

距离最近一次提交后对工作区若干文件(目录下文件)内容做了改动,且没有新增文件,因此这些文件都是被git跟踪了的,还未暂存,等待暂存提交。

本来只想提交某个文件作为一个提交版本,但是一不小心将所有文件都提交了,此时产生了一个新的提交。

想要回到之前的”状态“,就可以使用上述的命令。原理是之前(也就是即将暂存,提交)的状态是工作区文件修改,还未添加到暂存区

使用 git reset hard HEAD^ 等价于 git reset hard --mixed HEAD^,所谓的”混合重置“,作用(对于当前的命令)是将(1) HEAD指针指向当前提交的前一个提交(父提交) ,(2)然后将在暂存区中的文件”退回“到工作区。

退回到工作区的文件内容状态也就是 ”即将提交时刻“工作区”的文件内容状态。

尽管git会管理某个提交时刻已被git跟踪的所有文件,但是没有发生变动的文件不会产生新的副本(copy)。因此产生某个提交,一般理解为将已跟踪且修改,暂存的文件提交到版本库中会比较好。

所以错误提交了所有的文件,提交的文件特指 产生了副本的文件。当重置后,会将已经暂存的文件从暂存区撤销,但是撤销的也是之前提交的所有文件(包括不产生副本的文件),不过因为这些文件没有发生变动,所以看起来好像只是撤销了之前提交的文件

单纯用文字描述不直观,下面一些图示更能清晰说明过程

git-理解git-reset-HEAD命令

图 1-1-时刻1:即将暂存,准备提交

a3,a2表示文件状态(版本),此时因为工作区发生了新的变动,所以文件状态变化了,版本也更新了,而暂存区和版本库中文件状态还是之前的状态。

git-理解git-reset-HEAD命令

图 1-2-时刻2:执行暂存命令,执行提交命令

此时只是一个操作过程,内容没有发生改变

git-理解git-reset-HEAD命令

图 1-3-时刻3:提交产生了一个新的提交版本(a3),暂存区文件状态也变为了 a3

注意,此时内容发生较大的变动。暂存区文件状态由 a2 到 a3, 版本库中产生了一个新的提交a3,HEAD指针指向新的提交a3

开始执行 git reseet HEAD^ 命令

git-理解git-reset-HEAD命令

图 1-4-时刻4:执行 git reset HEAD^ 命令版本回退,HEAD指针指向之前的提交(a2)。暂存区内容撤销到工作区

版本回退后最终的效果

git-理解git-reset-HEAD命令

图 1-5-时刻5:版本回退后最终的效果

一切好像没有发生一样,工作区,暂存区,版本库的状态都和之前(即将暂存,提交的时刻)一样。

再次对比前后两个图片

git-理解git-reset-HEAD命令

图 1-6-时刻1:即将暂存,准备提交

git-理解git-reset-HEAD命令

图 1-7-时刻5:版本回退后最终的效果

看起来是一样,本质上有区别。即使 HEAD指针指向之前的提交,但是 a3的提交对应的文件快照还git版本中,只不过目前无法直接看到 a3的提交在分支视图中。实际上可以使用 git reflog来查看近期完整的git操作的过程,从中可以找到 a3提交的commit id ,从而可以回到到此版本。

这也说明一旦文件被提交,某个提交时刻的文件状态会永远的被git“记录”。git不会轻易的删除某个文件状态,因为一般删除提交只是删除了指向文件快照的引用,并不是文件数据本身。

总结

从上面的说明和图片过程可了解到 git reset 命令的作用是“撤销”暂存,提交的操作。就好像在 word 中添加了一行内容,使用 ctrl + Z撤销一样。