没想到,Git居然有3种“后悔药”!
没想到,Git居然有后悔药!
你知道Git版本控制系统中都有哪些“后悔药”吗?
本文通过案例讲解
git reset 、 git revert 、 git checkout
在版本控制中的作用;
场景
小明同学作为新人加入到一个新的项目组中做开发,在项目的迭代开发中,小明勤勤恳恳的写代码,直到有一次...
小明:完了,完蛋了
洋仔:怎么了,一惊一乍的
小明:我把错误代码用git commit后还push到线上代码库了! 这可怎么办!
洋仔:莫慌,git有“后悔药”!
洋仔:容我给你慢慢道来。 但是我们要先知道一些git的基础知识,你才能更好的理解git命令的作用
预备知识
git将项目的存储分为4部分,每部分有自己作用,
见下图:
Workspace
:工作区(当前用户操作修改的区域)Index / Stage
:暂存区 (add后的区域)Repository
:仓库区或本地仓库(commit后的区域)Remote
:远程仓库(push后的区域)
整体过程可以简述为:
- 工作区–>
add
–>暂存区–>commit
–>本地仓库区–>push
–>远程仓库区 - 远程仓库区–>
fetch
–>使用refs\remotes下对应分支文件记录远程分支末端commit_id 和 本地仓库区 -->merge
–>工作区 - 远程仓库区–>
pull
–>使用refs\remotes下对应分支文件记录远程分支末端commit_id and 本地仓库区 and 工作区
具体的git的组成部分和概念命令,请移步下述两个博客:
假设项目存在这么一个提交记录:
$ git log
commit commit_id4 (HEAD -> master)
Author: test
Date: Thu Aug 20 16:28:45 2020 +0800
第三次修改README文件
commit commit_id3 (HEAD -> master)
Author: test
Date: Thu Aug 20 16:28:45 2020 +0800
第二次修改README文件
commit commit_id2
Author: test
Date: Thu Aug 20 16:28:19 2020 +0800
第一次修改README文件
commit commit_id1
Author: test
Date: Thu Aug 20 16:26:59 2020 +080
初始化项目
提交顺序为:commit_id1
--> commit_id2
--> commit_id3
--> commit_id4
注意:在git中每次的commit都有一个commit id唯一标识当前的提交!
下面,我们先来解决小明的这个问题,使用git reset
即可完美解决~
问题解决
洋仔:小明,你的这个就可以用git reset 这个命令来完美的搞定,下面我们看一下如何解决
1、获取当前提交的commit id
命令:git log
获取到当前项目分支下的所有commit记录;
假设上述小明提交错误的commit id为commit id:commit_id4
这一次提交;
他的上一次提交就是commit id:commit_id3
,我们要将修改回滚到commit_id3
的时刻!
小明:我想要把我刚才 commit的修改保留下来,我修改的代码不能给我删除掉呀!
洋仔:没问题
2、将某个commit id前的commit清除,并保留修改的代码
命令:git reset <commit_id>
当前场景下就是:git reset commit_id3
将指定commit_id后的所有提交,都去除,并保留修改的代码在本地的区域,也就是Workspace
中
小明:啊哈,这样的话我就可以把错误代码修改后再提交了; 但是我已经push到线上仓库的数据怎么办呢?
洋仔:别急,有办法~
3、修改代码完成后,将修改好的代码add到暂存区,并提交到本地仓库中
命令:git add <file_name>
and git commit
当前场景下:git add .
and git commit
将最新修改后的代码commit
则提交后的提交记录假设如下: 可以看到,我们错误提交的commit_id4
提交记录消失,取而代之的是我们更新代码后提交的记录commit_id5
; 这样就完成了本地的代码修改和更新
$ git log
commit commit_id5 (HEAD -> master)
Author: test
Date: Thu Aug 20 16:28:45 2020 +0800
第三次修改README文件-更新错误后提交
commit commit_id3 (HEAD -> master)
Author: test
Date: Thu Aug 20 16:28:45 2020 +0800
第二次修改README文件
commit commit_id2
Author: test
Date: Thu Aug 20 16:28:19 2020 +0800
第一次修改README文件
commit commit_id1
Author: test
Date: Thu Aug 20 16:26:59 2020 +080
初始化项目
4、将本地修改同步到远程仓库
命令:git push origin HEAD --force
将本地修改强行同步到远程仓库,使得远程仓库和本地仓库保持一致!
整体流程如下:
git log
git reset commit_id3
修改代码
git add .
git commit -m '第三次修改README文件-更新错误后提交'
git push origin HEAD --force
洋仔:好了,小明,你的问题完美解决了
小明:哦吼,但是我还有一个问题: 如果我想要不保留回滚commit的修改,直接删除掉修改!该怎么处理呢?
洋仔:简单~ 我们整体看一下 git reset 命令
后悔药-git reset
在进行下面的讲解是,还是先假设有这么一个提交链:
commit_id1 --> commit_id2 --> commit_id3 --> commit_id4
git reset commit_id2:
reset是将HEAD重新定位到commit_id2
上,对于commit_id3 和 commit_id4 和本地当前的修改,对于不同的参数param,会有不同的处理;
reset命令有三种处理模式:
- --soft:保留commit修改,将修改存储到index中;也就是说git add后的区域
- --mixed:保留commit修改,将修改存储到本地工作区域中;也就是说git add前的区域
- --hard:删除commit修改,慎用!
git reset --soft
回滚commit_id前的所有提交,不删除修改:
git reset --soft commit_id
重设head,不动index,所以效果是commit_id之后的commit修改全部在index中
将id3 和 id4的修改放到index区(暂存区),也就是add后文件存放的区域,本地当前的修改保留
git reset --mixed
回滚commit_id前的所有提交,不删除修改:
git reset commit_id
等同于 git reset --mixed commit_id
与 下述的 git reset --hard commit_id效果不同
重设head 和 index,不重设work tree,效果就是commit_id之前的修改,全部在work tree中,为还未add的状态
将id3 和 id4 的所有修改放到本地工作区中,本地当前的修改保留
git reset --hard
回滚commit_id前的所有提交,将修改全部删除:
git reset --hard commit_id
重设head、index、work tree,也就是说将当前项目的状态恢复到commit_id的状态,其余的全部删除(包含commit_id后的提交和本地还未提交的修改)
慎用!!
后悔药-git revert
小明:原来git reset这么强大呀! 但是我这还有个问题:
如果想要只操作修改中间的一个commit,不对其他的commit产生影响; 也就是类似于我们只修改commit_id2,而对commit_id3 和 commit_id4无影响,该怎么处理呢?
洋仔:(这么多问题,幸亏我懂,要不这次就丢大了。。) 简单! git revert 命令!
适用场景: 在项目开发中,突然发现在前几次的提交中,有一次提交中包含一个bug; 当然我们可以进行一个新的修改,然后再提交一次; 但是,不优雅哈哈; 我们可以直接重做有bug的commit~
为什么不直接去再添加一个commit呢? git revert是用于“反做”某一个版本,以达到撤销该版本的修改的目的。
比如,我们commit了三个版本(版本一、版本二、 版本三),突然发现版本二不行(如:有bug),想要撤销版本二,但又不想影响撤销版本三的提交,就可以用 git revert 命令来反做版本二,生成新的版本四,这个版本四里会保留版本三的东西,但撤销了版本二的东西;
在revert命令中常用的就两个:
- git revert -e <commit_id>:重做指定commit的提交信息
- git revert -n <commit_id>:重做执行commit的代码修改
git revert -e
重做commit_id的提交信息,生成为一个新的new_commit_id
git revert -e commit_id
git revert -n
重做commit_id的提交
git revert -n commit_id
将commit_id中修改,放到index区,我们可以对他重新做修改并重新提交
revert vs reset
- git revert是用一次新的commit来回滚之前的commit,此次提交之前的commit都会被保留不动;
- git reset是回到某次提交,提交及之前的commit都会被保留,但是此commit id之后的修改都会被删除或放回工作区等待下一次提交;
小明:还有这种操作,可以直接单独操作提交过程中的某一个commit! 太棒了!
后悔药-git checkout
小明:还有最后一个问题:
如果我在一次开发中,发现某个文件修改错误了,想要将文件恢复到刚pull代码时的状态怎么办呢?
洋仔:简单! 看git checkout解决这个问题!
我们知道使用git checkout
可以
git checkout <branch_name>
切换分支git checkout -b <branch_bame>
创建分支等操作
它还有回滚指定文件的修改的功能
命令:git checkout -- <file_name>
上述语句的作用,就是将file_name的本地工作区的修改全部撤销,有两种情况:
如果file_name在commit后没有add过这个文件,则撤销到版本库中的状态
如果file_name在commit后add过这个文件,则撤销到暂存区的状态,也就是add后的状态
总之,就是让指定的文件回滚到最近的一次git add
或者 git commit
时的状态!
小明:太棒了,以后再也不怕提错代码了!
总结
上述,我们介绍了git reset \ git revert \ git checkout 在版本回滚、重做、撤销修改方面的作用;
可以应用到工作中对 误操作、不满足要求、不满足意愿的commit记录的重做和修改;
没想到,Git居然有3种“后悔药”!的更多相关文章
- 杀死众筹的N种方法:没想到山寨大军也参与了
众筹作为当下创业者筹集资金,将创意变为现实的最重要手段之一,正面临着越来越多的困难,甚至衍生出杀死众筹的N种方法.甚至这些方法还分为了两类,就众筹本身看,杀死它们的主要方法是:创业者卷钱跑路. ...
- 没想到吧!这个可可爱爱的游戏居然是用 ECharts 实现的!
摘要:echarts 是一个很强大的图表库,除了我们常见的图表功能,还可以自定义图形,这个功能让我们可以很简单地在画布上绘制一些非常规的图形,基于此,我们来玩一些花哨的:做一个 Flappy Bird ...
- 【原创】这道Java基础题真的有坑!我也没想到还有续集。
前情回顾 自从我上次发了<这道Java基础题真的有坑!我求求你,认真思考后再回答.>这篇文章后.我通过这样的一个行文结构: 解析了小马哥出的这道题,让大家明白了这题的坑在哪里,这题背后隐藏 ...
- 万万没想到!ModelArts与AppCube组CP了
摘要:嘘,华为云内部都不知道的秘密玩法,我悄悄告诉您! 双"魔"合璧庆双节 ↑开局一张图,故事全靠编 华为云的一站式开发平台ModelArts和应用魔方AppCube居然能玩到一起 ...
- 头条编程题 万万没想到之抓捕孔连顺 JavaScript
[编程题] 万万没想到之抓捕孔连顺 时间限制:1秒 空间限制:131072K 我叫王大锤,是一名特工.我刚刚接到任务:在字节跳动大街进行埋伏,抓捕恐怖分子孔连顺.和我一起行动的还有另外两名特工,我提议 ...
- 从github下载某个git库的4种方法
转自:http://blog.csdn.net/feiniao1221/article/details/7516421 以gerrit-trigger-plugin为例,下面的链接都是从相应页面上直接 ...
- 在做关于NIO TCP编程小案例时遇到无法监听write的问题,没想到只是我的if语句的位置放错了位置,哎,看了半天没看出来
在做关于NIO TCP编程小案例时遇到无法监听write的问题,没想到只是我的if语句的位置放错了位置,哎,看了半天没看出来 贴下课堂笔记: 在Java中使用NIO进行网络TCP套接字编程主要以下几个 ...
- centos clamav杀毒软件安装配置及查杀,没想到linux下病毒比windows还多!
centos clamav杀毒软件安装配置及查杀,没想到linux下病毒比windows还多! 一.手动安装 1.下载(官网) cd /soft wget http://www.clam ...
- 从github下载某个git库的4种方法[zz]
以gerrit-trigger-plugin为例,下面的链接都是从相应页面上直接拷贝的. 法一:不用github的账号,打开这个库在github上的主页,运行下面命令即可 read only 运行命令 ...
随机推荐
- odoo本地pycham环境搭建(mac)
本文以odoo12为例配置本地环境,注意不是docker环境 1.安装pycharm(推荐2020.1版本,破解地址:https://www.cnblogs.com/xuexianqi/p/12767 ...
- Linux的VMWare中Centos7的安装
Windows平台下VMWare 14安装Centos 7 一.虚拟机硬件配置 1.选择创建新的虚拟机: 2.选择自定义(高级)进行自定义配置,单击下一步: 3.选择虚拟机硬件兼容性为默认,单击下一步 ...
- 用大白话解释什么是Socket
好好学习,天天向上 本文已收录至我的Github仓库DayDayUP:github.com/RobodLee/DayDayUP,欢迎Star,更多文章请前往:目录导航 前言 我在去年就学习过Java中 ...
- 【NOI2017】游戏 题解(2-SAT+缩点)
题目链接 题目大意:有四种场地$a,b,c,x$和三种赛车$A,B,C$,$a$不能跑$A$,$b$不能跑$B$,$c$不能跑$C$,$x$都可以跑.给定$n$个场地和$m$个四元组$(i,h_i,j ...
- C#LeetCode刷题之#530-二叉搜索树的最小绝对差(Minimum Absolute Difference in BST)
问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/4123 访问. 给定一个所有节点为非负值的二叉搜索树,求树中任意两 ...
- C#LeetCode刷题-并查集
并查集篇 # 题名 刷题 通过率 难度 128 最长连续序列 39.3% 困难 130 被围绕的区域 30.5% 中等 200 岛屿的个数 38.4% 中等 547 朋友圈 45.1% ...
- JavaScript 通过prototype改变原型的两种方式
// -------------------- prototype 1 -------------------- function A(){} A.prototype.n = 1 let b = ne ...
- MySQL字符集操作
一.查看编码 show variables like 'character%'; 二.临时设置编码 1.set names xxx set names ${编码}; "set names x ...
- 使用vs2008的一个问题 2008-01-08 13:13
昨天在写控制台版的一个管理系统.语言是:c++ ,开发工具是:vs 2008 .功能简单的描述一下,它是就是简单的查询,插入,删除等操作,操作的对象是一个xml文件. 这时我要需要一个命令行参数,根据 ...
- 计算机网络要点---Http
计算机网络要点---Http 1.工作流程 一次HTTP操作称为一个事务,其工作过程可分为四步: 首先客户机与服务器需要建立 TCP 连接.只要单击某个超级链接,HTTP的工作开始. 建立连接后,客户 ...