新学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
- 首先来看第一种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 <file>..." to update what will be committed)
(use "git checkout -- <file>..." 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 <file>..." 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层级的回滚方式。