Git 版本回退与前进(03)

2023-10-27

现在,你已经学会了修改文件,然后把修改提交到Git版本库,现在,再练习一次,修改readme.txt文件如下:

Git is a distributed version control system.
Git is free software distributed under the GPL.
然后尝试提交:

$ git add readme.txt
$ git commit -m "append GPL"
[master 3628164] append GPL
 1 file changed, 1 insertion(+), 1 deletion(-)
像这样,你不断对文件进行修改,然后不断提交修改到版本库里,就好比玩RPG游戏时,每通过一关就会自动把游戏状态存盘,如果某一关没过去,你还可以选择读取前一关的状态。有些时候,在打Boss之前,你会手动存盘,以便万一打Boss失败了,可以从最近的地方重新开始。Git也是一样,每当你觉得文件修改到一定程度的时候,就可以“保存一个快照”,这个快照在Git中被称为commit。一旦你把文件改乱了,或者误删了文件,还可以从最近的一个commit恢复,然后继续工作,而不是把几个月的工作成果全部丢失。
现在,我们回顾一下readme.txt文件一共有几个版本被提交到Git仓库里了:

版本1:wrote a readme file
Git is a version control system.
Git is free software.
版本2:add distributed
Git is a distributed version control system.
Git is free software.
版本3:append GPL

Git is a distributed version control system.
Git is free software distributed under the GPL.
当然了,在实际工作中,我们脑子里怎么可能记得一个几千行的文件每次都改了什么内容,不然要版本控制系统干什么。版本控制系统肯定有某个命令可以告诉我们历史记录,在Git中,我们用git log命令查看:

$ git log

git log命令显示从最近到最远的提交日志,我们可以看到3次提交,最近的一次是append GPL,上一次是add distributed,最早的一次是wrote a readme file。
如果嫌输出信息太多,看得眼花缭乱的,可以试试加上--pretty=oneline参数:

$ git log --pretty=oneline
3628164fb26d48395383f8f31179f24e0882e1e0 append GPL
ea34578d5496d7dd233c827ed32a8cd576c5ee85 add distributed
cb926e7ea50ad11b8f9e909c05226233bf755030 wrote a readme file
需要友情提示的是,你看到的一大串类似3628164...882e1e0的是commit id(版本号),和SVN不一样,Git的commit id不是1,2,3……递增的数字,而是一个SHA1计算出来的一个非常大的数字,用十六进制表示,而且你看到的commit id和我的肯定不一样,以你自己的为准。为什么commit id需要用这么一大串数字表示呢?因为Git是分布式的版本控制系统,后面我们还要研究多人在同一个版本库里工作,如果大家都用1,2,3……作为版本号,那肯定就冲突了。
每提交一个新版本,实际上Git就会把它们自动串成一条时间线。如果使用可视化工具查看Git历史,就可以更清楚地看到提交历史的时间线:

git-log-timeline

好了,现在我们启动时光穿梭机,准备把readme.txt回退到上一个版本,也就是“add distributed”的那个版本,怎么做呢?
首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,也就是最新的提交3628164...882e1e0(注意我的提交ID和你的肯定不一样),上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100。
现在,我们要把当前版本“append GPL”回退到上一个版本“add distributed”,就可以使用git reset命令:

$ git reset --hard HEAD^
HEAD is now at ea34578 add distributed
--hard参数有啥意义?这个后面再讲,现在你先放心使用。
看看readme.txt的内容是不是版本add distributed:

$ cat readme.txt
Git is a distributed version control system.
Git is free software.
果然。
还可以继续回退到上一个版本wrote a readme file,不过且慢,然我们用git log再看看现在版本库的状态:

$ git log
commit ea34578d5496d7dd233c827ed32a8cd576c5ee85
Author: Michael Liao <askxuefeng@gmail.com>
Date:   Tue Aug 20 14:53:12 2013 +0800

    add distributed

commit cb926e7ea50ad11b8f9e909c05226233bf755030
Author: Michael Liao <askxuefeng@gmail.com>
Date:   Mon Aug 19 17:51:55 2013 +0800

    wrote a readme file
最新的那个版本append GPL已经看不到了!好比你从21世纪坐时光穿梭机来到了19世纪,想再回去已经回不去了,肿么办?
办法其实还是有的,只要上面的命令行窗口还没有被关掉,你就可以顺着往上找啊找啊,找到那个append GPL的commit id是3628164...,于是就可以指定回到未来的某个版本:

$ git reset --hard 3628164
HEAD is now at 3628164 append GPL
版本号没必要写全,前几位就可以了,Git会自动去找。当然也不能只写前一两位,因为Git可能会找到多个版本号,就无法确定是哪一个了。

再小心翼翼地看看readme.txt的内容:

$ cat readme.txt
Git is a distributed version control system.
Git is free software distributed under the GPL.
果然,我胡汉三又回来了。
Git的版本回退速度非常快,因为Git在内部有个指向当前版本的HEAD指针,当你回退版本的时候,Git仅仅是把HEAD从指向append GPL:

git-head

改为指向add distributed:

git-head-move

然后顺便把工作区的文件更新了。所以你让HEAD指向哪个版本号,你就把当前版本定位在哪。
现在,你回退到了某个版本,关掉了电脑,第二天早上就后悔了,想恢复到新版本怎么办?找不到新版本的commit id怎么办?
在Git中,总是有后悔药可以吃的。当你用$ git reset --hard HEAD^回退到add distributed版本时,再想恢复到append GPL,就必须找到append GPL的commit id。Git提供了一个命令git reflog用来记录你的每一次命令:

$ git reflog
ea34578 HEAD@{0}: reset: moving to HEAD^
3628164 HEAD@{1}: commit: append GPL
ea34578 HEAD@{2}: commit: add distributed
cb926e7 HEAD@{3}: commit (initial): wrote a readme file
终于舒了口气,第二行显示append GPL的commit id是3628164,现在,你又可以乘坐时光机回到未来了。

现在总结一下:
HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git reset --hard commit_id。
穿梭前,用git log可以查看提交历史,以便确定要回退到哪个版本。
要重返未来,用git reflog查看命令历史,以便确定要回到未来的哪个版本。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Git 版本回退与前进(03) 的相关文章

  • 阿里云 日志服务接入

    目前项目中都有用到日志记录 一般会存到本地 但是时间长了 去删除也是很麻烦的 阿里云日志服务 是个不错的选择 可分为两种 自动采集和自动上传到云 1 写文件到本地 然后配置 让阿里云自动采集 LogHub 支持客户端 网页 协议 SDK A
  • python pyplot logscale 画图对数

    原文来自公众号 工程师看海 事情的起因是我要在公众号 工程师看海 更新一篇文章 介绍电感 磁珠的区别 需要画阻抗 频率曲线 横坐标频率要按照log对数尺度缩放 就写了python代码 废话不多说 先看结果 公众号后台回复 python lo
  • Django:内置密码重置视图

    我正在遵循文档 当我单击页面以重新启动密码时 出现 NoReverseMatch 错误 resetpassword 处无反向匹配 与 password reset done 相反 未找到参数 和关键字参数 尝试了 0 个模式 urls py
  • 如何清除游戏中心实时排行榜数据?

    是否可以清除实时游戏中心排行榜 而不是沙盒排行榜 的数据 如果无法清除 是否有办法隐藏排行榜不显示 谢谢 转到 iTunesConnect 中的排行榜 并将分数范围更改为超出范围的值 例如 我的一些高尔夫球手发布的成绩远远低于标准杆 我将范
  • 重置输入元素的样式并重新设计以恢复默认外观

    我有一个简单的输入字段
  • 清理 Oracle 序列

    我广泛使用 SQL Server 但对 Oracle 的经验很少 我接到的任务是 清理 Oracle 数据库中的序列 但我不知道如何安全地完成此任务 我需要确定表中实际的最大值 假设 ID 105 然后查看该 ID 的下一个序列是什么 如果
  • git pull 和重置因错误“无法创建文件 <文件名>(文件存在)”而停止

    我目前正在将我的公司从 Vault 迁移到 Git 并且我已经在 Github 上设置了存储库 但是由于一些重复出现的错误 本地设置变得令人头疼 最令人困惑的是 当我尝试拉取时 它会取消 并显示一些文件的错误 错误 无法创建文件 文件存在
  • 如何重置/清除 erlang 终端

    我正在尝试重置提示 忘记所有变量并从第 1 行开始提示 gt 我知道以下内置函数 f forget all io format e H e J clear screen and moving cursor to the begin of t
  • JQuery - 表单重置 - 排除“选择”框

    All 我可以使用以下 JQuery 语法重置所有表单元素 myform 0 reset 如何修改它以排除 选择框 值的重置 Thanks 给大家 重置函数不会将所有内容设置为 空字符串 它重置为初始值 存储在值属性中 或选定的选项等 如果
  • 重置输入字段而不执行验证

    我有一个 Facelets 视图 如下所示
  • 如何在 Node.js 中强制重置套接字?

    我从 Node js 应用程序收到 read ECONNRESET 错误 可能是客户端或服务器连接 我不确定 作为修复这些问题的一部分 我想做一些本地测试 最好为其设置自动化测试 我想编写一个节点客户端和服务器 在连接建立后立即对其进行硬重
  • 如何在 R 中重置 par(mfrow)

    我设置了 par mfrow c 1 2 现在每次我绘制它时 它都会显示将其分成 2 个图 我怎样才能将其重置为仅显示一个图 非常感谢 您可以重置 mfrow 参数 par mfrow c 1 1
  • 是否有内置函数可以清除所有变量值

    我正在寻找一种方法来清除 Perl 程序中的所有数组 目前 我正在调用一个显式 重置 所有数组的子例程 sub clear arrays array1 array2 array3 这迫使我找到程序中的所有数组并在子例程中逐字引用它们 我查看
  • 如何重置 jquery 动画以重新开始?

    我已经构建了一段不错的代码 一些动画和一些单击 悬停事件 其中只有一小行 我打算在多个 html 文档上使用它 这是一个游戏 你必须得到正确的答案并继续下一个问题 用全页滑块构建在另一个 html 中 我不想加载 DOM 多个次 毫无意义
  • 异常后重置 Cuda 上下文

    我有一个使用 Cuda C 的工作应用程序 但有时 由于内存泄漏 会引发异常 我需要能够实时重置 GPU 我的应用程序是服务器 因此它必须保持可用 我尝试过类似的方法 但似乎不起作用 try do process using GPU cat
  • 重置表单,无需 JavaScript? (输入类型=重置不起作用)

    好吧 我想标题已经说明了一切 我正在寻找一种重置表单中所有字段的方法 我尝试过以下一些方法
  • 通过“后退”按钮重置表单

    试图找到一个优雅的解决方案来重置网络表单 或更具体地说两个INPUT Type hidden 字段 如果用户在提交表单后返回 据我所知 后退 按钮不会触发 onload 事件 但有什么办法可以解决这个问题吗 当按下后退按钮时 onbefor
  • 撤消已推送的合并

    好吧 我弄得有点乱了 显然 在我家里的机器上 开发分支没有更新 我做出了承诺并推动了 结果是实际的 origin develop 分支已合并到我的本地开发分支中 由于某种原因 它被视为不同的分支 一方面 我真的不明白这是怎么发生的 其次 我
  • 在 R 中撤消布局

    我最初创建了一个箱线图和直方图组合的图 为此我设置了 nf lt layout mat matrix c 1 2 2 1 byrow TRUE height c 1 3 par mar c 2 2 1 1 Draw box plot Dra
  • django 密码重置功能中出现 NoReverseMatch 错误

    我正在尝试在 django 中实现密码重置功能 下面是我的代码 urls py urlpatterns patterns url r signup accounts views signup name signup email url r

随机推荐

  • 【贪心算法】背包问题

    题目 有一个背包 背包容量是M 150 有7个物品 物品可以分割成任意大小 要求尽可能让装入背包中的物品总价值最大 但不能超过总容量 物品 A B C D E F G 重量 35 30 60 50 40 10 25 价值 10 40 30
  • esp8266单片机透传_ESP8266系列 NODEMCU初体验

    上一次 我们讲到了ESP 01s 实际上就是一块WiFi透传模块 只能挂在单片机上 起到一个沟通和桥梁的作用 今天 我们来介绍ESP家族另一款非常常用的芯片 ESP8266 12系列 这个想邮票一样的芯片就是我们的12E 可以看出他与01s
  • c++基础二

    c 基础 无符号整数 unsigned unsigned char的范围从0开始 至少到255 unsigned int的范围从0开始 至少到65535 unsigned short的范围从0开始 至少到65535 unsigned lon
  • linux,Centos7,yum安装的curl无法正常使用

    root centos yum y install curl Loaded plugins fastestmirror langpacks Loading mirror speeds from cached hostfile Package
  • adb连接报错:This adb server's $ADB_VENDOR_KEYS is not set Try 'adb kill-server' if that seems wrong.

    Microsoft Windows 版本 6 1 7601 版权所有 2009 Microsoft Corporation 保留所有权利 C Users Administrator gt adb install C Users Admini
  • 【备忘】Unity IOS 覆盖安装后进游戏黑屏

    情景 unity LuaFrameWork UGUI V2 把资源打在包内用于过审 上架appStore后 覆盖安装下进游戏出现黑屏情况 上一版本是打小包过审 即大部分资源在进游戏后下载 推测 查看项目代码后 发现资源路径没有按版本号区分
  • 进行人工智能机器人研发,应该选择哪种编程语言?

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 这个问题大多数新的机器人专家在他们的职业生涯中至少会思考一次 不幸的是 这也是一个没有直接答案的问题 如果你在 Stack Overflow Quora Trossen R
  • 运行springmvc时出现如下错误org.springframework.web.servlet.DispatcherServlet noHandlerFound

    出现错误 八月 12 2018 10 46 42 上午 org springframework web servlet DispatcherServlet noHandlerFound 警告 No mapping found for HTT
  • 飞书小程序开发

    1 tt showModal后跳转页面 跳转路径要为绝对路径 相对路径跳转无响应 2 手机息屏后将不再进入onload 生命周期 直接进入onshow 生命周期 onLoad 在页面初始化的时候触发 一个页面只调用一次 onShow 在切入
  • 杀死“比尔”

    所有人有一个初始的生命值 一个警官要杀一个人则该人的生命值减p 其他人则减Q 最少要杀多少次才可以把所有人杀掉 百度笔试手速太慢 没敲上去 可怜 include
  • 【观察】浪潮K1 Power:产业升级换挡提速,关键计算保驾护航

    今天 国家对数字经济给予了前所未有的高度重视 在 十四五 规划中 国家就明确提出了要将数字经济核心产业增加值占GDP的比重从7 8 提高到10 这也意味着未来整个计算产业将会迎来更大的需求 而算力也将成为数字经济时代的核心生产要素 在此过程
  • LeetCode 150. 逆波兰表达式求值

    题目链接 150 逆波兰表达式求值 遍历所有元素 如果当前元素是整数 则压入栈 如果是运算符 则将栈顶两个元素弹出做相应运算 再将结果入栈 最终表达式扫描完后 栈里的数就是结果 数组模拟栈 class Solution public int
  • Redis高级之IO多路复用和epoll(十二)

    nginx 的反向代理也是采用了IO多路复用 1 是什么 I O 网络 I O 多路 多个客户端连接 连接就是套接字描述符 即socket 或者 channel 指的是多条 TCP 连接 复用 用一个进程来处理多条的连接 使用单进程就能实现
  • 贪心算法三个经典例题

    贪心算法的三个经典例题 A Saruman s Army 题目描述 Saruman the White must lead his army along a straight path from Isengard to Helm s Dee
  • JVM:常用的四种垃圾回收机制

    1 CMS Concurrent Mark Sweep 并行 标记清除 老年代垃圾回收机制 cms是一个基于标记 清除 算法的综合多种算法的老年代垃圾回收器 适用场景 重视服务器响应速度 要求系统停顿时间最短 这里要说明下 这是一个老年代算
  • posefs1.perception.cs.cmu.edu 无法访问

    我尝试练习openpose时 发现运行的代码缺乏coffee的model 需要执行models 下的bat或sh 但是 posefs1 perception cs cmu edu 无法访问 从Kaggle上下载 https www kagg
  • Java学到什么程度才能叫精通?

    把下面这些内容掌握以后 你就可以自诩精通Java后端了 1 计算机基础 这部分内容是计算机相关专业同学的课程 但是非科班的小伙伴 譬如在下 就需要花时间恶补了 特别 是计算机网络 操作系统 数据结构这三门课程 至于编译原理 个人大概懂一点就
  • 段页式存储及分段分页优缺点分析,对比(王道考研_操作系统)

    分段分页优缺点分析 段页式管理 将进程按照逻辑模块分段 再将各段分页 再将内存空间分为大小相同的页框 最后将各个页装入各个内存块中 基本分段存储管理 与分页相比 离散分配时所分配的地址空间的基本单位不同 定义 进程的地址空间 按照程序的自身
  • STL中常用的排序算法

    merge 以下是排序和通用算法 提供元素排序策略 merge 合并两个有序序列 存放到另一个序列 例如 vecIntA vecIntB vecIntC是用vector
  • Git 版本回退与前进(03)

    现在 你已经学会了修改文件 然后把修改提交到Git版本库 现在 再练习一次 修改readme txt文件如下 Git is a distributed version control system Git is free software