如何在 GIT 撤销操作和恢复文件

作者: , 共 1759 字

1、撤销还未 add 的操作

如果还没有执行git add,此时被认为尚未暂存以备提交的变更,git status结果如下:

位于分支 dev
尚未暂存以备提交的变更:
  (使用 "git add <文件>..." 更新要提交的内容)
  (使用 "git checkout -- <文件>..." 丢弃工作区的改动)

        修改:     README.md
        删除:     package-lock.json

修改尚未加入提交(使用 "git add" 和/或 "git commit -a")

此时可直接按照提示使用git checkout --操作即可:

git checkout -- README.md package-lock.json # 支持单个或多个文件
git checkout -- .                           # 支持目录,会恢复该目录下所有文件
git checkout -- '*.c'                       # 也可以支持通配符

原理说明:

2、撤销已经 add 但还未 commit 的操作

此时git status的结果如下:

要提交的变更:
  (使用 "git reset HEAD <文件>..." 以取消暂存)

        修改:     README.md
        删除:     package-lock.json

因此根据提示,使用git reset HEAD操作即可:

git reset HEAD README.md package-lock.json # 支持单个或多个文件
git reset HEAD .                           # 支持目录,会恢复该目录下所有文件

注意撤销后,只是将撤销 commit 操作,如果想完全恢复,还需要执行上面的git checkout --的操作。

原理说明:

3、撤销某次 commit 之后所有操作

git checkout可以从任何一个提交中恢复文件,撤销该提交之后所有的操作:

git checkout 1816af0 README.md package-lock.json # 支持单个或多个文件 

其中1816af0是提交的 ID ,是要被恢复到的,应该是被改坏那次提交之前的那次提交。该操作之后,文件被恢复到那一次提交时的状态,那之后所有的提交所做的改动都被丢弃。

如果想把所有文件都恢复到之前的某一次 commit ,此时有两种方法。如果那次 commit 之后的还未 push ,可以直接reset hard,此时那次 commit 之后的所有提交都将直接丢弃,当前节点直接指向到指定的 commit 节点:

git reset --hard 1816af0

4、撤销某次 commit 当次的操作

现在我们有一次错误提交,在这之后又有了很多次正确的提交,但我们需要撤销这个错误的 commit ,但保留之后的正确的 commit。

如果从错误提交开始的所有提交都没有被推送到服务器,此时可以使用rebase -i:

git rebase -i 284d399

然后再弹出的提示中,把错误的提交前面的pick改成drop即可:

pick 0052aac wrong commit
pick 940d3d4 commit1
pick cf2eed6 commit2

此时涉及到的所有 commit 都会被重写, id 也会改变。但出错的 commit 在时间线里被删除,就像历史上没有存在过一样,有助于保持干净的时间线。

我们也可以使用git revert:

git revert 1816af0

其中1816af0是错误的提交。它在现有时间线后面,再增加一个新的 commit ,撤销指定的 commit。这个方法适合之前的 commit 已经推送到服务器的时候,而且如果远程分支被保护,这也是唯一的方法。

Q. E. D.

类似文章:
IT » GIT
分为三步。最简单的:
编程 » GIT
git经常出现类似于HEAD detached at origin/development的错误提示。这是因为当前的 HEAD 没有位于任何一个分支上的缘故。
IT » git
分支是一条线,随着开发进度一直往前推进,可以分叉、合并等。
编程 » GIT
有时候不小心把一些大文件 commit 到了本地版本库,但往网络版本库同步时,因为文件过大被拒绝。如果在上传前,本地有多次提交,此时再在当前版本里删除这些大文件还不够,还需要把历史记录全删掉。效果要跟从来没提交过这些文件一样。
相似度: 0.130
IT » GIT
GIT 的一个很大的问题是没有权限划分,所有人对项目下所有东西都有(查看)权限(只能设置分支的推送权限),无法对特定文件和文件夹设置单独的权限。这个功能只能借用 SUBMODULE 来实现。
相似度: 0.098
IT » GIT, proxy
大部分设置都是通过git config命令实现的:
假设你有多个很耗时的任务,比如训练多个神经网络模型:
IT » gitlab, git
用 gitlab 搭建的 git 私有服务器,占用空间不断增长,已高达 400G。仔细检查了一下,真正的库数据/var/opt/gitlab/git-data/repositories只有 7 个 G ,真正占用空间的是/var/opt/gitlab/prometheus/data,占用了将近 400G ,里面很多 80M 一个的大文件。
命令行参数的初步说明,请参考argparse 模块用法实例详解,写的很清晰而详细。
相似度: 0.056
IT » github
github 自从废除用户名密码直接登录之后,就乱了很多。直接用户名密码会提示:
IT » github
github 自从废除用户名密码直接登录之后,就乱了很多。直接用户名密码会提示:
IT » vim
之前用的是 ctrlp ,现在改用 leaderf ,配置更简单(主要是没搞定 ctrlp 过滤指定文件和文件夹),功能也更多一点。