入职第一天就在主分支修改了大量代码怎么办?急
如标题所示,应该是很多同学都遇到过的情况,忘记切分支就急急忙忙开始敲代码了,等全部敲完了准备 commit 了发现在 master 分支上改了一堆。
遇到这种不要慌,很简单的三条命令就可以让你将修改的代码无缝迁移到新分支:
1. git stash
2. git checkout -b "分支名"
3. git stash pop
没错,就是 git stash
命令。
Git Stash
通过上篇 三分钟上手!一文看懂 Git 的底层工作原理,想必大伙都知道了 Git 的三大对象 Commit、Tree 和 Blob,下面继续接着上篇文章用实例来演示 git stash
的工作原理:
![f952a6b5de874aa47ec44b4ada90f48a.webp](https://filescdn.proginn.com/f4b6f32c4da6aae1267a54cd1e49e731/f952a6b5de874aa47ec44b4ada90f48a.webp)
来看看 stash 之后 .git
文件夹发生了哪些变化:
![b71cab77fe1b75d8e8f2a0dd2b3c45dc.webp](https://filescdn.proginn.com/2b6d49c2ec268714a1d9fb3fdee7ed0a/b71cab77fe1b75d8e8f2a0dd2b3c45dc.webp)
其实就是 objects 目录中增加了一些对象文件,refs 中增加了一个 stash 文件。通过命令查看该文件内容:
![6a9e845da5ea3b4cb475a1a54e4de263.webp](https://filescdn.proginn.com/c7fe4e8a840212a2a4b23f2c4f35a30d/6a9e845da5ea3b4cb475a1a54e4de263.webp)
从命令行输出可以看到 git stash
实际上创建了一个新的 Commit 对象 aab0b
, 该 Commit 对象有两个父节点:0d6c7
和 4311e
,可以通过 git log --oneline --graph stash@{0}
清楚的看到层级关系:
![d670cda87c5a3e13e87125da9373decd.webp](https://filescdn.proginn.com/9af10d248ea2bbd4ea92fd245c881be9/d670cda87c5a3e13e87125da9373decd.webp)
很明显,aabobba
是本次 Commit 对象,拥有两个父节点 4311e
和 0d6c7
,其中,0d6c7
的父节点是 78af663
,4311e
是保存到暂存区(Stage)的 Commit 对象,它是在 0d6c7
(上一次 git commit 命令生成的 Commit 对象)的基础上做的操作
简单理解 Git 三大存储区域:
- 开发代码的时候在 Git 工作区(Workspace)
- commit 后就到了暂存区(Stage)
- push 后就到了仓库区(Repositorys)
从该试验可以得知,git stash
的本质其实就是创建了一个保存到暂存区(Stage)的 Commit 对象而已。
Git Reset
再来看一个场景,当我们通过 git commit 提交代码后,突然测出来代码有问题,希望回退刚才的改动,这个时候就需要用到 git reset
命令。
我们先来提交一个 commit:
![c9f6837530e19ddb8e15f86b11f64686.webp](https://filescdn.proginn.com/2c588907c74c7bc45b9e714956b25873/c9f6837530e19ddb8e15f86b11f64686.webp)
通过 git log
查看 commit 日志:
![19a8c520df8afa343eca8b3ae18bdd50.webp](https://filescdn.proginn.com/f3621217f0fa16debba125cb71f4b3ba/19a8c520df8afa343eca8b3ae18bdd50.webp)
然后通过 git reset
回退到上一个 commit。注意这里 HEAD 是一个指向当前 branch 最后一个 commit 的指针,因此 HEAD~1
表示之前的一个 commit,当然,git reset命令也可以直接使用 commit 哈希值作为命令参数:
![0c64e713ca1fcc845707eff2b7447b3f.webp](https://filescdn.proginn.com/7ce6a40f60879be87879d18f4384bc8f/0c64e713ca1fcc845707eff2b7447b3f.webp)
再执行 git log
就会发现刚才的 commit 被回退了(不过修改的文件还是存在的,处于 Unstaged 状态 - 已修改但未被 Git 跟踪,你可以对这些文件进行改动后再次提交):
![b0e0f71d33e40f0bfffd61cc4ecf6d79.webp](https://filescdn.proginn.com/5b3a8f35e610729a7b008c9799b1622a/b0e0f71d33e40f0bfffd61cc4ecf6d79.webp)
如果你不想保留修改的文件,可以使用 –hard
参数直接回退到指定的commit,该参数会将 HEAD 指向该 commit,并且工作区中的文件也会和该 commit 保持一致,该 commit 后的修改会被直接丢弃:
![30ad25017fc10e82a0e4117973c956e6.webp](https://filescdn.proginn.com/c1a45c34b524cf1e83a0ba5fef03a358/30ad25017fc10e82a0e4117973c956e6.webp)
分享大厂面试真题原创题解 & 成长经验.
面试题库 & 求职信息: itmtx.cn
回复『 校招 』获取招聘信息和交流群 回复『 项目 』获取多个项目教程与面试精讲 回复『 简历修改 』获取简历修改 & 模拟面试服务