Reputation: 803
I'd like that git prints me all unreachable objects, not considering commits that are only reachable by reflog entries as reachable. git fsck --unreachable --no-reflogs
misses to print a tree object which I know is unreachable. I am using git version 2.5.0. Am I missing something?
The following is a proof that there are unreachable tree objects which fsck does not print.
$ git init
Initialized empty Git repository in /somepath/.git/
$ echo hello >myfile
$ git add myfile
$ git commit -m initial
[master (root-commit) 30a7654] initial
1 file changed, 1 insertion(+)
create mode 100644 myfile
$ echo world >>myfile
The following commit creates three objects: a commit, a tree and a blob:
$ git commit -am 2nd
[master 4b96227] 2nd
1 file changed, 1 insertion(+)
We make these three objects unreachable. fsck
only reports the commit and the blob object as unreachable, but not the tree object:
$ git reset --hard HEAD^
HEAD is now at 30a7654 initial
$ git fsck --unreachable --no-reflogs
Checking object directories: 100% (256/256), done.
unreachable commit 4b96227ebf01b6947dd5710b6494f5e92cd62d49
unreachable blob 94954abda49de8615a048f8d2e64b5de848e27a1
prune
does report all three object as unreachable, including the tree object:
$ git reflog expire --expire=all --all
$ git prune --expire now -vn
1df502bff6e2a54e686a0a5eb4033fb6cd160ba1 tree
4b96227ebf01b6947dd5710b6494f5e92cd62d49 commit
94954abda49de8615a048f8d2e64b5de848e27a1 blob
Upvotes: 2
Views: 779
Reputation: 488183
You are correct that git fsck
fails to report unreachable trees. You can create additional unreachable trees using git write-tree
with an index that you do not commit (e.g., git add
something, then git rm --cached
the same entry after writing the tree; or use git update-index
to manipulate the index more directly before and after using git write-tree
).
I think the Git folks consider this a feature rather than a bug, on the theory that no one cares about trees.
Note that the documentation describes the --lost-found
flag as restoring dangling commits and blobs. It also (experimentally) restores annotated tag objects that are delinked from their external refs/tags/
reference, but when it does so it just writes the object name into the file name in .git/lost-found/other/
:
$ cat .git/lost-found/other/9c6db16bcff193bd5a814ce5bcda40027713ed8a
9c6db16bcff193bd5a814ce5bcda40027713ed8a
$ git cat-file -t 9c6db16bcff193bd5a814ce5bcda40027713ed8a
tag
It would make more sense to expand the contents of the tag object, the way Git does for blob objects. Git could even do this for trees, but just as --unreachable
ignores them, so does --lost-found
.
Upvotes: 2