git中stash的工作原理是什么?

【字号: 日期:2023-09-08浏览:22作者:雯心

问题描述

1.测试场景一:假设index.html本来就在代码仓库中,现在修改了index.html页面,然后add暂存index.html页面,接着继续修改index.html页面,然后git stash,这个时候代码仓库干净了,修改被暂存,然后执行git stash pop,还原修改,这个时候发现,工作区的修改还原了,但是暂存区的修改丢失了。也就是git status发现,没有任何修改被暂存,之前暂存的修改被废弃了,但是工作区的修改完全被保留。

2.测试场景二:现在添加test01.html页面,git status显示test01.html并没有被git跟踪,然后修改index.html文件,这个时候git stash,发现index.html文件被暂存,但是test01.html文件没有被暂存。也就是git status并没有暂存没有被git跟踪的文件。

3.测试场景三:延续场景二,修改index.html文件,test01.html文件为新添文件,这个时候git add test01.html文件,让test01.html被git追踪,再git stash,通过git stash show方法可以看到test01.html文件被暂存,接着git stash pop,修改被还原,git status发现test01.html文件是被暂存状态,index.html还是被保留的工作区的修改。也就是git add 一个之前未被git追踪的文件,git stash后,这个文件会被暂存,而且git stash pop后,新添加的这个文件还是暂存状态,对比测试场景一中,index.html文件只是工作区的修改被暂存,暂存区的修改被丢失。

4.测试场景四:延续场景三,修改index.html文件,test01.html文件为新添文件,这个时候git add test01.html文件,让test01.html被git追踪,然后再修改test01.html文件,接着git stash,git stash pop,发现test01.html依然是暂存状态,但是被暂存的文件内容却是工作区最终的修改内容。也就是git add 一个之前未被git追踪的文件,然后再修改这个文件,git stash后,这个文件会被暂存,而且git stash pop后,新添加的这个文件还是暂存状态,但是暂存的修改内容却是之前工作区的修改内容而不是通过add暂存的修改内容。

git中stash的工作原理是什么?通过以上测试,我没有发现git stash的工作规律,非常晕,希望git高手给我指导分析一下。

问题解答

回答1:

首先,我说明一下git stash命令的基本功能:处理工作目录脏的状态,即修改的跟踪文件暂存改动,然后将未完成的修改保存到一个栈上。知道了这些之后,我们来看看我总结的几个要点:

git stash命令会将已跟踪的文件压入栈中,而未被跟踪的文件不会被压入栈中,正如楼主的实验2中所描述的。

如果之前的工作有被添加到暂存区,git stash命令默认不会将弹出栈的那个修改再加入暂存区,正如楼主的实验1所描述的那样,但是楼主的描述其实有误,之前暂存的修改并不是被废弃或丢失而是保留在工作区,只是未加入暂存区而已。

对于楼主的实验2、3中的新添加文件test01.html,其实这算一种特殊情况吧。我们可以这样理解:stash pop的结果就是还原以前的修改,而它对于test01.html所能做的恢复操作也只能是重新加入暂存区,否则的话,test01.html将回到未被跟踪的状态。

如果想要重新应用之前暂存的修改,可以在git stash pop后加上--index选项,这样的话就可以恢复到和之前一模一样了,即之前暂存过的现在也会是暂存状态,为暂存的仍是未暂存的状态。

最后,我需要声明下楼主所说的:

之前暂存的修改被废弃了

或者

暂存区的修改被丢失

其实描述有误,或者不该这样描述,因为这样会使我们误解——我们可能会误认为git stash只会暂存工作区的修改,而实际情况应该是这样的:git stash默认会将被恢复的操作保留在工作区,但是不会自动帮你重新暂存。楼主可以重新做一下上述的实验以验证我的说法。

相关文章: