参考

https://git-scm.com/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E9%87%8D%E7%BD%AE%E6%8F%AD%E5%AF%86

https://git-scm.com/book/en/v2/Git-Tools-Reset-Demystified

https://git-scm.com/docs/git-reset

https://www.liaoxuefeng.com/wiki/896043488029600/897013573512192

前言

在使用git的时候,我们一般提倡是不允许回滚。对于问题的追踪和项目的发展历程而言历史记录都是有用的。并且为了节省一点存储空间而丢失宝贵的代码信息是不值当的。但是我们开发中,肯定会遇到特殊情况需要回退。比如确实操作错了一步历史提交,导致仓库混乱污染或是内容丢失,我们需要回退到干净的一次提交,重新操作。

在git等所有的版本管理软件中,删除操作,只是增加一次记录,内容并不会被删掉,我们可以大胆的操作,这也符合版本仓库的逻辑。只有特殊情况才需要真正的删除,做这种操作的时候需要特别注意,因为一旦失误,无法挽回。

从历史记录中删除 参考 https://www.cnblogs.com/studywithallofyou/p/11772684.html https://www.cnblogs.com/studywithallofyou/p/11772844.html

工作流程

要想理解git reset,那么就要搞清楚git仓库管理流程:

我们修改完内容后,这些记录单单是保存在我们本地目录下,也就是工作目录。如果丢了,就是丢了,无法找回。与普通磁盘上的文件一样,除非到回收站找回。

这时,如果运行了add,那么内容就被记录到本地的暂存仓库,也就是index。这时如果删除文件,在暂存区的内容还存在,并没有丢失。

如下图,我们创建了一个文件4,这时文件4在本地。我们add到暂存仓库,然后删掉文件4,我们发现又多了一条记录删除记录,原来的4还存在,我们可以commit。原来的文件4并没有丢失。

运行commit之后,修改的内容就被保存到了仓库,修改了HEAD(HEAD就是指向当前仓库在哪一个提交历史,不特殊修改,都指向最新的一次提交)。这时运行git status发现目录是干净的。git里面需要提交仓库,暂存仓库和本地目录内容都完全一致,才是干净的,任何一个不一致都会有不同的提示。

比如上面的图,提交的仓库中没有文件4,暂存仓库中增加了4,所以显示绿色的提示内容,add了文件但是还没有commit。但是本次又删除了文件,本地目录中的内容与暂存仓库也不一样,所以提示红色的内容,因为算是警告,没有add的内容是会丢失的。

修改

add

commit

git reset的三个选择

理解了上面的流程,就可以理解git reset了。git reset就是分别逆向操作,也就是把HEAD(提交的仓库)回退到一个指定历史,把HEAD、index(暂存仓库)都回退到指定历史,把HEAD、index和本地目录的内容都回退到一个指定历史。

git reset --soft就是把HEAD回退到指定历史。运行后结果如下

也就相当于我们add了修改的文件,本地目录和暂存仓库都已经一致了,就等待commit。如果我们commit,可以再次填写commit记录,也就实现了git commit --amend的功能。

git reset --mixed就是把HEAD和index都回退到指定的历史。这个也是运行git reset不加参数时的默认规则。运行结果如下

相当于我们仅仅修改了文件,还没做任何处理。

git reset --hard这个是把HEAD、index和本地目录的内容都回退到指定的历史记录。做这一步操作的时候一定要小心,最好把所有的内容都提交,并且push到远程或是拷贝一份。因为这个操作会重置本地的内容到一个指定历史。

我们先运行git log,看到有三个提交历史

运行git reset --hard HEAD~

我们发现仓库是干净的,并且原来的3文件没了,运行git log参看

提交的历史记录也没有了。

这次是真的回退到了指定历史,所有的记录都不见了,我们可以开心的(真的吗?)在原来一个干净的分支上继续写代码了。

git reset --hard的后悔药

世上有没有后悔药我不知道,但是git作为一个先进的分布式管理器,却有无限可能。如果你一不小心,脑袋发热,运行了git reset --hard,但是发现不是你想要的,原来的记录也没了。怎么办?大脑瞬间充血,一片空白。不要慌,首先冷静下来,然后运行git reflog,这个命令是告诉你你的每一次对仓库操作的历史记录,如下

看一下最上面的几条,第一条告诉你当前在e86d948这个提交记录,通过reset切换过来的。对照上面的git log,可以发现这个是第二个提交历史,也就是我们git reset --hard HEAD~的时候回退的分支。第二条记录告诉我们当前是fc9fbc6分支,通过reset回退到这个分支的,我们可以参考上面的git log记录,这个就是我们想要回去的分支。好了,有了记录的哈希值,我们只需再运行一次git reset --hard,如下

查看一下git log

回来了。

git不会删除任何已经提交到版本库的内容,除非你非要专门特殊这样做,并且为了再给你一次机会,像git reset这样,就算你明确说明不要了,它也不会立马删除,除非超过一定时间或是你主动运行git gc等操作,把无用的,没有关联的内容删掉。不然,那条记录还是在本地仓库,只不过它没有被载入历史的长河中。

git回退之git reset的更多相关文章

  1. 学Git,用Git ③

    不知道我前面是否将git讲清楚了,这里再稍微总结一下git的一个重要功能用法,同时增加两个很实用的git使用技巧. 1.git"读档"与git"回退" 我发现我 ...

  2. [原]git的使用(一)---建立本地仓库、add和commit、status和git diff、版本回退使用git reset

    在window下已经安装了git的环境 1.建立本地仓库 mkdir   test     #建立test目录 cd   test        #进入目录 git  init           # ...

  3. Git命令之回退篇 git revert git reset

    Git command之回退篇 欲练回退 必先了解:HEAD.index.WorkingCopy HEAD: 当前所在的分支版本顶端的别名,也就是最新的一次commit. git commit 之后与 ...

  4. Git回退---reset和revert

    今天学习了git回退的两个命令,现在总结一下: 1.git reset 如果想回退错误的提交C和D,只要把指针移到B上 git reset --hard a0fvf8 而这时候,远程仓库的指针还在D上 ...

  5. Git 中的回退操作:reset 和 revert

    Git 中回退有 reset 和 revert,这两个的区别就是是否保留更改记录 假设当前的提交情况是:A <- B <- C <- D <- HEAD,如下图: 当前是 D, ...

  6. 『现学现忘』Git后悔药 — 31、reset版本回退命令总结

    目录 1.--soft回退说明 2.--mixed回退说明 3.--hard回退说明 4.总结 在Git中进行版本回退需要使用git reset命令. 以前面文章中的示例为例,当我准备在V4版本,回退 ...

  7. git 远程仓库版本的回退以及git reset 几种常用方式记录

    由于 github push 了两个比较潦草的commit, 自己很不满意,又不想重新开vpn进行上传,所以找了一下相关的教程. 最后研究了一下,原理为先在本地还原到你想要的commit,然后强制pu ...

  8. 代码回滚:git reset、git checkout和git revert区别和联系

    git reset.git checkout和git revert是你的Git工具箱中最有用的一些命令.它们都用来撤销代码仓库中的某些更改,而前两个命令不仅可以作用于提交,还可以作用于特定文件. 因为 ...

  9. git reset、git checkout和git revert的区别

    这三个git命令都是用来撤销代码仓库中的某些更改,而前两个命令不仅可以作用于commit层面,还可以作用于file层面Reset在commit层面,reset通过移除当前分支的一些节点来实现版本回滚; ...

随机推荐

  1. JavaScript ES6函数式编程(一):闭包与高阶函数

    函数式编程的历史 函数的第一原则是要小,第二原则则是要更小 -- ROBERT C. MARTIN 解释一下上面那句话,就是我们常说的一个函数只做一件事,比如:将字符串首字母和尾字母都改成大写,我们此 ...

  2. js 变量与常量

    编辑器:Sublime Text 3 <!DOCTYPE html><html lang="en"><head> <meta charse ...

  3. opencv::基本阈值操作

    图像阈值(threshold) 阈值 是什么?简单点说是把图像分割的标尺,这个标尺是根据什么产生的,阈值产生算法?阈值类型.(Binary segmentation) 阈值类型一阈值二值化(thres ...

  4. 15.Linux软件管理

    1.什么是rpm? rpm软件包的组成部分有哪些? redhat packages manager 红帽推出软件包管理工具... rpm工具 xxxxx.rpm bash-4.2.46-28.el7. ...

  5. Visual Studio各版本及数据库各版本下载地址

    1.Visual Studio 2019下载地址:https://visualstudio.microsoft.com/zh-hans/downloads/ 2.Visual Studio 2017\ ...

  6. cxf 调用 .net webservice

    1.   问题背景          现在我们两套语言并行,其中必然会涉及到不同系统的相互访问. .net 的会员信息是用 webservice  提供服务的.那如何对现有 .net webservi ...

  7. 【网络安全】Dos攻击科普文

    目录 DOS攻击 什么是DOS攻击 攻击手段分类 具体的攻击方式举例 优秀博客参考 DDOS攻击 DOS攻击 什么是DOS攻击 DOS是Denial of Service的简称,用中文简单翻译就是拒绝 ...

  8. Mysql数据库(一)数据库设计概述

    1.数据库的体系结构 1.1 数据库系统的三级模式结构是指模式.外模式和内模式. 1.2 三级模式之间的映射分为外模式/模式映射和模式/内模式映射. 2.E-R图也称“实体-关系图”,用于描述现实世界 ...

  9. Linux之Centos7开机之后连不上网

    问题:ns33mtu 1500 qdisc noop state DOWN group default qlen 1000 解决方法: root@topcheer ~]# systemctl stop ...

  10. 常用 UML 类图

    一. 类 类图分三层: 第一层是类的名称,如果是抽象类,则用斜体显示. 第二层是类的特性,通常就是字段和属性. 第三层是类的操作,通常是方法或行为.注意 '+' 表示 public,'-' 表示 pr ...