8.再遇工作区和版本库

小白的故事

本故事纯属虚构,如有雷同,^0^那可太巧了

”大神我看你用使用git reset时使用了--hard参数,是不是还有其他参数啊。“小白虚心问道
”小伙很细心啊,不错,还有其余的2个参数,我挨个给你讲吧。刚才用过–hard,咱们从他讲起。咱们先创建个文件,加两条commit,方便讲解“老鸟说到

1
2
3
4
5
6
7
$ echo "1"> test.txt
$ git add test.txt
$ git commit -m "1"
$ echo "2"> test.txt
$ git add test.txt
$ git commit -m "2"

“咱们创建了2条commit记录了,第一条记录test.txt里的内容是1,第二条记录test.txt里的内容是2。先看一下记录” 老鸟说

1
2
3
4
5
6
7
8
9
10
11
12
$ git log
commit a609df431578e5061b5d0261bfa38cb0fa01efb1 (HEAD -> master)
Author: shooke <xingjiehu@163.com>
Date: Wed Mar 18 16:42:11 2020 +0800

2

commit b5a6d3a6c4d4f5899645f9469f116b050c9426b5
Author: shooke <xingjiehu@163.com>
Date: Wed Mar 18 16:41:55 2020 +0800

1

“接下来,咱们撤销一下看看效果”老鸟继续教导小白

1
2
3
4
5
6
7
8
9
$ git reset --hard HEAD^
HEAD is now at b5a6d3a 1
git log
commit b5a6d3a6c4d4f5899645f9469f116b050c9426b5 (HEAD -> master)
Author: shooke <xingjiehu@163.com>
Date: Wed Mar 18 16:41:55 2020 +0800

1

”现在历史被撤回了,咱们看git的状态“ 老鸟说

1
2
3
$ git status
On branch master
nothing to commit, working tree clean

”你看工作区和暂存区都是空的对吧“老鸟说
”恩恩,文件内容应该变成1了“小白说

1
2
$ cat test.txt
1

“回答正确,咱们先把历史还原,然后再来试试另一个参数”老鸟说。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ git reset --hard a609df431578e5061b5d0261bfa38cb0fa01efb1
HEAD is now at a609df4 2
$ git log
commit a609df431578e5061b5d0261bfa38cb0fa01efb1 (HEAD -> master)
Author: shooke <xingjiehu@163.com>
Date: Wed Mar 18 16:42:11 2020 +0800

2

commit b5a6d3a6c4d4f5899645f9469f116b050c9426b5
Author: shooke <xingjiehu@163.com>
Date: Wed Mar 18 16:41:55 2020 +0800

1

“接下来试试--mixed,看看会是什么效果”老鸟说

1
2
3
4
5
6
7
8
9
$ git reset --mixed HEAD^
Unstaged changes after reset:
M test.txt
$ git log
commit b5a6d3a6c4d4f5899645f9469f116b050c9426b5 (HEAD -> master)
Author: shooke <xingjiehu@163.com>
Date: Wed Mar 18 16:41:55 2020 +0800

1

“历史回退了”小白说
“恩,咱们看看文件状态有什么变化”老鸟说

1
2
3
4
5
6
7
8
9
10
$ 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: test.txt

no changes added to commit (use "git add" and/or "git commit -a")

“这是什么意思啊,这个提示不是文件发生修改的时候才有的吗”,小白疑惑
“看一下文件内容你就明白了”老鸟说到

1
2
$ cat test.txt 
2

”知道什么愿意你了吗“老鸟说
”哦,我明白了,历史回退了,按说文件的内容应该是1,但是现在内容是2,所以git以为文件发生了修改“小白说道。
”恭喜你答对了,--mixed参数会清空stage缓存区,但是不会直接修改文件的内容,如果需要将文件内容撤回,可以在执行git checkout <file>“老鸟解释道

1
2
3
$ git checkout test.txt
$ cat test.txt
1

”你看内容变了吧,接下来你猜一下--soft参数会是什么效果“老鸟说
”既然--hard文件工作区和缓存去都清空了,--mixed把缓存区清空了,那--soft是不是会保留缓存区啊“小白说道
”不错嘛,这都分析到了,没错,--soft参数只是撤销了记录,缓存区和工作区都不做修改,咱们来看下效果“。老鸟说,”先恢复一下记录方便看效果“

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ git reset --hard a609df431578e5061b5d0261bfa38cb0fa01efb1
HEAD is now at a609df4 2
$ git log
commit a609df431578e5061b5d0261bfa38cb0fa01efb1 (HEAD -> master)
Author: shooke <xingjiehu@163.com>
Date: Wed Mar 18 16:42:11 2020 +0800

2

commit b5a6d3a6c4d4f5899645f9469f116b050c9426b5
Author: shooke <xingjiehu@163.com>
Date: Wed Mar 18 16:41:55 2020 +0800

1

”历史回来了,咱们开始看下--soft的作用“老鸟敲下命令

1
2
3
4
5
6
7
8
$ git reset --soft HEAD^
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)

modified: test.txt

”你看,是不是和你想的一样啊,要想清理缓存区可以按提示执行git reset HEAD <file>,剩下的就不用我说了吧“老鸟说道
”恩恩,明白,文件线下的内容应该还是2吧,我清理完缓存区,然后git checkout <file>文件内容就会变回commit对应的内容,对吧“小白问道

”没错,那你知道为什么会有这三种不同的参数吗“老鸟问
”不明白,--hard很方便啊,其他两种还要做其他操作才能回复文件内容,多麻烦。“小白回答

”你现在只是一个文件,如果你的一个历史记录有很多文件怎么办,如果你只需要撤回其中一个文件呢,用--hard不是自杀吗。使用--mixed--soft可以保证文件内容不撤销,这样你就可以用git checkout针对你需要撤销的文件进行撤回。多方便 “老鸟说道
”哦,明白了,谢谢大神“小白激动的说

”走了,有问题随时问我“,老鸟再次潇洒离去,留下了激动的小白

小结

  • --hard 撤销commit记录,清空tage暂存区,清空工作区内容,文件内容彻底还原
  • --mixed 撤销commit记录,清空tage暂存区,保留工作区内容,执行git checkout <file>可撤销修改,让文件内容还原
  • --soft 撤销commit记录,保留stage暂存区,保留工作区内容,如果要撤回需要先执行git reset HEAD <file>撤销暂存区,然后执行git checkout <file> 撤销修改