Thread (24 messages) flat view 24 messages, 8 authors, 2016-06-15

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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help