From: Junio C Hamano Date: Wed, 19 Oct 2005 08:52:19 GMT Subject: Re: cg-clone, tag objects and cg-push/git-push don't play nice Message-ID: <7vbr1ldh30.fsf@assigned-by-dhcp.cox.net> In-Reply-To: <46a038f90510190110g53c90c5t419ad6065292269e@mail.gmail.com> Martin Langhoff 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.