git reset的三种模式

新学git,对git的reset操作总是怕狼怕虎的,这样是不对的,对于任何新鲜事物都要大胆去尝试。看几篇博客,看几页图书然后死记概念,永远也不能完全理解其中的道理。废话不多说,直接上货。

先看实例

mkdir git-reset
cd git-reset
git init

开始做几次提交

echo "Hello, git rest" > readme.txt
git add .
git commit -m 'first commit'
echo "new line" >> readme.txt
git add .
git commit -m 'second commit'
echo "third line" >> readme.txt
git add .
git commit -m 'third commit'

看下提交log

git log --graph --oneline
 1. 33be59b third commit
 2. ab56d39 second commit
 3. c773001 first commit

当前提交的readme

cat readme.txt 
Hello, git reset
a new line
the third line
  1. 首先来看第一种reset模式, mixed,即其默认的模式。结果如下。
git reset HEAD^
Unstaged changes after reset:
M   readme.txt

git status
On branch master
Changes not staged for commit:
  (use "git add ..." to update what will be committed)
  (use "git checkout -- ..." to discard changes in working directory)
    modified:   readme.txt
no changes added to commit (use "git add" and/or "git commit -a")

git log --graph --oneline 
* ab56d39 second commit
* c773001 first commit

看出什么了吗,git将提交回滚到了second commit, 同时清空了暂存区(也称stage或index,下文用stage代替暂存区),但是工作区仍然保留,所以git status时,显示时当前工作区相对于second commit的变动。使用这种模式不用害怕吧,他并不会清除你的工作区,你在third commit做的任何操作都不会消失。
2. 看另一种方式,soft模式

git reset --soft HEAD^

git status
On branch master
Changes to be committed:
  (use "git reset HEAD ..." to unstage)

    modified:   readme.txt

看到了吧,采用这种模式,git不回清除你的stage区,因此,git status时就显示了stage区相对于second commit的变化。此时工作区是clean 的,而stage区则有变化。
3. 第三种方式 hard

git reset --hard HEAD^
HEAD is now at ab56d39 second commit

git st
On branch master
nothing to commit, working directory clean

cat readme.txt 
Hello, git reset
a new line

这时工作区,stage区都是干净的,然而readme.txt则残忍的回到了第二次提交是的状态。这说明了啥,采用这种模式,git回用second commit 的内容覆盖stage区和工作区,因此所有的内容都回到了second commit的状态。

实例做完了,开始总结吧
git reset –soft 不会改变stage区,仅仅将commit回退到了指定的提交
git reset –mixed 不回改变工作区,但是会用指定的commit覆盖stage 区,之前所有暂存的内容都变为为暂存的状态
git reset –hard 使用指定的commit的内容覆盖stage区和工作区。

总有后悔药,git reset 是git给我们的commit层级的回滚方式。

你可能感兴趣的:(git)