前两天检视代码时,发现PR里面有两个提交的描述信息一模一样,于是我提出应该将这两个提交合并成一个,保持提交树的清晰。
而同事这时正在开发别的特性,工作区不是干净的,没法直接执行 git rebase 操作,于是很自然地执行
git stash 将正在修改的内容保存到一个栈中,并维持当前工作区干净。
这样就可以执行切换分支、变基等操作,这些操作能执行的前提是当前工作区是干净的。
我们先执行 git log 命令,找到要合并的两个提交之前的那个提交:cdedd430
commit ec0218ff feat: 增加国际化 commit 89f3d02c feat: 增加国际化 commit cdedd430 refactor: pnpm工程改造 然后执行 git rebase 变基命令:
git rebase -i cdedd430 这时会进入一个交互式命令行界面:
pick 89f3d02 feat: 增加国际化 pick ec0218f feat: 增加国际化 # Rebase cdedd43..ec0218f onto cdedd43 (2 commands) # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # b, break = stop here (continue rebase later with 'git rebase --continue') # d, drop = remove commit # l, label 这时你可以移动光标,但是无法输入字符,因为这是个只读的界面,需要先输入 i 字符进入编辑态,此时界面底部会出现 -- INSERT -- 标识。
... # Note that empty commits are commented out -- INSERT -- 下面那些以 # 开头的都是注释,只有前面两行比较关键。
pick 89f3d02 feat: 增加国际化 pick ec0218f feat: 增加国际化 # ... 每一行都由三部分组成:
我们需要将 ec0218f 合并到 89f3d02 上,因此需要将第二行的 pick 改成 squash(s) 或 fixup(f),这两个命令的区别在于:
由于我们两次提交信息完全一致,没必要保留,选择 fixup(f):
pick 89f3d02 feat: 增加国际化 f ec0218f feat: 增加国际化 修改好之后,先按 ESC 退出编辑态,然后按 :wq 保存,显示以下信息说明变基成功,两个提交已经合并在一起
Successfully rebased and updated refs/heads/kagol/test-rebase. 执行 git log 看下效果:
commit 86930d03 feat: 增加国际化 commit cdedd430 refactor: pnpm工程改造 可以看到两个提交已经合并在一起,并且生成了一个新的 Commit ID: 86930d03。

1小时之后,同事慌慌张张地跟我说:
我代码没了!
我心里第一反应是:
刚才一顿变基猛如虎,不过变基变出问题来了吧?

作为一个成熟稳重的程序员,什么大风大浪没见过,于是轻轻地回了句:
少年,莫慌!你先讲下你刚才做了什么?
我没,没做什么…
没做什么代码怎么会自己丢了呢?
我就执行了一下 git stash pop,然后我之前写了一上午的代码就没…没了…
突然开始心里有点慌,把同事一上午代码搞没了,我怎么赔给人家??

但心里不能表现出来,不着急,稳住少年!
你先执行下 git stash list 看下储存栈里还有没有内容:
$ git stash list stash@{0}: WIP on master: f90abfe Initial commit 看到之前储存的内容还在我立马不慌了!
不再执行下 git stash pop,我看下有没有报什么错?
执行完之后果然报了一个错:
$ git stash pop error: Your local changes to the following files would be overwritten by merge: main.ts Please commit your changes or stash them before you merge. Aborting The stash entry is kept in case you need it again. 大意是:
你本地修改了文件,储存栈里的内容如果弹出会覆盖掉你本地的代码,所以导致操作失败。
然后建议你先提交你本地的修改或者将你本地的修改储存起来。
并且特意提示你你储存的内容给你保留下来了,方便你下次要用的时候可以用。
不得不说,这 Git 真是太贴心了,考虑得很周到,为 Git 点个赞👍
虽然我其实已经猜到是什么原因了,但是作为成熟稳重的程序员,我依然不动声色地问了句:git rebase 之后,git stash pop 之前,中间你是不是还改了什么东西?
哦,好像是改了 main.ts 文件,我想起来了!
你把你改的东西先撤销下,然后执行 git stash pop 试试?
果然,执行 git stash pop 成功,之前的上百行代码都找回来了!
破案!收工!
上一篇:adj.md 形容词的用法