在git版本管理中,经常有将其他提交与当前代码环境内容交互的需求,其中
git reset
、git checkout
和git revert
是与此类需求有关的一些命令,它们可以用来调整代码仓库中的某些更改;而且git reset
和git checkout
两个命令不仅可以作用于提交,还可以作用于特定文件,本文介绍上述三个命令的区别与工作原理。
git 基础内容 {#git-基础内容}
git 相关基础概念与常用命令使用方法在 Git - 使用教程 中有介绍,本文在此基础上进行展开。
作用域 {#作用域}
这三个命令可以作用于提交 和文件:
| 命令 | 可用于提交 | 可用于文件 | |--------------|-------|-------| | git reset | √ | √ | | git checkout | √ | √ | | git revert | √ | × |
下面从这两个作用域的角度分别介绍相关命令的功能。
作用于提交 {#作用于提交}
三个命令常用的用法均为回退,但是三个命令的实现细节事实上有很大的区别。
git reset {#git-reset}
-
工作原理:
当 reset 的作用对象为提交时,reset将一个分支的末端指向另一个提交。
-
通过传入这些标记来修改你的缓存区或工作目录:
--soft -- 缓存区和工作目录都不会被改变
--mixed (默认选项) 缓存区和你指定的提交同步,但工作目录不受影响
--hard -- 缓存区和工作目录都同步到你指定的提交
-
-
实例应用:
把当前分支reset到HEAD~2。
将当前的改动从缓存区中移除,但是这些改动还留在工作目录中。
完全舍弃还没有提交的改动
checkout {#checkout}
-
工作原理:
checkout命令以提交为参数时,将当前工作区、暂存区、仓库均切换到目标提交时的状态。
-
实例应用:
切换到指定分支
切换到指定提交
revert {#revert}
-
工作原理:
通过创建一次新的
commit
来撤销一次commit
所做出的修改。这种撤销的方式是安全的,因为它并不修改commitm history
。 -
不建立新 commit:
此时相当于手动撤销了此次 commit 的修改并执行了
git add
命令 -
建立新 commit:
将会查出倒数第二次(即当前commit的往前一次)提交的修改,并创建一个新的提交,用于撤销当前提交的上一次
commit
。 -
反悔了我:
就是我执行了 revert 命令,诶我又不想执行了,就可以这样撤销 revert
作用于文件 {#作用于文件}
git reset {#git-reset-2}
-
工作原理:
当检测到文件路径时,
git reset
将缓存区同步到指定的提交。 -
实例应用:
将文件 foo.py 在缓冲区的状态更改为HEAD之前2个的提交。
注: --soft、--mixed和--hard对文件层面的
git reset
毫无作用,缓存区中的文件一定会变化,而工作目录中的文件一定不变。
checkout {#checkout-2}
-
工作原理:
提取某个已经缓存的文件状态(缓存区、提交)用于覆盖当前工作区的文件。
与reset作用于文件相比,不同的是checkout更改的文件位置为工作区,reset为暂存区。
-
实例应用:
将工作目录中的foo.py同步到了倒数第二个提交中的foo.py。
当不指定特定提交时,checkout 优先从暂存区中提取文件副本覆盖工作区文件;当文件没有在暂存区提交过(没有add过)时,从仓库中(当前提交)提取文件副本覆盖工作区文件。
也就是说,该命令会提取最近的一次保存的副本覆盖当前工作区的文件。
参考资料: {#参考资料:}
文章链接:
https://www.zywvvd.com/notes/tools/git/git-get-back/git-get-back/