]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/subversion/subversion/libsvn_ra_svn/protocol
Update Subversion and dependencies to 1.14.0 LTS.
[FreeBSD/FreeBSD.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] accepts-svndiff2  This capability advertises support for accepting
192                        svndiff2 deltas.  The sender of a delta (= the editor
193                        driver) may send it in any svndiff version the receiver
194                        has announced it can accept.
195 [CS] absent-entries    If the remote end announces support for this capability,
196                        it will accept the absent-dir and absent-file editor
197                        commands.
198 [S]  commit-revprops   If the server presents this capability, it supports the 
199                        rev-props parameter of the commit command.
200                        See section 3.1.1.
201 [S]  mergeinfo         If the server presents this capability, it supports the 
202                        get-mergeinfo command.  See section 3.1.1.
203 [S]  depth             If the server presents this capability, it understands
204                        requested operational depth (see section 3.1.1) and
205                        per-path ambient depth (see section 3.1.3).
206 [S]  atomic-revprops   If the server presents this capability, it
207                        supports the change-rev-prop2 command.
208                        See section 3.1.1.
209 [S]  inherited-props   If the server presents this capability, it supports the
210                        retrieval of inherited properties via the get-dir and
211                        get-file commands and also supports the get-iprops
212                        command (see section 3.1.1).
213 [S]  list              If the server presents this capability, it supports the
214                        list command (see section 3.1.1).
215
216 3. Commands
217 -----------
218
219 Commands match the prototypes:
220
221   command: ( command-name:word params:list )
222
223 The interpretation of command parameters is different from command to
224 command.
225
226 Initially, the client initiates commands from the main command set,
227 and the server responds.  Some commands in the main command set can
228 temporarily change the set of commands which may be issued, or change
229 the flow of control so that the server issues commands and the client
230 responds.
231
232 Here are some miscellaneous prototypes used by the command sets:
233
234   proplist:  ( ( name:string value:string ) ... )
235   iproplist: ( ( name:string proplist ) ... )
236   propdelta: ( ( name:string [ value:string ] ) ... )
237   node-kind: none|file|dir|unknown
238   bool:      true|false
239   lockdesc:  ( path:string token:string owner:string [ comment:string ]
240                created:string [ expires:string ] )
241
242 3.1. Command Sets
243
244 There are three command sets: the main command set, the editor command
245 set, and the report command set.  Initially, the protocol begins in
246 the main command set with the client sending commands; some commands
247 can change the command set and possibly the direction of control.
248
249 3.1.1. Main Command Set
250
251 The main command set corresponds to the svn_ra interfaces.  After each
252 main command is issued by the client, the server sends an auth-request
253 as described in section 2.  (If no new authentication is required, the
254 auth-request contains an empty mechanism list, and the server proceeds
255 immediately to sending the command response.)  Some commands include a
256 second place for auth-request point as noted below.
257
258   reparent
259     params:   ( url:string )
260     response: ( )
261
262   get-latest-rev
263     params:   ( )
264     response: ( rev:number )
265
266   get-dated-rev
267     params:   ( date:string )
268     response: ( rev:number )
269
270   change-rev-prop
271     params:   ( rev:number name:string ? value:string )
272     response: ( )
273     If value is not specified, the rev-prop is removed.
274     (Originally the value was required; for minimum impact, it was
275      changed to be optional without creating an optional tuple for
276      that one parameter as we normally do.)
277
278   change-rev-prop2
279     params:   ( rev:number name:string [ value:string ]
280                 ( dont-care:bool ? previous-value:string ) )
281     response: ( )
282     If value is not specified, the rev-prop is removed.  If dont-care is false,
283     then the rev-prop is changed only if it is currently set as previous-value
284     indicates.  (If dont-care is false and previous-value is unspecified, then
285     the revision property must be previously unset.)  If dont-care is true,
286     then previous-value must not be specified.
287
288   rev-proplist
289     params:   ( rev:number )
290     response: ( props:proplist )
291
292   rev-prop
293     params:   ( rev:number name:string )
294     response: ( [ value:string ] )
295
296   commit
297     params:   ( logmsg:string ? ( ( lock-path:string lock-token:string ) ... )
298                 keep-locks:bool ? rev-props:proplist )
299     response: ( )
300     Upon receiving response, client switches to editor command set.
301     Upon successful completion of edit, server sends auth-request.
302     After auth exchange completes, server sends commit-info.
303     If rev-props is present, logmsg is ignored.  Only the svn:log entry in
304     rev-props (if any) will be used.
305     commit-info: ( new-rev:number date:string author:string
306                    ? ( post-commit-err:string ) )
307     NOTE: when revving this, make 'logmsg' optional, or delete that parameter
308           and have the log message specified in 'rev-props'.
309
310   get-file
311     params:   ( path:string [ rev:number ] want-props:bool want-contents:bool
312                 ? want-iprops:bool )
313     response: ( [ checksum:string ] rev:number props:proplist
314                 [ inherited-props:iproplist ] )
315     If want-contents is specified, then after sending response, server
316      sends file contents as a series of strings, terminated by the empty
317      string, followed by a second empty command response to indicate
318      whether an error occurred during the sending of the file.
319     NOTE: the standard client doesn't send want-iprops as true, it uses
320      get-iprops, but does send want-iprops as false to workaround a server
321      bug in 1.8.0-1.8.8.
322
323   get-dir
324     params:   ( path:string [ rev:number ] want-props:bool want-contents:bool
325                 ? ( field:dirent-field ... ) ? want-iprops:bool )
326     response: ( rev:number props:proplist ( entry:dirent ... )
327                 [ inherited-props:iproplist ] )]
328     dirent:   ( name:string kind:node-kind size:number has-props:bool
329                 created-rev:number [ created-date:string ]
330                 [ last-author:string ] )
331     dirent-field: kind | size | has-props | created-rev | time | last-author
332                   | word
333     NOTE: the standard client doesn't send want-iprops as true, it uses
334      get-iprops, but does send want-iprops as false to workaround a server
335      bug in 1.8.0-1.8.8.
336
337   check-path
338     params:   ( path:string [ rev:number ] )
339     response: ( kind:node-kind )
340     If path is non-existent, 'svn_node_none' kind is returned.
341
342   stat
343     params:   ( path:string [ rev:number ] )
344     response: ( ? entry:dirent )
345     dirent:   ( kind:node-kind size:number has-props:bool
346                 created-rev:number [ created-date:string ]
347                 [ last-author:string ] )
348     New in svn 1.2.  If path is non-existent, an empty response is returned.
349
350   get-mergeinfo
351     params:   ( ( path:string ... ) [ rev:number ] inherit:word 
352                 descendants:bool)
353     response: ( ( ( path:string merge-info:string ) ... ) )
354     New in svn 1.5.  If no paths are specified, an empty response is
355     returned.  If rev is not specified, the youngest revision is used.
356
357   update
358     params:   ( [ rev:number ] target:string recurse:bool
359                 ? depth:word send_copyfrom_args:bool ? ignore_ancestry:bool )
360     Client switches to report command set.
361     Upon finish-report, server sends auth-request.
362     After auth exchange completes, server switches to editor command set.
363     After edit completes, server sends response.
364     response: ( )
365
366   switch
367     params:   ( [ rev:number ] target:string recurse:bool url:string
368                 ? depth:word ? send_copyfrom_args:bool ignore_ancestry:bool )
369     Client switches to report command set.
370     Upon finish-report, server sends auth-request.
371     After auth exchange completes, server switches to editor command set.
372     After edit completes, server sends response.
373     response: ( )
374
375   status
376     params:   ( target:string recurse:bool ? [ rev:number ] ? depth:word )
377     Client switches to report command set.
378     Upon finish-report, server sends auth-request.
379     After auth exchange completes, server switches to editor command set.
380     After edit completes, server sends response.
381     response: ( )
382
383   diff
384     params:   ( [ rev:number ] target:string recurse:bool ignore-ancestry:bool
385                 url:string ? text-deltas:bool ? depth:word )
386     Client switches to report command set.
387     Upon finish-report, server sends auth-request.
388     After auth exchange completes, server switches to editor command set.
389     After edit completes, server sends response.
390     response: ( )
391
392   log
393     params:   ( ( target-path:string ... ) [ start-rev:number ]
394                 [ end-rev:number ] changed-paths:bool strict-node:bool
395                 ? limit:number
396                 ? include-merged-revisions:bool
397                 all-revprops | revprops ( revprop:string ... ) )
398     Before sending response, server sends log entries, ending with "done".
399     If a client does not want to specify a limit, it should send 0 as the
400     limit parameter.  rev-props excludes author, date, and log; they are
401     sent separately for backwards-compatibility.
402     log-entry: ( ( change:changed-path-entry ... ) rev:number
403                  [ author:string ] [ date:string ] [ message:string ]
404                  ? has-children:bool invalid-revnum:bool
405                  revprop-count:number rev-props:proplist
406                  ? subtractive-merge:bool )
407              | done
408     changed-path-entry: ( path:string A|D|R|M
409                           ? ( ? copy-path:string copy-rev:number )
410                           ? ( ? node-kind:string ? text-mods:bool prop-mods:bool ) )
411     response: ( )
412
413   get-locations
414     params:   ( path:string peg-rev:number ( rev:number ... ) )
415     Before sending response, server sends location entries, ending with "done".
416     location-entry: ( rev:number abs-path:number ) | done
417     response: ( )
418
419   get-location-segments
420     params:   ( path:string [ start-rev:number ] [ end-rev:number ] )
421     Before sending response, server sends location entries, ending with "done".
422     location-entry: ( range-start:number range-end:number [ abs-path:string ] ) | done
423     response: ( )
424
425   get-file-revs
426     params:   ( path:string [ start-rev:number ] [ end-rev:number ]
427                 ? include-merged-revisions:bool )
428     Before sending response, server sends file-rev entries, ending with "done".
429     file-rev: ( path:string rev:number rev-props:proplist
430                 file-props:propdelta ? merged-revision:bool )
431               | done
432     After each file-rev, the file delta is sent as one or more strings,
433     terminated by the empty string.  If there is no delta, server just sends
434     the terminator.
435     response: ( )
436
437   lock
438     params:    ( path:string [ comment:string ] steal-lock:bool
439                  [ current-rev:number ] )
440     response:  ( lock:lockdesc )
441
442   lock-many
443     params:    ( [ comment:string ] steal-lock:bool ( ( path:string
444                  [ current-rev:number ] ) ... ) )
445     Before sending response, server sends lock cmd status and descriptions,
446     ending with "done".
447     lock-info: ( success ( lock:lockdesc ) ) | ( failure ( err:error ) )
448                 | done
449     response: ( )
450
451   unlock
452     params:    ( path:string [ token:string ] break-lock:bool )
453     response:  ( )
454
455   unlock-many
456     params:    ( break-lock:bool ( ( path:string [ token:string ] ) ... ) )
457     Before sending response, server sends unlocked paths, ending with "done".
458     pre-response: ( success ( path:string ) ) | ( failure ( err:error ) )
459                   | done
460     response:  ( )
461
462   get-lock
463     params:    ( path:string )
464     response:  ( [ lock:lockdesc ] )
465
466   get-locks
467     params:    ( path:string ? [ depth:word ] )
468     response   ( ( lock:lockdesc ... ) )
469
470   replay
471     params:    ( revision:number low-water-mark:number send-deltas:bool )
472     After auth exchange completes, server switches to editor command set.
473     After edit completes, server sends response.
474     response   ( )
475
476   replay-range
477     params:    ( start-rev:number end-rev:number low-water-mark:number 
478                  send-deltas:bool )
479     After auth exchange completes, server sends each revision
480     from start-rev to end-rev, alternating between sending 'revprops' 
481     entries and sending the revision in the editor command set.
482     After all revisions are complete, server sends response.
483     revprops:  ( revprops:word props:proplist )
484       (revprops here is the literal word "revprops".)
485     response   ( )
486
487   get-deleted-rev
488     params:   ( path:string peg-rev:number end-rev:number )
489     response: ( deleted-rev:number )
490
491   get-iprops
492     params:   ( path:string [ rev:number ] )
493     response: ( inherited-props:iproplist )
494     New in svn 1.8.  If rev is not specified, the youngest revision is used.
495
496   list
497     params:   ( path:string [ rev:number ] depth:word
498                 ( field:dirent-field ... ) ? ( pattern:string ... ) )
499     Before sending response, server sends dirents, ending with "done".
500     dirent:   ( rel-path:string kind:node-kind
501                 ? [ size:number ] [ has-props:bool ] [ created-rev:number ]
502                   [ created-date:string ] [ last-author:string ] )
503               | done
504     dirent-field: kind | size | has-props | created-rev | time | last-author
505                   | word
506     response: ( )
507     New in svn 1.10.  If rev is not specified, the youngest revision is used.
508     If the dirent-fields don't contain "kind", "unknown" will be returned
509     in the kind field.
510
511 3.1.2. Editor Command Set
512
513 An edit operation produces only one response, at close-edit or
514 abort-edit time.  However, the consumer may write an error response at
515 any time during the edit in order to terminate the edit operation
516 early; the driver must notice that input is waiting on the connection,
517 read the error, and send an abort-edit operation.  After an error is
518 returned, the consumer must read and discard editing operations until
519 the abort-edit.  In order to prevent TCP deadlock, the consumer must
520 use non-blocking I/O to send an early error response; if writing
521 blocks, the consumer must read and discard edit operations until
522 writing unblocks or it reads an abort-edit.
523
524   target-rev
525     params:   ( rev:number )
526
527   open-root
528     params:   ( [ rev:number ] root-token:string )
529
530   delete-entry
531     params:   ( path:string rev:number dir-token:string )
532
533   add-dir
534     params:   ( path:string parent-token:string child-token:string
535                 [ copy-path:string copy-rev:number ] )
536
537   open-dir
538     params:   ( path:string parent-token:string child-token:string rev:number )
539
540   change-dir-prop
541     params:   ( dir-token:string name:string [ value:string ] )
542
543   close-dir
544     params:   ( dir-token:string )
545
546   absent-dir
547     params:   ( path:string parent-token:string )
548
549   add-file
550     params:   ( path:string dir-token:string file-token:string
551                 [ copy-path:string copy-rev:number ] )
552
553   open-file
554     params:   ( path:string dir-token:string file-token:string rev:number )
555
556   apply-textdelta
557     params:   ( file-token:string [ base-checksum:string ] )
558
559   textdelta-chunk
560     params: ( file-token:string chunk:string )
561
562   textdelta-end
563     params: ( file-token:string )
564
565   change-file-prop
566     params:   ( file-token:string name:string [ value:string ] )
567
568   close-file
569     params:   ( file-token:string [ text-checksum:string ] )
570
571   absent-file
572     params:   ( path:string parent-token:string )
573
574   close-edit
575     params:   ( )
576     response: ( )
577
578   abort-edit
579     params:   ( )
580     response: ( )
581
582   finish-replay
583     params:   ( )
584     Only delivered from server to client, at the end of a replay.
585
586 3.1.3. Report Command Set
587
588 To reduce round-trip delays, report commands do not return responses.
589 Any errors resulting from a report call will be returned to the client
590 by the command which invoked the report (following an abort-edit
591 call).  Errors resulting from an abort-report call are ignored.
592
593   set-path:
594     params: ( path:string rev:number start-empty:bool
595               ? [ lock-token:string ] ? depth:word )
596
597   delete-path:
598     params: ( path:string )
599
600   link-path:
601     params: ( path:string url:string rev:number start-empty:bool 
602               ? [ lock-token:string ] ? depth:word )
603
604   finish-report:
605     params: ( )
606
607   abort-report
608     params: ( )
609
610 4. Extensibility
611 ----------------
612
613 This protocol may be extended in three ways, in decreasing order of
614 desirability:
615
616   * Items may be added to any tuple.  An old implementation will
617     ignore the extra items.
618
619   * Named extensions may be expressed at connection initiation time
620     by the client or server.
621
622   * The protocol version may be bumped.  Clients and servers can then
623     choose to any range of protocol versions.
624
625 4.1. Limitations
626
627 The current implementation limits the length of a word to 31 characters.
628 Longer words, such as capability names, will be cause an error on the
629 receiver side.
630
631 4.2. Extending existing commands
632
633 Extending an existing command is normally done by indicating that its
634 tuple is allowed to end where it currently ends, for backwards
635 compatibility, and then tacking on a new, possibly optional, item.
636
637 For example, diff was extended to include a new mandatory text-deltas
638 parameter like this:
639
640   /* OLD */ diff:
641     params:   ( [ rev:number ] target:string recurse:bool ignore-ancestry:bool
642                 url:string )
643   /* NEW */ diff:
644     params:   ( [ rev:number ] target:string recurse:bool ignore-ancestry:bool
645                 url:string ? text-deltas:bool )
646
647 The "?" says that the tuple is allowed to end here, because an old
648 client or server wouldn't know to send the new item.
649
650 For optional parameters, a slightly different approach must be used.
651 set-path was extended to include lock-tokens like this:
652
653   /* OLD */ set-path:
654     params: ( path:string rev:number start-empty:bool )
655
656   /* NEW */ set-path:
657     params: ( path:string rev:number start-empty:bool ? [ lock-token:string ] )
658
659 The new item appears in brackets because, even in the new protocol,
660 the lock-token is still optional.  However, if there's no lock-token
661 to send, an empty tuple must still be transmitted so that future
662 extensions to this command remain possible.