Git撤销操作(git reset)

Git撤销操作(git reset)教程

git reset 命令是用来将当前 branch 重置到另外一个 commit 的,这个动作可能同时影响到 index 以及 work directory。

git reset 有三种工作模式,即 --soft、–mixed 和 --hard。

Git reset命令功能

有时候,我们用 Git 的时候有可能 git commit 提交代码后,发现这一次 commit 的内容是有错误的,那么有两种处理方法:

  1. 修改错误内容,再次 commit 一次 。
  2. 使用 git reset 命令撤销这一次错误的 commit。

第一种方法比较直接,但会多次一次 commit 记录,但如果修改过多的话,那么就不太方便去修改了,因此,这时候更适合使用第二种方式。

Git reset三种模式区别

定义

git reset 有三种工作模式,即,git reset --soft、git reset --mixed 和 git reset --hard。其中 git reset --mixed 是默认的方式。

git reset --soft

仅仅移动当前 Head 指针,不会改变工作区和暂存区的内容,如下图所示:

103_git撤销修改回退版本git reset.png

我们看到,只有 HEAD 指针被修改了。

git reset --mixed

是 reset 的默认参数,移动 head 指针,改变暂存区内容,但不会改变工作区 ,如下图所示:

104_git撤销修改回退版本git reset.png

我们看到,HEAD 指针和暂存区的内容都被修改了。

git reset --hard

当前 head 指针、工作区和暂存区内容全部改变 ,如下图所示:

105_git撤销修改回退版本git reset.png

我们看到,head 指针、工作区和暂存区内容全部改变。

说明

–soft 用处不是很多,当 commit 之后想撤回 commit,但还不想覆盖工作区内容时,使用 --mixed;当想完全回滚时,使用 --hard 来覆盖工作区。

git 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. 要放弃目前本地的所有改变时,即去掉所有 git add 到暂存区的文件和工作区的文件,可以执行 git reset --hard HEAD 来强制恢复 git 管理的文件夹的內容及状态;

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

–soft

  1. 原节点和 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撤销操作(git reset)详解

功能

git reset 可以让 HEAD 这个指针指向其他的地方。例如我们有一次 commit 不是不是很满意,需要回到上一次的 Commit 里面。那么这个时候就需要通过 reset,把 HEAD 指针指向上一次的 commit 的点。

语法

git reset [options] [file]

参数

参数 描述
options git reset 命令使用的选项。
file 需要放弃修改的文件。

git reset命令常用实例

实例

参数 描述
git reset HEAD~1 回退一个版本,且会将暂存区的内容和本地已提交的内容全部恢复到未暂存的状态,不影响原来本地文件(未提交的也不受影响)。
git reset –soft HEAD~1 回退一个版本,不清空暂存区,将已提交的内容恢复到暂存区,不影响原来本地的文件(未提交的也不受影响)。
git reset –hard HEAD~1 回退一个版本,清空暂存区,将已提交的内容的版本恢复到本地,本地的文件也将被恢复的版本替换。

说明

git reset --soft 参数用的比较少。

git回滚文件总结

修改完还未git add

修改完,还未 git add,使用 git checkout 回滚:

git checkout .

使用暂存区的文件覆盖工作区,所以执行完 git add . 之后,再执行该命令是无效的。 git checkout . 和 git add . 是一对反义词。

git add提交还未commit

使用 git add 提交到暂存区,还未 commit 之前,使用 git reset 和 git checkout 回滚:

git reset # 先用 Head 指针覆盖当前的暂存区内容 git checkout . # 再用暂存区内容覆盖工作区内容

或者使用:

git reset --hard

直接使用 head 覆盖当前暂存区和工作区。

已经git commit还未git push

已经执行了 git commit,但还没有执行 git push,使用 git reset 回滚:

git reset --hard last_commit_id

覆盖本地仓库、暂存区和工作区。

已经git push

修改错了,完全覆盖掉,使用:

git reset --hard commit_id

错误的把大文件添加到了缓存区,使用:

git reset

撤回添加。

修改完还未git add

语法

git checkout .

案例

我们首先,修改本地工作区的文件,接着,我们使用 git status 命令,查看当前工作区状态,具体命令如下:

git status

执行完毕后,如下图所示:

106_git撤销修改回退版本git reset.png

我们看到,我们已经修改了 haicoder.txt 文件,现在,我们不想要该修改了,我们使用 git checkout 命令,放弃修改,具体命令如下:

git checkout .

执行完毕后,如下图所示:

107_git撤销修改回退版本git reset.png

现在,我们再次使用 git status 命令,查看文件状态,具体命令如下:

git status

执行完毕后,如下图所示:

108_git撤销修改回退版本git reset.png

我们看到,此时,工作区已经没有任何修改了,即,我们使用了 git checkout 放弃了工作区文件的修改。

git add提交还未commit

语法

git reset --hard

案例

我们首先,修改本地工作区的文件,接着,我们使用 git add 命令,提交本次修改,具体命令如下:

git add .

执行完毕后,如下图所示:

109_git撤销修改回退版本git reset.png

现在,我们不想要本次添加了,我们使用 git reset 命令,放弃本次添加,具体命令如下:

git reset --hard

执行完毕后,如下图所示:

110_git撤销修改回退版本git reset.png

现在,我们再次查看修改的文件,发现,已经被回退了,同时,我们使用 git status 命令查看文件状态,具体命令如下:

git status

执行完毕后,如下图所示:

111_git撤销修改回退版本git reset.png

我们看到,已经没有任何修改了。

已经git commit还未git push

语法

git reset --hard origin/master

案例

我们首先,修改本地工作区的文件,接着,我们使用 git add 命令添加,并使用 git commit 提交本次修改,我们使用 git log,查看提交记录,具体命令如下:

git log

执行完毕后,如下图所示:

112_git撤销修改回退版本git reset.png

现在,我们不想要最近的一次提交了,我们使用 git reset 命令,放弃最近提交,具体命令如下:

git reset --hard 3d82ab

执行完毕后,如下图所示:

113_git撤销修改回退版本git reset.png

现在,我们再次使用 git log,查看提交记录,具体命令如下:

git log

执行完毕后,如下图所示:

114_git撤销修改回退版本git reset.png

我们看到,版本已经被回退了。

回退到任意版本

语法

git reset --hard commitId

案例

我们首先,修改本地工作区的文件,接着,我们使用 git add 命令添加,并使用 git commit 提交本次修改,我们使用 git log,查看提交记录,具体命令如下:

git log

执行完毕后,如下图所示:

115_git撤销修改回退版本git reset.png

现在,我们想回退到第三个版本,我们使用 git reset 命令,放弃最近三次提交,具体命令如下:

git reset --hard b394f50

执行完毕后,如下图所示:

116_git撤销修改回退版本git reset.png

现在,我们再次使用 git log,查看提交记录,具体命令如下:

git log

执行完毕后,如下图所示:

117_git撤销修改回退版本git reset.png

我们看到,版本已经被回退了三个版本。

Git撤销操作(git reset)总结

git reset 命令是用来将当前 branch 重置到另外一个 commit 的,这个动作可能同时影响到 index 以及 work directory。

git reset 有三种工作模式,即 --soft、–mixed 和 --hard。