1

I exec cp -a gitrepo1/ gitrepo2/ in Mac, it seems files and dirs include .git/ are copied into gitrepo2/, how can I restore gitrepo2?

apaderno
  • 28,547
  • 16
  • 75
  • 90
nfpyfzyf
  • 2,891
  • 6
  • 26
  • 30

1 Answers1

6

The copy action shouldn't have overwritten the old objects - that's the point of hashed object names; they're unique! Maybe you just had a master branch, and so you've overwritten the .git/refs/heads/master branch and your .git/HEAD file. That just means the commits you want are no longer part of a referred-to chain of commits. That means the commits you lost are unreachable. We can find unreachable commits thus:

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

That should give you a list of all the commits that aren't in the ancestry (inclusive) of a branch, or tagged commit. You can do various things at this point. For example, you can glue all of these together and send them to gitk to visualize the crazy graph of all of them. If you just have a single master branch, though, things can be pretty easy. We just need to take all of these 'lost' commits, sort them by commit time (author time would be less helpful if commits had been reordered via cherry-pick or rebasing), and look at the commit(s) at the end of the list:

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

This will be a mix of two repos' worth of commits, but the messages should help. Once you [hopefully] find the old head, get its hash number and (presuming you're on master and want to restore the old master to its rightful place):

git reset --hard <hash>

That should do it! I'm not 100% sure that git fsck --unreachable really, truly shows all commits (this is worth a scan, even though they're talking about objects, not commits). There's also git fsck --full, which is supposed to find commits with no parents, but I'm even less trusting of it for finding commits from two separate, original source repos. I think the ideas are sound, though, so if this doesn't find the old head(s), then I'd look first at a better method of tracking down every single commit in the objects folder and any pack file(s).

Community
  • 1
  • 1
Gary Fixler
  • 5,632
  • 2
  • 23
  • 39