一次解决仓库管理问题的记录

问题起因

一天平静的夜晚,我刚写完web课程设计的其中一个功能的业务代码,准备提交到远程仓库,发现失败了,哦,原来是已经有人上传了新的代码,我需要pull一下。然后我就pull了,由于我们使用的是sqlite数据库,所以db文件大概率会发生冲突,解决了数据库文件冲突后,我push了上去,没想到,我本地的代码居然莫名少了一些!麻烦就此开始…

溯源

我去翻看了仓库的commit记录,发现一个逆天的commit,原来是另一个人(以下称为A同学),Revert了我之前的某一次提交,我找他了解了一下情况,他说本来是想Revert他自己的某次提交的,但是Revert错了~~(不是哥们这能错?)~~。我仔细观察了A同学的commit记录,发现有很多个同名或者类似的commit,甚至有些commit里几乎没有任何实质性的改动,至此算是知道了,A同学可能不太熟悉git((,导致了很多误操作,他想修复,但是越修越乱,我估计我的那份被Revert的代码也是他误操作的牺牲品之一。

尝试

为了尽快排除问题,我先在本地使用git reset --hard <commit-id>,reset到了我pull前的最新提交,然后我再次pull,发现在一个文件里我写的一部分代码确实丢失了,这是为什么呢?其实是因为他进行的revert操作比我本地写的那部分代码的commit要新一些,所以一旦pull下来,git会以他的为准,所以才出现了我的代码部分丢失的情况。然后我尝试直接reset他revert我的代码(((,结果导致他写的800多行代码直接没了,因为他写的那800多行是在他revert我的代码那次commit之后进行提交的,所以我如果直接reset到他revert我的代码的那次commit,会导致整个时间线上的代码全部都消失。

解决

那么到底应该怎么解决呢,我之前听说git有一个叫cherry-pick的命令非常好用,但是自己没有了解过,只知道它可以精确地操作某一次commit。我上网查了一些关于cherry-pick的用法,我感觉它说不定真的能解决我的问题。于是我马上开始了尝试。首先我还是将我本地的分支reset到了我pull之前的最新的commit,然后我创建了一个新的分支B,我切换到分支B,然后在B分支中进行pull操作,不出意料我的代码应该会没一部分,然后我用git log查看A同学提交的有实质性修改的那几次commit,我记下了那几个commit-id,然后我在checkout回了我原来的分支,使用:

1
2
git cherry-pick <commit-id1> <commit-id2> ......
git commit --allow-empty

发现他的代码成功被合并到了我当前的分支,并且我写的那一部分代码没有消失!

随后我使用

1
git push origin develop --force

将本地经过cherry-pick后的仓库强行覆盖到远程仓库,至此问题完美解决。

Happy Ending!