周五提交代码的时候,一如既往的拉取代码,提交自己的代码然后合并 develop 分支的代码再提交 PR。这次合并 develop 的时候没有冲突,本以为一切顺利,结果提交的时候触发了 Git 的代码检测,提示有几个变量定义了但没有使用。
当时脑子一抽,想都没想就给这些文件取消暂存、放弃更改,然后重新提交。等到提 PR 的时候瞄了一眼——不对,我明明只改了三个文件,怎么提交记录里显示改了二十多个?而且其中一个文件赫然显示为「删除」。
我果断撤销了 PR,感觉事情不太对劲。
发现问题
回到代码重新拉取,合并显示我的分支已经是最新了。但我越想越不对,于是切换到 develop 分支看了一眼——果然,那个文件在 develop 上是好好的,但我的分支上已经把它删掉了。
这时候我想起来之前另一个项目也出现过类似的情况:代码莫名其妙找不回来了,但回退显示都是最新的。当时没搞清楚原因,现在想想大概率也是同样的操作失误。
为什么会这样?
核心原因在于我做了「放弃更改」这个操作。
当时的流程是这样的:
合并 develop 的代码,产生了合并提交
触发了 lint 检测,报了几个未使用变量的警告
我在编辑器里选中这些文件,执行了「取消暂存 + 放弃更改」
问题就出在第 3 步。「放弃更改」不只是撤销我自己的修改,它把合并进来的那些变更也一起丢弃了。也就是说,develop 上有的文件,在我的分支上被直接删掉了。
更坑的是,Git 合并的时候比较的不是文件内容,而是提交记录。我的分支已经有了那次合并的提交记录,所以再次合并 develop 时,Git 认为「这两个分支已经同步过了」,直接显示「已经是最新」——哪怕文件根本不一样。
解决办法
好在 develop 分支是干净的,问题只出在我的分支上。解决方法很简单:
找到我提交之前的那个正确的提交记录
将分支回退到那个提交
git push --force强制推送覆盖远程分支
这样我的分支就恢复到了正常状态,再重新合并 develop 就行了。
教训
这件事给我最大的教训就是:在合并分支之后,不要轻易使用「放弃更改」。
因为合并产生的变更不只是你自己的,还有从其他分支带过来的。盲目放弃更改,很可能把别人的代码也一起丢掉了。
正确的做法应该是:
遇到 lint 报错,先看清楚是哪些文件、哪些变量
手动去修复问题,而不是批量放弃更改
如果真的需要撤销,先用
git status看清楚暂存区里到底有什么提交 PR 之前,一定检查一下文件变更列表,确认每个文件的改动都是你预期的
另外,这次还好我提交 PR 之前多看了一眼,否则要是合进去才发现问题,处理起来就麻烦多了。