threads / discuss / 27896

Is there a quick way to identify commits that reference missing trees or blobs?

Subject: Is there a quick way to identify commits that reference missing trees or blobs?

## tl;dr

5 messages between Jul 23, 2011 and Jul 26, 2011.

replies: 4people: 2as markdown or json

Jon Seymour· Jul 23, 2011, 16:48 UTC · lore

I was wondering if there is a quick way to identify commits that reference missing trees or blobs as identified by git fsck?

This would be quite useful in situations where one is trying to salvage as much history as possible from a damaged repository.

jon.
Clemens Buchacher· Jul 25, 2011, 22:34 UTC · re: Jon Seymour · lore

Re: Is there a quick way to identify commits that reference missing trees or blobs?

On Sun, Jul 24, 2011 at 02:48:20AM +1000, Jon Seymour wrote:
>
> I was wondering if there is a quick way to identify commits that
> reference missing trees or blobs as identified by git fsck?

The following command has served me well for this purpose. I apply it to each ref in git-for-each-ref:

$ git rev-list --objects $ref | git cat-file --batch-check

It may not be the fastest way to do it, but it did the trick for me. I then simply deleted any broken refs using git update-ref -d $ref, even if the tip of the branch was still intact. I could have tried to salvage some history from those refs, but I had a backup and at that point I just wanted to continue working.

hth, Clemens

Clemens Buchacher· Jul 25, 2011, 22:44 UTC · re: Clemens Buchacher · lore

Re: Is there a quick way to identify commits that reference missing trees or blobs?

On Tue, Jul 26, 2011 at 12:34:50AM +0200, Clemens Buchacher wrote:
Show 9 quoted lines
> On Sun, Jul 24, 2011 at 02:48:20AM +1000, Jon Seymour wrote:
> >
> > I was wondering if there is a quick way to identify commits that
> > reference missing trees or blobs as identified by git fsck?
> 
> The following command has served me well for this purpose. I apply
> it to each ref in git-for-each-ref:
> 
> $ git rev-list --objects $ref | git cat-file --batch-check

Oh, and here is the output you get for different situations. Exit status is always 0 unfortunately.

 - missing blob

fatal: missing blob object '78981922613b2afb6025042ff6bd878ac1994e85' d165426eba5cb4c125bd6e100d1b5de7298eb601 commit 168 848740929e99bda0e1a9783e7daa314c5a9732d5 missing

 - missing tree

error: Could not read 84bf061d017459b4be45a49b8d8dc945e7a7fdf5 fatal: bad tree object 84bf061d017459b4be45a49b8d8dc945e7a7fdf5 abce3ad54002628ab74d72b7e2baa687abcb77f9 commit 168

 - missing parent commit

error: Could not read 3aa66f30aa9799ac38a53b551ac4faca9cbd400b fatal: Failed to traverse parents of commit 3cfb98a3cbd3f42852e20bd011c7b835b8750df7

Clemens
Jon Seymour· Jul 26, 2011, 01:39 UTC · re: Clemens Buchacher · lore

Re: Is there a quick way to identify commits that reference missing trees or blobs?

On Tue, Jul 26, 2011 at 8:44 AM, Clemens Buchacher <drizzd@aon.at> wrote:
Show 33 quoted lines
> On Tue, Jul 26, 2011 at 12:34:50AM +0200, Clemens Buchacher wrote:
>> On Sun, Jul 24, 2011 at 02:48:20AM +1000, Jon Seymour wrote:
>> >
>> > I was wondering if there is a quick way to identify commits that
>> > reference missing trees or blobs as identified by git fsck?
>>
>> The following command has served me well for this purpose. I apply
>> it to each ref in git-for-each-ref:
>>
>> $ git rev-list --objects $ref | git cat-file --batch-check
>
> Oh, and here is the output you get for different situations. Exit
> status is always 0 unfortunately.
>
>  - missing blob
>
> fatal: missing blob object '78981922613b2afb6025042ff6bd878ac1994e85'
> d165426eba5cb4c125bd6e100d1b5de7298eb601 commit 168
> 848740929e99bda0e1a9783e7daa314c5a9732d5  missing
>
>  - missing tree
>
> error: Could not read 84bf061d017459b4be45a49b8d8dc945e7a7fdf5
> fatal: bad tree object 84bf061d017459b4be45a49b8d8dc945e7a7fdf5
> abce3ad54002628ab74d72b7e2baa687abcb77f9 commit 168
>
>  - missing parent commit
>
> error: Could not read 3aa66f30aa9799ac38a53b551ac4faca9cbd400b
> fatal: Failed to traverse parents of commit 3cfb98a3cbd3f42852e20bd011c7b835b8750df7
>
> Clemens
>
Thanks for that.

Junio, also pointed out in another thread that git rev-list --objects is quite useful for this purpose. His variant used git pack-objects which apparently does exit with zero status code. The zero exit code here looks like a bug, I think, so perhaps I will submit a patch for that too (I just did one for git ls-tree).

While concise it isn't a particularly fast way to find commits affected by damaged trees - it is O(N^2*M), where N is the number of commits and M is the size of the tree. As indicated in another thread, I think bisection can potentially be O(K * log(N) * M + K*N), where K is the number of fully connected bad subgraphs. [ by that I mean a subgraph consisting only of commits with damaged trees).

jon.
Jon Seymour· Jul 26, 2011, 04:20 UTC · re: Jon Seymour · lore

Re: Is there a quick way to identify commits that reference missing trees or blobs?

On Tue, Jul 26, 2011 at 11:39 AM, Jon Seymour <jon.seymour@gmail.com> wrote:
Show 40 quoted lines
> On Tue, Jul 26, 2011 at 8:44 AM, Clemens Buchacher <drizzd@aon.at> wrote:
>> On Tue, Jul 26, 2011 at 12:34:50AM +0200, Clemens Buchacher wrote:
>>> On Sun, Jul 24, 2011 at 02:48:20AM +1000, Jon Seymour wrote:
>>> >
>>> > I was wondering if there is a quick way to identify commits that
>>> > reference missing trees or blobs as identified by git fsck?
>>>
>>> The following command has served me well for this purpose. I apply
>>> it to each ref in git-for-each-ref:
>>>
>>> $ git rev-list --objects $ref | git cat-file --batch-check
>>
>> Oh, and here is the output you get for different situations. Exit
>> status is always 0 unfortunately.
>>
>>  - missing blob
>>
>> fatal: missing blob object '78981922613b2afb6025042ff6bd878ac1994e85'
>> d165426eba5cb4c125bd6e100d1b5de7298eb601 commit 168
>> 848740929e99bda0e1a9783e7daa314c5a9732d5  missing
>>
>>  - missing tree
>>
>> error: Could not read 84bf061d017459b4be45a49b8d8dc945e7a7fdf5
>> fatal: bad tree object 84bf061d017459b4be45a49b8d8dc945e7a7fdf5
>> abce3ad54002628ab74d72b7e2baa687abcb77f9 commit 168
>>
>>  - missing parent commit
>>
>> error: Could not read 3aa66f30aa9799ac38a53b551ac4faca9cbd400b
>> fatal: Failed to traverse parents of commit 3cfb98a3cbd3f42852e20bd011c7b835b8750df7
>>
>> Clemens
>>
>
> Thanks for that.
>
> Junio, also pointed out in another thread that git rev-list --objects
> is quite useful for this purpose. His variant used git pack-objects
> which apparently does exit with zero status code.
| _non-zero_ !

← back to recent threads