diff options
Diffstat (limited to 'Documentation/technical/pack-protocol.txt')
-rw-r--r-- | Documentation/technical/pack-protocol.txt | 130 |
1 files changed, 91 insertions, 39 deletions
diff --git a/Documentation/technical/pack-protocol.txt b/Documentation/technical/pack-protocol.txt index 7950eeeda4..546980c0a4 100644 --- a/Documentation/technical/pack-protocol.txt +++ b/Documentation/technical/pack-protocol.txt @@ -36,7 +36,7 @@ Git Transport The Git transport starts off by sending the command and repository on the wire using the pkt-line format, followed by a NUL byte and a -hostname paramater, terminated by a NUL byte. +hostname parameter, terminated by a NUL byte. 0032git-upload-pack /project.git\0host=myserver.com\0 @@ -60,6 +60,13 @@ process on the server side over the Git protocol is this: "0039git-upload-pack /schacon/gitbook.git\0host=example.com\0" | nc -v example.com 9418 +If the server refuses the request for some reasons, it could abort +gracefully with an error message. + +---- + error-line = PKT-LINE("ERR" SP explanation-text) +---- + SSH Transport ------------- @@ -149,7 +156,7 @@ advertisement list at all, but other refs may still appear. The stream MUST include capability declarations behind a NUL on the first ref. The peeled value of a ref (that is "ref^{}") MUST be immediately after the ref itself, if presented. A conforming server -MUST peel the ref if its an annotated tag. +MUST peel the ref if it's an annotated tag. ---- advertised-refs = (no-refs / list-of-refs) @@ -179,34 +186,36 @@ and descriptions. Packfile Negotiation -------------------- -After reference and capabilities discovery, the client can decide -to terminate the connection by sending a flush-pkt, telling the -server it can now gracefully terminate (as happens with the ls-remote -command) or it can enter the negotiation phase, where the client and -server determine what the minimal packfile necessary for transport is. - -Once the client has the initial list of references that the server -has, as well as the list of capabilities, it will begin telling the -server what objects it wants and what objects it has, so the server -can make a packfile that only contains the objects that the client needs. -The client will also send a list of the capabilities it wants to be in -effect, out of what the server said it could do with the first 'want' line. +After reference and capabilities discovery, the client can decide to +terminate the connection by sending a flush-pkt, telling the server it can +now gracefully terminate, and disconnect, when it does not need any pack +data. This can happen with the ls-remote command, and also can happen when +the client already is up-to-date. + +Otherwise, it enters the negotiation phase, where the client and +server determine what the minimal packfile necessary for transport is, +by telling the server what objects it wants, its shallow objects +(if any), and the maximum commit depth it wants (if any). The client +will also send a list of the capabilities it wants to be in effect, +out of what the server said it could do with the first 'want' line. ---- upload-request = want-list - have-list - compute-end + *shallow-line + *1depth-request + flush-pkt want-list = first-want *additional-want - flush-pkt + + shallow-line = PKT_LINE("shallow" SP obj-id) + + depth-request = PKT_LINE("deepen" SP depth) first-want = PKT-LINE("want" SP obj-id SP capability-list LF) additional-want = PKT-LINE("want" SP obj-id LF) - have-list = *have-line - have-line = PKT-LINE("have" SP obj-id LF) - compute-end = flush-pkt / PKT-LINE("done") + depth = 1*DIGIT ---- Clients MUST send all the obj-ids it wants from the reference @@ -215,21 +224,64 @@ discovery phase as 'want' lines. Clients MUST send at least one obj-id in a 'want' command which did not appear in the response obtained through ref discovery. -If client is requesting a shallow clone, it will now send a 'deepen' -line with the depth it is requesting. +The client MUST write all obj-ids which it only has shallow copies +of (meaning that it does not have the parents of a commit) as +'shallow' lines so that the server is aware of the limitations of +the client's history. Clients MUST NOT mention an obj-id which +it does not know exists on the server. + +The client now sends the maximum commit history depth it wants for +this transaction, which is the number of commits it wants from the +tip of the history, if any, as a 'deepen' line. A depth of 0 is the +same as not making a depth request. The client does not want to receive +any commits beyond this depth, nor objects needed only to complete +those commits. Commits whose parents are not received as a result are +defined as shallow and marked as such in the server. This information +is sent back to the client in the next step. + +Once all the 'want's and 'shallow's (and optional 'deepen') are +transferred, clients MUST send a flush-pkt, to tell the server side +that it is done sending the list. + +Otherwise, if the client sent a positive depth request, the server +will determine which commits will and will not be shallow and +send this information to the client. If the client did not request +a positive depth, this step is skipped. -Once all the "want"s (and optional 'deepen') are transferred, -clients MUST send a flush-pkt. If the client has all the references -on the server, client flushes and disconnects. +---- + shallow-update = *shallow-line + *unshallow-line + flush-pkt + + shallow-line = PKT-LINE("shallow" SP obj-id) + + unshallow-line = PKT-LINE("unshallow" SP obj-id) +---- -TODO: shallow/unshallow response and document the deepen command in the ABNF. +If the client has requested a positive depth, the server will compute +the set of commits which are no deeper than the desired depth, starting +at the client's wants. The server writes 'shallow' lines for each +commit whose parents will not be sent as a result. The server writes +an 'unshallow' line for each commit which the client has indicated is +shallow, but is no longer shallow at the currently requested depth +(that is, its parents will now be sent). The server MUST NOT mark +as unshallow anything which the client has not indicated was shallow. Now the client will send a list of the obj-ids it has using 'have' -lines. In multi_ack mode, the canonical implementation will send up -to 32 of these at a time, then will send a flush-pkt. The canonical -implementation will skip ahead and send the next 32 immediately, -so that there is always a block of 32 "in-flight on the wire" at a -time. +lines, so the server can make a packfile that only contains the objects +that the client needs. In multi_ack mode, the canonical implementation +will send up to 32 of these at a time, then will send a flush-pkt. The +canonical implementation will skip ahead and send the next 32 immediately, +so that there is always a block of 32 "in-flight on the wire" at a time. + +---- + upload-haves = have-list + compute-end + + have-list = *have-line + have-line = PKT-LINE("have" SP obj-id LF) + compute-end = flush-pkt / PKT-LINE("done") +---- If the server reads 'have' lines, it then will respond by ACKing any of the obj-ids the client said it had that the server also has. The @@ -261,7 +313,7 @@ Without either multi_ack or multi_ack_detailed: * upload-pack sends "NAK" on a flush-pkt if no common object has been found yet. If one has been found, and thus an ACK - was already sent, its silent on the flush-pkt. + was already sent, it's silent on the flush-pkt. After the client has gotten enough ACK responses that it can determine that the server has enough information to send an efficient packfile @@ -271,9 +323,9 @@ as common with the server, or the --date-order queue is empty), or the client determines that it wants to give up (in the canonical implementation, this is determined when the client sends 256 'have' lines without getting any of them ACKed by the server - meaning there is nothing in common and -the server should just send all it's objects), then the client will send +the server should just send all of its objects), then the client will send a 'done' command. The 'done' command signals to the server that the client -is ready to receive it's packfile data. +is ready to receive its packfile data. However, the 256 limit *only* turns on in the canonical client implementation if we have received at least one "ACK %s continue" @@ -286,7 +338,7 @@ ACK after 'done' if there is at least one common base and multi_ack or multi_ack_detailed is enabled. The server always sends NAK after 'done' if there is no common base found. -Then the server will start sending it's packfile data. +Then the server will start sending its packfile data. ---- server-response = *ack_multi ack / nak @@ -331,7 +383,7 @@ An incremental update (fetch) response might look like this: C: 0009done\n - S: 003aACK 74730d410fcb6603ace96f1dc55ea6196122532d\n + S: 0031ACK 74730d410fcb6603ace96f1dc55ea6196122532d\n S: [PACKFILE] ---- @@ -488,7 +540,7 @@ An example client/server communication might look like this: C: 0000 C: [PACKDATA] - S: 000aunpack ok\n - S: 0014ok refs/heads/debug\n - S: 0026ng refs/heads/master non-fast-forward\n + S: 000eunpack ok\n + S: 0018ok refs/heads/debug\n + S: 002ang refs/heads/master non-fast-forward\n ---- |