1. 万能演示代码

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
cd ~

rm -rf recovery

mkdir recovery;cd recovery

git init .

echo "hello v1" > file.txt

git status

git add .

git commit -m "v1"

echo "hello v2" >> file.txt

git add .

git commit -m "v2"

echo "hello v3" >> file.txt

git add .

git commit -m "v3"

git log

修改file.txt然后添加到暂存区,然后再次修改file.txt,让修改保留在工作区

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
➜  recovery git:(master) echo "version 4" >> file.txt 

➜  recovery git:(master) ✗ git status     

位于分支 master

尚未暂存以备提交的变更:

  (使用 "git add <文件>..." 更新要提交的内容)

  (使用 "git restore <文件>..." 丢弃工作区的改动)

修改:     file.txt



修改尚未加入提交(使用 "git add" 和/或 "git commit -a")

➜  recovery git:(master) ✗ cat file.txt

hello v1

hello v2

hello v3

version 4

➜  recovery git:(master) ✗ git add . 

➜  recovery git:(master) ✗ git status

位于分支 master

要提交的变更:

  (使用 "git restore --staged <文件>..." 以取消暂存)

修改:     file.txt



➜  recovery git:(master) ✗ cat file.txt

hello v1

hello v2

hello v3

version 4            
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
➜  recovery git:(master) ✗ echo "version 5" >> file.txt

➜  recovery git:(master) ✗ git status

位于分支 master

要提交的变更:

  (使用 "git restore --staged <文件>..." 以取消暂存)

修改:     file.txt



尚未暂存以备提交的变更:

  (使用 "git add <文件>..." 更新要提交的内容)

  (使用 "git restore <文件>..." 丢弃工作区的改动)

修改:     file.txt



➜  recovery git:(master) ✗ cat file.txt

hello v1

hello v2

hello v3

version 4

version 5

➜  recovery git:(master) ✗ git ls-files -s      

100644 b4e054860a983eda010551066303ce95a7ee3709 0 file.txt

➜  recovery git:(master) ✗ git show b4e0  



hello v1

hello v2

hello v3

version 4

(END)

2. 不加参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
➜  recovery git:(master) ✗ git restore file.txt

➜  recovery git:(master) ✗ git status          

位于分支 master

要提交的变更:

  (使用 "git restore --staged <文件>..." 以取消暂存)

修改:     file.txt



➜  recovery git:(master) ✗ cat file.txt

hello v1

hello v2

hello v3

version 4

我们可以看到工作区的修改被暂存区覆盖了

3. 加–staged

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
➜  recovery git:(master) ✗ git status   

位于分支 master

要提交的变更:

  (使用 "git restore --staged <文件>..." 以取消暂存)

修改:     file.txt



尚未暂存以备提交的变更:

  (使用 "git add <文件>..." 更新要提交的内容)

  (使用 "git restore <文件>..." 丢弃工作区的改动)

修改:     file.txt



➜  recovery git:(master) ✗ cat file.txt

hello v1

hello v2

hello v3

version 4

version 5

➜  recovery git:(master) ✗ git ls-files -s

100644 b4e054860a983eda010551066303ce95a7ee3709 0 file.txt

➜  recovery git:(master) ✗ git show b4e0   

hello v1

hello v2

hello v3

version 4

(END)

git restore --staged file.txt

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
34
35
36
37
38
39
40
41
42
43
➜  recovery git:(master) ✗ git restore --staged file.txt

➜  recovery git:(master) ✗ git status                   

位于分支 master

尚未暂存以备提交的变更:

  (使用 "git add <文件>..." 更新要提交的内容)

  (使用 "git restore <文件>..." 丢弃工作区的改动)

修改:     file.txt



修改尚未加入提交(使用 "git add" 和/或 "git commit -a")

➜  recovery git:(master) ✗ cat file.txt

hello v1

hello v2

hello v3

version 4

version 5

➜  recovery git:(master) ✗ git ls-files -s

100644 56dc9b1633a77efb15e9a9c869dfe4522b0ae0ac 0 file.txt

➜  recovery git:(master) ✗ git show 56dc  

hello v1

hello v2

hello v3

(END)

对比发现,工作区没有变化,暂存区被HEAD覆盖

4. 加 –worktree

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
➜  recovery git:(master) ✗ git status   

位于分支 master

要提交的变更:

  (使用 "git restore --staged <文件>..." 以取消暂存)

修改:     file.txt



尚未暂存以备提交的变更:

  (使用 "git add <文件>..." 更新要提交的内容)

  (使用 "git restore <文件>..." 丢弃工作区的改动)

修改:     file.txt



➜  recovery git:(master) ✗ cat file.txt

hello v1

hello v2

hello v3

version 4

version 5

➜  recovery git:(master) ✗ git ls-files -s

100644 b4e054860a983eda010551066303ce95a7ee3709 0 file.txt

➜  recovery git:(master) ✗ git show b4e0  

hello v1

hello v2

hello v3

version 4

(END)

git restore --worktree file.txt

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
34
35
36
37
38
39
➜  recovery git:(master) ✗ git restore --worktree file.txt

➜  recovery git:(master) ✗ git status                     

位于分支 master

要提交的变更:

  (使用 "git restore --staged <文件>..." 以取消暂存)

修改:     file.txt



➜  recovery git:(master) ✗ cat file.txt

hello v1

hello v2

hello v3

version 4

➜  recovery git:(master) ✗ git ls-files -s

100644 b4e054860a983eda010551066303ce95a7ee3709 0 file.txt

➜  recovery git:(master) ✗ git show b4e0  

hello v1

hello v2

hello v3

version 4

(END)

我们发现,拿HEAD的文件内容来覆盖工作区,跳过了暂存区

5. 加–staged –worktree

git restore --staged --worktree file.txt

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
➜  recovery git:(master) ✗ git status

位于分支 master

要提交的变更:

  (使用 "git restore --staged <文件>..." 以取消暂存)

修改:     file.txt



尚未暂存以备提交的变更:

  (使用 "git add <文件>..." 更新要提交的内容)

  (使用 "git restore <文件>..." 丢弃工作区的改动)

修改:     file.txt



➜  recovery git:(master) ✗ git restore --staged --worktree  file.txt

➜  recovery git:(master) git status                               

位于分支 master

无文件要提交,干净的工作区

➜  recovery git:(master) git ls-files -s                          

100644 56dc9b1633a77efb15e9a9c869dfe4522b0ae0ac 0 file.txt

➜  recovery git:(master) git show 56dc  

hello v1

hello v2

hello v3

(END)

➜  recovery git:(master) cat file.txt

hello v1

hello v2

hello v3

我们可以发现,暂存区和工作区都被HEAD覆盖

6. 加–source

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
➜  recovery git:(master) ✗ git restore --source=66062e1 --staged --worktree  file.txt

➜  recovery git:(master) ✗ git status                                                

位于分支 master

要提交的变更:

  (使用 "git restore --staged <文件>..." 以取消暂存)

修改:     file.txt


➜  recovery git:(master) ✗ cat file.txt

hello v1

➜  recovery git:(master) ✗ git ls-files -s

100644 d21fe316a0e9578aea75decc8c60e2a899534708 0 file.txt

➜  recovery git:(master) ✗ git show d21f  

hello v1

(END)

可以发现是拿commit 66062e1 来覆盖暂存区和工作区

参考:

https://git-scm.com/docs/git-restore/zh_HANS-CN