1、撤销操作说明

我们在使用Git版本管理时,往往需要撤销某些操作。比如说我们想将某个修改后的文件撤销到上一个版本,或者是想撤销某次多余的提交,都要用到Git的撤销操作,因此撤销操作在平时使用中还是比较多的。

本文介绍几种,对于已修改过的文件,需要进行撤销操作,根据修改文件出现的位置,可以分为三种情况:

  1. 仅仅是工作区中内容进行了修改,还未添加到暂存区。
  2. 文件已经添加到暂存区,但是还未提交到本地版本库。
  3. 文件已经提交到本地版本库。

前两种可以叫撤销操作,后面一种叫回退版本,不同的情况具有不同的撤销方式。

下面就撤销操作给出详细的解释。

2、撤销工作区中文件的修改

如果工作区的某个文件被改乱了,但还没有提交,可以用git restore或者git checkout命令找回本次修改之前的文件。

前提:test.txt文件已在本地版本库中。

(1)修改test.txt文件中的内容。

  1. # 1.查看test.txt文件内容
  2. L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
  3. $ cat test.txt
  4. hello git
  5. # 2.进行修改内容
  6. L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
  7. $ echo "hello git v2" >> test.txt
  8. L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
  9. $ cat test.txt
  10. hello git
  11. hello git v2

(2)查看工作目录中文件的状态。

  1. L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
  2. $ git status
  3. On branch master
  4. Changes not staged for commit:
  5. (use "git add <file>..." to update what will be committed)
  6. (use "git restore <file>..." to discard changes in working directory)
  7. modified: test.txt
  8. no changes added to commit (use "git add" and/or "git commit -a")

好好的说明一下这些提示信息:

  • On branch master:当前工作在主分支上。
  • Changes not staged for commit::暂存区中没有可提交的变化。
  • git add <file>...:可使用该命令把更新添加到暂存区。
  • git restore <file>...:丢弃工作区的修改。同git checkout -- <file>...命令一样。
  • no changes added to commit (use "git add" and/or "git commit -a"):可以使用git add命令添加到暂存区,也可以使用git commit -a命令直接提交到本地版本库。

Git的命令提示是非常详细的,我们按照提示信息操作就可以。

说明:

老版本Git会提示: (use "git checkout -- <file>..." to discard changes in working directory)

新版本Git会提示: (use "git restore <file>..." to discard changes in working directory)

git restore <file>...git checkout -- <file>...命令:

  • git checkout这个命令承担了太多职责,既被用来切换分支,又被用来恢复工作区文件,对用户造成了很大的认知负担。
  • Git社区发布了Git的2.23版本中,有一个特性非常引人瞩目,就是引入了两个新命令 git switchgit restore,用以替代现在的git checkout

    即:Git2.23版本开始,git restore <file>...命令可代替git checkout -- <file>...命令文件恢复的工作。

(3)撤销工作区中test.txt文件的修改。

  1. # 1.使用git restore 命令撤销工作区中的操作
  2. L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
  3. $ git restore test.txt
  4. L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
  5. $ git status
  6. On branch master
  7. nothing to commit, working tree clean
  8. # 2.再次修改test.txt文件
  9. L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
  10. $ echo "hello git v3" >> test.txt
  11. L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
  12. $ git status
  13. On branch master
  14. Changes not staged for commit:
  15. (use "git add <file>..." to update what will be committed)
  16. (use "git restore <file>..." to discard changes in working directory)
  17. modified: test.txt
  18. no changes added to commit (use "git add" and/or "git commit -a")
  19. # 使用git checkout命令撤销工作区中的操作
  20. # 撤销操作固定写法“git checkout -- 文件”
  21. L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
  22. $ git checkout -- test.txt
  23. L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
  24. $ git status
  25. On branch master
  26. nothing to commit, working tree clean

说明:git checkout -- file命令中的--很重要,没有--,就变成了“切换到另一个分支”的命令,我们在后面的分支管理中会再次遇到git checkout命令。

(4)总结

  1. git restore <file>...git checkout -- <file>...命令原理:

    这里有两种情况:

    一种是test.txt自修改后还没有被放到暂存区,现在的撤销修改就回到和版本库一模一样的状态;

    一种是test.txt已经添加到暂存区后,又作了修改,现在的撤销修改就回到添加到暂存区后的状态。
  2. 撤销命令是一个危险的命令,这个很重要,你对该文件做的任何修改都会消失。原理是你拷贝了该文件在暂存区或者本地版本库中的副本,来覆盖工作区的该文件。

    即:工作区的文件变化一旦被撤销,就无法找回了,除非你确实不想要这个文件了。

所以我的理解:撤销命令实际的操作是重置(原文件覆盖),而实际的效果上是撤回。

3、撤销暂存区中文件的修改

如果已经把修改的个文件添加到暂存区,可以用下面的命令撤销。

还是以上面test.txt文件为例。

(1)修改test.txt文件并存储到暂存区。

  1. # 1.修改文件
  2. L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
  3. $ git status
  4. On branch master
  5. nothing to commit, working tree clean
  6. L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
  7. $ echo "hello git v4" >> test.txt
  8. # 2.添加文件到暂存区
  9. L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
  10. $ git add test.txt
  11. warning: LF will be replaced by CRLF in test.txt.
  12. The file will have its original line endings in your working directory
  13. # 3.查看工作目录中文件状态
  14. L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
  15. $ git status
  16. On branch master
  17. Changes to be committed:
  18. (use "git restore --staged <file>..." to unstage)
  19. modified: test.txt

说明:

  • Changes to be committed::表示暂存区中所做的更改如下,可以提交。
  • git restore --staged <file>...:该命令表示取消暂存,把暂存区中的文件撤回到工作区。

Tips:

老版本Git会提示: (use "git reset HEAD <file>..." to unstage)

新版本Git会提示: (use "git restore --staged <file>..." to unstage)

和上面同理:

  • 早期的Git中git checkout命令承载了分支操作和文件恢复的部分功能,有点复杂,并且难以使用和学习,所以社区解决将这两部分功能拆分开,Git 2.23.0版本中中引入了两个新的命令git switchgit restore
  • 早期的Git中,文件恢复涉及到两个命令,一个是git checkout命令,一个是git reset命令。git reset命令除了重置分支之外,还提供了恢复文件的能力。
  • 而新的git restore命令,代替了checkout命令和reset命令(但是这两个命令还可以进行文件恢复),专门用来恢复暂存区和工作区的文件。

(2)撤销暂存区中test.txt文件的修改。

1)使用git restore --staged命令撤销暂存区中文件的修改。

  1. L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
  2. $ git restore --staged test.txt
  3. L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
  4. $ git status
  5. On branch master
  6. Changes not staged for commit:
  7. (use "git add <file>..." to update what will be committed)
  8. (use "git restore <file>..." to discard changes in working directory)
  9. modified: test.txt
  10. no changes added to commit (use "git add" and/or "git commit -a")

(重点)我们可以看到,test.txt文件从暂存区中撤销到工作区中,但是不会撤销工作区中文件的更改。

2)使用git restore命令,不带--staged参数,撤销暂存区中文件的修改。

  1. # 1.文件添加到暂存区中
  2. L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
  3. $ git add test.txt
  4. warning: LF will be replaced by CRLF in test.txt.
  5. The file will have its original line endings in your working directory
  6. L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
  7. $ git status
  8. On branch master
  9. Changes to be committed:
  10. (use "git restore --staged <file>..." to unstage)
  11. modified: test.txt
  12. # 2.使用`git restore`命令,撤销暂存区中文件的修改
  13. L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
  14. $ git restore test.txt
  15. L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
  16. $ git status
  17. On branch master
  18. Changes to be committed:
  19. (use "git restore --staged <file>..." to unstage)
  20. modified: test.txt

我们可以看到,工作目录中test.txt文件状态没有改变,所以要撤销暂存区中文件的修改,必须加上--staged参数。

这是为什么呢?(个人理解)

因为git restore命令,不带--staged参数,背后的执行逻辑是,把暂存中的test.txt文件复制一份,覆盖掉工作区的test.txt文件,但是这样就形成了test.txt文件在工作区和暂存区一样的状态,所以工作区和暂存区的状态也一样。这也就是上面执行完git restore test.txt命令,在工作目录test.txt文件的状态,没有变化的原因。

3)使用git reset HEAD <file>...命令撤销暂存区中文件的修改。

  1. L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
  2. $ git reset HEAD test.txt
  3. Unstaged changes after reset: # 表示重置后文件未被跟踪
  4. M test.txt # M:应该是modified的意思吧
  5. L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
  6. $ git status
  7. On branch master
  8. Changes not staged for commit:
  9. (use "git add <file>..." to update what will be committed)
  10. (use "git restore <file>..." to discard changes in working directory)
  11. modified: test.txt
  12. no changes added to commit (use "git add" and/or "git commit -a")

我们看到git reset HEAD <file>...命令的执行效果和git restore --staged命令执行的效果是一样的,这里就不多解释了。

之后要在进行撤销工作区中文件的修改,就和上一步一样了。

4、总结

前面通过详细的步骤,分别演示了从工作区和暂存区做撤销修改的操作。

下面我们总结一下,方便我们对前面知识的理解。

  1. git checkout命令,既可以用来切换分支,又可以用来恢复工作区文件。

    恢复文件命令:git checkout -- 文件
  2. git reset命令,除了能够重置分支之外,还提供了恢复文件的能力。

    恢复文件命令:git reset HEAD 文件
  3. Git 2.23.0版本中,提供了git restore命令,代替了git checkout命令和git reset命令的恢复文件功能。(但上面两个命令也能恢复文件)

    修改的文件只在工作区,没有添加到暂存区中,使用git restore 文件命令。

    修改的文件已经添加到暂存区,但还没有提交,使用git restore --staged 文件命令。

在来详细说明一下git restore命令:

这里有两种情况:

一种是test.txt自修改后还没有被放到暂存区,现在的撤销修改就回到和版本库一模一样的状态;

一种是test.txt已经添加到暂存区后,又作了修改,现在的撤销修改就回到添加到暂存区后的状态。

git restore --staged命令:

用于已经把修改的文件添加到暂存区,没有被修改,但还未提交。这时执行该命令,直接撤销暂存区总存储的修改,将文件恢复到工作区去。

参考:http://www.bubuko.com/infodetail-3431539.html

『现学现忘』Git基础 — 23、Git中的撤销操作的更多相关文章

  1. 『现学现忘』Docker基础 — 23、使用Docker安装Tomcat

    目录 步骤1:搜索镜像 步骤2:下载Tomcat镜像 步骤3:运行Tomcat镜像 步骤4:本机和外网测试 步骤5:解决问题 补充:--rm选项 步骤1:搜索镜像 使用docker search命令进 ...

  2. 『现学现忘』Git基础 — 5、Git的协作模式

    目录 1.分布式工作流程 2.集中式工作流 3.分支工作流 4.GitFlow 工作流(最流行) 5.Forking 工作流(偶尔使用) 6.总结 1.分布式工作流程 与传统的集中式版本控制系统(CV ...

  3. 『现学现忘』Git基础 — 13、Git的基础操作

    目录 1.Git最基础的使用方式 (1)初始化本地版本库 (2)查看文件的状态 (3)把文件添加到暂存区 (4)把暂存区的内容提交到本地版本库 2.总结本文用到的Git命令 1.Git最基础的使用方式 ...

  4. 『现学现忘』Git基础 — 3、Git介绍

    目录 1.Git的历史 2.Git的特点 3.Git在项目协作开发中所解决的问题 1.Git的历史 Git是目前世界上最先进的分布式版本控制系统,开源.免费. Git 是 Linus (林纳斯)为了帮 ...

  5. 『现学现忘』Git基础 — 4、Git下载与安装

    目录 1.Git下载 2.Git在Windows下的详细安装 3.验证Git是否安装成功 1.Git下载 进入官方地址下载Git客户端:https://git-scm.com/download/win ...

  6. 『现学现忘』Git基础 — 7、设置Git Bash终端默认路径

    目录 1.Git Bash默认路径 2.如何查看Git Bash终端默认路径 3.如何修改Git Bash终端的默认路径 4.拓展:指定目录进入Git Bash终端 5.注意事项 如果您不熟悉Git命 ...

  7. 『现学现忘』Git基础 — 8、Git创建本地版本库

    目录 1.Git版本库介绍 2.创建本地版本库 场景一:创建一个空的本地版本库. 场景二:项目中已存在文件时,创建该项目的本地版本库. 场景三:在GitHub网站上创建仓库,克隆到本地. 1.Git版 ...

  8. 『现学现忘』Git基础 — 11、配置Git用户签名的方式

    目录 1.配置Git签名 (1)语法 (2)配置系统用户签名 (3)配置全局用户签名 (4)配置本地用户签名 2.查看三个配置文件的用户签名 (1)语法 (2)查看项目/仓库级别的配置文件信息(loc ...

  9. 『现学现忘』Git基础 — 12、Git用户签名(补充)

    目录 1.修改用户签名 2.取消用户签名 3.用户签名的优先级 4.总结本文用到的Git命令 1.修改用户签名 其实很简单,就是重新执行git config命令,换个用户名和邮箱地址就可以了,新配置的 ...

  10. 『现学现忘』Git基础 — 14、Git基础操作的总结与补充

    目录 1.Git本地版本库结构 2.Git常用操作方法 3.补充:添加多个文件到暂存区 4.补充:提交操作未写备注 5.补充:从工作区直接提交到版本库 1.Git本地版本库结构 如下图所示: 工作区( ...

随机推荐

  1. 学习docker(三)

    一.Docker介绍 1.docker容器 docker是宿主机的一个进程,通过namespace实现了资源隔离,通过cgroup实现了资源限制, 通过写时复制技术(copy-on-write)实现了 ...

  2. 学习RabbitMQ(二)

    MOM(message oriented middleware) 消息中间件(是在消息的传递过程中保存消息的容器,消息中间件再将消息从它的源中继到它的目标时,充当中间人的作用,队列的主要目的是提供路由 ...

  3. 学习Squid(三)

    Squid 缓存服务 1.缓存服务器结束 缓存服务器(cache server),即用来存储(介质为内存及硬盘)用户访问的网页.图片.文件等等信息的专用服务器,这种服务器不仅可以使用户可以最快的得到他 ...

  4. ROS终端中创建功能包的常用命令

  5. Clickhouse-alter 对副本表修改表结构报元数据错误

    [应用场景] 对分片副本表的列进行 alter 操作 [问题复现] [解决办法] 检查该分片所有副本表的表结构和 zk 上存储的 column 信息保持一致,检查本地的表结构 sql 文件 /data ...

  6. 怎样用JavaScript和HTML5 Canvas绘制图表

    原文:https://code.tutsplus.com/zh-...原作:John Negoita翻译:Stypstive 在这篇教程中,我将展示用JavaScript和canvas作为手段,在饼状 ...

  7. 前端面试题整理——HTML/CSS

    如何理解语义化: 对应的内容是用相应意思的标签,增加开发者和机器爬虫对代码的可读性. 块状元素和内联元素: 块状元素有:display:block/table:有div h1 h2 table ul  ...

  8. 【Android开发】URL[] 转成 bitmap[]

    public static Bitmap[] getBitmapFromURL(String[] path) throws MalformedURLException { Bitmap[] b = n ...

  9. Windows测试Hadoop报错解决

    错误1:HADOOP_HOME and hadoop.home.dir are unset 原因:没有在Windows配置环境变量 解决办法:配置环境变量:记得配置到bin目录 错误2:Could n ...

  10. JS实现列表移动(通过DOM操作select标签)

    JS小例题 学习内容: 需求 总结: 学习内容: 需求 用 JavaScript 实现 select 标签的移动 实现代码 <!DOCTYPE html PUBLIC "-//W3C/ ...