使用 Git 作为代码版本管理,早已是现在开发工程师必备的技能。可大多数工程师还是只会最基本的保存、拉取、推送,遇到一些 commit
管理的问题就束手无策,或者用一些不优雅的方式解决。
一、stash
1、描述
官方解释:当您想记录工作目录和索引的当前状态,但又想返回一个干净的工作目录时,请使用 git stash
。该命令将保存本地修改,并恢复工作目录以匹配头部提交。
stash
命令能够将还未 commit
的代码存起来,让你的工作目录变得干净。
2、应用场景:
我猜你心里一定在想:为什么要变干净?
应用场景:某一天你正在 feature
分支开发新需求,突然产品经理跑过来说线上有 bug
,必须马上修复。而此时你的功能开发到一半,于是你急忙想切到 master
分支,然后你就会看到以下报错:
因为当前有文件更改了,需要提交 commit
保持工作区干净才能切分支。由于情况紧急,你只有急忙 commit
上去,commit
信息也随便写了个“暂存代码”,于是该分支提交记录就留了一条黑历史…(真人真事,看过这种提交)
3、命令使用
如果你学会 stash
,就不用那么狼狈了。你只需要:
git stash
就这么简单,代码就被存起来了。
当你修复完线上问题,切回 feature
分支,想恢复代码也只需要:
git stash apply
4、相关命令
# 保存当前未commit的代码
git stash
# 保存当前未commit的代码并添加备注
git stash save "备注的内容"
# 列出stash的所有记录
git stash list
# 删除stash的所有记录
git stash clear
# 应用最近一次的stash
git stash apply
# 应用最近一次的stash,随后删除该记录
git stash pop
# 删除最近的一次stash
git stash drop
当有多条 stash
,可以指定操作 stash
,首先使用 stash list
列出所有记录:
$ git stash list
stash@{0}: WIP on ...
stash@{1}: WIP on ...
stash@{2}: On ...
应用第二条记录:
$ git stash apply stash@{1}
5、IDEA 集成
在 IDEA 中 右击项目,选择 Git → Repository → Stash Changes
添加备注信息,就成功将代码保存起来了
恢复代码,点击 Git → Repository → UnStash Changes
就会弹出保存的代码记录,选择我们要恢复的版本,点击 Apply Stash
代码就还原回来了!!
注意:
如果在 IDEA 中没有将本地未提交的代码 stash 保存起来,切换分支时,就可能会弹出这样的提示框:
Smart Checkout 是智能切换,并且选择了 accept theirs 可能会导致原有代码丢失;
Force Checkout 是强制切换,此操作不会保留你的修改,切到另一个分支内容就消失了,且切回来原来分支也找不回,白写了。
2、reset --soft
1、描述
完全不接触索引文件或工作树(但会像所有模式一样,将头部重置为)。这使您的所有更改的文件更改为 “要提交的更改”。
回退你已提交的 commit
,并将 commit
的修改内容放回到暂存区。
一般我们在使用 reset 命令时,git reset --hard会被提及的比较多,它能让 commit 记录强制回溯到某一个节点。而git reset --soft的作用正如其名,–soft(柔软的) 除了回溯节点外,还会保留节点的修改内容。
2、应用场景
回溯节点,为什么要保留修改内容?
应用场景1:有时候手滑不小心把不该提交的内容 commit
了,这时想改回来,只能再 commit
一次,又多一条“黑历史”。
应用场景2:规范些的团队,一般对于 commit
的内容要求职责明确,颗粒度要细,便于后续出现问题排查。本来属于两块不同功能的修改,一起 commit
上去,这种就属于不规范。这次恰好又手滑了,一次性 commit
上去。
3、命令使用
学会 reset --soft
之后,你只需要:
# 恢复最近一次 commit
git reset --soft HEAD^
reset --soft
相当于后悔药,给你重新改过的机会。对于上面的场景,就可以再次修改重新提交,保持干净的 commit
记录。
以上说的是还未 push
的 commit
。对于已经 push
的 commit
,也可以使用该命令,不过再次 push
时,由于远程分支和本地分支有差异,需要强制推送 git push -f
来覆盖被 reset 的 commit
。
还有一点需要注意,在 reset --soft
指定 commit
号时,会将该 commit
到最近一次 commit
的所有修改内容全部恢复,而不是只针对该 commit
。
举个例子:
commit
记录有 c、b、a。
reset
到 a。
git reset --soft 1a900ac29eba73ce817bf959f82ffcb0bfa38f75
此时的 HEAD
到了 a,而 b、c 的修改内容都回到了暂存区。
⭐⭐⭐⭐⭐