1

cp -a gitrepo1/ gitrepo2/在 Mac 中执行,似乎文件和目录包含.git/被复制到 gitrepo2/,我该如何恢复 gitrepo2?

4

1 回答 1

6

复制操作不应该覆盖旧对象——这就是散列对象名称的意义;他们是独一无二的!也许你只有一个主分支,所以你已经覆盖了这个.git/refs/heads/master分支和你的.git/HEAD文件。这只是意味着您想要的提交不再是被引用的提交链的一部分。这意味着您丢失的提交是无法访问的。因此,我们可以找到无法访问的提交:

git fsck --unreachable | grep commits | cut -d' ' -3

这应该为您提供一个列表,其中列出了不在分支的祖先(包括)或标记提交中的所有提交。此时你可以做各种事情。例如,您可以将所有这些粘合在一起并将它们发送到 gitk 以可视化所有这些疯狂的图表。但是,如果您只有一个 master 分支,那么事情就很容易了。我们只需要获取所有这些“丢失”的提交,按提交时间对它们进行排序(如果提交已通过cherry-pick 或 rebase 重新排序,则作者时间将不太有用),并查看最后的提交名单:

git fsck --unreachable | cut -d' ' -f3 | while read c; do git log -1 --format='%ct %H %s' $c; done | sort

这将是两个 repos 的提交的混合,但这些消息应该会有所帮助。一旦你 [希望] 找到旧的头,获取它的哈希号并且(假设你在 master 上并且想要将旧的 master 恢复到它的正确位置):

git reset --hard <hash>

应该这样做!我不是 100% 确定git fsck --unreachable真的,真的显示了所有提交(值得一试,即使他们在谈论对象,而不是提交)。还有git fsck --full,它应该找到没有父母的提交,但我更不相信它可以从两个单独的原始源代码库中找到提交。不过,我认为这些想法是合理的,所以如果这没有找到旧的头,那么我首先会寻找一种更好的方法来跟踪对象文件夹和任何包文件中的每一个提交.

于 2013-05-09T05:02:46.293 回答