1251881SpeterThis file documents version 2 of the svn protocol.
2251881Speter
3251881Speter1. Syntactic structure
4251881Speter----------------------
5251881Speter
6251881SpeterThe Subversion protocol is specified in terms of the following
7251881Spetersyntactic elements, specified using ABNF [RFC 2234]:
8251881Speter
9251881Speter  item   = word / number / string / list
10251881Speter  word   = ALPHA *(ALPHA / DIGIT / "-") space
11251881Speter  number = 1*DIGIT space
12251881Speter  string = 1*DIGIT ":" *OCTET space
13251881Speter         ; digits give the byte count of the *OCTET portion
14251881Speter  list   = "(" space *item ")" space
15251881Speter  space  = 1*(SP / LF)
16251881Speter
17251881SpeterHere is an example item showing each of the syntactic elements:
18251881Speter
19251881Speter  ( word 22 6:string ( sublist ) )
20251881Speter
21251881SpeterAll items end with mandatory whitespace.  (In the above example, a
22251881Speternewline provides the terminating whitespace for the outer list.)  It
23251881Speteris possible to parse an item without knowing its type in advance.
24251881Speter
25251881SpeterLists are not constrained to contain items of the same type.  Lists
26251881Spetercan be used for tuples, optional tuples, or arrays.  A tuple is a list
27251881Speterexpected to contain a fixed number of items, generally of differing
28251881Spetertypes.  An optional tuple is a list containing either zero or a fixed
29251881Speternumber of items (thus "optional" here does not refer to the list's
30251881Speterpresence or absence, but to the presence or absence of its contents).
31251881SpeterAn array is a list containing zero or more items of the same type.
32251881Speter
33251881SpeterWords are used for enumerated protocol values, while strings are used
34251881Speterfor text or binary data of interest to the Subversion client or
35251881Speterserver.  Words are case-sensitive.
36251881Speter
37251881SpeterFor convenience, this specification will define prototypes for data
38251881Speteritems using a syntax like:
39251881Speter
40251881Speter  example: ( literal ( data:string ... ) )
41251881Speter
42251881SpeterA simple word such as "literal", with no colon, denotes a literal
43251881Speterword.  A choice of words may be given with "|" separating the choices.
44251881Speter"name:type" specifies a parameter with the given type.
45251881Speter
46251881SpeterA type is "word", "number", "string", "list", or the name of another
47251881Speterprototype.  Parentheses denote a tuple, unless the parentheses contain
48251881Speterellipses, in which case the parentheses denote an array containing
49251881Speterzero or more elements matching the prototype preceding the ellipses.
50251881Speter
51251881SpeterIf a tuple has an optional part after the fixed part, a '?' marks
52251881Speterplaces where the tuple is allowed to end.  The following tuple could
53251881Spetercontain one, three, or four or more items:
54251881Speter
55251881Speter  example: ( fixed:string ? opt1:number opt2:string ? opt3:number )
56251881Speter
57251881SpeterBrackets denote an optional tuple; they are equivalent to parentheses
58251881Speterand a leading '?'.  For example, this:
59251881Speter
60251881Speter  example: ( literal (? rev:number ) ( data:string ... ) )
61251881Speter
62251881Spetercan be written more compactly like this:
63251881Speter
64251881Speter  example: ( literal [ rev:number ] ( data:string ... ) )
65251881Speter
66251881SpeterFor extensibility, implementations must treat a list as matching a
67251881Speterprototype's tuple even if the list contains extra elements.  The extra
68251881Speterelements must be ignored.
69251881Speter
70251881SpeterIn some cases, a prototype may need to match two different kinds of
71251881Speterdata items.  This case will be written using "|" to separate the
72251881Speteralternatives; for example:
73251881Speter
74251881Speter  example: ( first-kind rev:number )
75251881Speter         | second-kind
76251881Speter
77251881SpeterThe "command response" prototype is used in several contexts of this
78251881Speterspecification to indicate the success or failure of an operation.  It
79251881Speteris defined as follows:
80251881Speter
81251881Speter  command-response: ( success params:list )
82251881Speter                  | ( failure ( err:error ... ) )
83251881Speter  error: ( apr-err:number message:string file:string line:number )
84251881Speter
85251881SpeterThe interpretation of parameters in a successful command response is
86251881Spetercontext-dependent.
87251881Speter
88251881SpeterURLs and repository paths are represented as strings.  They should be in
89251881Spetercanonical form when sent over the protocol.  However, as a matter of input
90251881Spetervalidation, an implementation should always canonicalize received paths if it
91251881Speterneeds them in canonicalized form.
92251881Speter
93251881Speter2. Connection establishment and protocol setup
94251881Speter----------------------------------------------
95251881Speter
96251881SpeterBy default, the client connects to the server on port 3690.
97251881Speter
98251881SpeterUpon receiving a connection, the server sends a greeting, using a
99251881Spetercommand response whose parameters match the prototype:
100251881Speter
101251881Speter  greeting: ( minver:number maxver:number mechs:list ( cap:word ... ) )
102251881Speter
103251881Speterminver and maxver give the minimum and maximum Subversion protocol
104251881Speterversions supported by the server.  mechs is present for historical
105251881Speterreasons, and is ignored by the client.  The cap values give a list of
106251881Speterserver capabilities (see section 2.1).
107251881Speter
108251881SpeterIf the client does not support a protocol version within the specified
109251881Speterrange, it closes the connection.  Otherwise, the client responds to
110251881Speterthe greeting with an item matching the prototype:
111251881Speter
112251881Speter  response: ( version:number ( cap:word ... ) url:string
113251881Speter              ? ra-client:string ( ? client:string ) )
114251881Speter
115251881Speterversion gives the protocol version selected by the client.  The cap
116251881Spetervalues give a list of client capabilities (see section 2.1).  url
117251881Spetergives the URL the client is accessing.  ra-client is a string
118251881Speteridentifying the RA implementation, e.g. "SVN/1.6.0" or "SVNKit 1.1.4".
119251881Speterclient is the string returned by svn_ra_callbacks2_t.get_client_string;
120251881Speterthat callback may not be implemented, so this is optional.
121251881Speter
122251881SpeterUpon receiving the client's response to the greeting, the server sends
123251881Speteran authentication request, which is a command response whose arguments
124251881Spetermatch the prototype:
125251881Speter
126251881Speter  auth-request: ( ( mech:word ... ) realm:string )
127251881Speter
128251881SpeterThe mech values give a list of SASL mechanisms supported by the
129251881Speterserver.  The realm string is similar to an HTTP authentication realm
130251881Speteras defined in [RFC 2617]; it allows the server to indicate which of
131251881Speterseveral protection spaces the server wishes to authenticate in.  If
132251881Speterthe mechanism list is empty, then no authentication is required and no
133251881Speterfurther action takes place as part of the authentication challenge;
134251881Speterotherwise, the client responds with a tuple matching the prototype:
135251881Speter
136251881Speter  auth-response: ( mech:word [ token:string ] )
137251881Speter
138251881Spetermech specifies the SASL mechanism and token, if present, gives the
139251881Speter"initial response" of the authentication exchange.  The client may
140251881Speterspecify an empty mechanism to decline authentication; otherwise, upon
141251881Speterreceiving the client's auth-response, the server sends a series of
142251881Speterchallenges, each a tuple matching the prototype:
143251881Speter
144251881Speter  challenge: ( step ( token:string ) )
145251881Speter           | ( failure ( message:string ) )
146251881Speter           | ( success [ token:string ] )
147251881Speter
148251881SpeterIf the first word of the challenge is "step", then the token is
149251881Speterinterpreted by the authentication mechanism, and the response token
150251881Spetertransmitted to the server as a string.  The server then proceeds with
151251881Speteranother challenge.  If the client wishes to abort the authentication
152251881Speterexchange, it may do so by closing the connection.
153251881Speter
154251881SpeterIf the first word of the challenge is "success", the authentication is
155251881Spetersuccessful.  If a token is provided, it should be interpreted by the
156251881Speterauthentication mechanism, but there is no response.
157251881Speter
158251881SpeterIf the first word of the challenge is "failure", the authentication
159251881Speterexchange is unsuccessful.  The client may then give up, or make
160251881Speteranother auth-response and restart the authentication process.
161251881Speter
162251881SpeterRFC 2222 requires that a protocol profile define a service name for
163251881Speterthe sake of the GSSAPI mechanism.  The service name for this protocol
164251881Speteris "svn".
165251881Speter
166251881SpeterAfter a successful authentication exchange, the server sends a command
167251881Speterresponse whose parameters match the prototype:
168251881Speter
169251881Speter  repos-info: ( uuid:string repos-url:string ( cap:word ... ) )
170251881Speter
171251881Speteruuid gives the universal unique identifier of the repository,
172251881Speterrepos-url gives the URL of the repository's root directory, and the
173251881Spetercap values list the repository capabilities (that is, capabilities
174251881Speterthat require both server and repository support before the server can
175251881Speterclaim them as capabilities, e.g., SVN_RA_SVN_CAP_MERGEINFO).
176251881Speter
177251881SpeterThe client can now begin sending commands from the main command set.
178251881Speter
179251881Speter2.1 Capabilities
180251881Speter
181251881SpeterThe following capabilities are currently defined (S indicates a server
182251881Spetercapability and C indicates a client capability):
183251881Speter
184251881Speter[CS] edit-pipeline     Every released version of Subversion since 1.0
185251881Speter                       announces the edit-pipeline capability; starting
186251881Speter                       in Subversion 1.5, both client and server
187251881Speter                       *require* the other side to announce edit-pipeline.
188251881Speter[CS] svndiff1          If both the client and server support svndiff version
189251881Speter                       1, this will be used as the on-the-wire format for 
190251881Speter                       svndiff instead of svndiff version 0.
191251881Speter[CS] absent-entries    If the remote end announces support for this capability,
192251881Speter                       it will accept the absent-dir and absent-file editor
193251881Speter                       commands.
194251881Speter[S]  commit-revprops   If the server presents this capability, it supports the 
195251881Speter                       rev-props parameter of the commit command.
196251881Speter                       See section 3.1.1.
197251881Speter[S]  mergeinfo         If the server presents this capability, it supports the 
198251881Speter                       get-mergeinfo command.  See section 3.1.1.
199251881Speter[S]  depth             If the server presents this capability, it understands
200251881Speter                       requested operational depth (see section 3.1.1) and
201251881Speter                       per-path ambient depth (see section 3.1.3).
202251881Speter[S]  atomic-revprops   If the server presents this capability, it
203251881Speter                       supports the change-rev-prop2 command.
204251881Speter                       See section 3.1.1.
205251881Speter[S]  inherited-props   If the server presents this capability, it supports the
206251881Speter                       retrieval of inherited properties via the get-dir and
207251881Speter                       get-file commands and also supports the get-iprops
208251881Speter                       command (see section 3.1.1).
209251881Speter
210251881Speter3. Commands
211251881Speter-----------
212251881Speter
213251881SpeterCommands match the prototypes:
214251881Speter
215251881Speter  command: ( command-name:word params:list )
216251881Speter
217251881SpeterThe interpretation of command parameters is different from command to
218251881Spetercommand.
219251881Speter
220251881SpeterInitially, the client initiates commands from the main command set,
221251881Speterand the server responds.  Some commands in the main command set can
222251881Spetertemporarily change the set of commands which may be issued, or change
223251881Speterthe flow of control so that the server issues commands and the client
224251881Speterresponds.
225251881Speter
226251881SpeterHere are some miscellaneous prototypes used by the command sets:
227251881Speter
228251881Speter  proplist:  ( ( name:string value:string ) ... )
229251881Speter  iproplist: ( ( name:string proplist ) ... )
230251881Speter  propdelta: ( ( name:string [ value:string ] ) ... )
231251881Speter  node-kind: none|file|dir|unknown
232251881Speter  bool:      true|false
233251881Speter  lockdesc:  ( path:string token:string owner:string [ comment:string ]
234251881Speter               created:string [ expires:string ] )
235251881Speter
236251881Speter3.1. Command Sets
237251881Speter
238251881SpeterThere are three command sets: the main command set, the editor command
239251881Speterset, and the report command set.  Initially, the protocol begins in
240251881Speterthe main command set with the client sending commands; some commands
241251881Spetercan change the command set and possibly the direction of control.
242251881Speter
243251881Speter3.1.1. Main Command Set
244251881Speter
245251881SpeterThe main command set corresponds to the svn_ra interfaces.  After each
246251881Spetermain command is issued by the client, the server sends an auth-request
247251881Speteras described in section 2.  (If no new authentication is required, the
248251881Speterauth-request contains an empty mechanism list, and the server proceeds
249251881Speterimmediately to sending the command response.)  Some commands include a
250251881Spetersecond place for auth-request point as noted below.
251251881Speter
252251881Speter  reparent
253251881Speter    params:   ( url:string )
254251881Speter    response: ( )
255251881Speter
256251881Speter  get-latest-rev
257251881Speter    params:   ( )
258251881Speter    response: ( rev:number )
259251881Speter
260251881Speter  get-dated-rev
261251881Speter    params:   ( date:string )
262251881Speter    response: ( rev:number )
263251881Speter
264251881Speter  change-rev-prop
265251881Speter    params:   ( rev:number name:string ? value:string )
266251881Speter    response: ( )
267251881Speter    If value is not specified, the rev-prop is removed.
268251881Speter    (Originally the value was required; for minimum impact, it was
269251881Speter     changed to be optional without creating an optional tuple for
270251881Speter     that one parameter as we normally do.)
271251881Speter
272251881Speter  change-rev-prop2
273251881Speter    params:   ( rev:number name:string [ value:string ]
274251881Speter                ( dont-care:bool ? previous-value:string ) )
275251881Speter    response: ( )
276251881Speter    If value is not specified, the rev-prop is removed.  If dont-care is false,
277251881Speter    then the rev-prop is changed only if it is currently set as previous-value
278251881Speter    indicates.  (If dont-care is false and previous-value is unspecified, then
279251881Speter    the revision property must be previously unset.)  If dont-care is true,
280251881Speter    then previous-value must not be specified.
281251881Speter
282251881Speter  rev-proplist
283251881Speter    params:   ( rev:number )
284251881Speter    response: ( props:proplist )
285251881Speter
286251881Speter  rev-prop
287251881Speter    params:   ( rev:number name:string )
288251881Speter    response: ( [ value:string ] )
289251881Speter
290251881Speter  commit
291251881Speter    params:   ( logmsg:string ? ( ( lock-path:string lock-token:string ) ... )
292251881Speter                keep-locks:bool ? rev-props:proplist )
293251881Speter    response: ( )
294251881Speter    Upon receiving response, client switches to editor command set.
295251881Speter    Upon successful completion of edit, server sends auth-request.
296251881Speter    After auth exchange completes, server sends commit-info.
297253734Speter    If rev-props is present, logmsg is ignored.  Only the svn:log entry in
298253734Speter    rev-props (if any) will be used.
299251881Speter    commit-info: ( new-rev:number date:string author:string
300251881Speter                   ? ( post-commit-err:string ) )
301253734Speter    NOTE: when revving this, make 'logmsg' optional, or delete that parameter
302253734Speter          and have the log message specified in 'rev-props'.
303251881Speter
304251881Speter  get-file
305251881Speter    params:   ( path:string [ rev:number ] want-props:bool want-contents:bool
306251881Speter                [ want-iprops:bool ] )
307251881Speter    response: ( [ checksum:string ] rev:number props:proplist
308251881Speter                [ inherited-props:iproplist ] )
309251881Speter    If want-contents is specified, then after sending response, server
310251881Speter     sends file contents as a series of strings, terminated by the empty
311251881Speter     string, followed by a second empty command response to indicate
312251881Speter     whether an error occurred during the sending of the file.
313269847Speter    NOTE: the standard client never sends want-iprops, it uses get-iprops. 
314251881Speter
315251881Speter  get-dir
316251881Speter    params:   ( path:string [ rev:number ] want-props:bool want-contents:bool
317251881Speter                ? ( field:dirent-field ... ) [ want-iprops:bool ] )
318251881Speter    response: ( rev:number props:proplist ( entry:dirent ... )
319251881Speter                [ inherited-props:iproplist ] )]
320251881Speter    dirent:   ( name:string kind:node-kind size:number has-props:bool
321251881Speter                created-rev:number [ created-date:string ]
322251881Speter                [ last-author:string ] )
323251881Speter    dirent-field: kind | size | has-props | created-rev | time | last-author
324251881Speter                  | word
325269847Speter    NOTE: the standard client never sends want-iprops, it uses get-iprops. 
326251881Speter
327251881Speter  check-path
328251881Speter    params:   ( path:string [ rev:number ] )
329251881Speter    response: ( kind:node-kind )
330251881Speter    If path is non-existent, 'svn_node_none' kind is returned.
331251881Speter
332251881Speter  stat
333251881Speter    params:   ( path:string [ rev:number ] )
334251881Speter    response: ( ? entry:dirent )
335251881Speter    dirent:   ( name:string kind:node-kind size:number has-props:bool
336251881Speter                created-rev:number [ created-date:string ]
337251881Speter                [ last-author:string ] )
338251881Speter    New in svn 1.2.  If path is non-existent, an empty response is returned.
339251881Speter
340251881Speter  get-mergeinfo
341251881Speter    params:   ( ( path:string ... ) [ rev:number ] inherit:word 
342251881Speter                descendents:bool)
343251881Speter    response: ( ( ( path:string merge-info:string ) ... ) )
344251881Speter    New in svn 1.5.  If no paths are specified, an empty response is
345251881Speter    returned.  If rev is not specified, the youngest revision is used.
346251881Speter
347251881Speter  update
348251881Speter    params:   ( [ rev:number ] target:string recurse:bool
349251881Speter                ? depth:word send_copyfrom_args:bool ? ignore_ancestry:bool )
350251881Speter    Client switches to report command set.
351251881Speter    Upon finish-report, server sends auth-request.
352251881Speter    After auth exchange completes, server switches to editor command set.
353251881Speter    After edit completes, server sends response.
354251881Speter    response: ( )
355251881Speter
356251881Speter  switch
357251881Speter    params:   ( [ rev:number ] target:string recurse:bool url:string
358251881Speter                ? depth:word ? send_copyfrom_args:bool ignore_ancestry:bool )
359251881Speter    Client switches to report command set.
360251881Speter    Upon finish-report, server sends auth-request.
361251881Speter    After auth exchange completes, server switches to editor command set.
362251881Speter    After edit completes, server sends response.
363251881Speter    response: ( )
364251881Speter
365251881Speter  status
366251881Speter    params:   ( target:string recurse:bool ? [ rev:number ] ? depth:word )
367251881Speter    Client switches to report command set.
368251881Speter    Upon finish-report, server sends auth-request.
369251881Speter    After auth exchange completes, server switches to editor command set.
370251881Speter    After edit completes, server sends response.
371251881Speter    response: ( )
372251881Speter
373251881Speter  diff
374251881Speter    params:   ( [ rev:number ] target:string recurse:bool ignore-ancestry:bool
375251881Speter                url:string ? text-deltas:bool ? depth:word )
376251881Speter    Client switches to report command set.
377251881Speter    Upon finish-report, server sends auth-request.
378251881Speter    After auth exchange completes, server switches to editor command set.
379251881Speter    After edit completes, server sends response.
380251881Speter    response: ( )
381251881Speter
382251881Speter  log
383251881Speter    params:   ( ( target-path:string ... ) [ start-rev:number ]
384251881Speter                [ end-rev:number ] changed-paths:bool strict-node:bool
385251881Speter                ? limit:number
386251881Speter                ? include-merged-revisions:bool
387251881Speter                all-revprops | revprops ( revprop:string ... ) )
388251881Speter    Before sending response, server sends log entries, ending with "done".
389251881Speter    If a client does not want to specify a limit, it should send 0 as the
390251881Speter    limit parameter.  rev-props excludes author, date, and log; they are
391251881Speter    sent separately for backwards-compatibility.
392251881Speter    log-entry: ( ( change:changed-path-entry ... ) rev:number
393251881Speter                 [ author:string ] [ date:string ] [ message:string ]
394251881Speter                 ? has-children:bool invalid-revnum:bool
395251881Speter                 revprop-count:number rev-props:proplist
396251881Speter                 ? subtractive-merge:bool )
397251881Speter             | done
398251881Speter    changed-path-entry: ( path:string A|D|R|M
399251881Speter                          ? ( ? copy-path:string copy-rev:number )
400251881Speter                          ? ( ? node-kind:string ? text-mods:bool prop-mods:bool ) )
401251881Speter    response: ( )
402251881Speter
403251881Speter  get-locations
404251881Speter    params:   ( path:string peg-rev:number ( rev:number ... ) )
405251881Speter    Before sending response, server sends location entries, ending with "done".
406251881Speter    location-entry: ( rev:number abs-path:number ) | done
407251881Speter    response: ( )
408251881Speter
409251881Speter  get-location-segments
410251881Speter    params:   ( path:string [ start-rev:number ] [ end-rev:number ] )
411251881Speter    Before sending response, server sends location entries, ending with "done".
412251881Speter    location-entry: ( range-start:number range-end:number [ abs-path:string ] ) | done
413251881Speter    response: ( )
414251881Speter
415251881Speter  get-file-revs
416251881Speter    params:   ( path:string [ start-rev:number ] [ end-rev:number ]
417251881Speter                ? include-merged-revisions:bool )
418251881Speter    Before sending response, server sends file-rev entries, ending with "done".
419251881Speter    file-rev: ( path:string rev:number rev-props:proplist
420251881Speter                file-props:propdelta ? merged-revision:bool )
421251881Speter              | done
422251881Speter    After each file-rev, the file delta is sent as one or more strings,
423251881Speter    terminated by the empty string.  If there is no delta, server just sends
424251881Speter    the terminator.
425251881Speter    response: ( )
426251881Speter
427251881Speter  lock
428251881Speter    params:    ( path:string [ comment:string ] steal-lock:bool
429251881Speter                 [ current-rev:number ] )
430251881Speter    response:  ( lock:lockdesc )
431251881Speter
432251881Speter  lock-many
433251881Speter    params:    ( [ comment:string ] steal-lock:bool ( ( path:string
434251881Speter                 [ current-rev:number ] ) ... ) )
435251881Speter    Before sending response, server sends lock cmd status and descriptions,
436251881Speter    ending with "done".
437251881Speter    lock-info: ( success ( lock:lockdesc ) ) | ( failure ( err:error ) )
438251881Speter                | done
439251881Speter    response: ( )
440251881Speter
441251881Speter  unlock
442251881Speter    params:    ( path:string [ token:string ] break-lock:bool )
443251881Speter    response:  ( )
444251881Speter
445251881Speter  unlock-many
446251881Speter    params:    ( break-lock:bool ( ( path:string [ token:string ] ) ... ) )
447251881Speter    Before sending response, server sends unlocked paths, ending with "done".
448251881Speter    pre-response: ( success ( path:string ) ) | ( failure ( err:error ) )
449251881Speter                  | done
450251881Speter    response:  ( )
451251881Speter
452251881Speter  get-lock
453251881Speter    params:    ( path:string )
454251881Speter    response:  ( [ lock:lockdesc ] )
455251881Speter
456251881Speter  get-locks
457251881Speter    params:    ( path:string ? [ depth:word ] )
458251881Speter    response   ( ( lock:lockdesc ... ) )
459251881Speter
460251881Speter  replay
461251881Speter    params:    ( revision:number low-water-mark:number send-deltas:bool )
462251881Speter    After auth exchange completes, server switches to editor command set.
463251881Speter    After edit completes, server sends response.
464251881Speter    response   ( )
465251881Speter
466251881Speter  replay-range
467251881Speter    params:    ( start-rev:number end-rev:number low-water-mark:number 
468251881Speter                 send-deltas:bool )
469251881Speter    After auth exchange completes, server sends each revision
470251881Speter    from start-rev to end-rev, alternating between sending 'revprops' 
471251881Speter    entries and sending the revision in the editor command set.
472251881Speter    After all revisions are complete, server sends response.
473251881Speter    revprops:  ( revprops:word props:proplist )
474251881Speter      (revprops here is the literal word "revprops".)
475251881Speter    response   ( )
476251881Speter
477251881Speter  get-deleted-rev
478251881Speter    params:   ( path:string peg-rev:number end-rev:number )
479251881Speter    response: ( deleted-rev:number )
480251881Speter
481251881Speter  get-iprops
482251881Speter    params:   ( path:string [ rev:number ] )
483251881Speter    response: ( inherited-props:iproplist )
484251881Speter    New in svn 1.8.  If rev is not specified, the youngest revision is used.
485251881Speter
486251881Speter3.1.2. Editor Command Set
487251881Speter
488251881SpeterAn edit operation produces only one response, at close-edit or
489251881Speterabort-edit time.  However, the consumer may write an error response at
490251881Speterany time during the edit in order to terminate the edit operation
491251881Speterearly; the driver must notice that input is waiting on the connection,
492251881Speterread the error, and send an abort-edit operation.  After an error is
493251881Speterreturned, the consumer must read and discard editing operations until
494251881Speterthe abort-edit.  In order to prevent TCP deadlock, the consumer must
495251881Speteruse non-blocking I/O to send an early error response; if writing
496251881Speterblocks, the consumer must read and discard edit operations until
497251881Speterwriting unblocks or it reads an abort-edit.
498251881Speter
499251881Speter  target-rev
500251881Speter    params:   ( rev:number )
501251881Speter
502251881Speter  open-root
503251881Speter    params:   ( [ rev:number ] root-token:string )
504251881Speter
505251881Speter  delete-entry
506251881Speter    params:   ( path:string rev:number dir-token:string )
507251881Speter
508251881Speter  add-dir
509251881Speter    params:   ( path:string parent-token:string child-token:string
510251881Speter                [ copy-path:string copy-rev:number ] )
511251881Speter
512251881Speter  open-dir
513251881Speter    params:   ( path:string parent-token:string child-token:string rev:number )
514251881Speter
515251881Speter  change-dir-prop
516251881Speter    params:   ( dir-token:string name:string [ value:string ] )
517251881Speter
518251881Speter  close-dir
519251881Speter    params:   ( dir-token:string )
520251881Speter
521251881Speter  absent-dir
522251881Speter    params:   ( path:string parent-token:string )
523251881Speter
524251881Speter  add-file
525251881Speter    params:   ( path:string dir-token:string file-token:string
526251881Speter                [ copy-path:string copy-rev:number ] )
527251881Speter
528251881Speter  open-file
529251881Speter    params:   ( path:string dir-token:string file-token:string rev:number )
530251881Speter
531251881Speter  apply-textdelta
532251881Speter    params:   ( file-token:string [ base-checksum:string ] )
533251881Speter
534251881Speter  textdelta-chunk
535251881Speter    params: ( file-token:string chunk:string )
536251881Speter
537251881Speter  textdelta-end
538251881Speter    params: ( file-token:string )
539251881Speter
540251881Speter  change-file-prop
541251881Speter    params:   ( file-token:string name:string [ value:string ] )
542251881Speter
543251881Speter  close-file
544251881Speter    params:   ( file-token:string [ text-checksum:string ] )
545251881Speter
546251881Speter  absent-file
547251881Speter    params:   ( path:string parent-token:string )
548251881Speter
549251881Speter  close-edit
550251881Speter    params:   ( )
551251881Speter    response: ( )
552251881Speter
553251881Speter  abort-edit
554251881Speter    params:   ( )
555251881Speter    response: ( )
556251881Speter
557251881Speter  finish-replay
558251881Speter    params:   ( )
559251881Speter    Only delivered from server to client, at the end of a replay.
560251881Speter
561251881Speter3.1.3. Report Command Set
562251881Speter
563251881SpeterTo reduce round-trip delays, report commands do not return responses.
564251881SpeterAny errors resulting from a report call will be returned to the client
565251881Speterby the command which invoked the report (following an abort-edit
566251881Spetercall).  Errors resulting from an abort-report call are ignored.
567251881Speter
568251881Speter  set-path:
569251881Speter    params: ( path:string rev:number start-empty:bool
570251881Speter              ? [ lock-token:string ] ? depth:word )
571251881Speter
572251881Speter  delete-path:
573251881Speter    params: ( path:string )
574251881Speter
575251881Speter  link-path:
576251881Speter    params: ( path:string url:string rev:number start-empty:bool 
577251881Speter              ? [ lock-token:string ] ? depth:word )
578251881Speter
579251881Speter  finish-report:
580251881Speter    params: ( )
581251881Speter
582251881Speter  abort-report
583251881Speter    params: ( )
584251881Speter
585251881Speter4. Extensibility
586251881Speter----------------
587251881Speter
588251881SpeterThis protocol may be extended in three ways, in decreasing order of
589251881Speterdesirability:
590251881Speter
591251881Speter  * Items may be added to any tuple.  An old implementation will
592251881Speter    ignore the extra items.
593251881Speter
594251881Speter  * Named extensions may be expressed at connection initiation time
595251881Speter    by the client or server.
596251881Speter
597251881Speter  * The protocol version may be bumped.  Clients and servers can then
598251881Speter    choose to any range of protocol versions.
599251881Speter
600251881Speter4.1. Extending existing commands
601251881Speter
602251881SpeterExtending an existing command is normally done by indicating that its
603251881Spetertuple is allowed to end where it currently ends, for backwards
604251881Spetercompatibility, and then tacking on a new, possibly optional, item.
605251881Speter
606251881SpeterFor example, diff was extended to include a new mandatory text-deltas
607251881Speterparameter like this:
608251881Speter
609251881Speter  /* OLD */ diff:
610251881Speter    params:   ( [ rev:number ] target:string recurse:bool ignore-ancestry:bool
611251881Speter                url:string )
612251881Speter  /* NEW */ diff:
613251881Speter    params:   ( [ rev:number ] target:string recurse:bool ignore-ancestry:bool
614251881Speter                url:string ? text-deltas:bool )
615251881Speter
616251881SpeterThe "?" says that the tuple is allowed to end here, because an old
617251881Speterclient or server wouldn't know to send the new item.
618251881Speter
619251881SpeterFor optional parameters, a slightly different approach must be used.
620251881Speterset-path was extended to include lock-tokens like this:
621251881Speter
622251881Speter  /* OLD */ set-path:
623251881Speter    params: ( path:string rev:number start-empty:bool )
624251881Speter
625251881Speter  /* NEW */ set-path:
626251881Speter    params: ( path:string rev:number start-empty:bool ? [ lock-token:string ] )
627251881Speter
628251881SpeterThe new item appears in brackets because, even in the new protocol,
629251881Speterthe lock-token is still optional.  However, if there's no lock-token
630251881Speterto send, an empty tuple must still be transmitted so that future
631251881Speterextensions to this command remain possible.
632