git reset你不知道的三种模式

565 阅读3分钟

撤回已提交版本。

# 回退所有内容到上一个版本
git reset HEAD^

# 回退a.py这个文件的版本到上一个版本
git reset HEAD^ a.py

# 向前回退到第3个版本
git reset –soft HEAD~3

# 将本地的状态回退到和远程的一样
git reset –hard [remote_name]/[branch_name]

# 回退到某个版本057d
git reset 057d

git_reset--soft_head.webp

共有三种模式:

  1. --hard
  2. --soft
  3. -- mixed

git reset --hard [commit_id] : 重置 暂存区 和 工作区

--hard 模式 会在重置 HEADbranch 的指针位置 的同时,重置 暂存区 和 工作区里的内容。

此时,git commit 记录强制回溯到某一个提交节点 commit_id,同时 commit_id 之前的记录与修改内容会彻底删除。

git reset --soft [commit_id] : 保留工作区,并将已 commit 到仓库的内容放到暂存区

--soft 模式 会在重置 HEADbranch 的指针位置 的同时,保留工作区和暂存区中的内容,并把重置 HEAD 指针位置 所带来的新的差异放进暂存区(将已 commit 到仓库的内容放到暂存区)。

什么是「重置 HEAD 所带来的新的差异」?重置 HEADbranch 的指针位置,就等于 HEAD指针回退到上一个版本,类似于 HEAD@{1}HEAD@{0} 的过程,但指针回退后已经被 git commit 的内容回本放到暂存区。

此模式保留了工作区的内容,同时将当前版本节点到目标版本节点的内容保留在暂存区,让其与重置前暂存区与工作区的内容保持一致。

所以当我们想合并「当前节点」与「reset 目标节点」之间不具太大意义的 commit 记录(可能是阶段性地频繁提交)時,可以考虑使用 Soft Reset 来让 commit 演进线图较为清晰点。

git reset [commit_id] : 保留工作区,并将已 commit 到仓库的内容和暂存区放到工作区

git reset 不带参数则默认使用--mixed模式。

--mixed模式 会在重置 HEADbranch 的指针位置 的同时,会保留工作目录,并将已 commit 到仓库的内容和暂存区放到工作区,并且清空暂存区。

换而言之,将工作区的修改、暂存区的内容以及由 reset 所导致的新的文件差异,都会被放进工作区。

简而言之,就是「把所有差异都混合(mixed)放在工作目录中」。

三种模式区别:

  • --hard : 重置指针位置的同时,将工作区、暂存区及仓库都重置回退到 [commit_id] 目标节点的内容。

  • --soft : 重置指针位置的同时,保留工作区和暂存区的内容,只让仓库中的内容和 [commit_id] 目标节点保持一致。其中暂存区的内容是指,将原节点和 [commit_id] 目标节点之间的「差异变更集」会放入 暂存区中。

  • --mixed(默认) : 重置指针位置的同时,只保留工作区的内容。其中工作区的内容是指,将原节点和 [commit_id] 目标节点之间的「差异变更集」会放入工作区中。

总结

git reset 的本质:所有模式都是通过 移动 HEADbranch 的指针位置来实现重置。

git reset 指令虽然可以用来撤销 commit ,但它的实质行为并不是撤销,而是移动 HEAD ,并且「捎带」上 HEAD 所指向的 branch(如果有的话)。

git reset --hard HEAD^ 之所以起到了撤销 commit 的效果,是因为它把 HEAD 和它所指向的 branch 一起移动到了当前 commit父 commit 上,从而起到了「撤销」的效果:

Git 的历史只能往回看,不能向未来看,所以把 HEADbranch 往回移动,就能起到撤回 commit 的效果。

所以同理,git reset --hard 不仅可以撤销提交,还可以用来把 HEAD 和 branch 移动到其他的任何地方。

git_reset--soft_head.gif

譬如:可以将某个分支的代码完全覆盖另一个分支代码。

想查看本文更多详情,可到下方参考文献查看O(∩_∩)O哈哈~

参考文献