> cat bar this is history1 this is history2 this is history3 rda@pa ~/T/test (master)> cat foo this is history1 this is history2 this is history3
我们将基于这两个文件原有的内容做简单的添加,以及执行reset和checkout,探究两者的功能和差异。本文不涉及介绍git中指针,头指针的操作和其他概念。 在foo文件尾添加”this is stage”的文本,并执行git add foo,暂存该修改,然后再在文件尾添加”this is work dir”的文本
1 2 3
> echo'this is stage' >> foo > git add foo > echo'this is work dir' >> foo
执行git diff,查看工作目录和暂存区的差别
1 2 3 4 5 6 7 8 9 10
> git diff diff --git a/foo b/foo index fc8c574..64512a0 100644 --- a/foo +++ b/foo @@ -2,3 +2,4 @@ this is history1 this is history2 this is history3 this is stage +this is work dir
执行git diff –staged,查看暂存区和仓库的差别
1 2 3 4 5 6 7 8 9 10
> git diff --staged diff --git a/foo b/foo index 55a27cf..fc8c574 100644 --- a/foo +++ b/foo @@ -1,3 +1,4 @@ this is history1 this is history2 this is history3 +this is stage
可见,相对于仓库,暂存区中添加了文本”this is stage”,而相对于暂存区,工作目录添加了”this is work dir”,同理,执行git diff HEAD,对比工作目录和仓库,文件foo追加了两条字符串
1 2 3 4 5 6 7 8 9 10 11
> git diff HEAD diff --git a/foo b/foo index 55a27cf..64512a0 100644 --- a/foo +++ b/foo @@ -1,3 +1,5 @@ this is history1 this is history2 this is history3 +this is stage +this is work dir
我们也可以执行git status -s,左边显示的M表示foo已经修改并暂存,右边的M表示foo再暂存后又有新的修改
git reset --hard HEAD HEAD is now at cabad03 history3 > git diff > git diff --staged > git diff HEAD > cat foo this is history1 this is history2 this is history3 > git status On branch master nothing to commit, working tree clean
可见,工作目录、暂存区和仓库的内容是一致的。 可以使用该命令“回退”到某一历史commit
1 2 3 4 5 6 7 8
> git reset --hard HEAD~ HEAD is now at 0c52905 history2 > git status On branch master nothing to commit, working tree clean > git log --pretty=oneline 0c5290517531ada5847cc418e9db2941e33fb62e (HEAD -> master) history2 f010d6d2831e827a16d4687076cf2de40f89076d history1
> git diff diff --git a/foo b/foo index 4c1d2ab..bd45079 100644 --- a/foo +++ b/foo @@ -1,3 +1,4 @@ this is history1 this is history2 this is stage +this is work dir > git diff --staged diff --git a/foo b/foo index 8e02c46..4c1d2ab 100644 --- a/foo +++ b/foo @@ -1,2 +1,3 @@ this is history1 this is history2 +this is stage > git diff HEAD diff --git a/foo b/foo index 8e02c46..bd45079 100644 --- a/foo +++ b/foo @@ -1,2 +1,4 @@ this is history1 this is history2 +this is stage +this is work dir
> git diff diff --git a/foo b/foo index 8e02c46..bd45079 100644 --- a/foo +++ b/foo @@ -1,2 +1,4 @@ this is history1 this is history2 +this is stage +this is work dir > git diff --staged > git diff HEAD diff --git a/foo b/foo index 8e02c46..bd45079 100644 --- a/foo +++ b/foo @@ -1,2 +1,4 @@ this is history1 this is history2 +this is stage +this is work dir
此时,原本已经暂存的内容也被丢弃,算作了工作目录和上一次提交的差异。–mixed是默认项,因此可以省略。 执行git reset HEAD~,预期该指令执行结果是: for:暂存区内容和第一次提交内容一致,均为”this is history1”,而工作目录不变,追加了三条字符串,分别是”this is history2””this is stage””this is work dir” bar:暂存区和第一次提交一致,工作目录中的”this is history2”为新加的内容
1 2 3 4
> git reset HEAD~ Unstaged changes after reset: M bar M foo
> git diff diff --git a/bar b/bar index 361b0e4..8e02c46 100644 --- a/bar +++ b/bar @@ -1 +1,2 @@ this is history1 +this is history2 diff --git a/foo b/foo index 361b0e4..bd45079 100644 --- a/foo +++ b/foo @@ -1 +1,4 @@ this is history1 +this is history2 +this is stage +this is work dir > git diff --staged > git diff HEAD diff --git a/bar b/bar index 361b0e4..8e02c46 100644 --- a/bar +++ b/bar @@ -1 +1,2 @@ this is history1 +this is history2 diff --git a/foo b/foo index 361b0e4..bd45079 100644 --- a/foo +++ b/foo @@ -1 +1,4 @@ this is history1 +this is history2 +this is stage +this is work dir
soft
git reset –soft会重置repository,但保留stage、workspace中的改动。 首先将仓库恢复到初始状态,即有三次commit,并且暂存区中有”this is stage”,工作目录中还额外添加了”this is work dir”。恢复的方法是,根据第三次commit,checkout到commit3(checkout可以移动HEAD指针,然后在commit3处新建一个分支,并将master合并到该分支即可) 执行git reset –soft HEAD~2,即reset到第一次commit,预期执行结果是: foo文件:仓库仅有”this is history1”,暂存区中有”this is history2””this is history3””this is stage”,而工作目录额外有”this is work dir” bar文件:仓库仅有”this is history1”,暂存区中有”this is history2””this is history3”,工作目录与暂存区内容一致
1
> git reset --soft HEAD~2
查看两个文件内容
1 2 3 4 5 6 7 8 9 10
> cat bar this is history1 this is history2 this is history3 > cat foo this is history1 this is history2 this is history3 this is stage this is work dir
> git diff diff --git a/foo b/foo index fc8c574..64512a0 100644 --- a/foo +++ b/foo @@ -2,3 +2,4 @@ this is history1 this is history2 this is history3 this is stage +this is work dir > git diff --staged diff --git a/bar b/bar index 361b0e4..55a27cf 100644 --- a/bar +++ b/bar @@ -1 +1,3 @@ this is history1 +this is history2 +this is history3 diff --git a/foo b/foo index 361b0e4..fc8c574 100644 --- a/foo +++ b/foo @@ -1 +1,4 @@ this is history1 +this is history2 +this is history3 +this is stage > git diff HEAD diff --git a/bar b/bar index 361b0e4..55a27cf 100644 --- a/bar +++ b/bar @@ -1 +1,3 @@ this is history1 +this is history2 +this is history3 diff --git a/foo b/foo index 361b0e4..64512a0 100644 --- a/foo +++ b/foo @@ -1 +1,5 @@ this is history1 +this is history2 +this is history3 +this is stage +this is work dir
> echo'this is stage' >> foo > echo'this is stage' >> bar > git add foo bar > echo'this is work dir' >> foo > echo'this is work dir' >> bar > git status -s MM bar MM foo
> git checkout HEAD foo Updated 1 path from 3ea0ad5 > git diff diff --git a/bar b/bar index fc8c574..64512a0 100644 --- a/bar +++ b/bar @@ -2,3 +2,4 @@ this is history1 this is history2 this is history3 this is stage +this is work dir > git diff --staged diff --git a/bar b/bar index 55a27cf..fc8c574 100644 --- a/bar +++ b/bar @@ -1,3 +1,4 @@ this is history1 this is history2 this is history3 +this is stage
可见,foo的暂存区和工作目录被HEAD处的提交覆盖了,相当于丢弃了暂存区和工作目录中的修改,而bar未受影响 同样,我们对bar进行操作,首先将仓库的状态恢复到初始状态。 执行git checkout HEAD~2 bar
1 2
> git checkout HEAD~2 bar Updated 1 path from f6fa925
> git diff foo diff --git a/foo b/foo index fc8c574..64512a0 100644 --- a/foo +++ b/foo @@ -2,3 +2,4 @@ this is history1 this is history2 this is history3 this is stage +this is work dir > git diff --staged foo diff --git a/foo b/foo index 55a27cf..fc8c574 100644 --- a/foo +++ b/foo @@ -1,3 +1,4 @@ this is history1 this is history2 this is history3 +this is stage > git diff HEAD foo diff --git a/foo b/foo index 55a27cf..64512a0 100644 --- a/foo +++ b/foo @@ -1,3 +1,5 @@ this is history1 this is history2 this is history3 +this is stage +this is work dir
未受到影响。 查看bar文件的情况
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
> git diff bar > git diff --staged bar diff --git a/bar b/bar index 55a27cf..361b0e4 100644 --- a/bar +++ b/bar @@ -1,3 +1 @@ this is history1 -this is history2 -this is history3 > git diff HEAD bar diff --git a/bar b/bar index 55a27cf..361b0e4 100644 --- a/bar +++ b/bar @@ -1,3 +1 @@ this is history1 -this is history2 -this is history3