git的reset和checkout的区别

在讲git的reset和checkout的区别以前,不得不说说HEAD、Index、Working Directory三个区域。git

HEAD、Index、Working Directory

Git里有三个区域很重要缓存

  1. HEAD 指向最近一次commit里的全部snapshot
  2. Index 缓存区域,只有Index区域里的东西才能够被commit
  3. Working Directory 用户操做区域

下图解释了这三个区域的状态的变化过程:spa

图片描述

初始状态

当你checkout分支的时候,git作了这么三件事情code

  1. 将HEAD指向那个分支的最后一次commit
  2. 将HEAD指向的commit里全部文件的snapshot替换掉Index区域里原来的内容
  3. 将Index区域里的内容填充到Working Directory里

因此你能够发现,HEAD、Index、Working Directory这个时候里的内容都是如出一辙的。blog

注意:通常会误解为,Index中的内容是空的,只有git add后才会有东西。实际上不是,Index里一直是有东西的。图片

因此,Git的全部操做就是对这三个区域的状态(或内容)的操做。开发

Changed

若是你在Working Directory里修改了文件,git会发现Working Directory里的内容和Index区域里的内容不一致了。get

这个时候git status的结果是:同步

# Changes not staged for commit:

Staged

一个文件仅仅changed是不能被commit的,Git要求只能提交Index里的东西。it

因此须要git add。这个命令的意思是,把Changed的文件的内容同步到Index区域里。这样Working Directory和Index区域的内容就一致了。这个过程被称之为stage

这个时候git status的结果是:

# Changes to be committed:

Committed

最后,你就能够提交了

git commit

这样,就把HEAD的状态和Index以及Working Directory造成一致了。

reset

reset是用来修改提交历史的,想象这种状况,若是你在2天前提交了一个东西,忽然发现此次提交是有问题的。

这个时候你有两个选择,要么使用git revert(推荐),要么使用git reset。

图片描述

上图能够看到git reset是会修改版本历史的,他会丢弃掉一些版本历史。

而git revert是根据那个commit逆向生成一个新的commit,版本历史是不会被破坏的。

已经push到远程仓库的commit不容许reset

上面已经讲了,git reset是会丢弃掉commit的。

若是commit已经被push到远程仓库上了,也就意味着其余开发人员就可能基于这个commit造成了新的commit,这时你去reset,就会形成其余开发人员的提交历史莫名其妙的丢失,或者其余灾难性的后果。

所以,一旦commit已经被push到远程仓库,那么是坚定不容许去reset它的。

不带文件参数的reset

前面章节已经说道Git有三个区域,Git的全部操做其实是在操做这三个区域的状态(或内容)。

git reset配合不一样的参数,对这三个区域会产生不一样的影响。

reset实际上有3个步骤,根据不一样的参数能够决定执行到哪一个步骤(--soft, --mixed, --hard)。

  1. 改变HEAD所指向的commit(--soft)
  2. 执行第1步,将Index区域更新为HEAD所指向的commit里包含的内容(--mixed)
  3. 执行第一、2步,将Working Directory区域更新为HEAD所指向的commit里包含的内容(--hard)

注意

–mixed是默认参数,也就是说执行reset的时候不给就认为是--mixed

下表说明了三种形式的git reset所产生的不一样效果。

target表明想要将git指向到哪一个commit

working index HEAD target         working index HEAD
----------------------------------------------------
  A       B     C    D     --soft   A       B     D
                           --mixed  A       D     D
                           --hard   D       D     D
                           --merge (disallowed)

working index HEAD target         working index HEAD
----------------------------------------------------
  A       B     C    C     --soft   A       B     C
                           --mixed  A       C     C
                           --hard   C       C     C
                           --merge (disallowed)

带文件参数的reset

上面讲到的git reset实际上不带参数的,若是带上文件参数,那么效果会是怎样的?

  1. HEAD不会动
  2. 将那个commit的snapshot里的那个文件放到Index区域中

须要注意的是带文件参数的git reset没有--hard, --soft这两个参数。只有--mixed参数。

unstage

下面这两个命令是同样的,都是reset到HEAD上。

git reset file.txt
git reset --mixed HEAD file.txt

这个例子的意义在于,unstage file,仔细想想是否是这样?当你把一个文件stage到Index区域里后后悔了,那么只须要把Index区域里的这个文件恢复到最近一次commit的状态(也就是HEAD),那就至关于unstage了。

恢复到历史版本

下面这个命令就是将某个文件恢复到历史版本上。

reset eb43bf file.txt

这个例子的意思在于,把某个文件恢复到Index区域里,而后直接commit,这样就等于把这个文件恢复到历史版本了,这样依赖你都不须要去改动Working Directory了。

checkout

前面讲到checkout是会修改HEAD的指向,变动Index区域里的内容,修改Working Directory里的内容。

这看上去很像reset --hard,但和reset --hard相比有两个重要的差异

  1. reset会把working directory里的全部内容都更新掉
  2. checkout不会去修改你在Working Directory里修改过的文件
  3. reset把branch移动到HEAD指向的地方
  4. checkout则把HEAD移动到另外一个分支

第二个区别可能有点难以理解,举例来讲:假设你有两个分支master和develop,这两个分支指向不同的commit,咱们如今在develop分支上(HEAD指向的地方)

若是咱们git reset master,那么develop就会指向master所指向的那个commit。

若是咱们git checkout master,那么develop不会动,只有HEAD会移动。HEAD会指向master。看图:

图片描述

带文件参数

当执行git checkout [branch] file时,checkout干了这件事情:

  1. 更新了index区域里file文件的内容
  2. 更新了working directory里file文件的内容

总结reset和checkout

head    index   work dir  wd safe
Commit Level
reset --soft [commit]    REF     NO      NO        YES
reset [commit]           REF     YES     NO        YES
reset --hard [commit]    REF     YES     YES       NO
checkout [commit]        HEAD    YES     YES       YES

File Level
reset (commit) [file]    NO      YES     NO        YES
checkout (commit) [file] NO      YES     YES       NO

“head”一列中的“REF”表示该命令移动了HEAD指向的分支引用,而“HEAD”则表示只移动了HEAD自身。 特别注意 “wd safe?” 一列,YES表示不会懂你在work dir的修改,NO表明会动你在work dir的修改。

相关文章
相关标签/搜索