1 This file documents version 2 of the svn protocol.
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
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 )
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
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
113 ? ra-client:string ( ? client:string ) )
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.
122 Upon receiving the client's response to the greeting, the server sends
123 an authentication request, which is a command response whose arguments
126 auth-request: ( ( mech:word ... ) realm:string )
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:
136 auth-response: ( mech:word [ token:string ] )
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:
144 challenge: ( step ( token:string ) )
145 | ( failure ( message:string ) )
146 | ( success [ token:string ] )
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.
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.
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.
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
166 After a successful authentication exchange, the server sends a command
167 response whose parameters match the prototype:
169 repos-info: ( uuid:string repos-url:string ( cap:word ... ) )
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).
177 The client can now begin sending commands from the main command set.
181 The following capabilities are currently defined (S indicates a server
182 capability and C indicates a client capability):
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
194 [S] commit-revprops If the server presents this capability, it supports the
195 rev-props parameter of the commit command.
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.
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).
213 Commands match the prototypes:
215 command: ( command-name:word params:list )
217 The interpretation of command parameters is different from command to
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
226 Here are some miscellaneous prototypes used by the command sets:
228 proplist: ( ( name:string value:string ) ... )
229 iproplist: ( ( name:string proplist ) ... )
230 propdelta: ( ( name:string [ value:string ] ) ... )
231 node-kind: none|file|dir|unknown
233 lockdesc: ( path:string token:string owner:string [ comment:string ]
234 created:string [ expires:string ] )
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.
243 3.1.1. Main Command Set
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.
253 params: ( url:string )
258 response: ( rev:number )
261 params: ( date:string )
262 response: ( rev:number )
265 params: ( rev:number name:string ? value:string )
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.)
273 params: ( rev:number name:string [ value:string ]
274 ( dont-care:bool ? previous-value:string ) )
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.
283 params: ( rev:number )
284 response: ( props:proplist )
287 params: ( rev:number name:string )
288 response: ( [ value:string ] )
291 params: ( logmsg:string ? ( ( lock-path:string lock-token:string ) ... )
292 keep-locks:bool ? rev-props:proplist )
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'.
305 params: ( path:string [ rev:number ] want-props:bool want-contents: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 doesn't send want-iprops as true, it uses
314 get-iprops, but does send want-iprops as false to workaround a server
318 params: ( path:string [ rev:number ] want-props:bool want-contents:bool
319 ? ( field:dirent-field ... ) ? want-iprops:bool )
320 response: ( rev:number props:proplist ( entry:dirent ... )
321 [ inherited-props:iproplist ] )]
322 dirent: ( name:string kind:node-kind size:number has-props:bool
323 created-rev:number [ created-date:string ]
324 [ last-author:string ] )
325 dirent-field: kind | size | has-props | created-rev | time | last-author
327 NOTE: the standard client doesn't send want-iprops as true, it uses
328 get-iprops, but does send want-iprops as false to workaround a server
332 params: ( path:string [ rev:number ] )
333 response: ( kind:node-kind )
334 If path is non-existent, 'svn_node_none' kind is returned.
337 params: ( path:string [ rev:number ] )
338 response: ( ? entry:dirent )
339 dirent: ( name:string kind:node-kind size:number has-props:bool
340 created-rev:number [ created-date:string ]
341 [ last-author:string ] )
342 New in svn 1.2. If path is non-existent, an empty response is returned.
345 params: ( ( path:string ... ) [ rev:number ] inherit:word
347 response: ( ( ( path:string merge-info:string ) ... ) )
348 New in svn 1.5. If no paths are specified, an empty response is
349 returned. If rev is not specified, the youngest revision is used.
352 params: ( [ rev:number ] target:string recurse:bool
353 ? depth:word send_copyfrom_args:bool ? ignore_ancestry:bool )
354 Client switches to report command set.
355 Upon finish-report, server sends auth-request.
356 After auth exchange completes, server switches to editor command set.
357 After edit completes, server sends response.
361 params: ( [ rev:number ] target:string recurse:bool url:string
362 ? depth:word ? send_copyfrom_args:bool ignore_ancestry:bool )
363 Client switches to report command set.
364 Upon finish-report, server sends auth-request.
365 After auth exchange completes, server switches to editor command set.
366 After edit completes, server sends response.
370 params: ( target:string recurse:bool ? [ rev:number ] ? depth:word )
371 Client switches to report command set.
372 Upon finish-report, server sends auth-request.
373 After auth exchange completes, server switches to editor command set.
374 After edit completes, server sends response.
378 params: ( [ rev:number ] target:string recurse:bool ignore-ancestry:bool
379 url:string ? text-deltas:bool ? depth:word )
380 Client switches to report command set.
381 Upon finish-report, server sends auth-request.
382 After auth exchange completes, server switches to editor command set.
383 After edit completes, server sends response.
387 params: ( ( target-path:string ... ) [ start-rev:number ]
388 [ end-rev:number ] changed-paths:bool strict-node:bool
390 ? include-merged-revisions:bool
391 all-revprops | revprops ( revprop:string ... ) )
392 Before sending response, server sends log entries, ending with "done".
393 If a client does not want to specify a limit, it should send 0 as the
394 limit parameter. rev-props excludes author, date, and log; they are
395 sent separately for backwards-compatibility.
396 log-entry: ( ( change:changed-path-entry ... ) rev:number
397 [ author:string ] [ date:string ] [ message:string ]
398 ? has-children:bool invalid-revnum:bool
399 revprop-count:number rev-props:proplist
400 ? subtractive-merge:bool )
402 changed-path-entry: ( path:string A|D|R|M
403 ? ( ? copy-path:string copy-rev:number )
404 ? ( ? node-kind:string ? text-mods:bool prop-mods:bool ) )
408 params: ( path:string peg-rev:number ( rev:number ... ) )
409 Before sending response, server sends location entries, ending with "done".
410 location-entry: ( rev:number abs-path:number ) | done
413 get-location-segments
414 params: ( path:string [ start-rev:number ] [ end-rev:number ] )
415 Before sending response, server sends location entries, ending with "done".
416 location-entry: ( range-start:number range-end:number [ abs-path:string ] ) | done
420 params: ( path:string [ start-rev:number ] [ end-rev:number ]
421 ? include-merged-revisions:bool )
422 Before sending response, server sends file-rev entries, ending with "done".
423 file-rev: ( path:string rev:number rev-props:proplist
424 file-props:propdelta ? merged-revision:bool )
426 After each file-rev, the file delta is sent as one or more strings,
427 terminated by the empty string. If there is no delta, server just sends
432 params: ( path:string [ comment:string ] steal-lock:bool
433 [ current-rev:number ] )
434 response: ( lock:lockdesc )
437 params: ( [ comment:string ] steal-lock:bool ( ( path:string
438 [ current-rev:number ] ) ... ) )
439 Before sending response, server sends lock cmd status and descriptions,
441 lock-info: ( success ( lock:lockdesc ) ) | ( failure ( err:error ) )
446 params: ( path:string [ token:string ] break-lock:bool )
450 params: ( break-lock:bool ( ( path:string [ token:string ] ) ... ) )
451 Before sending response, server sends unlocked paths, ending with "done".
452 pre-response: ( success ( path:string ) ) | ( failure ( err:error ) )
457 params: ( path:string )
458 response: ( [ lock:lockdesc ] )
461 params: ( path:string ? [ depth:word ] )
462 response ( ( lock:lockdesc ... ) )
465 params: ( revision:number low-water-mark:number send-deltas:bool )
466 After auth exchange completes, server switches to editor command set.
467 After edit completes, server sends response.
471 params: ( start-rev:number end-rev:number low-water-mark:number
473 After auth exchange completes, server sends each revision
474 from start-rev to end-rev, alternating between sending 'revprops'
475 entries and sending the revision in the editor command set.
476 After all revisions are complete, server sends response.
477 revprops: ( revprops:word props:proplist )
478 (revprops here is the literal word "revprops".)
482 params: ( path:string peg-rev:number end-rev:number )
483 response: ( deleted-rev:number )
486 params: ( path:string [ rev:number ] )
487 response: ( inherited-props:iproplist )
488 New in svn 1.8. If rev is not specified, the youngest revision is used.
490 3.1.2. Editor Command Set
492 An edit operation produces only one response, at close-edit or
493 abort-edit time. However, the consumer may write an error response at
494 any time during the edit in order to terminate the edit operation
495 early; the driver must notice that input is waiting on the connection,
496 read the error, and send an abort-edit operation. After an error is
497 returned, the consumer must read and discard editing operations until
498 the abort-edit. In order to prevent TCP deadlock, the consumer must
499 use non-blocking I/O to send an early error response; if writing
500 blocks, the consumer must read and discard edit operations until
501 writing unblocks or it reads an abort-edit.
504 params: ( rev:number )
507 params: ( [ rev:number ] root-token:string )
510 params: ( path:string rev:number dir-token:string )
513 params: ( path:string parent-token:string child-token:string
514 [ copy-path:string copy-rev:number ] )
517 params: ( path:string parent-token:string child-token:string rev:number )
520 params: ( dir-token:string name:string [ value:string ] )
523 params: ( dir-token:string )
526 params: ( path:string parent-token:string )
529 params: ( path:string dir-token:string file-token:string
530 [ copy-path:string copy-rev:number ] )
533 params: ( path:string dir-token:string file-token:string rev:number )
536 params: ( file-token:string [ base-checksum:string ] )
539 params: ( file-token:string chunk:string )
542 params: ( file-token:string )
545 params: ( file-token:string name:string [ value:string ] )
548 params: ( file-token:string [ text-checksum:string ] )
551 params: ( path:string parent-token:string )
563 Only delivered from server to client, at the end of a replay.
565 3.1.3. Report Command Set
567 To reduce round-trip delays, report commands do not return responses.
568 Any errors resulting from a report call will be returned to the client
569 by the command which invoked the report (following an abort-edit
570 call). Errors resulting from an abort-report call are ignored.
573 params: ( path:string rev:number start-empty:bool
574 ? [ lock-token:string ] ? depth:word )
577 params: ( path:string )
580 params: ( path:string url:string rev:number start-empty:bool
581 ? [ lock-token:string ] ? depth:word )
592 This protocol may be extended in three ways, in decreasing order of
595 * Items may be added to any tuple. An old implementation will
596 ignore the extra items.
598 * Named extensions may be expressed at connection initiation time
599 by the client or server.
601 * The protocol version may be bumped. Clients and servers can then
602 choose to any range of protocol versions.
606 The current implementation limits the length of a word to 31 characters.
607 Longer words, such as capability names, will be cause an error on the
610 4.2. Extending existing commands
612 Extending an existing command is normally done by indicating that its
613 tuple is allowed to end where it currently ends, for backwards
614 compatibility, and then tacking on a new, possibly optional, item.
616 For example, diff was extended to include a new mandatory text-deltas
620 params: ( [ rev:number ] target:string recurse:bool ignore-ancestry:bool
623 params: ( [ rev:number ] target:string recurse:bool ignore-ancestry:bool
624 url:string ? text-deltas:bool )
626 The "?" says that the tuple is allowed to end here, because an old
627 client or server wouldn't know to send the new item.
629 For optional parameters, a slightly different approach must be used.
630 set-path was extended to include lock-tokens like this:
633 params: ( path:string rev:number start-empty:bool )
636 params: ( path:string rev:number start-empty:bool ? [ lock-token:string ] )
638 The new item appears in brackets because, even in the new protocol,
639 the lock-token is still optional. However, if there's no lock-token
640 to send, an empty tuple must still be transmitted so that future
641 extensions to this command remain possible.