两个git repos意外合并,如何清理

时间:2015-01-20 19:17:12

标签: git

我的一个客户意外地在他的.git/config文件中设置了一个不同的项目作为遥控器,然后被拉,提交和推送。

这意味着来自repo" A"的所有文件(主要的)现在是回购" B" (次要的)。不幸的是,有几个人已经退出了" B"。

删除" A"的所有文件,提交和历史记录的最佳方法是什么?来自" B"?

1 个答案:

答案 0 :(得分:4)

我假设您的存储库看起来像这样,A-C在适当的存储库中提交,1-3在错误的存储库中提交。 D是拉动的两者之间的合并点(大概是pull --force你不应该这样做,除非你知道那里是一个反叛者。)

... A - B - C - D [master] [origin/master]
               /
... 1 -  2 -  3

你需要解决这个问题的所有方法就是将主人移回C.因为Git中的分支只是指向提交的标签,所以移动它们很便宜。这就是git reset所做的事情(git reset --完全做了其他事情。)

git checkout master
git reset --hard C

--hard表示抛出索引并使工作目录也与提交相匹配。现在您的存储库看起来像这样。

... A - B - C [master] - D [origin/master]
                        /
           ... 1 - 2 - 3

现在git push --force在远程存储库中进行相同的移动。没有其他任何引用它,违规提交最终将被垃圾收集。

... A - B - C [master] [origin/master]

如果在错误合并之上完成工作,这会变得有点复杂。

... A - B - C - D - E - F - G [master] [origin/master]
               /
... 1 -  2 -  3

你想做与以前相同的事情,但坚持G.你可以通过写下提交ID来做到这一点,或者你可以将其标记为安全。

git tag old-master master

看起来像......

... A - B - C - D - E - F - G [master] [origin/master] (old-master)
               /
... 1 -  2 -  3

像以前一样重置......

... A - B - C [master] - D - E - F - G [origin/master] (old-master)
                        /
         ... 1 -  2 -  3

但是现在你想把E,F和G挂起C.你可以用一个底板来做。这将把E,F和G作为补丁并逐个应用到C上。

git rebase --onto master D old-master

更改将具有新的提交ID,因为git中的每个提交ID都取决于其父ID(这使得推拉速度如此之快)。

              E1 - F1 - G1 [master]
             /
... A - B - C - D - E - F - G [origin/master] (old-master)
               /
... 1 -  2 -  3

现在您可以push --force掌握并删除旧主人。

... A - B - C - E1 - F1 - G1 [master]

由于存储库已从存储库中更改,因此已从存储库中取出的每个人都必须git pull --force。他们应该git pull --rebase --force。拉通常是一个提取和合并。 --rebase将此变为fetch和rebase。使用rebase会将用户未经删除的工作作为补丁应用于新存储库之上。这可以防止错误的存储库通过拉/合并返回。

例如,用户的存储库可能看起来像这样,其中H和I是他们自己未经删除的更改。我还会建立固定的远程存储库进行比较。

[local]
... A - B - C - D - E - F - G [origin/master] - H - I [master]
               /
... 1 -  2 -  3

[remote]
... A - B - C - E1 - F1 - G1 [master]

在你修复了远程存储库之后,如果他们拉Git将拒绝合并,因为G不是G1的祖先,他们必须强行。这更容易分别显示fetch和merge / rebase。因此git fetch origin会导致......

[local]
              E1 - F1 - G1 [origin/master]
             /
... A - B - C - D - E - F - G - H - I [master]
               /
... 1 -  2 -  3

[remote]
... A - B - C - E1 - F1 - G1 [master]

git merge origin/mastergit pull --force将会执行此操作,会导致此...

               - - - - - - E1 - F1 - G1 [origin/master]
             /                         \
... A - B - C - D - E - F - G - H - I - J [master]
               /
... 1 -  2 -  3

我们不希望这样,它会从错误的存储库中恢复历史记录。 git pull --force --rebase会改为git rebase origin/master将H和I置于原点/主人之上。

[local]
... A - B - C - E1 - F1 - G1 [origin/master] - H1 - I1 [master]

现在他们可以正常工作(没有必要立即推动)。