git 撤销命令 git reset 使用

一、功能说明

执行 git reset --help 可以看到帮助文档
公共说明:

[]:可选可不选
-q:静默操作,只提示错误信息(不会打印被影响到的文件信息)
commit:提交的 tree(目录树)对象 hash 值(其实就是执行 git log --oneline 前面的一段 hash 串)
工作区: .git 版本库所在的目录

1.1、git reset [-q] [] [--] ...

说明:使用指定提交下的文件替换暂存区的文件(两个 -- 为了避免路径和引用指向的提交同名冲突),不会改变工作区和引用指向的提交
例如:git reset HEAD 相当于git add 的反操作

1.2、git reset (--patch | -p) [] [--] [...]

说明:选择性将指定提交的文件内容替换暂存区的文件内容
例如:git reset -p HEAD 相当于git add -p 的反操作 [git add -p 详情待补]

  • 示例:
    构造的环境如下:

执行下列语句,参看下面的执行效果图更清楚:

git diff --cached lyrics.txt #查看暂存区和版本库的区别
git reset -p lyrics.txt #用当前分支HEAD指向的版本库内容替换暂存区的内容
s # 分割成更小的块
n #不替换暂存区的内容
y #替换暂存区的内容
git diff --cached lyrics.txt #查看暂存区和版本库的区别

特别说明:

y - 这块从暂存区退出
n - 这块不从暂存区退出
q - 退出 不做任何操作
a - 将此块和之后的块都退出暂存区
d - 将此块和之后的块都不退出暂存区
g - 在输入s后 选择跳去那一个块
/  - 在输入s后 使用正则表达式找到块
j - 离开当前未决定的块,跳到下一个未决定的块
J - 离开当前未决定的块, 跳到下一个块
k - 离开当前未决定的块, 跳到前一个未决定的块
K - 离开当前未决定的块, 跳到前一个的块
s - 将当前块分割为更小的块(注意连在一起的不能被分割的再小了)
e - 编辑当前块
? - 打印帮助
执行效果

1.3 git reset [--soft | --mixed [-N] | --hard | --merge | --keep] [-q] []

说明:此操作会重置提交的引用
例子中使用的初始环境都如下所示:

1.3.1、三种动作

1⃣️ 替换引用的指向,指向新的提交。
2⃣️ 替换暂存区。暂存区内容将和指定的提交内容一样。
3⃣️ 替换工作区。工作区和指定的提交内容一样。

1.3.2、 不同的参数会执行不同的动作

  • -- soft : git reset --soft
    只执行动作 1⃣️。
    • 举个栗子:
      模拟一次错误的提交,撤销提交后,再查看效果
    git commit -m "我好像写了一个错误的提交说明"
    git log --oneline --graph
    git reset --soft HEAD^ # HEAD^ 在当前况下相当于最后一次提交的前一次提交
    git diff #查看工作区和暂存区的区别
    git diff --cached #查看暂存区和版本库的区别
    

结果说明:工作区和暂存区都恢复到了初始环境的样子,只有上一次提交消失了。
注:修补提交命令 git commit --amend,用于将最新的提交进行重新提交以修补错误的提交说明。其相当于执行了如下命令(.git/COMMIT_EDITMSG保存了上次的提交日志,可以直接修改)

git reset --soft HEAD^
git commit -e -F .git/COMMIT_EDITMSG
  • --mixed git reset --mixed [-N]
    不带参,则默认为此参数。执行动作1⃣️2⃣️。
    • 举个栗子
git commit -m "我来试一下 --mixed"
git log --oneline --graph
git reset d6ea103 #此处的 d6ea10 只是我的上次提交id,不具有普遍性
# git reset --mixed d6ea103 等同于上一个命令
# git reset --mixed HEAD^ 同上 此命令具有普遍性
git diff #查看工作区和暂存区的区别
git diff --cached #查看暂存区和版本库的区别

结果说明:git diff可以很明显看出来之前加入暂存区的既替余以蕙纕兮,又申之以揽茝。,现在已经被退出暂存区了。但是本地文件没有变化。

  • --hard git reset --hard
    执行动作1⃣️2⃣️3⃣️。慎用,会改掉工作区文件。
    • 举个栗子
git commit -m "我再悄咪咪试一下 --hard"
git log --oneline --graph
git reset --hard HEAD^
git diff #查看工作区和暂存区的区别
git diff --cached #查看暂存区和版本库的区别
git diff HEAD #查看工作区和版本库的区别
cat lyrics.txt #查看 lyrics.txt 的内容

结果说明:可以看到工作区、暂存区、版本库都没有任何区别了,再看看 lyrics.txt 的内容,就可以发现刚刚工作区的改动全都不见了 ¯\_(ツ)_/¯,如果有需要的改动,从未提交过的内容真的是凉凉。但是之前提交过的541c01c (HEAD -> master) 我再悄咪咪试一下 --hard的内容既替余以蕙纕兮,又申之以揽茝。还是可以找回来的 ----- [撤销后又后悔待补充]

  • --merge git reset --merge
    如果撤销的是上一个操作是 git pull,执行动作1⃣️2⃣️3⃣️。工作区如果有改动的话,会停止重置。慎用,会改掉工作区文件。
    如果撤销的是上一个操作是 git merge,则执行动作1⃣️3⃣️。虽然工作区本地文件被重置了,但是暂存区会有之前本地的修改。还是慎用。
    栗子见 git merge 撤销
  • --keep git reset --keep
    执行动作1⃣️2⃣️3⃣️。但是工作区如果有未提交的内容的话,会停止重置。慎用,会改掉工作区文件。
    • 举个栗子
      为了方便写注释(#开头的为注释),此次把所有的都拷下来,图片还在后面有附 ^_^
#先将初始环境的暂存区内容提交了
steamed-bundeMacBook-Pro:gitTest steamed-bun$ git commit -m "再用 --keep 试一下喽"
[master e8c694e] 再用 --keep 试一下喽
 1 file changed, 1 insertion(+)
#再将初始环境的内容加到暂存区
steamed-bundeMacBook-Pro:gitTest steamed-bun$ git add lyrics.txt 
#再在文件 lyrics.txt 中加入新内容
steamed-bundeMacBook-Pro:gitTest steamed-bun$ echo "怨灵修之浩荡兮,终不察夫民心。" >> lyrics.txt 
#查看文件  lyrics.txt 
steamed-bundeMacBook-Pro:gitTest steamed-bun$ cat lyrics.txt 
离骚--高考必背
长太息以掩涕兮, 哀民生之多艰。
余虽好修姱以鞿羁兮,謇朝谇而夕替。
既替余以蕙纕兮,又申之以揽茝。
亦余心之所善兮,虽九死其犹未悔。
怨灵修之浩荡兮,终不察夫民心。
#查看工作区和暂存区的区别 
steamed-bundeMacBook-Pro:gitTest steamed-bun$ git diff 
diff --git a/lyrics.txt b/lyrics.txt
index 9fe96f6..9b05a22 100644
--- a/lyrics.txt
+++ b/lyrics.txt
@@ -3,3 +3,4 @@
 余虽好修姱以鞿羁兮,謇朝谇而夕替。
 既替余以蕙纕兮,又申之以揽茝。
 亦余心之所善兮,虽九死其犹未悔。
+怨灵修之浩荡兮,终不察夫民心。
#查看暂存区和版本库的区别
steamed-bundeMacBook-Pro:gitTest steamed-bun$ git diff --cached
diff --git a/lyrics.txt b/lyrics.txt
index bedad0e..9fe96f6 100644
--- a/lyrics.txt
+++ b/lyrics.txt
@@ -2,3 +2,4 @@
 长太息以掩涕兮, 哀民生之多艰。
 余虽好修姱以鞿羁兮,謇朝谇而夕替。
 既替余以蕙纕兮,又申之以揽茝。
+亦余心之所善兮,虽九死其犹未悔。
#执行撤回命令 可以看到 git 的提示
steamed-bundeMacBook-Pro:gitTest steamed-bun$ git reset --keep HEAD^
error: Entry 'lyrics.txt' would be overwritten by merge. Cannot merge.
#错误:文件 'lyrics.txt' 将被合并覆盖,但是无法合并。
fatal: Could not reset index file to revision 'HEAD^'.
#致命:无法将索引文件重置为“HEAD ^”。
#再试一下将工作区的内容全部提交到暂存区
steamed-bundeMacBook-Pro:gitTest steamed-bun$ git add lyrics.txt 
#在执行撤回命令 依然失败
steamed-bundeMacBook-Pro:gitTest steamed-bun$ git reset --keep HEAD^
error: Entry 'lyrics.txt' would be overwritten by merge. Cannot merge.
fatal: Could not reset index file to revision 'HEAD^'.
#查看工作区和暂存区确实无区别 (其实应该先查看的 囧rz)
steamed-bundeMacBook-Pro:gitTest steamed-bun$ git diff
#将 lyrics.txt 加入到暂存区的内容撤出
steamed-bundeMacBook-Pro:gitTest steamed-bun$ git reset -- lyrics.txt 
Unstaged changes after reset:
M   lyrics.txt
# 可以看到已全部撤出了暂存区了
steamed-bundeMacBook-Pro:gitTest steamed-bun$ git diff 
diff --git a/lyrics.txt b/lyrics.txt
index bedad0e..9b05a22 100644
--- a/lyrics.txt
+++ b/lyrics.txt
@@ -2,3 +2,5 @@
 长太息以掩涕兮, 哀民生之多艰。
 余虽好修姱以鞿羁兮,謇朝谇而夕替。
 既替余以蕙纕兮,又申之以揽茝。
+亦余心之所善兮,虽九死其犹未悔。
+怨灵修之浩荡兮,终不察夫民心。
#进入 vim 删除最后两句新内容 直接打开文件删除也是一样的 
steamed-bundeMacBook-Pro:gitTest steamed-bun$ vim lyrics.txt 
#查看文件内容 可以看到已经不见了
steamed-bundeMacBook-Pro:gitTest steamed-bun$ cat lyrics.txt 
离骚--高考必背
长太息以掩涕兮, 哀民生之多艰。
余虽好修姱以鞿羁兮,謇朝谇而夕替。
既替余以蕙纕兮,又申之以揽茝。
#查看区别
steamed-bundeMacBook-Pro:gitTest steamed-bun$ git diff
steamed-bundeMacBook-Pro:gitTest steamed-bun$ git diff --cached
#再执行撤回命令
steamed-bundeMacBook-Pro:gitTest steamed-bun$ git reset --keep HEAD^
#再次查看文件内容 已经可以看到工作区回到了上一此提交后的情况
steamed-bundeMacBook-Pro:gitTest steamed-bun$ cat lyrics.txt 
离骚--高考必背
长太息以掩涕兮, 哀民生之多艰。
余虽好修姱以鞿羁兮,謇朝谇而夕替。
steamed-bundeMacBook-Pro:gitTest steamed-bun$ git diff 
steamed-bundeMacBook-Pro:gitTest steamed-bun$ git diff --cached

你可能感兴趣的:(git 撤销命令 git reset 使用)