我的一个客户不小心在他的文件中将另一个项目设置为远程项目.git/config,然后拉取、提交和推送。
这意味着存储库“A”(主要文件)中的所有文件现在都位于存储库“B”(辅助文件)中。不幸的是,已经有几个人从“B”退出了。
从“B”中删除“A”的所有文件、提交和历史记录的最佳方法是什么?
我假设您的存储库看起来像这样,其中 AC 提交到正确的存储库中,而 1-3 提交到错误的存储库中。D 是由于拉取而导致的两者之间的合并点(大概pull --force您不应该这样做,除非您知道已经进行了变基)。
... A - B - C - D [master] [origin/master]
/
... 1 - 2 - 3
Run Code Online (Sandbox Code Playgroud)
解决这个问题所需要做的就是将 master 移回 C。由于 Git 中的分支只是指向提交的标签,因此移动它们的成本很低。这就是git reset(git reset --完全做其他事情)的作用。
git checkout master
git reset --hard C
Run Code Online (Sandbox Code Playgroud)
--hard表示丢弃索引并使工作目录也与提交匹配。现在你的存储库看起来像这样。
... A - B - C [master] - D [origin/master]
/
... 1 - 2 - 3
Run Code Online (Sandbox Code Playgroud)
现在git push --force在远程存储库中进行相同的操作。如果没有其他东西引用它,有问题的提交最终将被垃圾收集。
... A - B - C [master] [origin/master]
Run Code Online (Sandbox Code Playgroud)
如果工作是在错误的合并之上完成的,那么事情会变得更加复杂。
... A - B - C - D - E - F - G [master] [origin/master]
/
... 1 - 2 - 3
Run Code Online (Sandbox Code Playgroud)
您想做与以前相同的事情,但保留 G。您可以通过写下提交 ID 来完成此操作,也可以将其标记为安全。
git tag old-master master
Run Code Online (Sandbox Code Playgroud)
看起来像...
... A - B - C - D - E - F - G [master] [origin/master] (old-master)
/
... 1 - 2 - 3
Run Code Online (Sandbox Code Playgroud)
像以前一样进行重置...
... A - B - C [master] - D - E - F - G [origin/master] (old-master)
/
... 1 - 2 - 3
Run Code Online (Sandbox Code Playgroud)
但现在你想将 E、F 和 G 挂在 C 上。你可以通过变基来做到这一点。这会将 E、F 和 G 作为补丁,并将它们一一应用到 C 上。
git rebase --onto master D old-master
Run Code Online (Sandbox Code Playgroud)
更改将有新的提交 ID,因为 git 中的每个提交 ID 都取决于其父级的 ID(这就是推拉速度如此之快的原因)。
E1 - F1 - G1 [master]
/
... A - B - C - D - E - F - G [origin/master] (old-master)
/
... 1 - 2 - 3
Run Code Online (Sandbox Code Playgroud)
现在您可以push --force掌握和删除旧的掌握。
... A - B - C - E1 - F1 - G1 [master]
Run Code Online (Sandbox Code Playgroud)
由于存储库从他们的控制下发生了变化,因此已经从存储库中提取的每个人都必须这样做git pull --force。他们也许应该git pull --rebase --force。拉取通常是获取和合并。 --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]
Run Code Online (Sandbox Code Playgroud)
修复远程存储库后,如果他们拉取 Git 将拒绝合并,因为 G 不是 G1 的祖先,他们必须强制。单独显示获取和合并/变基更简单。所以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]
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
我们不希望这样,它会从错误的存储库中恢复历史记录。 git pull --force --rebase相反,将执行 a git rebase origin/master,将 H 和 I 置于 origin/master 之上。
[local]
... A - B - C - E1 - F1 - G1 [origin/master] - H1 - I1 [master]
Run Code Online (Sandbox Code Playgroud)
现在他们可以正常工作(无需立即推送)。
| 归档时间: |
|
| 查看次数: |
771 次 |
| 最近记录: |