Git分支的状态存储----git stash

1.情形

有时,当我们在项目的一部分上已经工作一段时间后,所有东西都进入了混乱的状态,而这时想要切换到另一个分支做一点别的事情,则必须将当前工作空间所做的操作提交到版本库,否则Git不允许切换分支。

当前的操作还不足以生成一次版本快照,此时我们就可以使用git stash命令,将当前工作状态存储起来,然后再切换到其他分支工作,最终工作完毕后切回当前分支,从Git存储中取出之前的工作内容。

2.git stash命令语法

git stash命令能够将当前工作目录中尚未提交的所有更改(包括暂存区和未暂存的修改)临时存储到stash堆栈中,从而让用户在不影响当前工作进度的前提下,轻松切换到其他分支处理问题、合并代码或恢复到干净的工作状态。

命令说明
git stath将当前工作空间的状态保存
git stash list查看当前Git中存储的所有状态
git stash apply {stashName}根据存储名称读取Git存储
git stash drop {stashName}根据存储名称删除Git存储
git stash save“日志信息” 将当前工作空间的状态保存并指定一个日志信息
git stash pop读取stash堆栈中的第一个存储,并将该存储从stash堆栈中移除
git stash show [-p] {stashName}查看指定存储与未建立存储时的差异; -p:显示详细差异
git stash branch {branchName} [stashName]创建并切换到一个新分支来读取指定的存储;stashName:存储的名称,默认情况下读取stash堆栈中栈顶的存储

3.Git存储的基本使用

3.1 搭建测试环境

初始化环境:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
编辑文件,编辑完了后还不想提交,此时接收到了新的"临时任务",想要切换到其他分支继续操作,发现切换失败。
在这里插入图片描述

3.2 使用存储状态

使用Git存储将当前状态存储起来。

git stash list  # 查看当前Git存储列表,发现列表为空

在这里插入图片描述
使用Git将当前状态存储起来后,文件内容变为了未更改前的内容:
在这里插入图片描述
再次查看git的状态,发现工作空间正常:
在这里插入图片描述
查看日志,发现使用Git存储也会产生日志,而且还产生了两个日志:
在这里插入图片描述
当前状态被Git存储了,所以当前的工作空间也是正常的,因此可以切换到其他分支继续操作。
在这里插入图片描述

3.3 读取存储状态

等到"临时任务"处理完后,我们可以切换回b1分支:
在这里插入图片描述
并将上一次使用Git存储的状态读取出来,示例代码如下:
在这里插入图片描述

3.4 删除存储状态

Git存储被读取之后状态并不会被删除,我们可以手动删除存储状态,示例代码如下:
在这里插入图片描述
查看日志,日志也被整理了:
在这里插入图片描述

4.Git存储的其他用法

stash堆栈是一个典型的“栈”数据结构,栈的特点是先进后出,因此当stash堆栈中存储了多个状态时那么最先存进去的状态在最底部,最后存储的状态在最顶部,如图所示。
在这里插入图片描述
接下来我们来学习一下Git存储关于查看存储状态、弹栈存储状态、基于存储创建分支等用法。为了方便测试,我们建立一个新的测试仓库来测试。

4.1 搭建测试环境

初始化环境:
在这里插入图片描述
使用状态存储,存储两个状态:
在这里插入图片描述
应用存储状态(应用了存储状态之后存储状态依然存在于stash堆栈中):
在这里插入图片描述
在这里插入图片描述

4.2 查看存储状态

stash是一个栈的数据结构,因此我们先存储进来的状态是在最底部,最顶部为最近一次存储进来的状态。

查看stash@{0}stash@{1}存储状态:
在这里插入图片描述
查看stash@{0}stash@{1}存储状态的详细信息:
在这里插入图片描述

4.3 弹栈stash

使用git stash apply命令只是读取指定的状态,该状态并没有从stash堆栈中删除。如果想要使用状态后将其删除可以使用git stash pop命令。git stash pop命令总是读取stash堆栈顶部的状态,然后将其移除,示例代码如下:
在这里插入图片描述

4.4 基于存储状态创建分支

在这里插入图片描述
将stash顶部的状态弹出,基于该状态创建一个分支,并切换到该分支:
在这里插入图片描述

5.Git存储与暂存区

我们之前测试的操作都是未添加到暂存区的操作然后使用git stash将其存储起来,实际上,就算是某个操作已经添加到暂存区了也可以使用Git存储将其存储起来,然后工作空间变为“noting to commit”状态。

需要注意的是,使用git stash命令将当前状态存储起来后虽然可以将当前工作空间的暂存区变为“noting to commit”状态,但是后期将该存储读取出来后,暂存区并不会回到之前的状态。
在这里插入图片描述
编辑操作,然后将操作添加到暂存区,最后使用git stash命令将当前状态存储起来。
在这里插入图片描述
查看暂存区的内容:
在这里插入图片描述
查看该Blob对象的内容:
在这里插入图片描述
使用Git状态存储,将当前状态存储起来:
在这里插入图片描述
读取状态,然后查看暂存区的内容,发现并没有回到使用git stash命令前的状态。
在这里插入图片描述

6.Git存储的原理

6.1 使用Git存储的原理

在使用git stash命令后,Git直接将当前工作空间的更改添加到暂存区,然后提交。中途生成了Blob对象、Tree对象、Commit对象等三类对象,用于存储在执行stash命令之前对工作空间的修改。

其中Commit对象会生成2次,第1次指向原来的Tree对象,即没有执行stash之前的Tree对象。第2次指向新的Tree对象,即执行了stash命令之后的Tree对象。之后再将暂存区改回原来的样子(执行git stash命令之前的样子)。在这个过程中,Blob对象生成了1个,Tree对象生成了1个,Commit对象生成了2个。

由于当前工作空间的操作均已提交,因此当前工作空间的状态自然为nothing to commit状态,然后就可以切换到其他分支了。

当使用git stash命令以后,会产生两个Commit对象,其还会在.git/refs/目录创建一个名为stash的文件,该文件保存着最新Commit对象的hash值(执行git stash命令后生成的那个新Commit对象),如下图所示。
在这里插入图片描述

6.2 读取Git存储状态的原理

当使用git stash apply {stashName}git stash pop命令读取Git存储状态时,其底层其实就是读取到stash文件中的Commit对象,通过该Commit对象找到执行git stash命令后生成的Blob对象,读取该Blob对象的内容写入当前工作空间,达到还原工作空间的目的。

6.3 删除Git存储状态的原理

整理Git提交日志(在Git日志中查询不到了),然后将git/refs/stash文件删除掉。

6.4 示例

下面我们通过代码来实际演示一下git stash命令的工作原理。

6.4.1 创建一个初始仓库

在这里插入图片描述
查看所有的Git对象( Blob对象、Commit对象、Tree对象):
在这里插入图片描述
在这里插入图片描述

6.4.2 使用存储状态的原理

编辑文件,使用stash命令观察效果,示例代码如下:
在这里插入图片描述

.git/objects/3e/b0efcbc9bf7866d4da7c9f4c69be1ea058740b  # Blob对象.v1
.git/objects/58/c9bdf9d017fcd178dc8c073cbfcbb7ff240d6c  # Tree对象.v2
.git/objects/69/53cbf5cf88d6e23d71cc6482e35b7b2c81b0f6  # Commit对象.v1
.git/objects/70/3a3923a3f4d516543ba3e6e9182467f31b328c  # Tree对象.v1
.git/objects/8f/96f2f60c766a6a6b78591e06e6c1529c0ad9af  # Commit对象.v2
.git/objects/a3/0a52a3be2c12cbc448a5c9be960577d13f4755  # Blob对象.v2
.git/objects/fa/bbaf2e5d1412bc6ec595428cd8e9fac34007b1  # Commit对象.v3

查看stash文件,保存的是最新Commit对象(v3)的hash值:
在这里插入图片描述
查看Blob对象.v2
在这里插入图片描述

6.4.3 读取存储状态的原理

在这里插入图片描述

6.4.4 删除存储状态的原理

在这里插入图片描述

/c/前端/git教程/git stash其它用法/git stash-demo3 (b1)
$ ll .git/refs/   # 发现stash文件已经被删除
total 0
drwxr-xr-x 1 25484 197609 0  39 15:26 heads/
drwxr-xr-x 1 25484 197609 0  39 15:20 tags/

/c/前端/git教程/git stash其它用法/git stash-demo3 (b1)
$ git log --oneline --all --graph  # 查看提交日志
* 6953cbf (HEAD -> b1, master) 111

/c/前端/git教程/git stash其它用法/git stash-demo3 (b1)
$ find .git/objects/ -type f  # 查看所有Git对象
.git/objects/3e/b0efcbc9bf7866d4da7c9f4c69be1ea058740b # Blob对象.v1
.git/objects/58/c9bdf9d017fcd178dc8c073cbfcbb7ff240d6c # Tree对象.v2
.git/objects/69/53cbf5cf88d6e23d71cc6482e35b7b2c81b0f6 # Commit对象.v1
.git/objects/70/3a3923a3f4d516543ba3e6e9182467f31b328c # Tree对象.v1
.git/objects/8f/96f2f60c766a6a6b78591e06e6c1529c0ad9af # Commit对象.v2
.git/objects/a3/0a52a3be2c12cbc448a5c9be960577d13f4755 # Blob对象.v2
.git/objects/fa/bbaf2e5d1412bc6ec595428cd8e9fac34007b1 # Commit对象.v3
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值