* cg-clone, tag objects and cg-push/git-push don't play nice
@ 2005-10-19 6:38 Martin Langhoff
2005-10-19 7:16 ` Junio C Hamano
0 siblings, 1 reply; 5+ messages in thread
From: Martin Langhoff @ 2005-10-19 6:38 UTC (permalink / raw)
To: Git Mailing List
I am seeing very strange issues with cloning one head with cg-clone
from a repo that holds many heads and tags. The session looks like
this:
cg-clone git+ssh://locke.catalyst.net.nz/var/git/moodle-test.git#mdl-topnz
testdir
cd testdir
echo "sillychange" >> version.php
cg-commit -m "testing" version.php
cg-push
updating 'refs/heads/mdl-topnz' using 'refs/heads/master'
from 06ca8b3c4826d60e8cf5850c6474e66f816ba5c7
to 482d4b88aa482dfea7f7549470902049a050020a
fatal: bad object 1b0efdd8f31e5b8c7d32c85d11492db122b62a0a
Packing 0 objects
Unpacking 0 objects
error: unpack should have generated
482d4b88aa482dfea7f7549470902049a050020a, but I can't find it!
I get the same error if I try git-push manually. Apparently, there's a
set of tag objects pointing nowhere.
git-fsck-objects --full --strict 482d4b88aa482dfea7f7549470902049a050020a
bad sha1 file: .git/objects/44/7472d455667e426a96acf116e27c2f1efe674e
3ae8dc25c642d8c59f3c44c5ba48faa6a0e7a2ee
2ddfec0dfd0cffd4892af9aaf48ee29c40c7ada3
missing commit 1b0efdd8f31e5b8c7d32c85d11492db122b62a0a
dangling commit 3e9472b3ef980e667d00d5374ccfa741cfb93fbc
broken link from tag 447472d455667e426a96acf116e27c2f1efe674e
to commit 1b0efdd8f31e5b8c7d32c85d11492db122b62a0a
dangling tag 447472d455667e426a96acf116e27c2f1efe674e
missing commit 5a0bdfb0f7af34d002c6ced40f96f977fd6471e2
dangling commit 715b3b0a7c94cb31760e87a320f0f612b962e3c3
missing commit 961bf469c6b309b8fc10d064368fd14480d231be
broken link from tag 984bed44df42422839705aa4bd6d8f00086b1307
to commit 961bf469c6b309b8fc10d064368fd14480d231be
dangling tag 984bed44df42422839705aa4bd6d8f00086b1307
broken link from tag ce3602d6a60c648402048b0970657a2961e1ed54
to commit dd8c6c172fbab9905dd306c17d83b8d21ea5bfda
dangling tag ce3602d6a60c648402048b0970657a2961e1ed54
missing commit dd8c6c172fbab9905dd306c17d83b8d21ea5bfda
broken link from tag ddb658d070ba6688541e5b91e963f629ddd63b6a
to commit 5a0bdfb0f7af34d002c6ced40f96f977fd6471e2
dangling tag ddb658d070ba6688541e5b91e963f629ddd63b6a
Now, if I go to the repository, it _has_ all the tags with their
matching commits. So the problem is in the cloned repo. It looks like:
+ cg-clone (cg-fetch actually) has brought in all the tag refs and
objects, regardless of whether they are relevant to this branch, but
did not fetch the commits, trees, or any other related bits and
pieces.
+ git-push is trying to walk all the refs it knows about when it does
the "what do I have that the repo doesn't" part, and it breaks on
those incomplete tag fetches.
Removing .git/refs/tags/* didn't help. If I actually rm all the
problematic tag objects from the object repository, I can then push
correctly. Lucky it wasn't packed.
I am going to write a quick'n'dirty script to fix our repos when this
happens, and I'll try my hand at a patch to cg-fetch. Can git-push be
taught to be smarter in these cases?
regards,
martin
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: cg-clone, tag objects and cg-push/git-push don't play nice
2005-10-19 6:38 cg-clone, tag objects and cg-push/git-push don't play nice Martin Langhoff
@ 2005-10-19 7:16 ` Junio C Hamano
2005-10-19 8:10 ` Martin Langhoff
0 siblings, 1 reply; 5+ messages in thread
From: Junio C Hamano @ 2005-10-19 7:16 UTC (permalink / raw)
To: Martin Langhoff; +Cc: git
Martin Langhoff <martin.langhoff@gmail.com> writes:
> + git-push is trying to walk all the refs it knows about when it does
> the "what do I have that the repo doesn't" part, and it breaks on
> those incomplete tag fetches.
That is expected.
> Removing .git/refs/tags/* didn't help. If I actually rm all the
> problematic tag objects from the object repository, I can then push
> correctly. Lucky it wasn't packed.
>
> I am going to write a quick'n'dirty script to fix our repos when this
> happens, and I'll try my hand at a patch to cg-fetch. Can git-push be
> taught to be smarter in these cases?
Although I do not follow Cogito development closely, I seem to
recall that it fetched tags without making them complete at some
point in the past; I hope it is now fixed but I am not sure.
I cannot think offhand of a way how git-push could help to cope
with a repository broken that way. However, we could probably
have a tool that tangles from each ref, find incomplete ones and
remove them from .git/refs. After running that maybe pull from
a know good copy would fix the broken repository.
I do not understand why removing .git/refs/tags/* did not help,
and that is the biggest thing that disturbs me in this whole
problem report. We (meaning git-* transfer, not cg-* transfer
whose correctness I cannot vouch for) _should_ be relying only
on refs not object existence. Maybe there are some other files
under .git/refs/ directory that had copies of them?
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: cg-clone, tag objects and cg-push/git-push don't play nice
2005-10-19 7:16 ` Junio C Hamano
@ 2005-10-19 8:10 ` Martin Langhoff
2005-10-19 8:52 ` Junio C Hamano
0 siblings, 1 reply; 5+ messages in thread
From: Martin Langhoff @ 2005-10-19 8:10 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
On 10/19/05, Junio C Hamano <junkio@cox.net> wrote:
> Martin Langhoff <martin.langhoff@gmail.com> writes:
>
> > + git-push is trying to walk all the refs it knows about when it does
> > the "what do I have that the repo doesn't" part, and it breaks on
> > those incomplete tag fetches.
>
> That is expected.
Hmmm. I was under the impression that if I call git-push naming a
particular head, it could restrict itself to the stuff needed for that
head only. Just to clarify, I'm running
git-push locke.catalyst.net.nz:/var/git/moodle-test.git master:mdl-topnz-prod
> Although I do not follow Cogito development closely, I seem to
> recall that it fetched tags without making them complete at some
> point in the past; I hope it is now fixed but I am not sure.
It isn't fixed, but I'm trying to address that one :-p
> I do not understand why removing .git/refs/tags/* did not help,
> and that is the biggest thing that disturbs me in this whole
> problem report
I can't understand that either, but I manually removed all the
refs/tags, and the only heads I have are origin and master. git-push
won't let me do it until the exact point where I have removed the
object from the repo. And that's only possible on unpacked repos.
> Maybe there are some other files
> under .git/refs/ directory that had copies of them?
No. I run a test again, to make sure. Removing .git/refs/tags is not
enough, and the only refs available are origin and master.
I've come up with this awful script to resolve it, while I try to fix cg-fetch:
#usr/bin/perl -w
use strict;
my @refs = `ls .git/refs/tags`;
foreach my $ref (@refs) {
chomp $ref;
print "testing for a commit linked from $ref\n";
my $commit = `git-rev-parse --verify "$ref"^{commit} 2>/dev/null`;
if ($?) {
# this one didn't even have a tag ref pointing to a commit!
#unlink ".git/refs/tags/$ref"
# or die "cannot remove .git/refs/tags/$ref";
#next;
}
# thest that we actually have the commit object...
chomp $commit;
my $file = `git-cat-file commit $commit 2>/dev/null`;
if ($?) {
# could not find the commit object, we better get rid of the
# tagref and tagobj
my $tagsha = `git-rev-parse --verify "$ref" 2>/dev/null`;
chomp $tagsha;
if ($tagsha) {
# doublecheck it is a tag
my $type = `git-cat-file -t $tagsha 2>/dev/null`;
chomp $type;
if ($type eq 'tag') {
my $fileobj = ".git/objects/" . substr($tagsha,0,2) . '/' .
substr($tagsha,2);
print " removing $fileobj for ref $ref tagsha $tagsha \n";
`rm -f $fileobj`;
unlink ".git/refs/tags/$ref";
}
}
}
}
cheers,
m
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: cg-clone, tag objects and cg-push/git-push don't play nice
2005-10-19 8:10 ` Martin Langhoff
@ 2005-10-19 8:52 ` Junio C Hamano
2005-10-19 9:06 ` Martin Langhoff
0 siblings, 1 reply; 5+ messages in thread
From: Junio C Hamano @ 2005-10-19 8:52 UTC (permalink / raw)
To: Martin Langhoff; +Cc: git
Martin Langhoff <martin.langhoff@gmail.com> writes:
>> That is expected.
>
> Hmmm. I was under the impression that if I call git-push naming a
> particular head, it could restrict itself to the stuff needed for that
> head only. Just to clarify, I'm running
>
> git-push locke.catalyst.net.nz:/var/git/moodle-test.git master:mdl-topnz-prod
Yeah. But the problem is that the repository on the other end
claims that it has everything reachable from those incomplete
tags. Hearing that, git-push (the real name of it is send-pack)
decides not to send things that are already reachable from the
refs the other end claims to have. So if an incomplete tag
refers to a commit that contains a blob that the remote actually
does not have, and if that blob is part of the head you are
pushing, send-pack would not (and should not) send that blob to
the remote.
>> I do not understand why removing .git/refs/tags/* did not help,
>> and that is the biggest thing that disturbs me in this whole
>> problem report
>
> I can't understand that either, but I manually removed all the
> refs/tags, and the only heads I have are origin and master. git-push
> won't let me do it until the exact point where I have removed the
> object from the repo. And that's only possible on unpacked repos.
Hmph. It worries me even more.
This error message:
error: unpack should have generated
482d4b88aa482dfea7f7549470902049a050020a, but I can't find it!
comes from receive-pack that runs on the other repo (i.e. the
one with incomplete tags you just removed), so it means
send-pack decided it does not need to send that object --
meaning the other end claimed it already has it. What to send
and what need not to be sent is determined solely based on what
send-pack hears from receive-pack in the initial handshake,
which is in receive-pack.c::write_head_info(). It scans
everything under ".git/refs" directory (not just .git/refs/heads
or .git/refs/tags; if you had ".git/refs/FOOBAR", it will cause
the remote end to claim it has everything reachable from it --
the only exceptions are things that starts with a dot '.', which
is probably why cg-fetch places a temporary heads in
refs/*/.$name-fetching) and sends them -- it does not look at
the object directory and magically claim it has something that
is not recorded in its .git/refs/ directory.
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: cg-clone, tag objects and cg-push/git-push don't play nice
2005-10-19 8:52 ` Junio C Hamano
@ 2005-10-19 9:06 ` Martin Langhoff
0 siblings, 0 replies; 5+ messages in thread
From: Martin Langhoff @ 2005-10-19 9:06 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
On 10/19/05, Junio C Hamano <junkio@cox.net> wrote:
> Yeah. But the problem is that the repository on the other end
> claims that it has everything reachable from those incomplete
> tags.
It definitely does.
> Hearing that, git-push (the real name of it is send-pack)
> decides not to send things that are already reachable from the
> refs the other end claims to have. So if an incomplete tag
> refers to a commit that contains a blob that the remote actually
> does not have, and if that blob is part of the head you are
> pushing, send-pack would not (and should not) send that blob to
> the remote.
*shrug* it's a bit over my head, but I've figured out taht
git-fetch-pack is segfaulting. Perhaps that helps?
> Hmph. It worries me even more.
>
> This error message:
>
> error: unpack should have generated
> 482d4b88aa482dfea7f7549470902049a050020a, but I can't find it!
>
> comes from receive-pack that runs on the other repo (i.e. the
> one with incomplete tags you just removed), so it means
> send-pack decided it does not need to send that object --
> meaning the other end claimed it already has it. What to send
> and what need not to be sent is determined solely based on what
> send-pack hears from receive-pack in the initial handshake,
> which is in receive-pack.c::write_head_info(). It scans
> everything under ".git/refs" directory (not just .git/refs/heads
> or .git/refs/tags; if you had ".git/refs/FOOBAR", it will cause
> the remote end to claim it has everything reachable from it --
> the only exceptions are things that starts with a dot '.', which
> is probably why cg-fetch places a temporary heads in
> refs/*/.$name-fetching) and sends them -- it does not look at
> the object directory and magically claim it has something that
> is not recorded in its .git/refs/ directory.
*Very* strange. The remote repo is packed, but is working well for
everyone else. I think we should follow the segfault and see where it
leads...
cheers,
m
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2005-10-19 9:06 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-10-19 6:38 cg-clone, tag objects and cg-push/git-push don't play nice Martin Langhoff
2005-10-19 7:16 ` Junio C Hamano
2005-10-19 8:10 ` Martin Langhoff
2005-10-19 8:52 ` Junio C Hamano
2005-10-19 9:06 ` Martin Langhoff
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox