Git 时光穿梭

简介: Git 时光穿梭

一、问题引入

假设这样一个场景:有一天你的老板让你整理一份报告,结果你很轻松的整理完了第一版,但是你的老板并不满意,于是老板给你不断的提出建议,你不断的修改,于是报告就迭代出了版本1、版本2、版本3……但是老板拿到最新版本的报告之后,摇了摇头说:“我还是觉得版本1比较好,你把版本1拿给我吧”。这个时候你可能想“杀”他的心都有了,因为你是在一个报告中迭代的,版本1你早就不知道长什么样了。


这次经历之后,你留了一个心眼,每次你在进行修改的时候,都创建一个副本,结果就是一份报告分散出好多的文件,可是如果过了一周,看着这些乱起八糟的文件,你想找到修改的内容,但是已经记不清保存在哪个文件中了,只好一个一个文件去找,非常麻烦。并且如果你想保留最新的文件,然后把其他文件删掉,但是你又不敢删,怕哪天还会用到,真郁闷。


针对以上问题,难道就没有一种完美的解决方案的吗?于是 Git 等版本控制系统横空出世。其中 Git 版本回退可以说是 Git 的杀手锏之一,注意是之一,后面还有之二、之三……这个我们之后在介绍。

二、前置知识

为了更好的理解 Git ,在讲 Git 之前,我们先引入一些前置知识:

  1. git add 将文件提交到暂存区。
  2. git commit 将文件提交到本地仓库。
  3. git status 可以让我们随时掌握工作区的状态(哪些文件被修改过)。
  4. git diff 顾名思义就是查看difference,可以查看修改内容,显示的格式是Unix通用的diff格式。
  5. git log 命令显示从最近到最远的提交日志(加上--pretty=oneline会更加可观)。

上面这些命令不作为本期重点,大家可以自行了解。

三、工作区暂存区和版本库

  • 工作区:就是你在电脑里能看到的目录。
  • 暂存区:英文叫 stageindex。一般存放在 “.git” 目录下的 index 文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。
  • 版本库:工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。

下面这张图就展示了

其实细心的小伙伴就发现了,除了工作区,暂存区,版本库,还有两个就是 objectmaster

  • 在Git中,所有的数据都以对象(objects)的形式存储(文件内容,提交信息,分支引用等等)。objects 标识的区域为 Git 的对象库,实际位于 “.git/objects” 目录下,里面包含了创建的各种对象及内容。
  • 当执行提交操作(git commit)时,暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。

Git 跟踪并管理的是修改(新增、删除、更改、新建)

四、版本回退

1、版本回退命令

git reset 命令在 Git 中被用来移动 HEAD 指针和重置当前分支的位置。它有几种不同的用法,主要包括以下三种模式:soft、mixed 和 hard。


1. Soft 模式:git reset --soft <commit_id>:该命令将 HEAD 指向 <commit_id>,但不会更改暂存区和工作目录的内容。你可以重新提交更改,新的提交将建立在指定的 <commit_id> 之上。


2. Mixed 模式:git reset --mixed <commit_id>(默认行为):该命令将 HEAD 指向 <commit_id>,并重置暂存区的内容为指定 <commit_id> 的内容,但不会更改工作目录的内容。这样你可以重新选择要提交的内容。


3. Hard 模式:git reset --hard <commit_id>:该命令将 HEAD 指向 <commit_id>,同时重置暂存区和工作目录的内容为指定 <commit_id> 的内容。慎用此命令,因为会丢失工作目录中未提交的更改。


除了以上几种模式外,git reset 还可以结合使用一些选项和参数来实现不同的操作,如:

(1)git reset HEAD <file>:将指定文件从暂存区中移除,但保留在工作目录中的更改。


(2)git reset --hard HEAD:将工作目录和暂存区都重置为最近一次提交的状态,丢弃所有未提交的更改。


(3)git checkout -- [file]: 命令让⼯作区的文件回到最近⼀次 add 或 commit 时的状态。要注意 git checkout – [file] 命令中的-- 很重要,切记不要省略,⼀旦省略,就变成了“切换到另一个分支”的命令。

注:

  • HEAD 表示当前版本
  • HEAD^ 上⼀个版本
  • HEAD^^ 上上⼀个版本
    以此类推…

也可以使⽤ 〜数字表示:

  • HEAD~0 表示当前版本
  • HEAD~1 上⼀个版本
  • HEAD^2 上上⼀个版本
    以此类推…

2、四大常见场景

(1)场景一:使用 --hard 将工作区、暂存区、版本库进行了回退,结果后悔了怎么办

在Git中,总是有后悔药可以吃的。例如当你用 git reset --hard HEAD^ 回退到上一个版本时,再想恢复到之前的版本,就必须找到之前版本的 commit id。Git提供了一个命令 git reflog 用来记录你的每一次命令,你可以通过这个命令找到之前的版本 id,然后使用 git reset --hard <commit_id> 进行恢复。

(2)场景二:对于⼯作区的代码,还没有 add

直接使用 git checkout -- <file_name> 即可回退到最近一次工作区修改。

(3)场景三:已经 add ,但没有 commit

先使用 git reset --mixed HEAD <file_name> 回到场景二。

再使用 git checkout -- <file_name> 回退到最近一次工作区修改。

(4)场景四:已经 add ,并且也 commit 了

不要担心,我们可以 git reset --hard HEAD^ 回退到上⼀个版本!不过,这是有条件的,就是你还没有把⾃⼰的本地版本库推送到远程。还记得Git是分布式版本控制系统吗?我们后⾯会讲到远程版本库,⼀旦你推送到远程版本库,你就真的惨了……

3、删除文件

再 Git 中删除也是修改,也可以被 Git 管理起来。

一般情况下,你直接在工作区中把文件给删除了,这个时候 Git 是可以知道你删除了文件的,你可以使用 git status 命令查看哪些文件被删除了。

其实在实际的工作中,删除文件的操作是比较少见的,此时一般会存在两种情况:

情况一:确实想要从版本库中删除文件

  1. 使用 git rm <file_name> 删除掉
  2. 使用 git commit 提交删除

情况二:不小心删错了,属于误删情况

  • git checkout – <file_name> 恢复即可

总结

值得注意的是,Git 的版本回退速度非常快,因为 Git 在内部有个指向当前版本的 HEAD 指针,当你回退版本的时候,Git 仅仅是把 HEAD 指针指向回退的版本即可。

相关文章
YI
|
开发工具 git
使用Git实现版本穿梭
使用Git实现版本穿梭
YI
101 0
|
开发工具 git
Git - 时光机穿梭之工作区和暂存区
Git - 时光机穿梭之工作区和暂存区
112 0
Git - 时光机穿梭之工作区和暂存区
|
数据可视化 开发工具 git
Git - 时光机穿梭之版本回退(下)
Git - 时光机穿梭之版本回退(下)
122 0
Git - 时光机穿梭之版本回退(下)
|
开发工具 git
Git - 时光机穿梭之删除文件
Git - 时光机穿梭之删除文件
99 0
|
开发工具 git
Git - 时光机穿梭之撤销修改
Git - 时光机穿梭之撤销修改
106 0
|
开发工具 git
Git - 时光机穿梭之管理修改
Git - 时光机穿梭之管理修改
82 0
|
25天前
|
开发工具 git
git 常用命令
这些只是 Git 命令的一部分,Git 还有许多其他命令和选项,可根据具体需求进行深入学习和使用。熟练掌握这些命令能够帮助你更高效地管理代码版本和协作开发。
|
17天前
|
机器学习/深度学习 Shell 网络安全
【Git】Git 命令参考手册
Git 命令参考手册的扩展部分,包含了从基础操作到高级功能的全面讲解。
24 3
|
1月前
|
缓存 Java Shell
[Git]入门及其常用命令
本文介绍了 Git 的基本概念和常用命令,包括配置、分支管理、日志查看、版本回退等。特别讲解了如何部分拉取代码、暂存代码、删除日志等特殊需求的操作。通过实例和图解,帮助读者更好地理解和使用 Git。文章强调了 Git 的细节和注意事项,适合初学者和有一定基础的开发者参考。
50 1
[Git]入门及其常用命令
|
2月前
|
开发工具 git
git学习四:常用命令总结,包括创建基本命令,分支操作,合并命令,压缩命令,回溯历史命令,拉取命令
这篇文章是关于Git常用命令的总结,包括初始化配置、基本提交、分支操作、合并、压缩历史、推送和拉取远程仓库等操作的详细说明。
140 1
git学习四:常用命令总结,包括创建基本命令,分支操作,合并命令,压缩命令,回溯历史命令,拉取命令