场景

一开始写了个方案1提交到了暂存区,后面在工作区继续修改后发现工作区的方案比暂存区的要好,此时我们希望丢弃暂存区的变更,需要把暂存区恢复成HEAD一样。即暂存区的东西还不成熟想要恢复成HEAD。

git reset HEAD <file>: 可以将某一个文件恢复成工作区,不加<file>默认全部恢复。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 G:\mygitea\GitLearn\learn03   master ± 
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: readme

Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: readme
modified: test.txt


G:\mygitea\GitLearn\learn03   master ± 
$ git reset HEAD
Unstaged changes after reset:
M readme
M test.txt

G:\mygitea\GitLearn\learn03   master ± 
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: readme
modified: test.txt

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

G:\mygitea\GitLearn\learn03   master ± 
$ git diff --cached # 使暂存区和HEAD比较,什么都没返回意味着暂存区和HEAD完全一致

总结

git reset 有三个参数
—soft 这个只是把 HEAD 指向的 commit 恢复到你指定的 commit,暂存区 工作区不变
—hard 这个是 把 HEAD, 暂存区, 工作区 都修改为 你指定的 commit 的时候的文件状态
—mixed 这个是不加时候的默认参数,把 HEAD,暂存区 修改为 你指定的 commit 的时候的文件状态,工作区保持不变

Q1:感觉很少会有需要将暂存区的内容恢复成和HEAD一样的。因为如果感觉暂存区的修改没有工作区的内容好,可以直接将工作区的内容添加到暂存区,那么暂存区会以新添加的文件状态为准。

可能有一种情况需要吧,比如已经确定不想保留暂存区的变更,其次工作区还没有改好,我想把暂存区恢复到HEAD,以便执行 git diff就能比较工作区和暂存区(也等于HEAD)的差异。

Q2:
1) 假定:HEAD、缓存区、工作区中的readme.md文件内容均不相同,【git reset —hard — readme.md】命令和【git checkout HEAD — readme.md】命令的执行结果是一样的,都是讲暂存区、工作区的readme.md文件内容和HEAD指向的保持一致,但是这两者的理解上有什么样的不同呢?

2) 针对“一步”笔记中的—soft参数,我尝试过该参数后,又通过—soft参数指向原来HEAD所在的commit,将HEAD指针所指向的内容修改了回来。使用git log这些命令看上去都和原来没有任何区别。但是在gitk窗口中,有两行记录。不是很清楚这种情况产生的原因。
Local uncommitted changes, not checked in to index
Local changes checked in to index but not committed

1)reset你用了hard参数 ,所以两个命令执行效果相同。注意reset命令的三个参数—hard, —mixed和—soft,除了hard外,你不妨用用其他两个方式再看看。
2)git只是好心提醒我们,有些改动的内容没加到暂存区(index),有些没创建commit

补充:

分析工作区、暂存区、HEAD三者,在工作区文件未提交到暂存区时,暂存区和HEAD是一致的。当工作区文件变动提交到了暂存区,此时暂存区和HEAD就不一致了。

即HEAD指向某个commit状态下的工作目录,同时备份该状况下的工作目录作为暂存区。