git reset 重置命令

发布于 2021-07-27  70 次阅读


1、reset命令的执行流程

以下3个命令,前一个命令都是后一个命令的前置操作:可以简单的理解为,reset命令会先覆盖提交历史区,然后覆盖暂存区,最后覆盖工作区。

  1. 移动HEAD指向
    git reset --soft [commit_ref]

    它仅仅是将 HEAD及HEAD所指向的分支 移动 到 commit_ref 节点上。该命令本质上是撤销了 commit_ref 到最后一次 commit 之间 git commit 记录,此时对暂存区与工作区都没有影响。

  2. 回滚暂存区
    git reset [--mixed] [commit_ref]
    等价
    git reset

    mixed 是默认参数,该命令撤销了 commit_ref 到最后一次 commit 之间 git commit 与 git add 命令,并且会取消暂存的所有内容,相对于将 commit_ref 记录同步到了 当前暂存区中。ps:此时工作区的内容并没有被回滚

  3. 回滚工作区
    git reset --hard [commit_ref]

    hard参数 将会连同工作区的内容也会被回滚掉,它会强制覆盖了工作区,这相当于你完全放弃了此前的所有工作内容,唯一还能找回的途径是reflog的提交历史,如果你工作区中有被add过但从未被commit过的内容,将等同永久丢失。
    ps:工作区中只要是被add过一次的文件,都会被直接丢弃掉,等同是删除文件。只要从未被add跟踪过的文件,才能保持原样

2、文件级的reset操作

上面的几条命令都是影响整个区域,这样范围实在是太大了,所以git贴心的提供了,对个别文件进行reset的命令。

从任意的提交历史中提取指定文件到当前暂存区中,前提是工作目录中存在该文件。

git reset file.txt

等同

git reset --mixed HEAD file.txt

选择指定 commit 记录

git reset [commit_ref] -- file.txt
git reset [commit_ref] -- <paths> (可以写文件路径和git add差不多)

完整
git reset [--mixed] [commit_ref] -- <paths>

这将会把HEAD指向或某个提交历史中的file.txt复制到当前暂存区中,此时HEAD指针的指向并没有改变。你无法直观的在工作区中观察到命令的效果,可以通过git status来观察。如果运行git commit将会把复制过来的file.txt提交,这时候再检出这个文件,就能在工作目录中直观的看到命令实际产生的效果。ps:如果运行此命令前,file.txt在工作区中被删除,会无法工作。由于这种效果,还能用这命令来取消暂存一个文件

3、压缩提交记录(修改commit提交历史git log)

需求:假设你有一个项目,第一次提交中有一个文件,第二次提交增加了一个新的文件并修改了第一个文件,第三次提交再次修改了第一个文件。 由于第二次提交是一个未完成的工作,因此你想要压缩它。
简单来说,就是在不改最后一次提交结果的前提下,只保留第一次与最后一次commit记录。

git reset --soft HEAD~2
将最后一次commit的内容覆盖到 HEAD~2 位置的 暂存区中

git commit -m "message"

【参考】

  1. Git-工具-重置揭密