Recover once staged but not committed files?

后端 未结 1 660
囚心锁ツ
囚心锁ツ 2021-01-22 03:08

I\'ve initialized git repo in existing project, staged all files and then without making initial commit decided to cleanup the index. Not sure why I thought it was a good idea,

相关标签:
1条回答
  • 2021-01-22 03:56

    If you did a git add to stage the files before the git reset, then all the files, and the tree objects describing the directory hierarchy are in your object data base .git/objects, unless it's been long enough that garbage collection has kicked in, or you've run something like git gc on your own. However, reconstructing things is going to take a bit of work - git doesn't come pre-packaged with this functionality built in. Here's some hints:

    1. Use git cat-file -t HASH on each object in your database to identify the types of each object. Look for the ones that are tree objects. Note the object hashes are split to name the files in .git/objects. So an object with hash "db6689df4f8aae84d35df2e496158b2746bb0f1e" is actually stored at .git/objects/db/6689df4f8aae84d35df2e496158b2746bb0f1e, with the first two characters used as a subdirectory - you can reconstruct the object hashes easily with that in mind. If you have files in .git/objects/pack, then you might need to additionally run git verify-pack -v .git/objects/pack/pack-HASH.pack to get the list of objects contained in each pack file.
    2. For each tree object, use git cat-file -p HASH to find the original file name and hash for your files (also known as "blobs"). One of these trees will match what the root of your working directory looked like. Once you've identified your root tree object, you can
    3. run git ls-tree -r HASH to get a full list of all the file names and their respective hashes.
    4. For each file that you want to restore from the above list, you can run git show HASH > FILENAME to recreate the file - you will need to create the subdirectories by hand, though, first.

    With that information, it shouldn't be too difficult to write a script that does the heavy lifting for you. Good luck!

    EDIT: alternatively, once you've identified your root tree object, you can simply echo "commit for recovery" | git commit-tree HASH, which will create a commit and report to you the hash of that new commit. Then you can git checkout HASH to get the files back in the working directory, and git branch BRANCHNAME to create a branch pointing to that commit. You might also take a look at git tar-tree, if your version of git is old enough, or git archive.

    0 讨论(0)
提交回复
热议问题