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 )
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
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
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 )
167 uuid gives the universal unique identifier of the repository, and
168 repos-url gives the URL of the repository's root directory. The
169 client can now begin sending commands from the main command set.
173 The following capabilities are currently defined (S indicates a server
174 capability and C indicates a client capability):
176 [CS] edit-pipeline Every released version of Subversion since 1.0
177 announces the edit-pipeline capability; starting
178 in Subversion 1.5, both client and server
179 *require* the other side to announce edit-pipeline.
180 [CS] svndiff1 If both the client and server support svndiff version
181 1, this will be used as the on-the-wire format for
182 svndiff instead of svndiff version 0.
183 [CS] absent-entries If the remote end announces support for this capability,
184 it will accept the absent-dir and absent-file editor
186 [S] commit-revprops If the server presents this capability, it supports the
187 rev-props parameter of the commit command.
189 [S] mergeinfo If the server presents this capability, it supports the
190 get-mergeinfo command. See section 3.1.1.
191 [S] depth If the server presents this capability, it understands
192 requested operational depth (see section 3.1.1) and
193 per-path ambient depth (see section 3.1.3).
198 Commands match the prototypes:
200 command: ( command-name:word params:list )
202 The interpretation of command parameters is different from command to
205 Initially, the client initiates commands from the main command set,
206 and the server responds. Some commands in the main command set can
207 temporarily change the set of commands which may be issued, or change
208 the flow of control so that the server issues commands and the client
211 Here are some miscellaneous prototypes used by the command sets:
213 proplist: ( ( name:string value:string ) ... )
214 propdelta: ( ( name:string [ value:string ] ) ... )
215 node-kind: none|file|dir|unknown
217 lockdesc: ( path:string token:string owner:string [ comment:string ]
218 created:string [ expires:string ] )
222 There are three command sets: the main command set, the editor command
223 set, and the report command set. Initially, the protocol begins in
224 the main command set with the client sending commands; some commands
225 can change the command set and possibly the direction of control.
227 3.1.1. Main Command Set
229 The main command set corresponds to the svn_ra interfaces. After each
230 main command is issued by the client, the server sends an auth-request
231 as described in section 2. (If no new authentication is required, the
232 auth-request contains an empty mechanism list, and the server proceeds
233 immediately to sending the command response.) Some commands include a
234 second place for auth-request point as noted below.
237 params: ( url:string )
242 response: ( rev:number )
245 params: ( date:string )
246 response: ( rev:number )
249 params: ( rev:number name:string ? value:string )
251 If value is not specified, the rev-prop is removed.
252 (Originally the value was required; for minimum impact, it was
253 changed to be optional without creating an optional tuple for
254 that one parameter as we normally do.)
257 params: ( rev:number )
258 response: ( props:proplist )
261 params: ( rev:number name:string )
262 response: ( [ value:string ] )
265 params: ( logmsg:string ? ( ( lock-path:string lock-token:string ) ... )
266 keep-locks:bool ? rev-props:proplist )
268 Upon receiving response, client switches to editor command set.
269 Upon successful completion of edit, server sends auth-request.
270 After auth exchange completes, server sends commit-info.
271 commit-info: ( new-rev:number date:string author:string
272 ? ( post-commit-err:string ) )
275 params: ( path:string [ rev:number ] want-props:bool want-contents:bool )
276 response: ( [ checksum:string ] rev:number props:proplist )
277 If want-contents is specified, then after sending response, server
278 sends file contents as a series of strings, terminated by the empty
279 string, followed by a second empty command response to indicate
280 whether an error occurred during the sending of the file.
283 params: ( path:string [ rev:number ] want-props:bool want-contents:bool
284 ? ( field:dirent-field ... ) )
285 response: ( rev:number props:proplist ( entry:dirent ... ) )]
286 dirent: ( name:string kind:node-kind size:number has-props:bool
287 created-rev:number [ created-date:string ]
288 [ last-author:string ] )
289 dirent-field: kind | size | has-props | created-rev | time | last-author
293 params: ( path:string [ rev:number ] )
294 response: ( kind:node-kind )
295 If path is non-existent, 'svn_node_none' kind is returned.
298 params: ( path:string [ rev:number ] )
299 response: ( ? entry:dirent )
300 dirent: ( name:string kind:node-kind size:number has-props:bool
301 created-rev:number [ created-date:string ]
302 [ last-author:string ] )
303 New in svn 1.2. If path is non-existent, an empty response is returned.
306 params: ( ( path:string ... ) [ rev:number ] inherit:word )
307 response: ( ( ( path:string merge-info:string ) ... ) )
308 New in svn 1.5. If no paths are specified, an empty response is
309 returned. If rev is not specified, the youngest revision is used.
312 params: ( [ rev:number ] target:string recurse:bool
313 ? depth:word send_copyfrom_param:bool )
314 Client switches to report command set.
315 Upon finish-report, server sends auth-request.
316 After auth exchange completes, server switches to editor command set.
317 After edit completes, server sends response.
321 params: ( [ rev:number ] target:string recurse:bool url:string
323 Client switches to report command set.
324 Upon finish-report, server sends auth-request.
325 After auth exchange completes, server switches to editor command set.
326 After edit completes, server sends response.
330 params: ( target:string recurse:bool ? [ rev:number ] ? depth:word )
331 Client switches to report command set.
332 Upon finish-report, server sends auth-request.
333 After auth exchange completes, server switches to editor command set.
334 After edit completes, server sends response.
338 params: ( [ rev:number ] target:string recurse:bool ignore-ancestry:bool
339 url:string ? text-deltas:bool ? depth:word )
340 Client switches to report command set.
341 Upon finish-report, server sends auth-request.
342 After auth exchange completes, server switches to editor command set.
343 After edit completes, server sends response.
347 params: ( ( target-path:string ... ) [ start-rev:number ]
348 [ end-rev:number ] changed-paths:bool strict-node:bool
350 ? include-merged-revisions:bool
351 all-revprops | revprops
352 ? ( revprop:string ... ) )
353 Before sending response, server sends log entries, ending with "done".
354 If a client does not want to specify a limit, it should send 0 as the
355 limit parameter. rev-props excludes author, date, and log; they are
356 sent separately for backwards-compatibility.
357 log-entry: ( ( change:changed-path-entry ... ) rev:number
358 [ author:string ] [ date:string ] [ message:string ]
359 ? has-children:bool invalid-revnum:bool
360 revprop-count:number rev-props:proplist )
362 changed-path-entry: ( path:string A|D|R|M [ copy-path:string ]
363 [ copy-rev:number ] )
367 params: ( path:string peg-rev:number ( rev:number ... ) )
368 Before sending response, server sends location entries, ending with "done".
369 location-entry: ( rev:number abs-path:number ) | done
372 get-location-segments
373 params: ( path:string [ start-rev:number ] [ end-rev:number ] )
374 Before sending response, server sends location entries, ending with "done".
375 location-entry: ( range-start:number range-end:number [ abs-path:string ] ) | done
379 params: ( path:string [ start-rev:number ] [ end-rev:number ]
380 ? include-merged-revisions:bool )
381 Before sending response, server sends file-rev entries, ending with "done".
382 file-rev: ( path:string rev:number rev-props:proplist
383 file-props:propdelta ? merged-revision:bool )
385 After each file-rev, the file delta is sent as one or more strings,
386 terminated by the empty string. If there is no delta, server just sends
391 params: ( path:string [ comment:string ] steal-lock:bool
392 [ current-rev:number ] )
393 response: ( lock:lockdesc )
396 params: ( [ comment:string ] steal-lock:bool ( ( path:string
397 [ current-rev:number ] ) ... ) )
398 Before sending response, server sends lock cmd status and descriptions,
400 lock-info: ( success ( lock:lockdesc ) ) | ( failure ( err:error ) )
405 params: ( path:string [ token:string ] break-lock:bool )
409 params: ( break-lock:bool ( ( path:string [ token:string ] ) ... ) )
410 Before sending response, server sends unlocked paths, ending with "done".
411 pre-response: ( success ( path:string ) ) | ( failure ( err:error ) )
416 params: ( path:string )
417 response: ( [ lock:lockdesc ] )
420 params: ( path:string )
421 response ( ( lock:lockdesc ... ) )
424 params: ( revision:number low-water-mark:number send-deltas:bool )
425 After auth exchange completes, server switches to editor command set.
426 After edit completes, server sends response.
430 params: ( start-rev:number end-rev:number low-water-mark:number
432 After auth exchange completes, server sends each revision
433 from start-rev to end-rev, alternating between sending 'revprops'
434 entries and sending the revision in the editor command set.
435 After all revisions are complete, server sends response.
436 revprops: ( props:proplist )
439 3.1.2. Editor Command Set
441 An edit operation produces only one response, at close-edit or
442 abort-edit time. However, the consumer may write an error response at
443 any time during the edit in order to terminate the edit operation
444 early; the driver must notice that input is waiting on the connection,
445 read the error, and send an abort-edit operation. After an error is
446 returned, the consumer must read and discard editing operations until
447 the abort-edit. In order to prevent TCP deadlock, the consumer must
448 use non-blocking I/O to send an early error response; if writing
449 blocks, the consumer must read and discard edit operations until
450 writing unblocks or it reads an abort-edit.
453 params: ( rev:number )
456 params: ( [ rev:number ] root-token:string )
459 params: ( path:string rev:number dir-token:string )
462 params: ( path:string parent-token:string child-token:string
463 [ copy-path:string copy-rev:number ] )
466 params: ( path:string parent-token:string child-token:string rev:number )
469 params: ( dir-token:string name:string [ value:string ] )
472 params: ( dir-token:string )
475 params: ( path:string parent-token:string )
478 params: ( path:string dir-token:string file-token:string
479 [ copy-path:string copy-rev:number ] )
482 params: ( path:string dir-token:string file-token:string rev:number )
485 params: ( file-token:string [ base-checksum:string ] )
488 params: ( file-token:string chunk:string )
491 params: ( file-token:string )
494 params: ( file-token:string name:string [ value:string ] )
497 params: ( file-token:string [ text-checksum:string ] )
500 params: ( path:string parent-token:string )
512 Only delivered from server to client, at the end of a replay.
514 3.1.3. Report Command Set
516 To reduce round-trip delays, report commands do not return responses.
517 Any errors resulting from a report call will be returned to the client
518 by the command which invoked the report (following an abort-edit
519 call). Errors resulting from an abort-report call are ignored.
522 params: ( path:string rev:number start-empty:bool
523 ? [ lock-token:string ] ? depth:word )
526 params: ( path:string )
529 params: ( path:string url:string rev:number start-empty:bool
530 ? [ lock-token:string ] ? depth:word )
541 This protocol may be extended in three ways, in decreasing order of
544 * Items may be added to any tuple. An old implementation will
545 ignore the extra items.
547 * Named extensions may be expressed at connection initiation time
548 by the client or server.
550 * The protocol version may be bumped. Clients and servers can then
551 choose to any range of protocol versions.
553 4.1. Extending existing commands
555 Extending an existing command is normally done by indicating that its
556 tuple is allowed to end where it currently ends, for backwards
557 compatibility, and then tacking on a new, possibly optional, item.
559 For example, diff was extended to include a new mandatory text-deltas
563 params: ( [ rev:number ] target:string recurse:bool ignore-ancestry:bool
566 params: ( [ rev:number ] target:string recurse:bool ignore-ancestry:bool
567 url:string ? text-deltas:bool )
569 The "?" says that the tuple is allowed to end here, because an old
570 client or server wouldn't know to send the new item.
572 For optional parameters, a slightly different approach must be used.
573 set-path was extended to include lock-tokens like this:
576 params: ( path:string rev:number start-empty:bool )
579 params: ( path:string rev:number start-empty:bool ? [ lock-token:string ] )
581 The new item appears in brackets because, even in the new protocol,
582 the lock-token is still optional. However, if there's no lock-token
583 to send, an empty tuple must still be transmitted so that future
584 extensions to this command remain possible.