前言
git作为我们日常开发常用的代码版本管理工具,熟练地掌握它,对于提高我们日常工作效率显得尤为重要,在此主要对stash、reset、revert、reflog四个命令进行梳理。
一、stash
应用场景:当我在feature分支开发新功能时(开发了一部分),接到测试同学的反馈,需要在dev分支上修复bug,这时我需要切换到dev分支,当执行切换分支命令时,会有报错说需要先提交后才可以切换分支,这时如果我们提交了,就有了一次不需要的提交记录。或者不报错,但是之前在feature分支的更改也会添加到dev分支,这时如果在dev分支取消在feature分支的更改,当我们切换到feature分支后,之前的更改就丢失了。
解决方法: stash命令就是把当下的代码贮存起来,然后在一定的时机弹出来,既不会将更改带入新的分支,同样当切回原来的分支时,可以弹出贮存,恢复之前的更改。
示例代码如下
// 贮存代码
git stash save '备注内容'
// 查看贮存
git stash list
打印内容:
stash@{0}: On feature-v5.2.7-72150591: 1
stash@{1}: On feature-v5.2.7-72150591: 2
// 弹出贮存
// 1. 弹出最新贮存代码
git stash apply
// 2. 指定弹出
例如: git stash apply stash@{0} (在powershell中需要`{0`}转译)
// 3. 删除某段贮存
用法同添加贮存,git stash drop(删除最新) git stash drop stash@{0}(指定删除)
// 4. 清除贮存
git stash clear
二、reset --soft
应用场景1:有时候手滑不小心把不该提交的内容 commit 了,这时想改回来,只能再 commit 一次,又多一条“黑历史”。
应用场景2:规范些的团队,一般对于 commit 的内容要求职责明确,颗粒度要细,便于后续出现问题排查。本来属于两块不同功能的修改,一起 commit 上去,这种就属于不规范。这次恰好又手滑了,一次性 commit 上去。
解决方案:例如如最近有a->b->c三条提交记录,c为最新记录,有一次发觉b和c两次提交的相关文件修改还有需要修改的地方,所以此时可以用git reset --soft (a的commitId),让状态此时返回到a提交的状态,同时b,c的更改仍旧保存着,这时我们就可以在之前的基础上继续对文件进行修改了。
疑问: 为啥不用git reset --hard命令 ?
因为该命令虽然可以使工作区的状态回到想要的提交状态,但是之前在b,c两次提交的相关文件修改也丢失了,所以不可用。
三、revert
应用场景:有一天测试突然跟你说,你开发上线的功能有问题,需要马上撤回,否则会影响到系统使用。这时可能会想到用 reset 回退,可是你看了看分支上最新的提交还有其他同事的代码,用 reset 会把这部分代码也撤回了,这时同事提交的代码也丢失了。
解决方法:
(1) 普通提交:假如最近的提交记录有a(我的提交)-> b(同事的提交)
运用git revert (我提交的commitId),revert 掉自己提交的 commit。
因为 revert 会生成一条新的提交记录,这时会让你编辑提交信息,编辑完后 :wq 保存退出就好了。
再来看下最新的 log,生成了一条 revert 记录,虽然自己之前的提交记录还是会保留着,但你修改的代码内容已经被撤回了。
(2)合并提交:最近的提交记录如果有合并提交记录,这时就要另外处理.
需要命令git revert -m 1
我的理解是因为合并提交是两条分支的交集节点,而 git 不知道需要撤销的哪一条分支,需要添加参数 -m 指定主线分支,保留主线分支的代码,另一条则被撤销。
-m 后面要跟一个 parent number 标识出"主线",一般使用 1 保留主分支代码。
(3)还是上面的场景,在 master 分支 revert 合并提交后,然后切到 feature 分支修复好 bug,再合并到 master 分支时,会发现之前被 revert 的修改内容没有重新合并进来。
因为使用 revert 后, feature 分支的 commit 还是会保留在 master 分支的记录中,当你再次合并进去时,git 判断有相同的 commitHash,就忽略了相关 commit 修改的内容。
这时就需要 revert 掉之前 revert 的合并提交。
现在 master 的记录是这样的。
再次使用 revert,之前被 revert 的修改内容就又回来了。
四、 更改 commit 信息
git commit --amend -m“新提交消息”
五、reflog
对于疏忽错误地把没打算提交的代码push的情况,可以通过如下方法撤销:
//撤回最新提交
git reset --hard HEAD^
//或者撤回某次提交
git reset --hard commit_id 退到/进到 指定commit的sha码
注意本地代码会被回退到上次修改前,如果本地已有修改注意备份。
之后,使用 –force 或 -f 参数强制push:
git push origin 分支名 --force
再看git记录就没有上次的提交了,就可以使提交记录更为可读,简洁。
当你回滚之后,又后悔了,想恢复到新的版本怎么办?
用git reflog打印你记录你的每一次操作记录
git reflog 可以查看所有分支的所有操作记录(包括(包括commit和reset的操作),包括已经被删除的commit记录,git log则不能察看已经删除了的commit记录。
简单的说,它会记录所有HEAD的历史,也就是说当你做 reset,checkout等操作的时候,这些操作会被记录在reflog中。
之后就可以重新执行git reset --hard commit_id 使代码回滚到指定提交
六、相关文章
参考文章
git reset --soft命令的使用
Git 之 revert
Git 命令 reset 和 revert 的区别【笔记】
其它相关学习文章