0%

好好玩git:git-stash

好好玩git之git-stash,这系列文章我并不是想说git那些基本的知识,毕竟git的使用到了如今这个阶段。但是还是有很多人还只停留在:git addgit commitgit pullgit push这些基本的基本的git操作;当遇到一些稍微复杂一些处理的时候显得方法不多,工具没有的情况,本片博客我就简单说一说git-stash这个命令或者说工具(每一个命令其实都是一个工具)

git-stash释义

先来一张 manual 截图:

  • stash

    stash 隐藏,存放,存储

  • git-stash的手册释义意思是:隐藏/存储 发生变化的‘脏’的工作区;

使用git我们一定清楚git的三个代码存放环境:工作区、版本库、远程仓库;简单描述就是我们修改的代码在工作区中,通过git-addgit-commit提交到版本库,纳入版本(git)管理,再通过git-push明天推送到远程仓库,和小伙伴们共享我们的劳动成果。在没有执行相应的命令之前,版本库和远程仓库保持原有的代码,我们的变更只是在我们本地的机器上,而版本库和远程仓库没有任何影响。

其实git还有一个仓储区:一个堆栈式的存储区;以方便我们任何时候将我们的‘脏’的工作区变成一个‘干净’的工作区;我们辛苦的劳动成果此时就不见了,但是别担心,git已经把修改的代码保存到了一个暂存区中,并没有丢失。

为什么要使用git-stash?有什么便捷好处呢?看完下面的内容就明白了!

问题情景

现在我简单说三个情景:

  • 我在入职上一家公司时,发现团队中的小伙伴对git还不是很熟悉,只是按照客户那边技术给出的git提交方法每次来提交,当时我看到他在笔记上记录的是这样的:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    git stash clear
    git stash
    git pull

    --
    git stash pop
    git add .
    git commit -m 'xx'
    git push

    为什么客户那边的技术会有使用git-stash的要求呢?

  • 当我们在某个feature分支上面正在进行某个功能开发时,线上系统此时出现了一个紧急的bug需要你来解决,但是呢?feature分支上你正在开发的功能你只是刚刚开始了一下初步实现尝试,不想完成一次提交。但是呢,如果工作区不“干净”,切换分支时会带来一些问题,什么问题呢?
    现在有个项目:分支是这样的:

    假如我们在feature/v1.0.0上开发时,遇到线上紧急bug需要切换到分支hotfix/issue-01上解决问题,然后再回到feature分支继续开发,
    1.如果我们在feature分支上新建了一个文件feature.js,或者说未被git追踪的操作时,

    我们切换分支:

    切换成功了!but,出现大问题了!! 我们在feature分支上的修改被带到了hotfix分支上,这个新增的不是我想在hotfix上的修改啊 😢 ~~~~ 咋办啊?
    2.如果我们在feature分支上修改了一个已经被git追踪的文件model.php文件时:

    尽然切换不了分支,直接终止了!提示我们feature上的变更还没有提交,可是我暂时不想提交啊,怎么办?

  • 如果有个糊涂蛋错误的将A分支的代码提交到了B分支怎么办?

    假如就是这个a.php文件,提交错了分支怎么办?

更多的情景就让我们遇到问题时灵活应用,就是一个字:玩,好好玩,慢慢玩 git

利用git-stash解决

ok,针对上面三种情况,借用git-stash来解决,先来说说git-stash相关option吧!

1
2
3
4
5
6
git stash        存储工作区的变更
git stash list 列出暂存区中已经保存的变更
git stash apply 应用某个暂存的变更到工作区,也就是取出指定的某一次暂存内容应用到当前工作区
git stash pop 应用某个暂存的变更到工作区,并从堆栈中将这次暂存记录移走
git stash drop 删除指定的某个暂存记录
git stash clear 清空所有的暂存记录

来说说上面的问题情境:

  • 情境一:为什么要先用git-stash?再拉去代码?再提交代码?
    也许是客户那边的代码管理开发想要让对git还不是很熟悉的小伙伴们尽可能的减少提交代码时出现问题!但是我仔细想了想也测试一下,发现其实这样并没有什么作用!该冲突的还是会在git stash pop时冲突需要解决,也并不能保证线性提交(fast-forward);
    我能想到的好处就是:可能代码管理者是为了让每个开发人员在需要同步代码时,不在必须提交自己还在工作中的那些工作区代码!因为当git pull拉去远程代码时,如果远程仓库中的某次提交修改的某个文件也正是你正在改动的文件,git会要求你先提交,再拉取;所以如果你暂时还不想提交,就可以使用git-stash。所以这么做其实是为了你能实时同步远程仓库代码而不必每次同步都必须把自己未完成的代码也提交到版本库
    所以,上个公司的小伙伴是对git还不熟悉,以为每次提交时才进行这一系列操作,其实正确的顺序应该是这样:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    git stash clear
    git stash
    git pull
    git stash pop
    -- 上面的可随时执行,用于同步远程仓库代码

    -- 提交代码时执行
    git stash clear
    git stash
    git pull
    git stash pop
    git add .
    git commit -m 'xx'
    git push

  • 情景二:出现紧急情况,需要立即切换到另一个分支去解决问题,而当问题解决以后 回到功能分支后 分支上的东西还是我离开时的东西
    我们在feature分支上新建了feature.js,然后去先把它存起来:

    暂存以后,使用git stash list查看暂存记录是这个样子的:

    我暂存了两次,为的是让大家看到,如果在使用git stash apply stash@{x}时,apply后面就是要指定的具体那一次暂存记录
    同时,我们暂存对model.php的修改,此时可以看到feature分支已经是干净的了!

  • 情景三:代码提交错了分支
    首先,git log找到错误的开始:

    然后回退代码:git reset 38bdad2 记住此时一定不要--hard项,如果不懂git-reset自行补习一下。

    然后暂存B中的修改

    最后,回到A分支,应用该次暂存,并提交到分支,问题解决!

由上面的操作,不难看出stash保存的区域是分支共享的,利用这一点,我们就可以将一个分支上的变动原样带到另外一个分支上应用。公用同一个暂存区也只是在同一个git仓库上
ok!就先这样,关于stash更多、更高级的玩法和场景还需要在工作学习中加入想象力尽可能使用,这里就不在赘述了,后续如果发现更多有用好玩的的解决关键问题的方法情景我会
继续补上的。

夜深了~~~~ 睡觉!