1:背景描述
git工具真的是互联网人的开发利器,我愿意称之为IT届开发工具最伟大的发明。git stash
的使用不用多说,在修改当前分支内容后,临时想要放下当前项目,切换其他分支时,就可以通过这个命令保存当前的分支更改,这样可以在保留当前分支已有修改不丢失的情况下,任意的切换其他分支,如果其他分支处理结束后,可以直接切回该分支,再通过git stash pop
弹出该分支之前保留的修改,继续开发。但是在工作中有时会有特殊情况,使用git stash也有需要注意的地方。
这里直接先给出相关的指令:
git stash
git stash list
git stash pop
git stash pop +索引
git stash drop +索引
git stash list --date=local
git stash list --date=relative
git stash list --date=short
2:注意事项
1:git stash pop弹出的缓存记录和当前分支不匹配
git stash所存储的修改记录是全局的,不是指定某个分支下的缓存。通俗的讲,git stash是git工具维护的一个全局的栈,会按照调用git stash的顺序,将各个分支下git stash
的修改保存起来并压入同一个全局(全分支共享)的栈中,也就是说,每次想要调用方法git stash pop
弹出的总是栈顶的那条记录,如果栈顶记录不是当前分支,之前所git stash时的分支,此时弹出的内容会不符当前分支的版本,会产生错误或冲突,会对开发效率产生不良影响。
避免方法:每次使用git stash pop前,检查当前全局的栈记录
命令:git stash list
结果如下所示,很显然,git stash维护的是一个栈数据结构,且每次栈顶记录都是最新的全局分支的缓存。下面就展示了当前分支和栈顶的记录stash@{0}不是同一分支,此时git stash pop就会出现没有预料的问题。
leel@dirname (branch_1) <-----------当前所处分支
$ git stash list
stash@{0}: WIP on branch_2: 9b9354d Merge branch 'add_global_rr' into 'branch_2'
stash@{1}: WIP on branch_1: f68749d bugfix
stash@{2}: WIP on branch_2: 23fe861 bug fix 4
stash@{3}: WIP on branch_3: c06b8da bug fix
stash@{4}: WIP on branch_4: 9ed1dd6 move reload method to parent class
stash@{5}: WIP on branch_5: c833e3f Merge branch 'fix_add_version' into 'branch_2'
通过每次pop前使用git stash list
查看栈顶记录是否是分支一致的,如果是当前分支,那么就可以放心git stash pop。
2:git stash list后栈顶记录不是当前分支
以及避免了直接git stash pop的坑,先git stash list了,但是栈顶的记录不是当前分支的,怎么办?其实与其说是栈结构,不如准确来说是个链栈,所以支持索引弹出指定的记录,例如上个例子中,通过git stash list后发现当前分支是branch_1,而栈顶记录的分支是branch_2,此时想要弹出的是branch_1的记录,可以通过命令git stash pop stash@{1}
实现指定记录的弹出。
当然,我们已经确定不需要的分支可以手动的删除掉,例如git stash drop + 索引
来防止对开发者产生干扰。
3:git stash list 后出现多条同分支的修改记录
如下面的案例所示
$ git stash list
stash@{0}: WIP on branch_2: 9b9354d Merge branch 'add_global_rr' into 'branch_2'
stash@{1}: WIP on branch_1: f68749d bugfix
stash@{2}: WIP on branch_1: f68749d bugfix
stash@{3}: WIP on branch_1: 6589f5f rebase and rebuild
stash@{4}: WIP on branch_1: da85af0 Merge branch 'branch_2' into branch_1
stash@{5}: WIP on branch_3: 23fe861 bug fix
stash@{6}: WIP on branhc_3: c06b8da bug fix
stash@{7}: WIP on branch_4: 9ed1dd6 move reload method to parent class
stash@{8}: WIP on branch_5: c833e3f Merge branch 'fix_add_version' into 'branch_1'
当前我在branch_1分支,现在我想要将上次的stash记录弹出,但是栈顶不是当前分支的记录,此时如果确定栈顶记录不在需要,可以删除掉git stash drop,或者直接git stash pop +索引,这里有个问题,由于关于branch_1的记录很多,如果不知道应该弹出哪个记录,此时就需要注意:
首先stash保存记录是一个栈的结构我们已经清楚了,即,只要自己没有弹出过当前分支的缓存记录,那么,距离栈顶最近的那条该分支的记录就是最近的git stash了,可以直接以该索引直接弹出。但是问题在于,如果原来的记录被自己误删了,或者某种原因不确定是否是什么时间点的缓存,就需要谨慎操作了,推荐如下的指令:
git stash list --date=local
git stash list --date=relative
git stash list --date=short
以上三个指令都会在列出栈中缓存记录的同时给出缓存时间,只是显示的时间格式不同
分别如下:
$ git stash list --date=local
stash@{Sat Mar 12 16:43:00 2022}: WIP on branch_2: 9b9354d Merge branch 'add_global_rr' into 'branch_2'
$ git stash list --date=relative
stash@{6 days ago}: WIP on branch_2: 9b9354d Merge branch 'add_global_rr' into 'branch_2'
$ git stash list --date=short
stash@{2022-03-12}: WIP on branch_2: 9b9354d Merge branch 'add_global_rr' into 'branch_2'
因此根据缓存的时间就能回想起自己在某个时间缓存了哪个记录
3:后记
如果害怕通过git stash pop弹出记录而导致记录消失,而后续还想要继续应用某个记录,可以通过命令
git stash apply + stash@{1} 不删除对应的记录,只应用记录,和pop的删除并应用不同
希望以上的注意事项和使用能够给同学们带来帮助,避免入坑。