git reset揭秘
一、命令
首先,让我们来解释几个定义.
HEAD(头)
指向当前branch最顶端的一个commit,该分支上一次commit后的节点
Index(索引)
The index, 也可以被认为是staging area(暂存区), 是一堆将在下一次commit中提交的文件,提交之后它就是 HEAD的父节点. (译注:git add添加的文件)
Working Copy(工作副本)
当前工作目录下的文件,(译注:一般指,有修改,没有git add,没有git commit的文件)
Flow(流程如下)
当你第一次checkout一个新的分支,HEAD指向该分支上最近一次commit。它和index和working copy是一样一样的。
当你修改了一个文件,Git注意到了会说“哦,有些东西被改了”,你的working copy不再和index和HEAD相同了,所以当文件有改动,它会标记这些文件。
然后,你执行git add命令,这条命令会将上面修改的文件缓存在index中,Git又说了“哦,你的working copy和index相同了,而他们俩和HEAD不同了”。
当你执行git commit,Git创建了一个新的commit,HEAD这时指向这个新的commit,此时,HEAD & index & working copy又相同了,Git又开心了一次。
二、命令
git reset 命令是git中最常用的命令,但也是最危险,最容易被误用的命令。reset命令本身很简单,但是它的参数让人迷惑,主要的参数有soft, hard and mixed,它们告诉Git,当执行reset时,要对index和working copy做什么。
Soft
The --soft参数只告诉Git将其他的commit重置到HEAD,就仅此而已。index和working copy中的文件都不改变。
实例:
git reset --soft 回退到某个版本,只回退了commit的信息,不会恢复到index file一级(即git add一级)。如果还要提交,直接commit即可
Mixed (default)
The --mixed 改变HEAD和index,指向那个你要reset到的commit上。而working copy文件不被改变。当然会显示工作目录下有修改,但没有缓存到index中。
实例:
git reset --mixed 此为默认方式,不带任何参数的git reset,即时这种方式,它回退到某个版本,只保留源码,回退commit和index信息
Hard
The --hard HEAD & index & working copy同时改变到你要reset到的那个commit上。这个参数很危险,执行了它,你的本地修改可能就丢失了。
实例:
git reset --mixed:彻底回退到某个版本,本地的源码也会变为上一个版本的内容,此命令 慎用!
命令后面就跟的是我们需要reset的位置,比如 origin/develop 、 origin/master 当然也可以使上几次commit的id。
id的话我们可以通过git log查看
三、揭秘
之前我们看到了reset后master文件的内容发生了变化,其实这就是reset命令的本质,但结合不同的参数,会有额外的工作:如--hard --soft --mixed等,他们决定了是否重置暂存区或工作区。
我们来看下面图片
其实reset命令有两种用法:
git reset [-q] [commit] [--] <paths>
git reset [--soft | --mixed | --hard | --merge | --keep] [-q] [<commit>]
第一种用法是不会重置引用的,即不会修改master文件。只是用某一次提交的文件提交暂存区的文件
第二种用法不使用<paths> 则会重置引用,并且参数不同决定是否覆盖暂存区和工作区:
--hard参数会执行途中1,2,3 全部动作,即暂存区,工作区全部用指定提交版本的目录树替换掉
--soft 参数只执行1, 不进行暂存区和工作区的覆盖
--mixed或不使用参数,执行1,2覆盖暂存区,但不覆盖工作区
好了git reset 命令就说到这里吧,还有更多的git命令详解等有时间了再总结放出来。