记一次git误操作恢复全过程

我们团队使用git flow方式,和此次误操作有关的有3个分支:develop、feature/discuss和feature/search,两个feature分支都是从develop分支上拉出来的,feature/discuss先从develop分支拉出来,然后develop分支上有了新的commit(其他分支feature/other开发完毕合入develop),之后再从develop分支拉出feature/search分支。

本次事故实际上是由两次误操作导致的,第一次误操作是在feature/discuss分支上执行了

git pull origin feature/search

这就导致处于开发状态的分支feature/search被合入到feature/discuss,我在发现这个误操作之后立刻让同事撤销此次merge,我以为同事会使用

git reset --hard cab39f53

来撤销提交,也就没有去详细看提交日志,于是就继续开发。

等到这个分支功能开发完毕,将这个分支合入develop

git flow feature finish discuss

这个时候git会将发生合并的文件列出来,这个时候我发现有大量文件在这次合并过程中被删除,这些文件都是分支feature/other合并到develop时新增的,于是我看了一下git log,主要的提交如下图:

记一次git误操作恢复全过程_第1张图片git提交历史

原来是同事使用了revert而不是reset来回滚,git revert实际上是把当前的要revert到的hash和head做diff,然后对head应用这些diff作为一个新的commit,这样在feature/discuss这个分支上来看,代码是回到了cab39f53这个版本。

但是当把feature/discuss合入develop分支时就有问题了,revert产生的提交也会应用到develop分支,这就把feature/other分支产生的所有变更都“撤销”了。

如果只有第一个误操作,那恢复起来就是一个reset命令的事情,现在两个误操作在一块就会麻烦一点。

  1. 把develop分支通过reset命令恢复到merge feature/discuss之前
  2. 从develop分支上拉出一个新的feature/tmp分支
  3. 找到拉feature/discuss分支之前的一个commit A
  4. 找到feature/search合入feature/discuss分支之前的一个commit B
  5. 通过git diff A B获取discuss分支到误操作前的所有提交,保存到patch1
  6. 找到最后一个revert的commit C
  7. 切换到feature/discuss分支,通过git diff C来获取误操作之后的所有提交,保存到patch2
  8. 切到develop分支,依次执行git apply patch1和git apply patch1

这样就把错误的提交给剔除了,不过遗憾的是feature/discuss的提交历史全都合并成了1个提交。

===========================================================

在写这篇博客的时候我突然想到,第一次的patch应该是没必要的,生成patch2之后,直接checkout B,拉出一个tmp分支,然后apply patch2,提交后,再把tmp合入develop,这样会丢失误操作之后的提交历史,但误操作之前的提交历史都还在。

原文:http://leo108.com/pid-2026.asp

你可能感兴趣的:(git)