git reset,git restore and git revert

git reset,git restore and git revert

git-reset - Reset current HEAD to the specified state

git-restore - Restore working tree files

git-revert - Revert some existing commits

git reset

1
2
3
4
git reset [-q] [<tree-ish>] [--] <pathspec>…​
git reset [-q] [--pathspec-from-file=<file> [--pathspec-file-nul]] [<tree-ish>]
git reset (--patch | -p) [<tree-ish>] [--] [<pathspec>…​]
git reset [--soft | --mixed [-N] | --hard | --merge | --keep] [-q] [<commit>]

reset 三种模式

–hard:

重置位置的同时,直接将 working Tree 工作目录、 index 暂存区及 repository 都重置成目标 Reset 节点的內容,所以效果看起来等同于清空暂存区和工作区。

–soft:

重置位置的同时,保留 working Tree 工作目录和 index 暂存区的内容,只让 repository 中的内容和 reset 目标节点保持一致,因此原节点和 reset 节点之间的【差异变更集】会放入 index 暂存区中 (Staged files)。所以效果看起来就是工作目录的内容不变,暂存区原有的内容也不变,只是原节点和 Reset 节点之间的所有差异都会放到暂存区中。

–mixed(默认):

重置位置的同时,只保留 Working Tree 工作目录的內容,但会将 Index 暂存区 和 Repository 中的內容更改和 reset 目标节点一致,因此原节点和 Reset 节点之间的【差异变更集】会放入 Working Tree 工作目录中。所以效果看起来就是原节点和 Reset 节点之间的所有差异都会放到工作目录中。

使用场景:

–hard:

(1) 要放弃目前本地的所有改变時,即去掉所有 add 到暂存区的文件和工作区的文件,可以执行 git reset -hard HEAD 来强制恢复 git 管理的文件夹的內容及状态;

(2) 真的想抛弃目标节点后的所有 commit(可能觉得目标节点到原节点之间的 commit 提交都是错了,之前所有的 commit 有问题)。

–soft:

原节点和 reset 节点之间的【差异变更集】会放入 index 暂存区中 (Staged files),所以假如我们之前工作目录没有改过任何文件,也没 add 到暂存区,那么使用 reset –soft 后,我们可以直接执行 git commit 將 index 暂存区中的內容提交至 repository 中。为什么要这样呢?这样做的使用场景是:假如我们想合并「当前节点」与「reset 目标节点」之间不具太大意义的 commit 记录 (可能是阶段性地频繁提交,就是开发一个功能的时候,改或者增加一个文件的时候就 commit,这样做导致一个完整的功能可能会好多个 commit 点,这时假如你需要把这些 commit 整合成一个 commit 的时候) 時,可以考虑使用 reset –soft 来让 commit 演进线图较为清晰。总而言之,可以使用 –soft 合并 commit 节点。

–mixed(默认):

(1) 使用完 reset –mixed 后,我們可以直接执行 git add 将這些改变果的文件內容加入 index 暂存区中,再执行 git commit 将 Index 暂存区 中的內容提交至 Repository 中,这样一样可以达到合并 commit 节点的效果(与上面 –soft 合并 commit 节点差不多,只是多了 git add 添加到暂存区的操作);

(2) 移除所有 Index 暂存区中准备要提交的文件 (Staged files),我们可以执行 git reset HEAD 来 Unstage 所有已列入 Index 暂存区 的待提交的文件。(有时候发现 add 错文件到暂存区,就可以使用命令)。

(3) commit 提交某些错误代码,或者没有必要的文件也被 commit 上去,不想再修改错误再 commit(因为会留下一个错误 commit 点),可以回退到正确的 commit 点上,然后所有原节点和 reset 节点之间差异会返回工作目录,假如有个没必要的文件的话就可以直接删除了,再 commit 上去就 OK 了。

git restore

1
2
3
git restore [<options>] [--source=<tree>] [--staged] [--worktree] [--] <pathspec>…​
git restore [<options>] [--source=<tree>] [--staged] [--worktree] --pathspec-from-file=<file> [--pathspec-file-nul]
git restore (-p|--patch) [<options>] [--source=<tree>] [--staged] [--worktree] [--] [<pathspec>…​]

restore 两种模式

git restore

表示将在工作空间但是不在暂存区的文件撤销更改。

git restore –staged

作用是将暂存区的文件从暂存区撤出,但不会更改文件。

git revert

1
2
git revert [--[no-] edit] [-n] [-m parent-number] [-s] [-S [<keyid>]] <commit>…​
git revert (--continue | --skip | --abort | --quit)

git revert 是用于 “反做” 某一个版本,以达到撤销该版本的修改的目的。比如,我们 commit 了三个版本(版本一、版本二、 版本三),突然发现版本二不行(如:有 bug),想要撤销版本二,但又不想影响撤销版本三的提交,就可以用 git revert 命令来反做版本二,生成新的版本四,这个版本四里会保留版本三的东西,但撤销了版本二的东西。如下图所示:

在这里插入图片描述

参考文献

git - the stupid content tracker