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

作者: , 共 1759 字 , 共阅读 0

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.131
IT » GIT
GIT 的一个很大的问题是没有权限划分,所有人对项目下所有东西都有(查看)权限(只能设置分支的推送权限),无法对特定文件和文件夹设置单独的权限。这个功能只能借用 SUBMODULE 来实现。
相似度: 0.095
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.054
IT » github
github 自从废除用户名密码直接登录之后,就乱了很多。直接用户名密码会提示:
IT » github
github 自从废除用户名密码直接登录之后,就乱了很多。直接用户名密码会提示:
IT » vim
之前用的是 ctrlp ,现在改用 leaderf ,配置更简单(主要是没搞定 ctrlp 过滤指定文件和文件夹),功能也更多一点。