Re: "git-send-pack"
From: Linus Torvalds <torvalds@osdl.org>
Date: 2016-06-15 22:42:01
On Thu, 30 Jun 2005, Daniel Barkalow wrote:
I suspect that I'll be able to merge send-pack/receive-pack with ssh-push/ssh-pull this evening, and then it'll have the feature of not caring too much which side your command line is on.
The simple thing to do is to just get one commit at a time, see if you have it already, parse if it not, and go on to the parents. That would fit the current git-pull thing, and may be good enough, but it has the downside that it can need a _lot_ of back-and-forth fecthing of commit objects from the other side until you find the one you want. That's going to be _very_ slow over a high-latency connection. So what I'd suggest is: - puller starts by just asking "what's your SHA1 for the ref I want" The puller wants to know this, because a common case may be that it already has it, in which case it doesn't need to do anything. But more importantly, the puller will need to know this anyway if it gets an object-pack, so that the puller can update it's FETCH_HEAD. - if puller doesn't have it, then the _puller_ does: "git-rev-list my-current-refs" to generate an in-date-order list of commits it has, and it starts feeding the result in chunks of 100 entries or something to the other end. - now, the server sees this stream of SHA1's that the client wants, and it can very cheaply just test "do I have this SHA1". Now, if the client hasn't made any changes at all, then the first one will be a hit, and we already have sufficient knowledge to tell what the difference between the client and the server is. But more importantly, even if the client _has_ made changes, the client likely has more available CPU than the server has, _and_ the client likely has a shorter list of changes than the server has, so it's really the client that should do this. We should burden the server as lightly as possible for this to scale. - At some point the server sees the first SHA1 it recognizes, and at that point the server will have to start working. It will just send back an "ok, got it" message (telling the client to not bother continuing to send it any more commit ID's), and then does git-rev-list --objects ref-client-wants ^first-common-sha1 | git-pack-objects --stdout - the client just unpacks the objects, and if successful, it puts the new top ref it got into FETCH_HEAD. It's now done. And I do _not_ think that it makes a lot of sense to try to be symmetric. For one thing, while a "git-send-pack" should update all the refs in-place, a "git-pull-pack" should _not_ update the ref, it should just set FETCH_HEAD instead and the puller can decide what he wants to do with that ref (possibly merge it, but possibly just make it be a new local branch "remote-branch"). So I think sending and receiving are fundamentally non-symmetric. Linus