Fix Git Merge Mis-Deleting files
• • ☕️ 1 min read你可以从本文了解到
背景
看到了一片其他团队的关于冲代码的文,这篇文章做了一些分析和定位问题,但是没有给出特别好的拯救办法。本文结合实际经验,进行补充。
咱们有一个项目,有很多人在不同的分支上开发。有一天,A 同学提交了一个 merge 提交,这个 merge 把其他人的代码删除了。在不知道的情况下,大家又默默开发了好几天。
最后,这个问题被发现了,然后大家很着急,不知道该怎么还原被删的代码。
问题分析和方案比较
首先,为什么提交前后代码都可以编译通过呢?
1、A 在开发的时候,肯定代码是可以跑的。 2、merge 合入主干后,别人的代码被删了,理论上,也有一定概率可以跑的(被删的代码是静态资源或者没有被什么依赖到)。
然后,回到灾难现场。现在的 git 提交是个什么情况呢?
简化成如下,a比b少了一堆文件
a [merge 节点]
|\ b
| |c
假如a提交是一个普通提交,那么我们只需要revert a提交即可。
但是a这个merge提交不携带任何信息,不能revert。该如何修复呢?
有很多方法,不同的方法复杂度不一样。其中咱们采用的是如下的方法。其思路如下。
1、求出b从a删除的文件
2、并把他们加回来,提交,解决冲突。
其中1这个步骤我们可以以一种反向思维去做。先git checkout
到b,然后git reset --soft
到a,这样,工作区就出现了被删掉的文件,直接将其提交即可。
这是什么原理呢?我们这样来理解一下。
首先,假如先checkout到a,然后reset到b,那么工作区暂存的就是b删掉的文件
。
咱们反过来操作,先checkout到b,然后reset到a,那么工作区暂存的就是revert b删掉的文件
即加回来这些文件。
其实,reset —soft做了什么呢?
reset --soft 会在重置 HEAD 和 branch 时,保留工作目录和暂存区中的内容,并把重置 HEAD 所带来的新的差异放进暂存区。
。
理解了这句话。差异是before - after
。那么我们带入a和bbefore:b, after:a
,这个差异就是b-a=被删的文件加回来
步骤2的操作可以用git pull -r
将本地提交追加到最新,并解决冲突即可。
反思
1、预防:CR要仔细,发现有大量文件别通过,仔细核对。
2、错误已经发生,要沉着冷静。有时候正向走不通,可以考虑反向操作,会有意想不到的效果。