被`git push -f`后的应对方式

原则上git的force push是不能push到公共repo的,但实际难免会出现由force push引起的冲突。昨天我在A机器上push到了develop分支之后,在B机器上做了些小修改然后force-push,之后又回到A机器上工作,commit之后push发现冲突。

1
2
3
      C---D (local `develop`, HEAD)
/
A---B---C' (remote `develop`)

现在怎样能修复这一冲突,使最新的commit(D)能接在force push后的C'后呢?

首先重新命名本地的develop分支,解决分支命名上和remote的冲突:

1
git branch -m develop backup

当前状态为:

1
2
3
      C---D (local `backup`, HEAD)
/
A---B---C' (remote `develop`)

然后就可以把remote的develop分支拉到本地:

1
2
git fetch --all
git checkout develop

现在的状态是:

1
2
3
      C---D (local `backup`)
/
A---B---C' (local `develop`, HEAD)

然后回到backup分支,进行rebase:

1
2
git checkout backup
git rebase develop

rebase时可能要处理冲突。rebase成功后,D就被接到了C'上。如果C'仅仅是在C的基础上加了一些东西的话,我们就达到了目标的状态。但是一般情况下C'中间和隔着一个git自动生成的commit,代表了CC'之间的差:

1
2
3
4
A---B---C'---(C-C')---D (local `backup`, HEAD)
^
|
(local `develop`)

这时利用rebase将这个commit丢弃掉即可

1
git rebase -i HEAD~2

这样就达到了目标的状态:

1
2
3
4
A---B---C'---D (local `backup`, HEAD)
^
|
(local `develop`)

之后就是常规操作了,push到remote时可以fast-forward。