]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/subversion/subversion/libsvn_ra_svn/protocol
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / subversion / subversion / libsvn_ra_svn / protocol
1 This file documents version 2 of the svn protocol.
2
3 1. Syntactic structure
4 ----------------------
5
6 The Subversion protocol is specified in terms of the following
7 syntactic elements, specified using ABNF [RFC 2234]:
8
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)
16
17 Here is an example item showing each of the syntactic elements:
18
19   ( word 22 6:string ( sublist ) )
20
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.
24
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.
32
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.
36
37 For convenience, this specification will define prototypes for data
38 items using a syntax like:
39
40   example: ( literal ( data:string ... ) )
41
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.
45
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.
50
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:
54
55   example: ( fixed:string ? opt1:number opt2:string ? opt3:number )
56
57 Brackets denote an optional tuple; they are equivalent to parentheses
58 and a leading '?'.  For example, this:
59
60   example: ( literal (? rev:number ) ( data:string ... ) )
61
62 can be written more compactly like this:
63
64   example: ( literal [ rev:number ] ( data:string ... ) )
65
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.
69
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:
73
74   example: ( first-kind rev:number )
75          | second-kind
76
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:
80
81   command-response: ( success params:list )
82                   | ( failure ( err:error ... ) )
83   error: ( apr-err:number message:string file:string line:number )
84
85 The interpretation of parameters in a successful command response is
86 context-dependent.
87
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.
92
93 2. Connection establishment and protocol setup
94 ----------------------------------------------
95
96 By default, the client connects to the server on port 3690.
97
98 Upon receiving a connection, the server sends a greeting, using a
99 command response whose parameters match the prototype:
100
101   greeting: ( minver:number maxver:number mechs:list ( cap:word ... ) )
102
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).
107
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:
111
112   response: ( version:number ( cap:word ... ) url:string
113               ? ra-client:string ( ? client:string ) )
114
115 version gives the protocol version selected by the client.  The cap
116 values give a list of client capabilities (see section 2.1).  url
117 gives the URL the client is accessing.  ra-client is a string
118 identifying the RA implementation, e.g. "SVN/1.6.0" or "SVNKit 1.1.4".
119 client is the string returned by svn_ra_callbacks2_t.get_client_string;
120 that callback may not be implemented, so this is optional.
121
122 Upon receiving the client's response to the greeting, the server sends
123 an authentication request, which is a command response whose arguments
124 match the prototype:
125
126   auth-request: ( ( mech:word ... ) realm:string )
127
128 The mech values give a list of SASL mechanisms supported by the
129 server.  The realm string is similar to an HTTP authentication realm
130 as defined in [RFC 2617]; it allows the server to indicate which of
131 several protection spaces the server wishes to authenticate in.  If
132 the mechanism list is empty, then no authentication is required and no
133 further action takes place as part of the authentication challenge;
134 otherwise, the client responds with a tuple matching the prototype:
135
136   auth-response: ( mech:word [ token:string ] )
137
138 mech specifies the SASL mechanism and token, if present, gives the
139 "initial response" of the authentication exchange.  The client may
140 specify an empty mechanism to decline authentication; otherwise, upon
141 receiving the client's auth-response, the server sends a series of
142 challenges, each a tuple matching the prototype:
143
144   challenge: ( step ( token:string ) )
145            | ( failure ( message:string ) )
146            | ( success [ token:string ] )
147
148 If the first word of the challenge is "step", then the token is
149 interpreted by the authentication mechanism, and the response token
150 transmitted to the server as a string.  The server then proceeds with
151 another challenge.  If the client wishes to abort the authentication
152 exchange, it may do so by closing the connection.
153
154 If the first word of the challenge is "success", the authentication is
155 successful.  If a token is provided, it should be interpreted by the
156 authentication mechanism, but there is no response.
157
158 If the first word of the challenge is "failure", the authentication
159 exchange is unsuccessful.  The client may then give up, or make
160 another auth-response and restart the authentication process.
161
162 RFC 2222 requires that a protocol profile define a service name for
163 the sake of the GSSAPI mechanism.  The service name for this protocol
164 is "svn".
165
166 After a successful authentication exchange, the server sends a command
167 response whose parameters match the prototype:
168
169   repos-info: ( uuid:string repos-url:string ( cap:word ... ) )
170
171 uuid gives the universal unique identifier of the repository,
172 repos-url gives the URL of the repository's root directory, and the
173 cap values list the repository capabilities (that is, capabilities
174 that require both server and repository support before the server can
175 claim them as capabilities, e.g., SVN_RA_SVN_CAP_MERGEINFO).
176
177 The client can now begin sending commands from the main command set.
178
179 2.1 Capabilities
180
181 The following capabilities are currently defined (S indicates a server
182 capability and C indicates a client capability):
183
184 [CS] edit-pipeline     Every released version of Subversion since 1.0
185                        announces the edit-pipeline capability; starting
186                        in Subversion 1.5, both client and server
187                        *require* the other side to announce edit-pipeline.
188 [CS] svndiff1          If both the client and server support svndiff version
189                        1, this will be used as the on-the-wire format for 
190                        svndiff instead of svndiff version 0.
191 [CS] absent-entries    If the remote end announces support for this capability,
192                        it will accept the absent-dir and absent-file editor
193                        commands.
194 [S]  commit-revprops   If the server presents this capability, it supports the 
195                        rev-props parameter of the commit command.
196                        See section 3.1.1.
197 [S]  mergeinfo         If the server presents this capability, it supports the 
198                        get-mergeinfo command.  See section 3.1.1.
199 [S]  depth             If the server presents this capability, it understands
200                        requested operational depth (see section 3.1.1) and
201                        per-path ambient depth (see section 3.1.3).
202 [S]  atomic-revprops   If the server presents this capability, it
203                        supports the change-rev-prop2 command.
204                        See section 3.1.1.
205 [S]  inherited-props   If the server presents this capability, it supports the
206                        retrieval of inherited properties via the get-dir and
207                        get-file commands and also supports the get-iprops
208                        command (see section 3.1.1).
209
210 3. Commands
211 -----------
212
213 Commands match the prototypes:
214
215   command: ( command-name:word params:list )
216
217 The interpretation of command parameters is different from command to
218 command.
219
220 Initially, the client initiates commands from the main command set,
221 and the server responds.  Some commands in the main command set can
222 temporarily change the set of commands which may be issued, or change
223 the flow of control so that the server issues commands and the client
224 responds.
225
226 Here are some miscellaneous prototypes used by the command sets:
227
228   proplist:  ( ( name:string value:string ) ... )
229   iproplist: ( ( name:string proplist ) ... )
230   propdelta: ( ( name:string [ value:string ] ) ... )
231   node-kind: none|file|dir|unknown
232   bool:      true|false
233   lockdesc:  ( path:string token:string owner:string [ comment:string ]
234                created:string [ expires:string ] )
235
236 3.1. Command Sets
237
238 There are three command sets: the main command set, the editor command
239 set, and the report command set.  Initially, the protocol begins in
240 the main command set with the client sending commands; some commands
241 can change the command set and possibly the direction of control.
242
243 3.1.1. Main Command Set
244
245 The main command set corresponds to the svn_ra interfaces.  After each
246 main command is issued by the client, the server sends an auth-request
247 as described in section 2.  (If no new authentication is required, the
248 auth-request contains an empty mechanism list, and the server proceeds
249 immediately to sending the command response.)  Some commands include a
250 second place for auth-request point as noted below.
251
252   reparent
253     params:   ( url:string )
254     response: ( )
255
256   get-latest-rev
257     params:   ( )
258     response: ( rev:number )
259
260   get-dated-rev
261     params:   ( date:string )
262     response: ( rev:number )
263
264   change-rev-prop
265     params:   ( rev:number name:string ? value:string )
266     response: ( )
267     If value is not specified, the rev-prop is removed.
268     (Originally the value was required; for minimum impact, it was
269      changed to be optional without creating an optional tuple for
270      that one parameter as we normally do.)
271
272   change-rev-prop2
273     params:   ( rev:number name:string [ value:string ]
274                 ( dont-care:bool ? previous-value:string ) )
275     response: ( )
276     If value is not specified, the rev-prop is removed.  If dont-care is false,
277     then the rev-prop is changed only if it is currently set as previous-value
278     indicates.  (If dont-care is false and previous-value is unspecified, then
279     the revision property must be previously unset.)  If dont-care is true,
280     then previous-value must not be specified.
281
282   rev-proplist
283     params:   ( rev:number )
284     response: ( props:proplist )
285
286   rev-prop
287     params:   ( rev:number name:string )
288     response: ( [ value:string ] )
289
290   commit
291     params:   ( logmsg:string ? ( ( lock-path:string lock-token:string ) ... )
292                 keep-locks:bool ? rev-props:proplist )
293     response: ( )
294     Upon receiving response, client switches to editor command set.
295     Upon successful completion of edit, server sends auth-request.
296     After auth exchange completes, server sends commit-info.
297     If rev-props is present, logmsg is ignored.  Only the svn:log entry in
298     rev-props (if any) will be used.
299     commit-info: ( new-rev:number date:string author:string
300                    ? ( post-commit-err:string ) )
301     NOTE: when revving this, make 'logmsg' optional, or delete that parameter
302           and have the log message specified in 'rev-props'.
303
304   get-file
305     params:   ( path:string [ rev:number ] want-props:bool want-contents:bool
306                 [ want-iprops:bool ] )
307     response: ( [ checksum:string ] rev:number props:proplist
308                 [ inherited-props:iproplist ] )
309     If want-contents is specified, then after sending response, server
310      sends file contents as a series of strings, terminated by the empty
311      string, followed by a second empty command response to indicate
312      whether an error occurred during the sending of the file.
313     NOTE: the standard client never sends want-iprops, it uses get-iprops. 
314
315   get-dir
316     params:   ( path:string [ rev:number ] want-props:bool want-contents:bool
317                 ? ( field:dirent-field ... ) [ want-iprops:bool ] )
318     response: ( rev:number props:proplist ( entry:dirent ... )
319                 [ inherited-props:iproplist ] )]
320     dirent:   ( name:string kind:node-kind size:number has-props:bool
321                 created-rev:number [ created-date:string ]
322                 [ last-author:string ] )
323     dirent-field: kind | size | has-props | created-rev | time | last-author
324                   | word
325     NOTE: the standard client never sends want-iprops, it uses get-iprops. 
326
327   check-path
328     params:   ( path:string [ rev:number ] )
329     response: ( kind:node-kind )
330     If path is non-existent, 'svn_node_none' kind is returned.
331
332   stat
333     params:   ( path:string [ rev:number ] )
334     response: ( ? entry:dirent )
335     dirent:   ( name:string kind:node-kind size:number has-props:bool
336                 created-rev:number [ created-date:string ]
337                 [ last-author:string ] )
338     New in svn 1.2.  If path is non-existent, an empty response is returned.
339
340   get-mergeinfo
341     params:   ( ( path:string ... ) [ rev:number ] inherit:word 
342                 descendents:bool)
343     response: ( ( ( path:string merge-info:string ) ... ) )
344     New in svn 1.5.  If no paths are specified, an empty response is
345     returned.  If rev is not specified, the youngest revision is used.
346
347   update
348     params:   ( [ rev:number ] target:string recurse:bool
349                 ? depth:word send_copyfrom_args:bool ? ignore_ancestry:bool )
350     Client switches to report command set.
351     Upon finish-report, server sends auth-request.
352     After auth exchange completes, server switches to editor command set.
353     After edit completes, server sends response.
354     response: ( )
355
356   switch
357     params:   ( [ rev:number ] target:string recurse:bool url:string
358                 ? depth:word ? send_copyfrom_args:bool ignore_ancestry:bool )
359     Client switches to report command set.
360     Upon finish-report, server sends auth-request.
361     After auth exchange completes, server switches to editor command set.
362     After edit completes, server sends response.
363     response: ( )
364
365   status
366     params:   ( target:string recurse:bool ? [ rev:number ] ? depth:word )
367     Client switches to report command set.
368     Upon finish-report, server sends auth-request.
369     After auth exchange completes, server switches to editor command set.
370     After edit completes, server sends response.
371     response: ( )
372
373   diff
374     params:   ( [ rev:number ] target:string recurse:bool ignore-ancestry:bool
375                 url:string ? text-deltas:bool ? depth:word )
376     Client switches to report command set.
377     Upon finish-report, server sends auth-request.
378     After auth exchange completes, server switches to editor command set.
379     After edit completes, server sends response.
380     response: ( )
381
382   log
383     params:   ( ( target-path:string ... ) [ start-rev:number ]
384                 [ end-rev:number ] changed-paths:bool strict-node:bool
385                 ? limit:number
386                 ? include-merged-revisions:bool
387                 all-revprops | revprops ( revprop:string ... ) )
388     Before sending response, server sends log entries, ending with "done".
389     If a client does not want to specify a limit, it should send 0 as the
390     limit parameter.  rev-props excludes author, date, and log; they are
391     sent separately for backwards-compatibility.
392     log-entry: ( ( change:changed-path-entry ... ) rev:number
393                  [ author:string ] [ date:string ] [ message:string ]
394                  ? has-children:bool invalid-revnum:bool
395                  revprop-count:number rev-props:proplist
396                  ? subtractive-merge:bool )
397              | done
398     changed-path-entry: ( path:string A|D|R|M
399                           ? ( ? copy-path:string copy-rev:number )
400                           ? ( ? node-kind:string ? text-mods:bool prop-mods:bool ) )
401     response: ( )
402
403   get-locations
404     params:   ( path:string peg-rev:number ( rev:number ... ) )
405     Before sending response, server sends location entries, ending with "done".
406     location-entry: ( rev:number abs-path:number ) | done
407     response: ( )
408
409   get-location-segments
410     params:   ( path:string [ start-rev:number ] [ end-rev:number ] )
411     Before sending response, server sends location entries, ending with "done".
412     location-entry: ( range-start:number range-end:number [ abs-path:string ] ) | done
413     response: ( )
414
415   get-file-revs
416     params:   ( path:string [ start-rev:number ] [ end-rev:number ]
417                 ? include-merged-revisions:bool )
418     Before sending response, server sends file-rev entries, ending with "done".
419     file-rev: ( path:string rev:number rev-props:proplist
420                 file-props:propdelta ? merged-revision:bool )
421               | done
422     After each file-rev, the file delta is sent as one or more strings,
423     terminated by the empty string.  If there is no delta, server just sends
424     the terminator.
425     response: ( )
426
427   lock
428     params:    ( path:string [ comment:string ] steal-lock:bool
429                  [ current-rev:number ] )
430     response:  ( lock:lockdesc )
431
432   lock-many
433     params:    ( [ comment:string ] steal-lock:bool ( ( path:string
434                  [ current-rev:number ] ) ... ) )
435     Before sending response, server sends lock cmd status and descriptions,
436     ending with "done".
437     lock-info: ( success ( lock:lockdesc ) ) | ( failure ( err:error ) )
438                 | done
439     response: ( )
440
441   unlock
442     params:    ( path:string [ token:string ] break-lock:bool )
443     response:  ( )
444
445   unlock-many
446     params:    ( break-lock:bool ( ( path:string [ token:string ] ) ... ) )
447     Before sending response, server sends unlocked paths, ending with "done".
448     pre-response: ( success ( path:string ) ) | ( failure ( err:error ) )
449                   | done
450     response:  ( )
451
452   get-lock
453     params:    ( path:string )
454     response:  ( [ lock:lockdesc ] )
455
456   get-locks
457     params:    ( path:string ? [ depth:word ] )
458     response   ( ( lock:lockdesc ... ) )
459
460   replay
461     params:    ( revision:number low-water-mark:number send-deltas:bool )
462     After auth exchange completes, server switches to editor command set.
463     After edit completes, server sends response.
464     response   ( )
465
466   replay-range
467     params:    ( start-rev:number end-rev:number low-water-mark:number 
468                  send-deltas:bool )
469     After auth exchange completes, server sends each revision
470     from start-rev to end-rev, alternating between sending 'revprops' 
471     entries and sending the revision in the editor command set.
472     After all revisions are complete, server sends response.
473     revprops:  ( revprops:word props:proplist )
474       (revprops here is the literal word "revprops".)
475     response   ( )
476
477   get-deleted-rev
478     params:   ( path:string peg-rev:number end-rev:number )
479     response: ( deleted-rev:number )
480
481   get-iprops
482     params:   ( path:string [ rev:number ] )
483     response: ( inherited-props:iproplist )
484     New in svn 1.8.  If rev is not specified, the youngest revision is used.
485
486 3.1.2. Editor Command Set
487
488 An edit operation produces only one response, at close-edit or
489 abort-edit time.  However, the consumer may write an error response at
490 any time during the edit in order to terminate the edit operation
491 early; the driver must notice that input is waiting on the connection,
492 read the error, and send an abort-edit operation.  After an error is
493 returned, the consumer must read and discard editing operations until
494 the abort-edit.  In order to prevent TCP deadlock, the consumer must
495 use non-blocking I/O to send an early error response; if writing
496 blocks, the consumer must read and discard edit operations until
497 writing unblocks or it reads an abort-edit.
498
499   target-rev
500     params:   ( rev:number )
501
502   open-root
503     params:   ( [ rev:number ] root-token:string )
504
505   delete-entry
506     params:   ( path:string rev:number dir-token:string )
507
508   add-dir
509     params:   ( path:string parent-token:string child-token:string
510                 [ copy-path:string copy-rev:number ] )
511
512   open-dir
513     params:   ( path:string parent-token:string child-token:string rev:number )
514
515   change-dir-prop
516     params:   ( dir-token:string name:string [ value:string ] )
517
518   close-dir
519     params:   ( dir-token:string )
520
521   absent-dir
522     params:   ( path:string parent-token:string )
523
524   add-file
525     params:   ( path:string dir-token:string file-token:string
526                 [ copy-path:string copy-rev:number ] )
527
528   open-file
529     params:   ( path:string dir-token:string file-token:string rev:number )
530
531   apply-textdelta
532     params:   ( file-token:string [ base-checksum:string ] )
533
534   textdelta-chunk
535     params: ( file-token:string chunk:string )
536
537   textdelta-end
538     params: ( file-token:string )
539
540   change-file-prop
541     params:   ( file-token:string name:string [ value:string ] )
542
543   close-file
544     params:   ( file-token:string [ text-checksum:string ] )
545
546   absent-file
547     params:   ( path:string parent-token:string )
548
549   close-edit
550     params:   ( )
551     response: ( )
552
553   abort-edit
554     params:   ( )
555     response: ( )
556
557   finish-replay
558     params:   ( )
559     Only delivered from server to client, at the end of a replay.
560
561 3.1.3. Report Command Set
562
563 To reduce round-trip delays, report commands do not return responses.
564 Any errors resulting from a report call will be returned to the client
565 by the command which invoked the report (following an abort-edit
566 call).  Errors resulting from an abort-report call are ignored.
567
568   set-path:
569     params: ( path:string rev:number start-empty:bool
570               ? [ lock-token:string ] ? depth:word )
571
572   delete-path:
573     params: ( path:string )
574
575   link-path:
576     params: ( path:string url:string rev:number start-empty:bool 
577               ? [ lock-token:string ] ? depth:word )
578
579   finish-report:
580     params: ( )
581
582   abort-report
583     params: ( )
584
585 4. Extensibility
586 ----------------
587
588 This protocol may be extended in three ways, in decreasing order of
589 desirability:
590
591   * Items may be added to any tuple.  An old implementation will
592     ignore the extra items.
593
594   * Named extensions may be expressed at connection initiation time
595     by the client or server.
596
597   * The protocol version may be bumped.  Clients and servers can then
598     choose to any range of protocol versions.
599
600 4.1. Extending existing commands
601
602 Extending an existing command is normally done by indicating that its
603 tuple is allowed to end where it currently ends, for backwards
604 compatibility, and then tacking on a new, possibly optional, item.
605
606 For example, diff was extended to include a new mandatory text-deltas
607 parameter like this:
608
609   /* OLD */ diff:
610     params:   ( [ rev:number ] target:string recurse:bool ignore-ancestry:bool
611                 url:string )
612   /* NEW */ diff:
613     params:   ( [ rev:number ] target:string recurse:bool ignore-ancestry:bool
614                 url:string ? text-deltas:bool )
615
616 The "?" says that the tuple is allowed to end here, because an old
617 client or server wouldn't know to send the new item.
618
619 For optional parameters, a slightly different approach must be used.
620 set-path was extended to include lock-tokens like this:
621
622   /* OLD */ set-path:
623     params: ( path:string rev:number start-empty:bool )
624
625   /* NEW */ set-path:
626     params: ( path:string rev:number start-empty:bool ? [ lock-token:string ] )
627
628 The new item appears in brackets because, even in the new protocol,
629 the lock-token is still optional.  However, if there's no lock-token
630 to send, an empty tuple must still be transmitted so that future
631 extensions to this command remain possible.