先简单说一下,在提交到远程库之前我们使用git reset 命令完全可以满足我们 撤销操作的需求,如果操作已经提交到远程库,那只好使用 git revert 来提交一个新的撤销操作 撤销 需要撤销的那次commit。
本地创建一个文件夹,随意放哪里,终端进入该文件夹,执行 git init 建立本地git仓库。
现在我们可以在该文件夹里添加一个.txt文件,然后.txt文件内随意写上几句话。执行git status 查看状态
我们是为了测试 git reset 和git revert,为了方便测试,使用git add和git commit给此次修改提交 ,到版本库。
然后在给.txt 添加一行新文字 ,执行git status 显示如下
现在执行git reset HEAD,再执行git status如下:
可以看到没有起到任何作用,况且命令行也提示我们了,要么使用git add <file> 添加修改到暂存区,要么使用 git checkout --<file> 放弃修改文件。所以我们使用 git reset HEAD 不起作用,如果我们先 add 再 reset 如下:
又回到了我们执行add命令之前的状态,等于撤销了add 这个操作,我们 add ,commit再执行reset命令呢?
可以看到,我们 使用 git reset HEAD并不起作用,而是用 git reset HEAD^才起作用,这是因为在Git中,HEAD表示当前版本,上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,可以写成HEAD~100。
可以看到执行完git reset HEAD^之后,我们最新一次commit就被撤销了。注意这里我们使用的是 git reset HEAD^ ,也就是默认的git reset --mixed HEAD^,此时我们执行git status看到:我们的修改又回到了工作区。
那么 git reset --hard HEAD^ 和 git reset --soft HEAD^ 呢,
可以看到,我们重新修改commit 之后 如果执行的是 --soft的话,那么修改就会被放回暂存区,执行git log 的话,最新的一次提交同样不见了,同理,如果使用 --hard 的话 ,如下:
可以看到什么都没有了,修改直接被丢弃了,工作区和暂存区都没有了。
到这里,我们都没有提交到远程库,也就是没有执行git push命令,我们所有的操作都可以通过 git checkout --<file> 或者 git reset HEAD命令来撤销掉。
为了便于测试 git revert,我先 commit了几次,
可以看到commit 了三次,现在我们想回滚最新的一次commit,使用reset 的话就不说了,使用 revert 呢?
找到我们想要revert的commit id 执行 git revert <commitid> 然后命令行会让你输入本次 操作的信息,自动生成的是
Revert "***"
This reverts commit ***.
退出编辑模式,然后 执行 git log,我们发现多了一次commit,该次commit信息就是上面的。我们最新一次的修改,在我们源文件就是文本文档中没有了,(有时候需要重新打开一次文件才能看到效果)。
总结来说:
git checkout --<file> 可以撤销工作区的修改
git reset HEAD 可以撤销 git add 操作
git reset HEAD^ 可以撤销 git commit 操作(默认为 git reset --mixed HEAD^:修改会被放回工作区,--soft 修改会放到暂存区 ,--hard 修改会直接被丢弃)
到这里,基本理清了这二者的区别了。如果有理解错误的地方,欢迎指正。谢谢。