开发者

Git ref master now empty, how to recover?

I'm not entirely sure what happened, but for some reason my git repository's master ref file is now empty. We're hosting the repository on Dropbox, so maybe it has to do with that..but now I can't pull from it. It says this:

Your configuration specifies to merge with the ref 'master' from the remote, but no such ref was fetched.

Dropbox keeps versions of files, so if I go back to the previous version of 'master' it says:

fatal: object 2d154f82e59a41开发者_运维问答56a5d3ea04a0617c243ae6dc3a is corrupted
fatal: The remote end hung up unexpectedly

How do I recover from this?


Sigh.

I like Dropbox, but I would never recommend it for “hosting” Git repositories. Its synchronization works well enough for single-file documents, but it does not come close to providing the distributed/remote filesystem semantics that would be required for safe hosting of a Git repository.

Hopefully you are just “hosting” a bare Git repository on Dropbox. If so, you should be able to cobble together the commits and references from your non-bare (working) repositories. It should also be possible to manually recover your existing repository, but you will likely end up needing to copy objects from your other repositories anyway, so you might as well do it the following “high level” way (instead of going “low level” and dealing with copying objects from other repositories (or copying pack files and unpacking parts of them)).

Start by making an independent clone of one of your working directories.

git clone file://path/to/myrepo /path/to/myrepo-recovery-work

Import the refs and objects from your other working repositories.

# If you have network access to the other repositories:
cd /path/to/myrepo-recovery-work
git remote add other1 user@machine:path/to/other/working-repo-1
git remote add other2 ssh://user@machine/path/to/other/working-repo-2
# etc.
git fetch --all


# If you do not have network access:
cd /path/to/other/working-repo-1 &&  # on machine with working-repo-1
  git bundle create /path/to/other1.gitbundle --all HEAD
cd /path/to/other/working-repo-2 &&  # on machine with working-repo-2
  git bundle create /path/to/other2.gitbundle --all HEAD
# etc.
# Transfer the bundle files to the machine that has "myrepo-recovery-work"
# (Dropbox is OK to copy the bundles, they are just single files),
# then on that machine:
cd /path/to/myrepo-recovery-work
git remote add other1 /path/to/transferred/other1.gitbundle
git remote add other2 /path/to/transferred/other2.gitbundle
# etc.
git fetch --all

Then, look through all the branches on your new remotes and determine which branches should point to which commits for your rebuilt central repository.

git log --oneline --graph --decorate --abbrev-commit --all
# In addition to looking at the history graph, you might need to examine
# the content of certain commits. Just check them out as a detached HEADs.
git branch recovered/maintenance decafbad
git branch recovered/master cafebabe
git branch recovered/development deadbeef
git branch recovered/bug-1234 8badf00d

The create and push your recovered branches (and tags) to a new bare repository.

git init --bare /path/to/new-central-bare-repo.git # or real Git hosting service!
git remote add new /path/to/new-central-bare-repo.git
git push --tags new 'refs/heads/recovered/*:refs/heads/*'
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜