Followup to r29625: fix getopt tests.
[svn.git] / subversion / libsvn_ra_svn / protocol
blobee0134200efc7a8712d5e059269b035f6334a1c9
1 This file documents version 2 of the svn protocol.
3 1. Syntactic structure
4 ----------------------
6 The Subversion protocol is specified in terms of the following
7 syntactic elements, specified using ABNF [RFC 2234]:
9   item   = word / number / string / list
10   word   = ALPHA *(ALPHA / DIGIT / "-") space
11   number = 1*DIGIT space
12   string = 1*DIGIT ":" *OCTET space
13          ; digits give the byte count of the *OCTET portion
14   list   = "(" space *item ")" space
15   space  = 1*(SP / LF)
17 Here is an example item showing each of the syntactic elements:
19   ( word 22 6:string ( sublist ) )
21 All items end with mandatory whitespace.  (In the above example, a
22 newline provides the terminating whitespace for the outer list.)  It
23 is possible to parse an item without knowing its type in advance.
25 Lists are not constrained to contain items of the same type.  Lists
26 can be used for tuples, optional tuples, or arrays.  A tuple is a list
27 expected to contain a fixed number of items, generally of differing
28 types.  An optional tuple is a list containing either zero or a fixed
29 number of items (thus "optional" here does not refer to the list's
30 presence or absence, but to the presence or absence of its contents).
31 An array is a list containing zero or more items of the same type.
33 Words are used for enumerated protocol values, while strings are used
34 for text or binary data of interest to the Subversion client or
35 server.  Words are case-sensitive.
37 For convenience, this specification will define prototypes for data
38 items using a syntax like:
40   example: ( literal ( data:string ... ) )
42 A simple word such as "literal", with no colon, denotes a literal
43 word.  A choice of words may be given with "|" separating the choices.
44 "name:type" specifies a parameter with the given type.
46 A type is "word", "number", "string", "list", or the name of another
47 prototype.  Parentheses denote a tuple, unless the parentheses contain
48 ellipses, in which case the parentheses denote an array containing
49 zero or more elements matching the prototype preceding the ellipses.
51 If a tuple has an optional part after the fixed part, a '?' marks
52 places where the tuple is allowed to end.  The following tuple could
53 contain one, three, or four or more items:
55   example: ( fixed:string ? opt1:number opt2:string ? opt3:number )
57 Brackets denote an optional tuple; they are equivalent to parentheses
58 and a leading '?'.  For example, this:
60   example: ( literal (? rev:number ) ( data:string ... ) )
62 can be written more compactly like this:
64   example: ( literal [ rev:number ] ( data:string ... ) )
66 For extensibility, implementations must treat a list as matching a
67 prototype's tuple even if the list contains extra elements.  The extra
68 elements must be ignored.
70 In some cases, a prototype may need to match two different kinds of
71 data items.  This case will be written using "|" to separate the
72 alternatives; for example:
74   example: ( first-kind rev:number )
75          | second-kind
77 The "command response" prototype is used in several contexts of this
78 specification to indicate the success or failure of an operation.  It
79 is defined as follows:
81   command-response: ( success params:list )
82                   | ( failure ( err:error ... ) )
83   error: ( apr-err:number message:string file:string line:number )
85 The interpretation of parameters in a successful command response is
86 context-dependent.
88 URLs and repository paths are represented as strings.  They should be in
89 canonical form when sent over the protocol.  However, as a matter of input
90 validation, an implementation should always canonicalize received paths if it
91 needs them in canonicalized form.
93 2. Connection establishment and protocol setup
94 ----------------------------------------------
96 By default, the client connects to the server on port 3690.
98 Upon receiving a connection, the server sends a greeting, using a
99 command response whose parameters match the prototype:
101   greeting: ( minver:number maxver:number mechs:list ( cap:word ... ) )
103 minver and maxver give the minimum and maximum Subversion protocol
104 versions supported by the server.  mechs is present for historical
105 reasons, and is ignored by the client.  The cap values give a list of
106 server capabilities (see section 2.1).
108 If the client does not support a protocol version within the specified
109 range, it closes the connection.  Otherwise, the client responds to
110 the greeting with an item matching the prototype:
112   response: ( version:number ( cap:word ... ) url:string )
114 version gives the protocol version selected by the client.  The cap
115 values give a list of client capabilities (see section 2.1).  url
116 gives the URL the client is accessing.
118 Upon receiving the client's response to the greeting, the server sends
119 an authentication request, which is a command response whose arguments
120 match the prototype:
122   auth-request: ( ( mech:word ... ) realm:string )
124 The mech values give a list of SASL mechanisms supported by the
125 server.  The realm string is similar to an HTTP authentication realm
126 as defined in [RFC 2617]; it allows the server to indicate which of
127 several protection spaces the server wishes to authenticate in.  If
128 the mechanism list is empty, then no authentication is required and no
129 further action takes place as part of the authentication challenge;
130 otherwise, the client responds with a tuple matching the prototype:
132   auth-response: ( mech:word [ token:string ] )
134 mech specifies the SASL mechanism and token, if present, gives the
135 "initial response" of the authentication exchange.  The client may
136 specify an empty mechanism to decline authentication; otherwise, upon
137 receiving the client's auth-response, the server sends a series of
138 challenges, each a tuple matching the prototype:
140   challenge: ( step ( token:string ) )
141            | ( failure ( message:string ) )
142            | ( success [ token:string ] )
144 If the first word of the challenge is "step", then the token is
145 interpreted by the authentication mechanism, and the response token
146 transmitted to the server as a string.  The server then proceeds with
147 another challenge.  If the client wishes to abort the authentication
148 exchange, it may do so by closing the connection.
150 If the first word of the challenge is "success", the authentication is
151 successful.  If a token is provided, it should be interpreted by the
152 authentication mechanism, but there is no response.
154 If the first word of the challenge is "failure", the authentication
155 exchange is unsuccessful.  The client may then give up, or make
156 another auth-response and restart the authentication process.
158 RFC 2222 requires that a protocol profile define a service name for
159 the sake of the GSSAPI mechanism.  The service name for this protocol
160 is "svn".
162 After a successful authentication exchange, the server sends a command
163 response whose parameters match the prototype:
165   repos-info: ( uuid:string repos-url:string ( cap:word ... ) )
167 uuid gives the universal unique identifier of the repository,
168 repos-url gives the URL of the repository's root directory, and the
169 cap values list the repository capabilities (that is, capabilities
170 that require both server and repository support before the server can
171 claim them as capabilities, e.g., SVN_RA_SVN_CAP_MERGEINFO).
173 The client can now begin sending commands from the main command set.
175 2.1 Capabilities
177 The following capabilities are currently defined (S indicates a server
178 capability and C indicates a client capability):
180 [CS] edit-pipeline     Every released version of Subversion since 1.0
181                        announces the edit-pipeline capability; starting
182                        in Subversion 1.5, both client and server
183                        *require* the other side to announce edit-pipeline.
184 [CS] svndiff1          If both the client and server support svndiff version
185                        1, this will be used as the on-the-wire format for 
186                        svndiff instead of svndiff version 0.
187 [CS] absent-entries    If the remote end announces support for this capability,
188                        it will accept the absent-dir and absent-file editor
189                        commands.
190 [S]  commit-revprops   If the server presents this capability, it supports the 
191                        rev-props parameter of the commit command.
192                        See section 3.1.1.
193 [S]  mergeinfo         If the server presents this capability, it supports the 
194                        get-mergeinfo command.  See section 3.1.1.
195 [S]  depth             If the server presents this capability, it understands
196                        requested operational depth (see section 3.1.1) and
197                        per-path ambient depth (see section 3.1.3).
199 3. Commands
200 -----------
202 Commands match the prototypes:
204   command: ( command-name:word params:list )
206 The interpretation of command parameters is different from command to
207 command.
209 Initially, the client initiates commands from the main command set,
210 and the server responds.  Some commands in the main command set can
211 temporarily change the set of commands which may be issued, or change
212 the flow of control so that the server issues commands and the client
213 responds.
215 Here are some miscellaneous prototypes used by the command sets:
217   proplist:  ( ( name:string value:string ) ... )
218   propdelta: ( ( name:string [ value:string ] ) ... )
219   node-kind: none|file|dir|unknown
220   bool:      true|false
221   lockdesc:  ( path:string token:string owner:string [ comment:string ]
222                created:string [ expires:string ] )
224 3.1. Command Sets
226 There are three command sets: the main command set, the editor command
227 set, and the report command set.  Initially, the protocol begins in
228 the main command set with the client sending commands; some commands
229 can change the command set and possibly the direction of control.
231 3.1.1. Main Command Set
233 The main command set corresponds to the svn_ra interfaces.  After each
234 main command is issued by the client, the server sends an auth-request
235 as described in section 2.  (If no new authentication is required, the
236 auth-request contains an empty mechanism list, and the server proceeds
237 immediately to sending the command response.)  Some commands include a
238 second place for auth-request point as noted below.
240   reparent
241     params:   ( url:string )
242     response: ( )
244   get-latest-rev
245     params:   ( )
246     response: ( rev:number )
248   get-dated-rev
249     params:   ( date:string )
250     response: ( rev:number )
252   change-rev-prop
253     params:   ( rev:number name:string ? value:string )
254     response: ( )
255     If value is not specified, the rev-prop is removed.
256     (Originally the value was required; for minimum impact, it was
257      changed to be optional without creating an optional tuple for
258      that one parameter as we normally do.)
260   rev-proplist
261     params:   ( rev:number )
262     response: ( props:proplist )
264   rev-prop
265     params:   ( rev:number name:string )
266     response: ( [ value:string ] )
268   commit
269     params:   ( logmsg:string ? ( ( lock-path:string lock-token:string ) ... )
270                 keep-locks:bool ? rev-props:proplist )
271     response: ( )
272     Upon receiving response, client switches to editor command set.
273     Upon successful completion of edit, server sends auth-request.
274     After auth exchange completes, server sends commit-info.
275     commit-info: ( new-rev:number date:string author:string
276                    ? ( post-commit-err:string ) )
278   get-file
279     params:   ( path:string [ rev:number ] want-props:bool want-contents:bool )
280     response: ( [ checksum:string ] rev:number props:proplist )
281     If want-contents is specified, then after sending response, server
282      sends file contents as a series of strings, terminated by the empty
283      string, followed by a second empty command response to indicate
284      whether an error occurred during the sending of the file.
286   get-dir
287     params:   ( path:string [ rev:number ] want-props:bool want-contents:bool
288                 ? ( field:dirent-field ... ) )
289     response: ( rev:number props:proplist ( entry:dirent ... ) )]
290     dirent:   ( name:string kind:node-kind size:number has-props:bool
291                 created-rev:number [ created-date:string ]
292                 [ last-author:string ] )
293     dirent-field: kind | size | has-props | created-rev | time | last-author
294                   | word
296   check-path
297     params:   ( path:string [ rev:number ] )
298     response: ( kind:node-kind )
299     If path is non-existent, 'svn_node_none' kind is returned.
301   stat
302     params:   ( path:string [ rev:number ] )
303     response: ( ? entry:dirent )
304     dirent:   ( name:string kind:node-kind size:number has-props:bool
305                 created-rev:number [ created-date:string ]
306                 [ last-author:string ] )
307     New in svn 1.2.  If path is non-existent, an empty response is returned.
309   get-mergeinfo
310     params:   ( ( path:string ... ) [ rev:number ] inherit:word 
311                 descendents:bool)
312     response: ( ( ( path:string merge-info:string ) ... ) )
313     New in svn 1.5.  If no paths are specified, an empty response is
314     returned.  If rev is not specified, the youngest revision is used.
316   update
317     params:   ( [ rev:number ] target:string recurse:bool
318                 ? depth:word send_copyfrom_param:bool )
319     Client switches to report command set.
320     Upon finish-report, server sends auth-request.
321     After auth exchange completes, server switches to editor command set.
322     After edit completes, server sends response.
323     response: ( )
325   switch
326     params:   ( [ rev:number ] target:string recurse:bool url:string
327                 ? depth:word)
328     Client switches to report command set.
329     Upon finish-report, server sends auth-request.
330     After auth exchange completes, server switches to editor command set.
331     After edit completes, server sends response.
332     response: ( )
334   status
335     params:   ( target:string recurse:bool ? [ rev:number ] ? depth:word )
336     Client switches to report command set.
337     Upon finish-report, server sends auth-request.
338     After auth exchange completes, server switches to editor command set.
339     After edit completes, server sends response.
340     response: ( )
342   diff
343     params:   ( [ rev:number ] target:string recurse:bool ignore-ancestry:bool
344                 url:string ? text-deltas:bool ? depth:word )
345     Client switches to report command set.
346     Upon finish-report, server sends auth-request.
347     After auth exchange completes, server switches to editor command set.
348     After edit completes, server sends response.
349     response: ( )
351   log
352     params:   ( ( target-path:string ... ) [ start-rev:number ]
353                 [ end-rev:number ] changed-paths:bool strict-node:bool
354                 ? limit:number
355                 ? include-merged-revisions:bool
356                 all-revprops | revprops
357                 ? ( revprop:string ... ) )
358     Before sending response, server sends log entries, ending with "done".
359     If a client does not want to specify a limit, it should send 0 as the
360     limit parameter.  rev-props excludes author, date, and log; they are
361     sent separately for backwards-compatibility.
362     log-entry: ( ( change:changed-path-entry ... ) rev:number
363                  [ author:string ] [ date:string ] [ message:string ]
364                  ? has-children:bool invalid-revnum:bool
365                  revprop-count:number rev-props:proplist )
366              | done
367     changed-path-entry: ( path:string A|D|R|M [ copy-path:string ]
368                           [ copy-rev:number ] )
369     response: ( )
371   get-locations
372     params:   ( path:string peg-rev:number ( rev:number ... ) )
373     Before sending response, server sends location entries, ending with "done".
374     location-entry: ( rev:number abs-path:number ) | done
375     response: ( )
377   get-location-segments
378     params:   ( path:string [ start-rev:number ] [ end-rev:number ] )
379     Before sending response, server sends location entries, ending with "done".
380     location-entry: ( range-start:number range-end:number [ abs-path:string ] ) | done
381     response: ( )
383   get-file-revs
384     params:   ( path:string [ start-rev:number ] [ end-rev:number ]
385                 ? include-merged-revisions:bool )
386     Before sending response, server sends file-rev entries, ending with "done".
387     file-rev: ( path:string rev:number rev-props:proplist
388                 file-props:propdelta ? merged-revision:bool )
389               | done
390     After each file-rev, the file delta is sent as one or more strings,
391     terminated by the empty string.  If there is no delta, server just sends
392     the terminator.
393     response: ( )
395   lock
396     params:    ( path:string [ comment:string ] steal-lock:bool
397                  [ current-rev:number ] )
398     response:  ( lock:lockdesc )
400   lock-many
401     params:    ( [ comment:string ] steal-lock:bool ( ( path:string
402                  [ current-rev:number ] ) ... ) )
403     Before sending response, server sends lock cmd status and descriptions,
404     ending with "done".
405     lock-info: ( success ( lock:lockdesc ) ) | ( failure ( err:error ) )
406                 | done
407     response: ( )
409   unlock
410     params:    ( path:string [ token:string ] break-lock:bool )
411     response:  ( )
413   unlock-many
414     params:    ( break-lock:bool ( ( path:string [ token:string ] ) ... ) )
415     Before sending response, server sends unlocked paths, ending with "done".
416     pre-response: ( success ( path:string ) ) | ( failure ( err:error ) )
417                   | done
418     response:  ( )
420   get-lock
421     params:    ( path:string )
422     response:  ( [ lock:lockdesc ] )
424   get-locks
425     params:    ( path:string )
426     response   ( ( lock:lockdesc ... ) )
428   replay
429     params:    ( revision:number low-water-mark:number send-deltas:bool )
430     After auth exchange completes, server switches to editor command set.
431     After edit completes, server sends response.
432     response   ( )
434   replay-range
435     params:    ( start-rev:number end-rev:number low-water-mark:number 
436                  send-deltas:bool )
437     After auth exchange completes, server sends each revision
438     from start-rev to end-rev, alternating between sending 'revprops' 
439     entries and sending the revision in the editor command set.
440     After all revisions are complete, server sends response.
441     revprops:  ( revprops:word props:proplist )
442       (revprops here is the literal word "revprops".)
443     response   ( )
445 3.1.2. Editor Command Set
447 An edit operation produces only one response, at close-edit or
448 abort-edit time.  However, the consumer may write an error response at
449 any time during the edit in order to terminate the edit operation
450 early; the driver must notice that input is waiting on the connection,
451 read the error, and send an abort-edit operation.  After an error is
452 returned, the consumer must read and discard editing operations until
453 the abort-edit.  In order to prevent TCP deadlock, the consumer must
454 use non-blocking I/O to send an early error response; if writing
455 blocks, the consumer must read and discard edit operations until
456 writing unblocks or it reads an abort-edit.
458   target-rev
459     params:   ( rev:number )
461   open-root
462     params:   ( [ rev:number ] root-token:string )
464   delete-entry
465     params:   ( path:string rev:number dir-token:string )
467   add-dir
468     params:   ( path:string parent-token:string child-token:string
469                 [ copy-path:string copy-rev:number ] )
471   open-dir
472     params:   ( path:string parent-token:string child-token:string rev:number )
474   change-dir-prop
475     params:   ( dir-token:string name:string [ value:string ] )
477   close-dir
478     params:   ( dir-token:string )
480   absent-dir
481     params:   ( path:string parent-token:string )
483   add-file
484     params:   ( path:string dir-token:string file-token:string
485                 [ copy-path:string copy-rev:number ] )
487   open-file
488     params:   ( path:string dir-token:string file-token:string rev:number )
490   apply-textdelta
491     params:   ( file-token:string [ base-checksum:string ] )
493   textdelta-chunk
494     params: ( file-token:string chunk:string )
496   textdelta-end
497     params: ( file-token:string )
499   change-file-prop
500     params:   ( file-token:string name:string [ value:string ] )
502   close-file
503     params:   ( file-token:string [ text-checksum:string ] )
505   absent-file
506     params:   ( path:string parent-token:string )
508   close-edit
509     params:   ( )
510     response: ( )
512   abort-edit
513     params:   ( )
514     response: ( )
516   finish-replay
517     params:   ( )
518     Only delivered from server to client, at the end of a replay.
520 3.1.3. Report Command Set
522 To reduce round-trip delays, report commands do not return responses.
523 Any errors resulting from a report call will be returned to the client
524 by the command which invoked the report (following an abort-edit
525 call).  Errors resulting from an abort-report call are ignored.
527   set-path:
528     params: ( path:string rev:number start-empty:bool
529               ? [ lock-token:string ] ? depth:word )
531   delete-path:
532     params: ( path:string )
534   link-path:
535     params: ( path:string url:string rev:number start-empty:bool 
536               ? [ lock-token:string ] ? depth:word )
538   finish-report:
539     params: ( )
541   abort-report
542     params: ( )
544 4. Extensibility
545 ----------------
547 This protocol may be extended in three ways, in decreasing order of
548 desirability:
550   * Items may be added to any tuple.  An old implementation will
551     ignore the extra items.
553   * Named extensions may be expressed at connection initiation time
554     by the client or server.
556   * The protocol version may be bumped.  Clients and servers can then
557     choose to any range of protocol versions.
559 4.1. Extending existing commands
561 Extending an existing command is normally done by indicating that its
562 tuple is allowed to end where it currently ends, for backwards
563 compatibility, and then tacking on a new, possibly optional, item.
565 For example, diff was extended to include a new mandatory text-deltas
566 parameter like this:
568   /* OLD */ diff:
569     params:   ( [ rev:number ] target:string recurse:bool ignore-ancestry:bool
570                 url:string )
571   /* NEW */ diff:
572     params:   ( [ rev:number ] target:string recurse:bool ignore-ancestry:bool
573                 url:string ? text-deltas:bool )
575 The "?" says that the tuple is allowed to end here, because an old
576 client or server wouldn't know to send the new item.
578 For optional parameters, a slightly different approach must be used.
579 set-path was extended to include lock-tokens like this:
581   /* OLD */ set-path:
582     params: ( path:string rev:number start-empty:bool )
584   /* NEW */ set-path:
585     params: ( path:string rev:number start-empty:bool ? [ lock-token:string ] )
587 The new item appears in brackets because, even in the new protocol,
588 the lock-token is still optional.  However, if there's no lock-token
589 to send, an empty tuple must still be transmitted so that future
590 extensions to this command remain possible.