前几篇文章讲到了git分支之间的各种合并和使用的操作,但是在各种开发分支之间切换(或者是拉取远程代码,当前需要一个干净的工作空间),其实非常依赖一个命令,git分支切换过程中非常常用的命令,git stash——保存当前分支未提交的内容。
git stash的应用场景有如下,多分支切换工作即当前的工作内容未形成一个有效的提交,就先给保存;解决临时bug、拉去同步远程分支之前清理保存当前工作空间。当前命令有:
git stash保存当前分支内;
git stash pop 取出栈顶即上一次保存的内容;
git stash list 查看stash list列表。
但并不只是这么简单,大家都知道,git stash的数据模型是基于栈的,但是他到底是基于整个git工作空间的栈,还是当前分支的保存栈呢?那么首先说一下结论,他的存储栈是基于整个工作空间的,同时储存文件操作是当前操作分支维度的。
具体的来说,如图下所示,当前从master之后又三个分支,分别是1-F,2-F,3-F,对应的不同的工作内容。我前段时间就经常游走于这样的一个工作场景中:
我正在1-F分支做管理后台,这时线上出现了一个bug,于是需要2-F分支去继续修复bug,只能先保存,使用git stash,这时git stash list栈是这样的,然后在2-F分支的重构还没做完一个完整的功能,3-F分支的登陆系统来了一个bug,只能继续在2-F保存,git stash,最后继续开发系统的登陆功能,还没完成自测呢,这会管理后台有出问题了,又得先回去,只能先在3-F上执行git stash,这样整个git stash list栈就成这样了,先入的在下面。
此时回去1-F,我想把之前保存的东西拿出来,很自然的git stash pop,这样就会弹出栈顶的stash,拿到的就是3-F分支的保存063de88 ,因此就全乱了。
因此在使用stash功能的时候,需要注意的就是stash所操作的栈是建立在整个git 工作空间的基础之上,跟单独的每个分支并没有关系,虽然是在分支上执行的git stash操作,但入栈出栈的数据模型都是整个git。
上述对git stash的使用显然有些问题,非常蹩脚,因此我们在了解stash栈的结构之后,就应该在使用时尽量的优化:
1.给每个stash入栈的保存操作加入一个可标识 自己可理解的标签,比之前很乱的commit id有较高的辨识度;
2.其次在有了标签后,进行出栈操作时指定栈中需要出栈的位置即可。
具体如下, 还是回到刚才的使用场景,我们这一次使用 git stash save “”,这样我们在使用git stash list时就会很清晰的看到我们之前所加标签的stash,git stash pop stash@{2}对对应的stash出栈,具体如下图所示。
git stash pop stash@{2} 取出对应“管理后台”的stash,并出栈;
git stash apply stash@{2} 取出对应“管理后台”的stash,不初战。
在本文中,我们队git stash的原理及使用作出了总结,并且给出优化使用的建议,对git stash入栈是加标签,出栈时指定该标签的id即可。