免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 22296 | 回复: 4
打印 上一主题 下一主题

'git stash' 一个强大却容易被忽视的命令 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-10-11 11:40 |只看该作者 |倒序浏览
在使用git的时候,我们往往使用branch解决任务切换问题,例如,我们往往会建一个自己的分支去修改和调试代码, 如果别人或者自己发现原有的分支上有个不得不修改的bug,我们往往会把完成一半的代码 commit提交到本地仓库,然后切换分支去修改bug,改好之后再切换回来。这样的话往往log上会有大量不必要的记录。其实如果我们不想提交完成一半或者不完善的代码,但是却不得不去修改一个紧急Bug,那么使用'git stash'就可以将你当前未提交到本地(和服务器)的代码推入到Git的栈中,这时候你的工作区间和上一次提交的内容是完全一样的,所以你可以放心的修 Bug,等到修完Bug,提交到服务器上后,再使用'git stash apply'将以前一半的工作应用回来。也许有的人会说,那我可不可以多次将未提交的代码压入到栈中?答案是可以的。当你多次使用'git stash'命令后,你的栈里将充满了未提交的代码,这时候你会对将哪个版本应用回来有些困惑,'git stash list'命令可以将当前的Git栈信息打印出来,你只需要将找到对应的版本号,例如使用'git stash apply stash@{1}'就可以将你指定版本号为stash@{1}的工作取出来,当你将所有的栈都应用回来的时候,可以使用'git stash clear'来将栈清空。
在这里顺便提下git format-patch -n , n是具体某个数字, 例如 'git format-patch -1' 这时便会根据log生成一个对应的补丁,如果 'git format-patch -2' 那么便会生成2个补丁,当然前提是你的log上有至少有两个记录。
git 还有很多强大并实用的功能,这里就不一一列举了,大家可以自己去玩玩git。

论坛徽章:
0
2 [报告]
发表于 2011-10-11 12:25 |只看该作者
非常不错,这样的话我们就没必要在branch之间切换来切换去了。
不过这样做有个危险,就是如果我们把未提交的内容存入栈中,fix bug并提交,但是这部分fix的内容和栈中的内容有冲突,再执行git stash apply时候可能会失败,这似乎是个永恒的问题:)

论坛徽章:
0
3 [报告]
发表于 2011-10-18 16:23 |只看该作者
关于git stash apply 和git stash pop的区别:

    学习过栈的朋友都知道栈有个特点‘后进先出’,当我们用git stash (或者 git stash save)把未提交本地仓库的修改保存入栈的时候,用git stash list 可以查看到栈的记录,如果我们想恢复刚才的改动,可以使用git stash apply 或者 git stash pop,虽然都能恢复之前的改动,但是这两者还是有区别的:git stash apply 只是把栈里面记录的内容运用到当前的版本上,这时候栈里面的记录还保存着。 git stash pop 也是把栈里面记录的内容运用到当前的版本上,但是它会把出栈的记录删掉,也就是说如果之前栈里面有3个记录,当执行 ‘git stash pop’之后,栈里的记录变成2个,这就是pop(出栈)的特点。

   关于git stash apply 和git stash pop的选择我个人倾向于 git stash apply,原因如下:
   假设我们 git stash 之后栈里面有一条记录,如果我们使用 git stash pop ,虽然也能恢复到入栈之前的改动,但是栈里的记录没了,如果这时我们 ‘git checkout .’,那么所有的改动都没了,而且也不能再次运用 git stash pop 来恢复,而如果我们用git stash apply 不仅能恢复入栈前的改动,栈里面的记录还保存着,即使我们 ‘git checkout .’ 也能再次运用 git stash apply 来恢复。如果觉得栈里面的记录太多,而且也不需要栈里记录的改动的话,大家可以用 git stash clear 清理一下。

   以上仅仅是我对git stash apply 和git stash pop看法,关于这二者的运用还是希望大家‘仁者见仁,智者见智’,也许你会发现其他巧妙的技巧也不一定。

论坛徽章:
0
4 [报告]
发表于 2011-12-15 23:30 |只看该作者
本帖最后由 kunkka_lu 于 2011-12-15 23:32 编辑

我们本地的git目录下, 其实分为三种类型的文件: working tree、index file和native repository;
working tree就是我们当前修改的文件;
在使用"git add"命令后, git就会把diff合入index file(通过“git diff”来查看working tree与index file的差别);
再使用"git commit"命令, 把修改合入native repository("git commit -a"相当于"git add" + "git commit"; 在commit之前, 可以通过""git diff --cached"来查看index file与commit的差别);

其实, 还可以使用"git reset"命令来还原git节点.
"git reset --hard patch-hash-name" 可以使working tree、index file以及native repository彻底回复到指定的节点;
"git reset --mixed patch-hash-name" 可以使index  file和native repository被还原;
"git reset --soft patch-hash-name" 可以使native repository被还原;

论坛徽章:
0
5 [报告]
发表于 2013-09-19 19:32 |只看该作者
Great!Thanks for sharing!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP