我的一个客户意外地在他的.git/config
文件中设置了一个不同的项目作为遥控器,然后被拉,提交和推送。
这意味着来自repo" A"的所有文件(主要的)现在是回购" B" (次要的)。不幸的是,有几个人已经退出了" B"。
删除" A"的所有文件,提交和历史记录的最佳方法是什么?来自" B"?
答案 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/master
,git 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]
现在他们可以正常工作(没有必要立即推动)。