1、reset命令的执行流程
以下3个命令,前一个命令都是后一个命令的前置操作:可以简单的理解为,reset命令会先覆盖提交历史区,然后覆盖暂存区,最后覆盖工作区。
- 移动HEAD指向
git reset --soft [commit_ref]
它仅仅是将 HEAD及HEAD所指向的分支 移动 到 commit_ref 节点上。该命令本质上是撤销了 commit_ref 到最后一次 commit 之间 git commit 记录,此时对暂存区与工作区都没有影响。
- 回滚暂存区
git reset [--mixed] [commit_ref] 等价 git reset
mixed 是默认参数,该命令撤销了 commit_ref 到最后一次 commit 之间 git commit 与 git add 命令,并且会取消暂存的所有内容,相对于将 commit_ref 记录同步到了 当前暂存区中。ps:此时工作区的内容并没有被回滚
- 回滚工作区
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"
【参考】
Comments | NOTHING