* subversion/libsvn_fs_fs/structure
[svn.git] / www / hacking.html
blob4b1c79d2b3a458662673d5f158cc834d3be5dc19
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml">
4 <head>
5 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
6 <style type="text/css"> /* <![CDATA[ */
7 @import "branding/css/tigris.css";
8 @import "branding/css/inst.css";
9 /* ]]> */</style>
10 <link rel="stylesheet" type="text/css" media="print"
11 href="branding/css/print.css" />
12 <script type="text/javascript" src="branding/scripts/tigris.js"></script>
13 <title>Hacker's Guide to Subversion</title>
14 </head>
16 <body>
17 <div class="app">
19 <h1 style="text-align: center;">Hacker's Guide to Subversion</h1>
21 <p>If you are contributing code to the Subversion project, please read
22 this first.</p>
24 <pre>
25 $LastChangedDate$
26 </pre>
29 <!-- Other pages seem to use "h2" for ToC, but I think "h1" works
30 better, because the ToC is fundamentally different from other
31 sections and therefore it's confusing when it looks the same as
32 the others. -->
33 <div class="h1"><!-- no 'id' or 'title' attribute for ToC -->
34 <h1>Table of Contents</h1>
36 <ul>
37 <li><a href="#participating">Participating in the community</a></li>
38 <li><a href="#docs">Theory and documentation</a></li>
39 <li><a href="#code-to-read">Code to read</a></li>
40 <li><a href="#directory-layout">Directory layout</a></li>
41 <li><a href="#coding-style">Coding style</a></li>
42 <li><a href="#secure-coding">Secure coding guidelines</a></li>
43 <li><a href="#destruction-of-stacked-resources">Destruction of stacked resources</a></li>
44 <li><a href="#documenting">Documentation</a></li>
45 <li><a href="#use-page-breaks">Using page breaks</a></li>
46 <li><a href="#error-messages">Error message conventions</a></li>
47 <li><a href="#other-conventions">Other conventions</a></li>
48 <li><a href="#apr-pools">APR pool usage conventions</a></li>
49 <li><a href="#apr-status-codes">APR status codes</a></li>
50 <li><a href="#exception-handling">Exception handling</a></li>
51 <li><a href="#automated-tests">Automated tests</a></li>
52 <li><a href="#write-test-cases-first">Writing test cases before code</a></li>
53 <li><a href="#server-debugging">Debugging the server</a></li>
54 <li><a href="#tracing-memory-leaks">Tracking down memory leaks</a></li>
55 <li><a href="#log-messages">Writing log messages</a></li>
56 <li><a href="#crediting">Crediting</a></li>
57 <li><a href="#patches">Patch submission guidelines</a></li>
58 <li><a href="#filing-issues">Filing bugs / issues</a></li>
59 <li><a href="#issue-triage">Issue triage</a></li>
60 <li><a href="#commit-access">Commit access</a></li>
61 <li><a href="#lightweight-branches">Use lightweight branches</a></li>
62 <li><a href="#configury">The configuration/build system under unix</a></li>
63 <li><a href="#releasing">How to release a distribution tarball</a></li>
64 <li><a href="#release-numbering">Release numbering, compatibility, and deprecation</a></li>
65 <li><a href="#release-stabilization">Stabilizing and maintaining releases</a></li>
66 <li><a href="#tarball-signing">Signing source distribution packages</a></li>
67 <li><a href="#l10n">Localization (l10n)</a></li>
68 </ul>
70 </div>
73 <div class="h2" id="participating" title="participating">
74 <h2>Participating in the community</h2>
76 <p>Although Subversion is originally sponsored and hosted by CollabNet
77 (<a href="http://www.collab.net">http://www.collab.net</a>), it's a
78 true open-source project under a BSD-style license. A number of
79 developers work for CollabNet, some work for other large companies
80 (such as RedHat), and many others are simply excellent volunteers who
81 are interested in building a better version control system.</p>
83 <p>The community exists mainly through mailing lists and a Subversion
84 repository. To participate:</p>
86 <p>Go to <a href="http://subversion.tigris.org/"
87 >http://subversion.tigris.org/</a> and</p>
89 <ul>
90 <li><p>Join the "dev", "svn", and "announce" mailing lists.
91 The dev list, dev@subversion.tigris.org, is where almost all
92 discussion takes place. All development questions should go
93 there, though you might want to check the list archives first.
94 The "svn" list receives automated commit emails.</p></li>
96 <li><p>Get a copy of the latest development sources from
97 <a href="http://svn.collab.net/repos/svn/trunk/"
98 >http://svn.collab.net/repos/svn/trunk/</a>.
99 <br />
100 New development always takes place on trunk. Bugfixes,
101 enhancements, and new features are backported from there to the
102 various release branches.</p></li>
103 </ul>
105 <p>There are many ways to join the project, either by writing code, or
106 by testing and/or helping to manage the bug database. If you'd like
107 to contribute, then look at:</p>
109 <ul>
110 <li><p>The bugs/issues database
111 <a href="http://subversion.tigris.org/project_issues.html"
112 >http://subversion.tigris.org/project_issues.html</a></p></li>
114 <li><p>The bite-sized tasks page
115 <a href="http://subversion.tigris.org/project_tasks.html"
116 >http://subversion.tigris.org/project_tasks.html</a></p></li>
117 </ul>
119 <p>To submit code, simply send your patches to
120 dev@subversion.tigris.org. No, wait, first read the rest of this
121 file, <i>then</i> start sending patches to
122 dev@subversion.tigris.org. :-)</p>
124 <p>To help manage the issues database, read over the issue summaries,
125 looking and testing for issues that are either invalid, or are
126 duplicates of other issues. Both kinds are very common, the first
127 because bugs often get unknowingly fixed as side effects of other
128 changes in the code, and the second because people sometimes file an
129 issue without noticing that it has already been reported. If you are
130 not sure about an issue, post a question to dev@subversion.tigris.org.
131 ("Subversion: We're here to help you help us!")</p>
133 <p>Another way to help is to set up automated builds and test suite
134 runs of Subversion on some platform, and have the output sent to the
135 svn-breakage@subversion.tigris.org mailing list. See more details at
136 <a href="http://subversion.tigris.org/servlets/ProjectMailingListList"
137 >http://subversion.tigris.org/servlets/ProjectMailingListList</a>
138 in the description for the svn-breakage list.</p>
140 </div>
143 <div class="h2" id="docs" title="docs">
144 <h2>Theory and documentation</h2>
146 <ol>
147 <li><p>Design</p>
149 <p>A <a href="design.html">design spec</a> was written in June 2000,
150 and is a bit out of date. But it still gives a good theoretical
151 introduction to the inner workings of the repository, and to
152 Subversion's various layers.</p>
153 </li>
155 <li><p>API Documentation</p>
156 <p>See the section on the <a href="#doxygen-docs">public API
157 documentation</a> for more information.</p>
158 </li>
160 <li><p>Delta Editors</p>
161 <p>Karl Fogel wrote a chapter for O'Reilly's 2007 book
162 <a href="http://beautifulcode.oreillynet.com/">
163 Beautiful Code: Leading Programmers Explain How They Think</a>
164 covering the design and use of
165 <a href="http://www.red-bean.com/kfogel/beautiful-code/bc-chapter-02.html">
166 Subversion's delta editor interface</a>.</p>
167 </li>
169 <li> <p>Network Protocols</p>
171 <p>The <a href="webdav-usage.html">WebDAV Usage</a> document is
172 an introduction to Subversion's DAV network protocol, which is
173 an extended dialect of HTTP and uses URLs beginning with
174 "http://" or "https://".</p>
176 <p>The <a
177 href="http://svn.collab.net/repos/svn/trunk/subversion/libsvn_ra_svn/protocol"
178 >SVN Protocol</a> document contains a formal description of
179 Subversion ra_svn network protocol, which is a custom protocol
180 on port 3690 (by default), whose URLs begin with "svn://" or
181 "svn+ssh://".</p>
182 </li>
184 <li><p>User Manual</p>
186 <p>Version Control with Subversion is a book published by
187 O'Reilly that shows in detail how to effectively use Subversion.
188 The text of the book is free, and is actively being revised.
189 On-line versions are available
190 at <a href="http://svnbook.red-bean.com"
191 >http://svnbook.red-bean.com</a>. The XML source and
192 translations to other languages are maintained in their own
193 repository at <a href="http://svn.red-bean.com/svnbook"
194 >http://svn.red-bean.com/svnbook</a>.</p>
195 </li>
197 <li><p>System notes</p>
199 <p>A lot of the design ideas for particular aspects of the system
200 have been documented in individual files in the
201 <a href="http://svn.collab.net/repos/svn/trunk/notes/">notes/</a>
202 directory.</p>
203 </li>
205 </ol>
207 </div>
210 <div class="h2" id="code-to-read" title="code-to-read">
211 <h2>Code to read</h2>
213 <p>Before you can contribute code, you'll need to familiarize yourself
214 with the existing code base and interfaces.</p>
216 <p>Check out a copy of Subversion (anonymously, if you don't yet have
217 an account with commit access)&nbsp;&mdash;&nbsp;so you can look at
218 the code.</p>
220 <p>Within 'subversion/include/' are a bunch of header files with huge
221 doc comments. If you read through these, you'll have a pretty good
222 understanding of the implementation details. Here's a suggested
223 perusal order:</p>
225 <ol>
226 <li><p>the basic building blocks: svn_string.h, svn_error.h, svn_types.h</p>
227 </li>
228 <li><p>useful utilities: svn_io.h, svn_path.h, svn_hash.h, svn_xml.h</p>
229 </li>
230 <li><p>the critical interface: svn_delta.h</p>
231 </li>
232 <li><p>client-side interfaces: svn_ra.h, svn_wc.h, svn_client.h</p>
233 </li>
234 <li><p>the repository and versioned filesystem: svn_repos.h, svn_fs.h</p>
235 </li>
236 </ol>
238 <p>Subversion tries to stay portable by using only ANSI/ISO C and by
239 using the Apache Portable Runtime (APR) library. APR is the
240 portability layer used by the Apache httpd server, and more
241 information can be found at <a href="http://apr.apache.org/"
242 >http://apr.apache.org/</a>.</p>
244 <p>Because Subversion depends so heavily on APR, it may be hard to
245 understand Subversion without first glancing over certain header files
246 in APR (look in 'apr/include/'):</p>
248 <ul>
249 <li><p>memory pools: apr_pools.h</p></li>
250 <li><p>filesystem access: apr_file_io.h</p></li>
251 <li><p>hashes and arrays: apr_hash.h, apr_tables.h</p></li>
252 </ul>
254 <p>Subversion also tries to deliver reliable and secure software. This
255 can only be achieved by developers who understand secure programming
256 in the C programming language. Please see 'notes/assurance.txt' for
257 the full rationale behind this. Specifically, you should make it a
258 point to carefully read David Wheeler's Secure Programming (as
259 mentioned in 'notes/assurance.txt'). If at any point you have
260 questions about the security implications of a change, you are urged
261 to ask for review on the developer mailing list.</p>
263 </div>
266 <div class="h2" id="directory-layout" title="directory-layout">
267 <h2>Directory layout</h2>
269 <p>A rough guide to the source tree:</p>
271 <ul>
272 <li><p><tt>doc/</tt><br />
273 User and Developer documentation.</p>
274 </li>
275 <li><p><tt>www/</tt><br />
276 Subversion web pages (live content at
277 <a href="http://subversion.tigris.org/"
278 >http://subversion.tigris.org/</a>).</p>
279 </li>
280 <li><p><tt>tools/</tt><br />
281 Stuff that works with Subversion, but that Subversion doesn't
282 depend on. Code in tools/ is maintained collectively by the
283 Subversion project, and is under the same open source copyright as
284 Subversion itself.</p>
285 </li>
286 <li><p><tt>contrib/</tt><br />
287 Stuff that works with Subversion, but that Subversion doesn't
288 depend on, and that is maintained by individuals who may or may
289 not participate in Subversion development. Code in contrib/ is
290 open source, but may have a different license or copyright holder
291 than Subversion itself.</p>
292 </li>
293 <li><p><tt>packages/</tt><br />
294 Stuff to help packaging systems, like rpm and dpkg.</p>
295 </li>
296 <li><p><tt>subversion/</tt><br />
297 Source code to Subversion itself (as opposed to external
298 libraries).</p>
299 </li>
300 <li><p><tt>subversion/include/</tt><br />
301 Public header files for users of Subversion libraries.</p>
302 </li>
303 <li><p><tt>subversion/include/private/</tt><br />
304 Private header files shared internally by Subversion libraries.</p>
305 </li>
306 <li><p><tt>subversion/libsvn_fs/</tt><br />
307 The versioning "filesystem" API.</p>
308 </li>
309 <li><p><tt>subversion/libsvn_repos/</tt><br />
310 Repository functionality built around the `libsvn_fs' core.</p>
311 </li>
312 <li><p><tt>subversion/libsvn_delta/</tt><br />
313 Common code for tree deltas, text deltas, and property deltas.</p>
314 </li>
315 <li><p><tt>subversion/libsvn_wc/</tt><br />
316 Common code for working copies.</p>
317 </li>
318 <li><p><tt>subversion/libsvn_ra/</tt><br />
319 Common code for repository access.</p>
320 </li>
321 <li><p><tt>subversion/libsvn_client/</tt><br />
322 Common code for client operations.</p>
323 </li>
324 <li><p><tt>subversion/svn/</tt><br />
325 The command line client.</p>
326 </li>
327 <li><p><tt>subversion/tests/</tt><br />
328 Automated test suite.</p>
329 </li>
330 <li><p><tt>apr/</tt><br />
331 Apache Portable Runtime library. (Note: This is not in the same
332 repository as Subversion. Read INSTALL for instructions on how to
333 get it if you don't already have it.)</p>
334 </li>
335 <li><p><tt>neon/</tt><br />
336 Neon library from Joe Orton. (Note: This is not in the same
337 repository as Subversion. Read INSTALL for instructions on how to
338 get it if you don't already have it.)</p>
339 </li>
340 </ul>
342 </div>
345 <div class="h2" id="coding-style" title="coding-style">
346 <h2>Coding style</h2>
348 <p>Subversion uses ANSI C, and follows the GNU coding standards,
349 except that we do not put a space between the name of a function and
350 the opening parenthesis of its parameter list. Emacs users can just
351 load svn-dev.el to get the right indentation behavior (most source
352 files here will load it automatically, if `enable-local-eval' is set
353 appropriately).</p>
355 <p>Read <a href="http://www.gnu.org/prep/standards.html"
356 >http://www.gnu.org/prep/standards.html</a> for a full description of
357 the GNU coding standards. Below is a short example demonstrating the
358 most important formatting guidelines, including our
359 no-space-before-param-list-paren exception:</p>
361 <pre>
362 char * /* func type on own line */
363 argblarg(char *arg1, int arg2) /* func name on own line */
364 { /* first brace on own line */
365 if ((some_very_long_condition &amp;&amp; arg2) /* indent 2 cols */
366 || remaining_condition) /* new line before operator */
367 { /* brace on own line, indent 2 */
368 arg1 = some_func(arg1, arg2); /* NO SPACE BEFORE PAREN */
369 } /* close brace on own line */
370 else
372 do /* format do-while like this */
374 arg1 = another_func(arg1);
376 while (*arg1);
379 </pre>
381 <p>In general, be generous with parentheses even when you're sure
382 about the operator precedence, and be willing to add spaces and
383 newlines to avoid "code crunch". Don't worry too much about vertical
384 density; it's more important to make code readable than to fit that
385 extra line on the screen.</p>
387 </div>
390 <div class="h2" id="secure-coding" title="secure-coding">
391 <h2>Secure coding guidelines</h2>
393 <p>Just like almost any other programming language, C has undesirable
394 features which enables an attacker to make your program fail in
395 predictable ways, often to the attacker's benefit. The goal of these
396 guidelines is to make you aware of the pitfalls of C as they apply to
397 the Subversion project. You are encouraged to keep these pitfalls in
398 mind when reviewing code of your peers, as even the most skilled and
399 paranoid programmers make occasional mistakes.</p>
401 <p>Input validation is the act of defining legal input and rejecting
402 everything else. The code must perform input validation on all
403 untrusted input. </p>
405 <p>Security boundaries:</p>
407 <p>A security boundary in the Subversion server code must be
408 identified as such as this enables auditors to quickly determine the
409 quality of the boundary. Security boundaries exist where the running
410 code has access to information the user does not or where the code
411 runs with privileges above those of the user making the
412 request. Typical examples of such is code that does access control or
413 an application with the SUID bit set.</p>
415 <p>Functions which make calls to a security boundary must include
416 validation checks of the arguments passed. Functions which themselves
417 are security boundaries should audit the input received and alarm when
418 invoked with improper values. </p>
420 <p>[### todo: need some examples from Subversion here...]</p>
422 <p>String operations:</p>
424 <p>Use the string functions provided in apr_strings.h instead of
425 standard C library functions that write to strings. The APR functions
426 are safer because they do bounds-checking and dest allocation
427 automatically. Although there may be circumstances where it's
428 theoretically safe to use plain C string functions (such as when you
429 already know the lengths of the source and dest), please use the APR
430 functions anyway, so the code is less brittle and more reviewable.</p>
432 <p>Password storage:</p>
434 <p>Help users keep their passwords secret: When the client reads or
435 writes password locally, it should ensure that the file is mode
436 0600. If the file is readable by other users, the client should exit
437 with a message that tells the user to change the filemode due to the
438 risk of exposure.</p>
440 </div>
443 <div class="h2" id="destruction-of-stacked-resources"
444 title="destruction-of-stacked-resources">
445 <h2>Destruction of stacked resources</h2>
447 <p>Some resources need destruction to ensure correct functioning of the
448 application. Such resources include files, especially since open
449 files cannot be deleted on Windows.</p>
451 <p>When writing an API which creates and returns a stream, in the
452 background this stream may be stacked on a file or other stream. To
453 ensure correct destruction of the resources the stream is built upon,
454 it must correctly call the destructors of the stream(s) it is built
455 upon (owns).</p>
457 <p>At first in <a href="http://svn.haxx.se/dev/archive-2005-12/0487.shtml">
458 http://svn.haxx.se/dev/archive-2005-12/0487.shtml</a>
459 and later in <a href="http://svn.haxx.se/dev/archive-2005-12/0633.shtml">
460 http://svn.haxx.se/dev/archive-2005-12/0633.shtml</a> this
461 was discussed in more general terms for files, streams, editors and
462 window handlers.</p>
464 <p>As Greg Hudson put it:</p>
466 <blockquote>
467 <p>On consideration, here is where I would like us to be:</p>
469 <ul><li>Streams which read from or write to an underlying object own that
470 object, i.e. closing the stream closes the underlying object, if
471 applicable.</li>
473 <li>The layer (function or data type) which created a stream is
474 responsible for closing it, except when the above rule applies.</li>
476 <li>Window handlers are thought of as an odd kind of stream, and passing
477 the final NULL window is considered closing the stream.</li>
478 </ul>
480 <p>If you think of apply_textdelta as creating a window handler, then I
481 don't think we're too far off. svn_stream_from_aprfile isn't owning its
482 subsidiary file, svn_txdelta_apply is erroneously taking responsibility
483 for closing the window stream it is passed, and there may be some other
484 deviations.</p>
485 </blockquote>
487 <p>There is one exception to the rules above though. When a stream is passed
488 to a function as an argument (for example: the 'out' parameter of
489 svn_client_cat2()), that routine can't call the streams destructor, since
490 it did not create that resource.</p>
492 <p>If svn_client_cat2() creates a stream, it must also call the destructor
493 for that stream. By the above model, that stream will call the destructor
494 for the 'out' parameter. This is however wrong, because the responsibility
495 to destruct the 'out' parameter lies elsewhere.</p>
497 <p>To solve this problem, at least in the stream case, svn_stream_disown()
498 has been introduced. This function wraps a stream, making sure it's
499 <em>not</em> destroyed, even though any streams stacked upon it may try
500 to do so.</p>
502 </div>
505 <div class="h2" id="documenting" title="documenting">
506 <h2>Documentation</h2>
508 <div class="h3" id="document-everything" title="document-everything">
509 <h3>Document Everything</h3>
510 <p>Every function, whether public or internal, must start out with a
511 documentation comment that describes what the function does. The
512 documentation should mention every parameter received by the function,
513 every possible return value, and (if not obvious) the conditions under
514 which the function could return an error.</p>
516 <p>For internal documentation put the parameter names in upper case
517 in the doc string, even when they are not upper case in the actual
518 declaration, so that they stand out to human readers.</p>
520 <p>For public or semi-public API functions, the doc string should go
521 above the function in the .h file where it is declared; otherwise, it
522 goes above the function definition in the .c file.</p>
524 <p>For structure types, document each individual member of the structure as
525 well as the structure itself.</p>
527 <p>For actual source code, internally document chunks of each function, so
528 that an someone familiar with Subversion can understand the algorithm being
529 implemented. Do not include obvious or overly verbose documentation; the
530 comments should help understanding of the code, not hinder it.</p>
532 <p>For example:</p>
533 <pre>
534 <span style="color: red;">/*** How not to document. Don't do this. ***/</span>
536 /* Make a foo object. */
537 static foo_t *
538 make_foo_object(arg1, arg2, apr_pool_t *pool)
540 /* Create a subpool. */
541 apr_pool_t *subpool = svn_pool_create(pool);
543 /* Allocate a foo object from the main pool */
544 foo_t *foo = apr_palloc(pool, sizeof(*foo));
547 </pre>
549 <p>Instead, document decent sized chunks of code, like this:</p>
550 <pre>
551 /* Trasmit the segment (if its within the scope of our concern). */
552 SVN_ERR(maybe_crop_and_send_segment(segment, start_rev, end_rev,
553 receiver, receiver_baton, subpool));
555 /* If we've set CURRENT_REV to SVN_INVALID_REVNUM, we're done
556 (and didn't ever reach END_REV). */
557 if (! SVN_IS_VALID_REVNUM(current_rev))
558 break;
560 /* If there's a gap in the history, we need to report as much
561 (if the gap is within the scope of our concern). */
562 if (segment-&gt;range_start - current_rev &lt; 1)
564 svn_location_segment_t *gap_segment;
565 gap_segment = apr_pcalloc(subpool, sizeof(*gap_segment));
566 gap_segment-&gt;range_end = segment-&gt;range_start - 1;
567 gap_segment-&gt;range_start = current_rev + 1;
568 gap_segment-&gt;path = NULL;
569 SVN_ERR(maybe_crop_and_send_segment(gap_segment, start_rev, end_rev,
570 receiver, receiver_baton,
571 subpool));
573 </pre>
575 <p>Read over the Subversion code to get an overview of how documentation looks
576 in practice; in particular, see
577 <a href="http://svn.collab.net/repos/svn/trunk/subversion/include/">
578 subversion/include/*.h</a> for doxygen examples.
579 </p>
581 </div>
583 <div class="h3" id="doxygen-docs" title="doxygen-docs">
584 <h3>Public API Documentation</h3>
585 <p>We use the <a href="http://www.doxygen.org/">Doxygen</a> format for
586 public interface documentation. This means anything that goes in a
587 public header file. <a href="http://svn.collab.net/svn-doxygen/">Snapshots
588 </a> of the public API documentation are generated nightly from the latest
589 Subversion sources.</p>
591 <p>We use only a small portion of the available
592 <a href="http://www.stack.nl/~dimitri/doxygen/commands.html">doxygen
593 commands</a> to markup our source. When writing doxygen documentation, the
594 following conventions apply:</p>
595 <ul>
596 <li>Use complete sentences and prose descriptions of the function, preceding
597 paramater names with <code>@a</code>, and type and macro names with
598 <code>@c</code>.</li>
600 <li>Use <code>&lt;tt&gt;...&lt;tt&gt;</code> to display multiple words
601 and <code>@p</code> to display only one word in typewriter font.</li>
603 <li>Constant values, such as <code>TRUE</code>, <code>FALSE</code> and
604 <code>NULL</code> should be in all caps.</li>
606 <li>When several functions are related, define a group name, and group them
607 together using <code>@defgroup</code> and <code>@{...@}</code>.</li>
608 </ul>
610 <p>See the <a href="http://www.stack.nl/~dimitri/doxygen/manual.html">Doxygen
611 manual</a> for a complete list of commands.</p>
613 </div>
615 </div>
618 <div class="h2" id="use-page-breaks" title="use-page-breaks">
619 <h2>Using page breaks</h2>
621 <p>We're using page breaks (the Ctrl-L character, ASCII 12) for
622 section boundaries in both code and plaintext prose files. Each
623 section starts with a page break, and immediately after the page break
624 comes the title of the section.</p>
626 <p>This helps out people who use the Emacs page commands, such as
627 `pages-directory' and `narrow-to-page'. Such people are not as scarce
628 as you might think, and if you'd like to become one of them, then add
629 (require 'page-ext) to your .emacs and type C-x C-p C-h sometime.</p>
631 </div>
634 <div class="h2" id="error-messages" title="error-messages">
635 <h2>Error message conventions</h2>
637 <p>For error messages the following conventions apply:</p>
639 <ul>
641 <li><p>Provide specific error messages only when there is information
642 to add to the general error message found in
643 subversion/include/svn_error_codes.h.</p></li>
645 <li><p>Messages start with a capital letter.</p></li>
647 <li><p>Try keeping messages below 70 characters.</p></li>
649 <li><p>Don't end the error message with a period (".").</p></li>
651 <li><p>Don't include newline characters in error messages.</p></li>
653 <li><p>Quoting information is done using single quotes (e.g. "'some info'").</p></li>
655 <li><p>Don't include the name of the function where the error occurs
656 in the error message. If Subversion is compiled using the
657 '--enable-maintainer-mode' configure-flag, it will provide this
658 information by itself.</p></li>
660 <li><p>When including path or filenames in the error string, be sure
661 to quote them (e.g. "Can't find '/path/to/repos/userfile'").</p></li>
663 <li><p>When including path or filenames in the error string, be sure
664 to convert them using <a
665 href="http://svn.collab.net/svn-doxygen/svn__path_8h.html#a1"
666 ><tt>svn_path_local_style()</tt></a> before inclusion (since
667 paths passed to and from Subversion APIs are assumed to be
668 in <a href="http://svn.collab.net/svn-doxygen/svn__path_8h.html#a0"
669 >canonical form</a>).</p></li>
671 <li><p>Don't use Subversion-specific abbreviations (e.g. use "repository"
672 instead of "repo", "working copy" instead of "wc").</p></li>
674 <li><p>If you want to add an explanation to the error, report it
675 followed by a colon and the explanation like this:</p>
676 <pre>
677 "Invalid " SVN_PROP_EXTERNALS " property on '%s': "
678 "target involves '.' or '..'".
679 </pre></li>
681 <li><p>Suggestions or other additions can be added after a semi-colon,
682 like this:</p>
683 <pre>
684 "Can't write to '%s': object of same name already exists; remove "
685 "before retrying".
686 </pre></li>
688 <li><p>Try to stay within the boundaries of these conventions, so please avoid
689 separating different parts of error messages by other separators such
690 as '--' and others.</p></li>
692 </ul>
694 <p>Also read about <a href="#l10n">Localization</a>.</p>
696 </div>
699 <div class="h2" id="other-conventions" title="other-conventions">
700 <h2>Other conventions</h2>
702 <p>In addition to the GNU standards, Subversion uses these
703 conventions:</p>
705 <ul>
706 <li><p>When using a path or file name as input to most <a
707 href="http://svn.collab.net/svn-doxygen/">Subversion APIs</a>, be
708 sure to convert them to Subversion's internal/canonical form
709 using the <a href="http://svn.collab.net/svn-doxygen/svn__path_8h.html#a0"
710 ><tt>svn_path_internal_style()</tt></a> API. Alternately, when
711 receiving a path or file name as output from a Subversion API,
712 convert them into the expected form for your platform using the
713 <a href="http://svn.collab.net/svn-doxygen/svn__path_8h.html#a1"
714 ><tt>svn_path_local_style()</tt></a> API.</p></li>
716 <li><p>Use only spaces for indenting code, never tabs. Tab display
717 width is not standardized enough, and anyway it's easier to
718 manually adjust indentation that uses spaces.</p>
719 </li>
721 <li><p>Restrict lines to 79 columns, so that code will display well in a
722 minimal standard display window. (There can be exceptions, such
723 as when declaring a block of 80-column text with a few extra
724 columns taken up by indentation, quotes, etc., if splitting each
725 line in two would be unreasonably messy.)</p>
726 </li>
728 <li><p>All published functions, variables, and structures must be signified
729 with the corresponding library name - such as libsvn_wc's
730 svn_wc_adm_open. All library-internal declarations made in a
731 library-private header file (such as libsvn_wc/wc.h) must be signified
732 by two underscores after the library prefix (such as
733 svn_wc__ensure_directory). All declarations private to a single file
734 (such as the static function get_entry_url inside of
735 <tt>libsvn_wc/update_editor.c</tt>) do not require any
736 additional namespace decorations. Symbols that need to be used
737 outside a library, but still are not public are put in a shared
738 header file in the <tt>include/private/</tt> directory, and use
739 the double underscore notation. Such symbols may be used by
740 Subversion core code only.</p>
742 <p>To recap:</p>
743 <pre>
744 /* Part of published API: subversion/include/svn_wc.h */
745 svn_wc_adm_open()
746 #define SVN_WC_ADM_DIR_NAME ...
747 typedef enum svn_wc_schedule_t ...
749 /* For use within one library only: subversion/libsvn_wc/wc.h */
750 svn_wc__ensure_directory()
751 #define SVN_WC__BASE_EXT ...
752 typedef struct svn_wc__compat_notify_baton_t ...
754 /* For use within one file: subversion/libsvn_wc/update_editor.c */
755 get_entry_url()
756 struct handler_baton {
758 /* For internal use in svn core code only:
759 subversion/include/private/svn_wc_private.h */
760 svn_wc__entry_versioned()
761 </pre>
763 <p>Pre-Subversion 1.5, private symbols which needed to be used
764 outside of a library were put into public header files,
765 using the double underscore notation. This practice has been
766 abandoned, and any such symbols are legacy, maintained for <a
767 href="#release-numbering">backwards compatibility</a>.</p>
768 </li>
770 <li><p>In text strings that might be printed out (or otherwise made
771 available) to users, use only forward quotes around paths and
772 other quotable things. For example:</p>
773 <pre>
774 $ svn revert foo
775 svn: warning: svn_wc_is_wc_root: 'foo' is not a versioned resource
777 </pre>
779 <p>There used to be a lot of strings that used a backtick for
780 the first quote (`foo' instead of 'foo'), but that looked bad in
781 some fonts, and also messed up some people's auto-highlighting,
782 so we settled on the convention of always using forward
783 quotes.</p>
784 </li>
786 <li><p>If you use Emacs, put something like this in your .emacs file,
787 so you get svn-dev.el and svnbook.el when needed:</p>
788 <pre>
789 ;;; Begin Subversion development section
790 (defun my-find-file-hook ()
791 (let ((svn-tree-path (expand-file-name "~/projects/subversion"))
792 (book-tree-path (expand-file-name "~/projects/svnbook")))
793 (cond
794 ((string-match svn-tree-path buffer-file-name)
795 (load (concat svn-tree-path "/tools/dev/svn-dev")))
796 ((string-match book-tree-path buffer-file-name)
797 ;; Handle load exception for svnbook.el, because it tries to
798 ;; load psgml, and not everyone has that available.
799 (condition-case nil
800 (load (concat book-tree-path "/src/tools/svnbook"))
801 (error
802 (message "(Ignored problem loading svnbook.el.)")))))))
804 (add-hook 'find-file-hooks 'my-find-file-hook)
805 ;;; End Subversion development section
806 </pre>
808 <p>You'll need to customize the path for your setup, of course.
809 You can also make the regexp to string-match more selective; for
810 example, one developer says:</p>
811 <pre>
812 &gt; Here's the regexp I'm using:
813 &gt;
814 &gt; "src/svn/[^/]*/\\(subversion\\|tools\\|build\\)/"
815 &gt;
816 &gt; Two things to notice there: (1) I sometimes have several
817 &gt; working copies checked out under ...src/svn, and I want the
818 &gt; regexp to match all of them; (2) I want the hook to catch only
819 &gt; in "our" directories within the working copy, so I match
820 &gt; "subversion", "tools" and "build" explicitly; I don't want to
821 &gt; use GNU style in the APR that's checked out into my repo. :-)
822 </pre>
823 </li>
825 <li><p>We have a tradition of not marking files with the names of
826 individual authors (i.e., we don't put lines like
827 "Author:&nbsp;foo" or "@author&nbsp;foo" in a special position
828 at the top of a source file). This is to discourage
829 territoriality&nbsp;&mdash;&nbsp;even when a file has only one
830 author, we want to make sure others feel free to make changes.
831 People might be unnecessarily hesitant if someone appears to
832 have staked a personal claim to the file.</p>
833 </li>
835 <li><p>Put two spaces between the end of one sentence and the start of
836 the next. This helps readability, and allows people to use
837 their editors' sentence-motion and -manipulation commands.</p>
838 </li>
840 <li><p>There are many other unspoken conventions maintained throughout
841 the code, that are only noticed when someone unintentionally
842 fails to follow them. Just try to have a sensitive eye for the
843 way things are done, and when in doubt, ask.</p>
844 </li>
845 </ul>
847 </div>
850 <div class="h2" id="apr-pools" title="apr-pools">
851 <h2>APR pool usage conventions</h2>
853 <p>(This assumes you already basically understand how APR pools work;
854 see apr_pools.h for details.)</p>
856 <p>Applications using the Subversion libraries must call
857 apr_initialize() before calling any Subversion functions.</p>
859 <p>Subversion's general pool usage strategy can be summed up in two
860 principles:</p>
862 <ol>
863 <li><p>The call level that created a pool is the only place to clear or
864 destroy that pool.</p>
865 </li>
866 <li><p>When iterating an unbounded number of times, create a subpool
867 before entering the iteration, use it inside the loop and clear
868 it at the start of each iteration, then destroy it after the loop
869 is done, like so:</p>
870 <pre>
871 apr_pool_t *subpool = svn_pool_create(pool);
873 for (i = 0; i &lt; n; ++i)
875 svn_pool_clear(subpool);
876 do_operation(..., subpool);
879 svn_pool_destroy(subpool);
880 </pre>
881 </li>
882 </ol>
884 <p>By using a loop subpool for loop-bounded data, you ensure O(1) instead
885 of O(N) memory leakage should the function return abruptly from
886 within the loop (say, due to error). That's why you shouldn't make a
887 subpool for data which persists throughout a function, but instead
888 should use the pool passed in by the caller. That memory will be
889 reclaimed when the caller's pool is cleared or destroyed. If the
890 caller is invoking the callee in a loop, then trust the caller to take
891 care of clearing the pool on each iteration. The same logic
892 propagates all the way up the call stack.</p>
894 <p>The pool you use also helps readers of the code understand object
895 lifetimes. Is a given object used only during one iteration of the
896 loop, or will it need to last beyond the end of the loop? For
897 example, pool choices indicate a lot about what's going on in this
898 code:</p>
900 <pre>
901 apr_hash_t *persistent_objects = apr_hash_make(pool);
902 apr_pool_t *subpool = svn_pool_create(pool);
904 for (i = 0; i &lt; n; ++i)
906 const char *intermediate_result;
907 const char *key, *val;
909 svn_pool_clear(subpool);
910 SVN_ERR(do_something(&amp;intermediate_result, ..., subpool));
911 SVN_ERR(get_result(intermediate_result, &amp;key, &amp;val, ..., pool));
912 apr_hash_set(persistent_objects, key, APR_HASH_KEY_STRING, val);
914 svn_pool_destroy(subpool);
916 return persistent_objects;
917 </pre>
919 <p>Except for some legacy code, which was written before these
920 principles were fully understood, virtually all pool usage in
921 Subversion follows the above guidelines.</p>
923 <p>One such legacy pattern is a tendency to allocate an object inside
924 a pool, store the pool in the object, and then free that pool (either
925 directly or through a close_foo() function) to destroy the object.</p>
927 <p>For example:</p>
929 <pre>
930 <span style="color: red;">/*** Example of how NOT to use pools. Don't be like this. ***/</span>
932 static foo_t *
933 make_foo_object(arg1, arg2, apr_pool_t *pool)
935 apr_pool_t *subpool = svn_pool_create(pool);
936 foo_t *foo = apr_palloc(subpool, sizeof(*foo));
938 foo-&gt;field1 = arg1;
939 foo-&gt;field2 = arg2;
940 foo-&gt;pool = subpool;
943 [...]
945 [Now some function calls make_foo_object() and returns, passing
946 back a new foo object.]
948 [...]
950 [Now someone, at some random call level, decides that the foo's
951 lifetime is over, and calls svn_pool_destroy(foo-&gt;pool).]
952 </pre>
954 <p>This is tempting, but it defeats the point of using pools, which is
955 to not worry so much about individual allocations, but rather about
956 overall performance and lifetime groups. Instead, foo_t generally
957 should not have a `pool' field. Just allocate as many foo objects as
958 you need in the current pool&nbsp;&mdash;&nbsp;when that pool gets
959 cleared or destroyed, they will all go away simultaneously.</p>
961 <p>See also the <a href="#exception-handling">Exception handling</a>
962 section, for details of how resources associated with a pool are
963 cleaned up when that pool is destroyed.</p>
965 <p>In summary:</p>
967 <ul>
969 <li><p>Objects should not have their own pools. An object is
970 allocated into a pool defined by the constructor's caller. The
971 caller knows the lifetime of the object and will manage it via
972 the pool.</p>
973 </li>
975 <li><p>Functions should not create/destroy pools for their operation;
976 they should use a pool provided by the caller. Again, the
977 caller knows more about how the function will be used, how
978 often, how many times, etc. thus, it should be in charge of the
979 function's memory usage.</p>
981 <p>For example, the caller might know that the app will exit upon
982 the function's return. Thus, the function would create extra
983 work if it built/destroyed a pool. Instead, it should use the
984 passed-in pool, which the caller is going to be tossing as part
985 of app-exit anyway.</p>
986 </li>
988 <li><p>Whenever an unbounded iteration occurs, an iteration subpool
989 should be used.</p>
990 </li>
992 <li><p>Given all of the above, it is pretty well mandatory to pass a
993 pool to every function. Since objects are not recording pools
994 for themselves, and the caller is always supposed to be
995 managing memory, then each function needs a pool, rather than
996 relying on some hidden magic pool. In limited cases, objects
997 may record the pool used for their construction so that they
998 can construct sub-parts, but these cases should be examined
999 carefully.</p>
1000 </li>
1001 </ul>
1004 <p>See also <a href="#tracing-memory-leaks">Tracking down memory
1005 leaks</a> for tips on diagnosing pool usage problems.</p>
1007 </div>
1010 <div class="h2" id="apr-status-codes" title="apr-status-codes">
1011 <h2>APR status codes</h2>
1013 <p>Always check for APR status codes (except APR_SUCCESS) with the
1014 APR_STATUS_IS_...() macros, not by direct comparison. This is required
1015 for portability to non-Unix platforms.</p>
1017 </div>
1020 <div class="h2" id="exception-handling" title="exception-handling">
1021 <h2>Exception handling</h2>
1023 <p>OK, here's how to use exceptions in Subversion.</p>
1025 <ol>
1027 <li><p>Exceptions are stored in svn_error_t structures:</p>
1029 <pre>
1030 typedef struct svn_error_t
1032 apr_status_t apr_err; /* APR error value, possibly SVN_ custom err */
1033 const char *message; /* details from producer of error */
1034 struct svn_error_t *child; /* ptr to the error we "wrap" */
1035 apr_pool_t *pool; /* place to generate message strings from */
1036 const char *file; /* Only used iff SVN_DEBUG */
1037 long line; /* Only used iff SVN_DEBUG */
1038 } svn_error_t;
1039 </pre>
1041 </li>
1043 <li><p>If you are the <em>original</em> creator of an error, you would do
1044 something like this:</p>
1046 <pre>
1047 return svn_error_create(SVN_ERR_FOO, NULL,
1048 "User not permitted to write file");
1049 </pre>
1051 <p>NOTICE the NULL field... indicating that this error has no
1052 child, i.e. it is the bottom-most error.</p>
1054 <p>See also the <a href="#error-messages"> section on writing
1055 error messages</a>.</p>
1057 <p>Subversion internally uses UTF-8 to store its data. This also
1058 applies to the 'message' string. APR is assumed to return its data
1059 in the current locale, so any text returned by APR needs
1060 conversion to UTF-8 before inclusion in the message string.</p>
1061 </li>
1063 <li><p>If you <em>receive</em> an error, you have three choices:</p>
1065 <ol>
1066 <li><p>Handle the error yourself. Use either your own code, or
1067 just call the primitive svn_handle_error(err). (This
1068 routine unwinds the error stack and prints out messages
1069 converting them from UTF-8 to the current locale.)</p>
1071 <p>When your routine receives an error which it intends to
1072 ignore or handle itself, be sure to clean it up using
1073 svn_error_clear(). Any time such an error is not cleared
1074 constitutes a <em>memory leak</em>.</p>
1075 </li>
1077 <li><p>Throw the error upwards, unmodified:</p>
1079 <pre>
1080 error = some_routine(foo);
1081 if (error)
1082 return (error);
1083 </pre>
1085 <p>Actually, a better way to do this would be with the
1086 SVN_ERR() macro, which does the same thing:</p>
1087 <pre>
1088 SVN_ERR(some_routine(foo));
1089 </pre>
1090 </li>
1092 <li><p>Throw the error upwards, wrapping it in a new error
1093 structure by including it as the "child" argument:</p>
1095 <pre>
1096 error = some_routine(foo);
1097 if (error)
1099 svn_error_t *wrapper = svn_error_create(SVN_ERR_FOO, error,
1100 "Authorization failed");
1101 return wrapper;
1103 </pre>
1105 <p>Of course, there's a convenience routine which creates a
1106 wrapper error with the same fields as the child, except for
1107 your custom message:</p>
1109 <pre>
1110 error = some_routine(foo);
1111 if (error)
1113 return svn_error_quick_wrap(error,
1114 "Authorization failed");
1116 </pre>
1118 <p>The same can (and should) be done by using the SVN_ERR_W()
1119 macro:</p>
1121 <pre>
1122 SVN_ERR_W(some_routine(foo), "Authorization failed");
1123 </pre>
1124 </li>
1125 </ol>
1127 <p>In cases (b) and (c) it is important to know that resources
1128 allocated by your routine which are associated with a pool, are
1129 automatically cleaned up when the pool is destroyed. This means
1130 that there is no need to cleanup these resources before passing
1131 the error. There is therefore no reason not to use the SVN_ERR()
1132 and SVN_ERR_W() macros. Resources associated with pools are:</p>
1134 <ul>
1136 <li><p>Memory</p></li>
1138 <li><p>Files</p>
1140 <p>All files opened with apr_file_open are closed at pool
1141 cleanup. Subversion uses this function in its svn_io_file_*
1142 api, which means that files opened with svn_io_file_* or
1143 apr_file_open will be closed at pool cleanup.</p>
1145 <p>Some files (lock files for example) need to be removed when
1146 an operation is finished. APR has the APR_DELONCLOSE flag for
1147 this purpose. The following functions create files which are
1148 removed on pool cleanup:</p>
1150 <ul>
1151 <li><p>apr_file_open and svn_io_file_open (when passed the
1152 APR_DELONCLOSE flag)</p></li>
1153 <li><p>svn_io_open_unique_file (when passed TRUE in its
1154 delete_on_close)</p></li>
1155 </ul>
1157 <p>Locked files are unlocked if they were locked using
1158 svn_io_file_lock.</p>
1159 </li>
1160 </ul>
1162 </li>
1163 </ol>
1165 </div>
1168 <div class="h2" id="automated-tests" title="automated-tests">
1169 <h2>Automated tests</h2>
1171 <p>For a description of how to use and add tests to Subversion's
1172 automated test framework, please read <a
1173 href="http://svn.collab.net/repos/svn/trunk/subversion/tests/README"
1174 >subversion/tests/README</a> and <a
1175 href="http://svn.collab.net/repos/svn/trunk/subversion/tests/cmdline/README"
1176 >subversion/tests/cmdline/README</a>.</p>
1178 <p>Various people have arranged for the automated test framework to
1179 run at regular intervals on their own machines, sending the results to
1180 the svn-breakage@subversion.tigris.org mailing list. The more
1181 different platforms the tests run on, the more quickly we can detect
1182 portability bugs in Subversion. If you'd like to send svn-breakage
1183 messages too, use the <a
1184 href="http://svn.collab.net/repos/svn/trunk/tools/test-scripts/svntest/"
1185 >svntest</a> framework (start at the <a
1186 href="http://svn.collab.net/repos/svn/trunk/tools/test-scripts/svntest/README"
1187 >README</a>).</p>
1189 <p>Lieven Govaerts has set up a
1190 <a href="http://buildbot.sourceforge.net/" >BuildBot</a> build/test
1191 farm at <a href="http://www.mobsol.be/buildbot/"
1192 >http://www.mobsol.be/buildbot/</a>, see his message</p>
1194 <pre>
1195 <a href="http://subversion.tigris.org/servlets/ReadMsg?list=dev&amp;msgNo=114212">http://subversion.tigris.org/servlets/ReadMsg?list=dev&amp;msgNo=114212</a>
1196 (Thread URL: <a href="http://subversion.tigris.org/servlets/BrowseList?list=dev&amp;by=thread&amp;from=450110">http://subversion.tigris.org/servlets/BrowseList?list=dev&amp;by=thread&amp;from=450110</a>)
1197 Message-ID: 20060326205918.F3C50708B0@adicia.telenet-ops.be
1198 From: "Lieven Govaerts" &lt;lgo@mobsol.be&gt;
1199 To: &lt;dev@subversion.tigris.org&gt;
1200 Subject: Update: Subversion build and test farm with Buildbot.
1201 Date: Sun, 26 Mar 2006 22:56:11 +0200
1202 </pre>
1204 <p>for more details. (<a href="http://buildbot.sourceforge.net/"
1205 >BuildBot</a> is a system for centrally managing multiple automated
1206 testing environments; it's especially useful for portability testing,
1207 including of uncommitted changes.)</p>
1209 </div>
1212 <div class="h2" id="write-test-cases-first" title="write-test-cases-first">
1213 <h2>Writing test cases before code</h2>
1215 <pre>
1216 From: Karl Fogel &lt;kfogel@collab.net&gt;
1217 Subject: writing test cases
1218 To: dev@subversion.tigris.org
1219 Date: Mon, 5 Mar 2001 15:58:46 -0600
1221 Many of us implementing the filesystem interface have now gotten into
1222 the habit of writing the test cases (see fs-test.c) *before* writing
1223 the actual code. It's really helping us out a lot -- for one thing,
1224 it forces one to define the task precisely in advance, and also it
1225 speedily reveals the bugs in one's first try (and second, and
1226 third...).
1228 I'd like to recommend this practice to everyone. If you're
1229 implementing an interface, or adding an entirely new feature, or even
1230 just fixing a bug, a test for it is a good idea. And if you're going
1231 to write the test anyway, you might as well write it first. :-)
1233 Yoshiki Hayashi's been sending test cases with all his patches lately,
1234 which is what inspired me to write this mail to encourage everyone to
1235 do the same. Having those test cases makes patches easier to examine,
1236 because they show the patch's purpose very clearly. It's like having
1237 a second log message, one whose accuracy is verified at run-time.
1239 That said, I don't think we want a rigid policy about this, at least
1240 not yet. If you encounter a bug somewhere in the code, but you only
1241 have time to write a patch with no test case, that's okay -- having
1242 the patch is still useful; someone else can write the test case.
1244 As Subversion gets more complex, though, the automated test suite gets
1245 more crucial, so let's all get in the habit of using it early.
1248 </pre>
1250 </div>
1253 <div class="h2" id="server-debugging" title="server-debugging">
1254 <h2>Debugging the server</h2>
1256 <div class="h3" id="debugging-ra-dav" title="debugging-ra-dav">
1257 <h3>Debugging the DAV server</h3>
1259 <p>'mod_dav_svn.so' contains the main Subversion server logic; it runs
1260 as a module within mod_dav, which runs as a module within httpd.
1261 Since httpd is probably using dynamic shared modules, you normally
1262 won't be able to set breakpoints in advance when you start Apache in a
1263 debugger such as GDB. Instead, you'll need to start up, then
1264 interrupt httpd, set your breakpoint, and continue:</p>
1266 <pre>
1267 % gdb httpd
1268 (gdb) run -X
1270 (gdb) break some_func_in_mod_dav_svn
1271 (gdb) continue
1272 </pre>
1274 <p>The -X switch is equivalent to -DONE_PROCESS and -DNO_DETACH, which
1275 ensure that httpd runs as a single thread and remains attached to the
1276 tty, respectively. As soon as it starts, it sits and waits for
1277 requests; that's when you hit control-C and set your breakpoint.</p>
1279 <p>You'll probably want to watch Apache's run-time logs</p>
1281 <pre>
1282 /usr/local/apache2/logs/error_log
1283 /usr/local/apache2/logs/access_log
1284 </pre>
1286 <p>to help determine what might be going wrong and where to set
1287 breakpoints.</p>
1289 </div>
1291 <div class="h3" id="debugging-ra-svn" title="debugging-ra-svn">
1292 <h3>Debugging the ra_svn client and server, on Unix</h3>
1294 <p>Bugs in ra_svn usually manifest themselves with one of the
1295 following cryptic error messages:</p>
1297 <pre>
1298 svn: Malformed network data
1299 svn: Connection closed unexpectedly
1300 </pre>
1302 <p>(The first message can also mean the data stream was corrupted in
1303 tunnel mode by user dotfiles or hook scripts; see
1304 <a href="http://subversion.tigris.org/issues/show_bug.cgi?id=1145"
1305 >issue&nbsp;#1145</a>.) The first message generally means you to have
1306 to debug the client; the second message generally means you have to
1307 debug the server.</p>
1309 <p>It is easiest to debug ra_svn using a build with --disable-shared
1310 --enable-maintainer-mode. With the latter option, the error message
1311 will tell you exactly what line to set a breakpoint at; otherwise,
1312 look up the line number at the end of marshal.c:vparse_tuple() where
1313 it returns the "Malformed network data" error.</p>
1315 <p>To debug the client, simply pull it up in gdb, set a breakpoint,
1316 and run the offending command:</p>
1318 <pre>
1319 % gdb svn
1320 (gdb) break marshal.c:NNN
1321 (gdb) run ARGS
1322 Breakpoint 1, vparse_tuple (list=___, pool=___, fmt=___,
1323 ap=___) at subversion/libsvn_ra_svn/marshal.c:NNN
1324 NNN "Malformed network data");
1325 </pre>
1327 <p>There are several bits of useful information:</p>
1329 <ul>
1330 <li><p>A backtrace will tell you exactly what protocol exchange is
1331 failing.</p>
1332 </li>
1334 <li><p>"print *conn" will show you the connection buffer. read_buf,
1335 read_ptr, and read_end represent the read buffer, which can
1336 show
1337 you the data the marshaller is looking at. (Since read_buf isn't
1338 generally 0-terminated at read_end, be careful of falsely assuming
1339 that there's garbage data in the buffer.)</p>
1340 </li>
1342 <li><p>The format string determines what the marshaller was expecting to
1343 see.</p>
1344 </li>
1345 </ul>
1347 <p>To debug the server in daemon mode, pull it up in gdb, set a
1348 breakpoint (usually a "Connection closed unexpectedly" error on the
1349 client indicates a "Malformed network data" error on the server,
1350 although it can also indicate a core dump), and run it with the "-X"
1351 option to serve a single connection:</p>
1353 <pre>
1354 % gdb svnserve
1355 (gdb) break marshal.c:NNN
1356 (gdb) run -X
1357 </pre>
1359 <p>Then run the offending client command. From there, it's just like
1360 debugging the client.</p>
1362 <p>Debugging the server in tunnel mode is more of a pain. You'll need
1363 to stick something like "{ int x = 1; while (x); }" near the top of
1364 svnserve's main() and put the resulting svnserve in the user path on
1365 the server. Then start an operation, gdb attach the process on the
1366 server, "set x = 0", and step through the code as desired.</p>
1368 </div>
1370 </div>
1373 <div class="h2" id="tracing-memory-leaks" title="tracing-memory-leaks">
1374 <h2>Tracking down memory leaks</h2>
1376 <p>Our use of APR pools makes it unusual for us to have memory leaks
1377 in the strictest sense; all the memory we allocate will be cleaned up
1378 eventually. But sometimes an operation takes more memory than it
1379 should; for instance, a checkout of a large source tree should not use
1380 much more memory than a checkout of a small source tree. When that
1381 happens, it generally means we're allocating memory from a pool whose
1382 lifetime is too long.</p>
1384 <p>If you have a favorite memory leak tracking tool, you can configure
1385 with --enable-pool-debug (which will make every pool allocation use
1386 its own malloc()), arrange to exit in the middle of the operation, and
1387 go to it. If not, here's another way:</p>
1389 <ul>
1391 <li><p>Configure with --enable-pool-debug=verbose-alloc. Make sure to
1392 rebuild all of APR and Subversion so that every allocation gets
1393 file-and-line information.</p>
1394 </li>
1396 <li><p>Run the operation, piping stderr to a file. Hopefully you have
1397 lots of disk space.</p>
1398 </li>
1400 <li><p>In the file, you'll see lots of lines which look like:</p>
1402 <pre>
1403 POOL DEBUG: [5383/1024] PCALLOC ( 2763/ 2763/ 5419) \
1404 0x08102D48 "subversion/svn/main.c:612" \
1405 &lt;subversion/libsvn_subr/auth.c:122&gt; (118/118/0)
1406 </pre>
1408 <p>What you care about most is the tenth field (the one in
1409 quotes), which gives you the file and line number where the
1410 pool for this allocation was created. Go to that file and line
1411 and determine the lifetime of the pool. In the example above,
1412 main.c:612 indicates that this allocation was made in the
1413 top-level pool of the svn client. If this were an allocation
1414 which was repeated many times during the course of an
1415 operation, that would indicate a source of a memory leak. The
1416 eleventh field (the one in brackets) gives the file and line
1417 number of the allocation itself.</p>
1418 </li>
1420 </ul>
1422 </div>
1425 <div class="h2" id="log-messages" title="log-messages">
1426 <h2>Writing log messages</h2>
1428 <p>Every commit needs a log message. </p>
1430 <p>The intended audience for a log message is a developer who is
1431 already familiar with Subversion, but not necessarily familiar with
1432 this particular commit. Usually when someone goes back and reads a
1433 change, he no longer has in his head all the context around that
1434 change. This is true even if he is the author of the change! All the
1435 discussions and mailing list threads and everything else may be
1436 forgotten; the only clue to what the change is about comes from the
1437 log message and the diff itself. People revisit changes with
1438 surprising frequency, too: for example, it might be months after the
1439 original commit and now the change is being ported to a maintenance
1440 branch.</p>
1442 <p>The log message is the introduction to the change. Start it off
1443 with one line indicating the general nature of the change, and follow
1444 that with a descriptive paragraph if necessary. This not only helps
1445 put developers in the right frame of mind for reading the rest of the
1446 log message, but also plays well with the "CIA" bot that echoes the
1447 first line of each commit to realtime forums like IRC. (For details,
1448 see <a href="http://cia.navi.cx/">http://cia.navi.cx/</a>.) However,
1449 if the commit is just one simple change to one file, then you can
1450 dispense with the general description and simply go straight to the
1451 detailed description, in the standard filename-then-symbol format
1452 shown below.</p>
1454 <p>Throughout the log message, use full sentences, not sentence
1455 fragments. Fragments are more often ambiguous, and it takes only a
1456 few more seconds to write out what you mean. Certain fragments like
1457 "Doc fix", "New file", or "New function" are acceptable because they
1458 are standard idioms, and all further details should appear in the
1459 source code.</p>
1461 <p>The log message should name every affected function, variable,
1462 macro, makefile target, grammar rule, etc, including the names of
1463 symbols that are being removed in this commit. This helps people
1464 searching through the logs later. Don't hide names in wildcards,
1465 because the globbed portion may be what someone searches for later.
1466 For example, this is bad:</p>
1468 <pre>
1469 * subversion/libsvn_ra_pigeons/twirl.c
1470 (twirling_baton_*): Removed these obsolete structures.
1471 (handle_parser_warning): Pass data directly to callees, instead
1472 of storing in twirling_baton_*.
1474 * subversion/libsvn_ra_pigeons/twirl.h: Fix indentation.
1475 </pre>
1477 <p>Later on, when someone is trying to figure out what happened to
1478 `twirling_baton_fast', they may not find it if they just search for
1479 "_fast". A better entry would be:</p>
1481 <pre>
1482 * subversion/libsvn_ra_pigeons/twirl.c
1483 (twirling_baton_fast, twirling_baton_slow): Removed these
1484 obsolete structures.
1485 (handle_parser_warning): Pass data directly to callees, instead
1486 of storing in twirling_baton_*.
1488 * subversion/libsvn_ra_pigeons/twirl.h: Fix indentation.
1489 </pre>
1491 <p>The wildcard is okay in the description for
1492 `handle_parser_warning', but only because the two structures were
1493 mentioned by full name elsewhere in the log entry.</p>
1495 <p>Note how each file gets its own entry prefixed with an "*", and the
1496 changes within a file are grouped by symbol, with the symbols listed
1497 in parentheses followed by a colon, followed by text describing the
1498 change. Please adhere to this format, even when only one file is
1499 changed&nbsp;&mdash;&nbsp;not only does consistency aid readability,
1500 it also allows software to colorize log entries automatically.</p>
1502 <p>As an exception to the above, if you make exactly the same change
1503 in several files, list all the changed files in one entry. For
1504 example:</p>
1506 <pre>
1507 * subversion/libsvn_ra_pigeons/twirl.c,
1508 subversion/libsvn_ra_pigeons/roost.c:
1509 Include svn_private_config.h.
1510 </pre>
1512 <p>If all the changed files are deep inside the source tree, you can
1513 shorten the file name entries by noting the common prefix before the
1514 change entries:</p>
1516 <pre>
1517 [in subversion/bindings/swig/birdsong]
1519 * dialects/nightingale.c (get_base_pitch): Allow 3/4-tone
1520 pitch variation to account for trait variability amongst
1521 isolated populations Erithacus megarhynchos.
1523 * dialects/gallus_domesticus.c: Remove. Unreliable due to
1524 extremely low brain-to-body mass ratio.
1525 </pre>
1527 <p>If your change is related to a specific issue in the issue tracker,
1528 then include a string like "issue #N" in the log message, but make
1529 sure you still summarize what the change is about. For example, if a
1530 patch resolves issue #1729, then the log message might be:</p>
1532 <pre>
1533 Fix issue #1729: Don't crash because of a missing file.
1535 * subversion/libsvn_ra_ansible/get_editor.c
1536 (frobnicate_file): Check that file exists before frobnicating.
1537 </pre>
1539 <p>Try to put related changes together. For example, if you create
1540 svn_ra_get_ansible2(), deprecating svn_ra_get_ansible(), then those
1541 two things should be near each other in the log message:</p>
1543 <pre>
1544 * subversion/include/svn_ra.h
1545 (svn_ra_get_ansible2): New prototype, obsoletes svn_ra_get_ansible.
1546 (svn_ra_get_ansible): Deprecate.
1547 </pre>
1549 <p>For large changes or change groups, group the log entry into
1550 paragraphs separated by blank lines. Each paragraph should be a set
1551 of changes that accomplishes a single goal, and each group should
1552 start with a sentence or two summarizing the change. Truly
1553 independent changes should be made in separate commits, of course.</p>
1555 <p>See <a href="#crediting">Crediting</a> for how to give credit to
1556 someone else if you are committing their patch, or committing a change
1557 they suggested.</p>
1559 <p>One should never need the log entries to understand the current
1560 code. If you find yourself writing a significant explanation in the
1561 log, you should consider carefully whether your text doesn't actually
1562 belong in a comment, alongside the code it explains. Here's an
1563 example of doing it right:</p>
1565 <pre>
1566 (consume_count): If `count' is unreasonable, return 0 and don't
1567 advance input pointer.
1568 </pre>
1570 <p>And then, in `consume_count' in `cplus-dem.c':</p>
1572 <pre>
1573 while (isdigit((unsigned char)**type))
1575 count *= 10;
1576 count += **type - '0';
1577 /* A sanity check. Otherwise a symbol like
1578 `_Utf390_1__1_9223372036854775807__9223372036854775'
1579 can cause this function to return a negative value.
1580 In this case we just consume until the end of the string. */
1581 if (count &gt; strlen(*type))
1583 *type = save;
1584 return 0;
1586 </pre>
1588 <p>This is why a new function, for example, needs only a log entry
1589 saying "New Function" --- all the details should be in the source.</p>
1591 <p>You can make common-sense exceptions to the need to name everything
1592 that was changed. For example, if you have made a change which
1593 requires trivial changes throughout the rest of the program (e.g.,
1594 renaming a variable), you needn't name all the functions affected, you
1595 can just say "All callers changed". However, if you rename symbols
1596 (e.g., to add or remove a library prefix), please mention every
1597 affected symbol, both old and new&nbsp;&mdash;&nbsp;this is the only
1598 way the rename of a particular symbol would be traceable later. See
1599 r20946 for an example of this.</p>
1601 <p>In general, there is a tension between making entries easy to find
1602 by searching for identifiers, and wasting time or producing unreadable
1603 entries by being exhaustive. Use the above guidelines and your best
1604 judgment, and be considerate of your fellow developers. (Also, run
1605 "svn log" to see how others have been writing their log entries.)</p>
1607 <p>Log messages for documentation or translation have somewhat looser
1608 guidelines. The requirement to name every symbol obviously does not
1609 apply, and if the change is just one more increment in a continuous
1610 process such as translation, it's not even necessary to name every
1611 file. Just briefly summarize the change, for example: "More work on
1612 Malagasy translation." Please write your log messages in English, so
1613 everybody involved in the project can understand the changes you
1614 made.</p>
1616 </div>
1619 <div class="h2" id="crediting" title="crediting">
1620 <h2>Crediting</h2>
1622 <p>It is very important to record code contributions in a consistent
1623 and parseable way. This allows us to write scripts to figure out who
1624 has been actively contributing&nbsp;&mdash;&nbsp;and what they have
1625 contributed&nbsp;&mdash;&nbsp;so we can <a
1626 href="http://www.red-bean.com/svnproject/contribulyzer/">spot
1627 potential new committers quickly</a>. The Subversion project uses
1628 human-readable but machine-parseable fields in log messages to
1629 accomplish this.</p>
1631 <p>When committing a patch written by someone else, use
1632 "Patch&nbsp;by:&nbsp;" at the beginning of a line to indicate the
1633 author:</p>
1635 <pre>
1636 Fix issue #1729: Don't crash because of a missing file.
1638 * subversion/libsvn_ra_ansible/get_editor.c
1639 (frobnicate_file): Check that file exists before frobnicating.
1641 Patch by: J. Random &lt;jrandom@example.com&gt;
1642 </pre>
1644 <p>If multiple individuals wrote the patch, list them each on a
1645 separate line&nbsp;&mdash;&nbsp;making sure to start each continuation
1646 line with whitespace. Non-committers should be listed by name, if
1647 known, and e-mail. Committers may be listed similarly, or by their
1648 canonical usernames from COMMITTERS (the leftmost column).
1649 Additionally, "me" is an acceptable shorthand for the person actually
1650 committing the change.</p>
1652 <pre>
1653 Fix issue #1729: Don't crash because of a missing file.
1655 * subversion/libsvn_ra_ansible/get_editor.c
1656 (frobnicate_file): Check that file exists before frobnicating.
1658 Patch by: J. Random &lt;jrandom@example.com&gt;
1659 Enrico Caruso &lt;codingtenor@codingtenor.com&gt;
1660 jcommitter
1662 </pre>
1664 <p>If someone found the bug or pointed out the problem, but didn't
1665 write the patch, indicate their contribution with
1666 "Found&nbsp;by:&nbsp;":</p>
1668 <pre>
1669 Fix issue #1729: Don't crash because of a missing file.
1671 * subversion/libsvn_ra_ansible/get_editor.c
1672 (frobnicate_file): Check that file exists before frobnicating.
1674 Found by: J. Random &lt;jrandom@example.com&gt;
1675 </pre>
1677 <p>If someone suggested something useful, but didn't write the patch,
1678 indicate their contribution with "Suggested&nbsp;by:&nbsp;":</p>
1680 <pre>
1681 Extend the Contribulyzer syntax to distinguish finds from ideas.
1683 * www/hacking.html (crediting): Adjust accordingly.
1685 Suggested by: dlr
1686 </pre>
1688 <p>If someone reviewed the change, use "Review&nbsp;by:&nbsp;"
1689 (or "Reviewed&nbsp;by:&nbsp;" if you prefer):</p>
1691 <pre>
1692 Fix issue #1729: Don't crash because of a missing file.
1694 * subversion/libsvn_ra_ansible/get_editor.c
1695 (frobnicate_file): Check that file exists before frobnicating.
1697 Review by: Eagle Eyes &lt;eeyes@example.com&gt;
1698 </pre>
1700 <p>A field may have multiple lines, and a log message may contain any
1701 combination of fields:</p>
1703 <pre>
1704 Fix issue #1729: Don't crash because of a missing file.
1706 * subversion/libsvn_ra_ansible/get_editor.c
1707 (frobnicate_file): Check that file exists before frobnicating.
1709 Patch by: J. Random &lt;jrandom@example.com&gt;
1710 Enrico Caruso &lt;codingtenor@codingtenor.com&gt;
1712 Found by: J. Random &lt;jrandom@example.com&gt;
1713 Review by: Eagle Eyes &lt;eeyes@example.com&gt;
1714 jcommitter
1715 </pre>
1717 <p>Further details about a contribution should be listed in a
1718 parenthetical aside immediately after the corresponding field. Such
1719 an aside always applies to the field right above it; in the following
1720 example, the fields have been spaced out for readability, but note
1721 that the spacing is optional and not necessary for parseability:</p>
1723 <pre>
1724 Fix issue #1729: Don't crash because of a missing file.
1726 * subversion/libsvn_ra_ansible/get_editor.c
1727 (frobnicate_file): Check that file exists before frobnicating.
1729 Patch by: J. Random &lt;jrandom@example.com&gt;
1730 (Tweaked by me.)
1732 Review by: Eagle Eyes &lt;eeyes@example.com&gt;
1733 jcommitter
1734 (Eagle Eyes caught an off-by-one-error in the basename extraction.)
1735 </pre>
1737 <p>Currently, these fields</p>
1739 <pre>
1740 Patch by:
1741 Suggested by:
1742 Found by:
1743 Review by:
1744 </pre>
1746 <p>are the only officially-supported crediting fields (where
1747 "supported" means scripts know to look for them), and they are widely
1748 used in Subversion log messages. Future fields will probably be of
1749 the form "VERB&nbsp;by:&nbsp;", and from time to time someone may use
1750 a field that sounds official but really is not&nbsp;&mdash;&nbsp;for
1751 example, there are a few instances of "Reported&nbsp;by:&nbsp;".
1752 These are okay, but try to use an official field, or a parenthetical
1753 aside, in preference to creating your own. Also, don't use
1754 "Reported&nbsp;by:&nbsp;" when the reporter is already recorded in an
1755 issue; instead, simply refer to the issue.</p>
1757 <p>Look over Subversion's existing log messages to see how to use
1758 these fields in practice. This command from the top of your trunk
1759 working copy will help:</p>
1761 <pre>
1762 svn log | contrib/client-side/search-svnlog.pl "(Patch|Review|Suggested) by: "
1763 </pre>
1765 <p><b>Note:</b> The "Approved&nbsp;by:&nbsp;" field seen in some
1766 commit messages is totally unrelated to these crediting fields, and is
1767 generally not parsed by scripts. It is simply the standard syntax for
1768 indicating either who approved a partial committer's commit outside
1769 their usual area, or (in the case of merges to release branches) who
1770 voted for the change to be merged.</p>
1772 </div>
1775 <div class="h2" id="patches" title="patches">
1776 <h2>Patch submission guidelines</h2>
1778 <p>Mail patches to dev@subversion.tigris.org, starting the subject
1779 line with <tt>[PATCH]</tt>. This helps our patch manager spot patches
1780 right away. For example:</p>
1782 <pre>
1783 Subject: [PATCH] fix for rev printing bug in svn status
1784 </pre>
1786 <p>If the patch addresses a particular issue, include the issue number
1787 as well: "<tt>[PATCH]&nbsp;issue&nbsp;#1729: ...</tt>". Developers
1788 who are interested in that particular issue will know to read the
1789 mail.</p>
1791 <p>A patch submission should contain one logical change; please don't
1792 mix N unrelated changes in one submission&nbsp;&mdash;&nbsp;send N
1793 separate emails instead.</p>
1795 <p>Generate the patch using <tt>svn&nbsp;diff</tt> from the top of a
1796 Subversion trunk working copy. If the file you're diffing is not
1797 under revision control, you can achieve the same effect by using
1798 <tt>diff&nbsp;-u</tt>.</p>
1800 <p>Please include a log message with your patch. A good log message
1801 helps potential reviewers understand the changes in your patch, and
1802 increases the likelihood that it will be applied. You can put the log
1803 message in the body of the email, or at the top of the patch
1804 attachment (see below). Either way, it should follow the guidelines
1805 given in <a href="#log-messages">Writing log messages</a>, and be
1806 enclosed in triple square brackets, like so:</p>
1808 <pre>
1810 Fix issue #1729: Don't crash because of a missing file.
1812 * subversion/libsvn_ra_ansible/get_editor.c
1813 (frobnicate_file): Check that file exists before frobnicating.
1815 </pre>
1817 <p>(The brackets are not actually part of the log message, they're
1818 just a way to clearly mark off the log message from its surrounding
1819 context.)</p>
1821 <p>If possible, send the patch as an attachment with a mime-type of
1822 text/x-diff, text/x-patch, or text/plain. Most people's mailreaders
1823 can display those inline, and having the patch as an attachment allows
1824 them to extract the patch from the message conveniently. Never send
1825 patches in archived or compressed form (e.g., tar, gzip, zip, bzip2),
1826 because that prevents people from reviewing the patch directly in
1827 their mailreaders.</p>
1829 <p>If you can't attach the patch with one of these mime-types, or if
1830 the patch is very short, then it's okay to include it directly in the
1831 body of your message. But watch out: some mail editors munge inline
1832 patches by inserting unasked-for line breaks in the middle of long
1833 lines. If you think your mail software might do this, then please use
1834 an attachment instead.</p>
1836 <p>If the patch implements a new feature, make sure to describe the
1837 feature completely in your mail; if the patch fixes a bug, describe
1838 the bug in detail and give a reproduction recipe. An exception to
1839 these guidelines is when the patch addresses a specific issue in the
1840 issues database&nbsp;&mdash;&nbsp;in that case, just refer to the
1841 issue number in your log message, as described
1842 in <a href="#log-messages">Writing log messages</a>.</p>
1844 <p>It is normal for patches to undergo several rounds of feedback and
1845 change before being applied. Don't be discouraged if your patch is
1846 not accepted immediately&nbsp;&mdash;&nbsp;it doesn't mean you goofed,
1847 it just means that there are a <em>lot</em> of eyes looking at every
1848 code submission, and it's a rare patch that doesn't have at least a
1849 little room for improvement. After reading people's responses to your
1850 patch, make the appropriate changes and resubmit, wait for the next
1851 round of feedback, and lather, rinse, repeat, until some committer
1852 applies it.</p>
1854 <p>If you don't get a response for a while, and don't see the patch
1855 applied, it may just mean that people are really busy. Go ahead and
1856 repost, and don't hesitate to point out that you're still waiting for
1857 a response. One way to think of it is that patch management is highly
1858 parallizable, and we need you to shoulder your share of the management
1859 as well as the coding. Every patch needs someone to shepherd it
1860 through the process, and the person best qualified to do that is the
1861 original submitter.</p>
1863 <div class="h3" id="patch-manager" title="patch-manager">
1864 <h3>The "Patch Manager" Role</h3>
1866 <p>Subversion usually has a Patch Manager, whose job is to watch the
1867 dev@ mailing list and make sure that no patches "slip through the
1868 cracks".</p>
1870 <p>This means watching every thread containing "[PATCH]" mails, and
1871 taking appropriate action based on the progress of the thread. If the
1872 thread resolves on its own (because the patch gets committed, or
1873 because there is consensus that the patch doesn't need to be applied,
1874 or whatever) then no further action need be taken. But if the thread
1875 fades out without any clear decision, then the patch needs to be saved
1876 in the issue tracker. This means that a summary of any discussion
1877 threads around that patch, and links to relevant mailing list
1878 archives, will be added to some issue in the tracker. For a patch
1879 which addresses an existing issue tracker item, the patch is saved to
1880 that item. Otherwise, a new issue of type 'PATCH' is filed, and the
1881 patch is saved to that new issue.</p>
1883 <p>The Patch Manager needs a basic technical understanding of
1884 Subversion, and the ability to skim a thread and get a rough
1885 understanding of whether consensus has been reached, and if so, of
1886 what kind. It does <em>not</em> require actual Subversion development
1887 experience or commit access. Expertise in using one's mail reading
1888 software is optional, but recommended :-).</p>
1890 <p>The current patch manager is Hyrum Wright
1891 &lt;hyrum_wright@mail.utexas.edu&gt;.</p>
1893 </div>
1895 </div>
1898 <div class="h2" id="filing-issues" title="filing-issues">
1899 <h2>Filing bugs / issues</h2>
1901 <p>This pretty much says it all:</p>
1903 <pre>
1904 From: Karl Fogel &lt;kfogel@collab.net&gt;
1905 Subject: Please ask on the list before filing a new issue.
1906 To: dev@subversion.tigris.org
1907 Date: Tue, 30 Jul 2002 10:51:24 (CDT)
1909 Folks, we're getting tons of new issues, which is a Good Thing in
1910 general, but some of them don't really belong in the issue tracker.
1911 They're things that would be better solved by a quick conversation
1912 here on the dev list. Compilation problems, behavior questions,
1913 feature ideas that have been discussed before, that sort of thing.
1915 *Please* be more conservative about filing issues. The issues
1916 database is physically much more cumbersome than email. It wastes
1917 people's time to have conversations in the issues database that should
1918 be had in email. (This is not a libel against the issue tracker, it's
1919 just a result of the fact that the issues database is for permanent
1920 storage and flow annotation, not for real-time conversation.)
1922 If you encounter a situation where Subversion is clearly behaving
1923 wrongly, or behaving opposite to what the documentation says, then
1924 it's okay to file the issue right away (after searching to make sure
1925 it isn't already filed, of course!). But if you're
1927 a) Requesting a new feature, or
1928 b) Having build problems, or
1929 c) Not sure what the behavior should be, or
1930 d) Disagreeing with current intended behavior, or
1931 e) Not TOTALLY sure that others would agree this is a bug, or
1932 f) For any reason at all not sure this should be filed,
1934 ...then please post to the dev list first. You'll get a faster
1935 response, and others won't be forced to use the issues database to
1936 have the initial real-time conversations.
1938 Nothing is lost this way. If we eventually conclude that it should be
1939 in the issue tracker, then we can still file it later, after the
1940 description and reproduction recipe have been honed on the dev list.
1942 Thank you,
1943 -Karl
1944 </pre>
1946 </div>
1948 <div class="h2" id="issue-triage" title="issue-triage">
1949 <h2>Issue triage</h2>
1951 <p>When an issue is filed, it goes into the special milestone "---",
1952 meaning <em>unmilestoned</em>. This is a holding area that issues
1953 live in until someone gets a chance to look at them and decide what to
1954 do.</p>
1956 <p>The unmilestoned issues are listed first when you sort by
1957 milestone, and <em>issue triage</em> is the process of trawling
1958 through all the <a
1959 href="http://subversion.tigris.org/issues/buglist.cgi?component=subversion&amp;issue_status=UNCONFIRMED&amp;issue_status=NEW&amp;issue_status=STARTED&amp;issue_status=REOPENED&amp;order=issues.target_milestone%2C%20issues.priority%2C%20issues.issue_type"
1960 >open issues</a> (starting with the unmilestoned ones), determining
1961 which are important enough to be fixed now, which can wait until
1962 another release, which are duplicates of existing issues, which have
1963 been resolved already, etc. For each issue that will remain open, it
1964 also means making sure that the various fields are set appropriately:
1965 type, subcomponent, platform, OS, version, keywords (if any), and so
1966 on.</p>
1968 <p>Here's an overview of the process (in this example, 1.5 is the next
1969 release, so urgent issues would go there):</p>
1971 <pre>
1972 for i in issues_marked_as("---"):
1973 if issue_is_a_dup_of_some_other_issue(i):
1974 close_as_dup(i)
1975 elif issue_is_invalid(i):
1976 # A frequent reason for invalidity is that the reporter
1977 # did not follow the <a href="http://subversion.tigris.org/project_issues.html#buddy-system">"buddy system"</a> for filing.
1978 close_as_invalid(i)
1979 elif issue_already_fixed(i):
1980 close_as_fixed(i)
1981 elif issue_unreproducible(i):
1982 close_as_worksforme(i)
1983 elif issue_is_real_but_we_won't_fix_it(i):
1984 close_as_wontfix(i)
1985 elif issue_is_closeable_for_some_other_reason(i):
1986 close_as_it_for_that_reason(i)
1988 # Else issue should remain open, so DTRT with it...
1990 # Set priority, platform, subcomponent, etc, as needed.
1991 adjust_all_fields_that_need_adjustment(i)
1993 # Figure out where to put it.
1994 if issue_is_a_lovely_fantasy(i):
1995 move_to_milestone(i, "blue-sky")
1996 if issue_is_not_important_enough_to_block_any_particular_release(i):
1997 move_to_milestone(i, "nonblocking")
1998 elif issue_resolution_would_require_incompatible_changes(i):
1999 move_to_milestone(i, "2.0")
2000 elif issue_hurts_people_somewhat(i):
2001 move_to_milestone(i, "1.6") # or whatever
2002 elif issue_hurts_people_a_lot(i):
2003 move_to_milestone(i, "1.5-consider")
2004 elif issue_hurts_and_hurts_and_won't_stop_hurting(i):
2005 move_to_milestone(i, "1.5")
2006 </pre>
2008 </div>
2010 <div class="h2" id="commit-access" title="commit-access">
2011 <h2>Commit access</h2>
2013 <p>There are two types of commit access: full and partial. Full means
2014 anywhere in the tree, partial means only in that committer's specific
2015 area(s) of expertise. The COMMITTERS file lists all committers, both
2016 full and partial, and says the domains for each partial committer.</p>
2018 <div class="h3" id="full-commit-access" title="full-commit-access">
2019 <h3>How full commit access is granted</h3>
2021 <p>After someone has successfully contributed a few non-trivial
2022 patches, some full committer, usually whoever has reviewed and applied
2023 the most patches from that contributor, proposes them for commit
2024 access. This proposal is sent only to the other full committers --
2025 the ensuing discussion is private, so that everyone can feel
2026 comfortable speaking their minds. Assuming there are no objections,
2027 the contributor is granted commit access. The decision is made by
2028 consensus; there are no formal rules governing the procedure, though
2029 generally if someone strongly objects the access is not offered, or is
2030 offered on a provisional basis.</p>
2032 <p><i>The primary criterion for full commit access is good
2033 judgment.</i></p>
2035 <p>You do not have to be a technical wizard, or demonstrate deep
2036 knowledge of the entire codebase, to become a full committer. You
2037 just need to know what you don't know. If your patches adhere to the
2038 guidelines in this file, adhere to all the usual unquantifiable rules
2039 of coding (code should be readable, robust, maintainable, etc.), and
2040 respect the Hippocratic Principle of "first, do no harm", then you
2041 will probably get commit access pretty quickly. The size, complexity,
2042 and quantity of your patches do not matter as much as the degree of
2043 care you show in avoiding bugs and minimizing unnecessary impact on
2044 the rest of the code. Many full committers are people who have not
2045 made major code contributions, but rather lots of small, clean fixes,
2046 each of which was an unambiguous improvement to the code. (Of course,
2047 this does not mean the project needs a bunch of very trivial patches
2048 whose only purpose is to gain commit access; knowing what's worth a
2049 patch post and what's not is part of showing good judgement :-) .)</p>
2051 <p>To assist developers in discovering new committers, we record
2052 patches and other contributions in a <a href="#crediting">special
2053 crediting format</a>, which is then parsed to produce a
2054 browser-friendly <a
2055 href="http://www.red-bean.com/svnproject/contribulyzer/">contribution
2056 list</a>, updated nightly. If you're thinking of proposing someone
2057 for commit access and want to look over all their changes, that <a
2058 href="http://www.red-bean.com/svnproject/contribulyzer/">contribution
2059 list</a> might be the most convenient place to do it.</p>
2061 </div>
2063 <div class="h3" id="partial-commit-access" title="partial-commit-access">
2064 <h3>How partial commit access is granted</h3>
2066 <p>A full committer sponsors the partial committer. Usually this
2067 means the full committer has applied several patches to the same area
2068 from the proposed partial committer, and realizes things would be
2069 easier if the person were just committing directly. Approval is not
2070 required from the full committers; it is assumed that sponsors know
2071 what they're doing and will watch the partial committer's first few
2072 commits to make sure everything's going smoothly.</p>
2074 <p>Patches submitted by a partial committer may be committed by that
2075 committer even if they are outside that person's domain. This
2076 requires approval (often expressed as a +1 vote) from at least one
2077 full committer. In such a case, the approval should be noted in the
2078 log message, like so:</p>
2080 <pre>
2081 Approved by: lundblad
2082 </pre>
2084 <p>Any full committer may offer anyone commit access to an
2085 experimental branch at any time. It is not necessary that the
2086 experimental branch have a high likelihood of being merged to trunk
2087 (although that's always a good goal to aim for). It's just as
2088 imporant that the full committer&nbsp;&mdash;&nbsp;all the full
2089 committers, actually&nbsp;&mdash;&nbsp;view such branches as training
2090 grounds for new developers, by giving feedback on the commits. The
2091 goal of these branches is both to get new code into Subversion and to
2092 get new developers into the project. See also the <a
2093 href="#lightweight-branches" >section on lightweight branches</a>, and
2094 this mail:</p>
2096 <pre>
2097 <a href="http://subversion.tigris.org/servlets/ReadMsg?list=dev&amp;msgNo=132746"
2098 >http://subversion.tigris.org/servlets/ReadMsg?list=dev&amp;msgNo=132746
2099 From: Karl Fogel &lt;kfogel@red-bean.com&gt;
2100 To: dev@subversion.tigris.org
2101 Subject: branch liberalization (was: Elego tree conflicts work)
2102 Date: Tue, 20 Nov 2007 10:49:38 -0800
2103 Message-Id: &lt;87y7cswy4d.fsf@red-bean.com&gt;</a>
2104 </pre>
2106 </div>
2108 <div class="h3" id="contrib-area" title="contrib-area">
2109 <h3>The contrib/ area</h3>
2111 <p>When a tool is accepted into the <i>contrib/</i> area, we
2112 automatically offer its author partial commit access to maintain the
2113 tool there. Any full committer can sponsor this. Usually no
2114 discussion or vote is necessary, though if there are objections then
2115 the usual decision-making procedures apply (attempt to reach consensus
2116 first, then vote among the full committers if consensus cannot be
2117 reached).</p>
2119 <p>Code under contrib/ must be open source, but need not have the same
2120 license or copyright holder as Subversion itself.</p>
2122 </div>
2124 <div class="h3" id="obvious-fix" title="obvious-fix">
2125 <h3>The "obvious fix" rule</h3>
2127 <p>Any committer, whether full or partial, may commit fixes for
2128 obvious typos, grammar mistakes, and formatting problems wherever they
2129 may be&nbsp;&mdash;&nbsp;in the web pages, API documentation, code
2130 comments, commit messages, etc. We rely on the committer's judgement
2131 to determine what is "obvious"; if you're not sure, just ask.</p>
2133 </div>
2135 </div>
2137 <div class="h2" id="lightweight-branches" title="lightweight-branches">
2138 <h2>Use lightweight branches</h2>
2140 <p>If you're working on a feature or bugfix in stages involving
2141 multiple commits, and some of the intermediate stages aren't stable
2142 enough to go on trunk, then create a temporary branch in /branches.
2143 There's no need to ask&nbsp;&mdash;&nbsp;just do it. It's fine to try
2144 out experimental ideas in a temporary branch, too. And all the
2145 preceding applies to partial as well as full committers.</p>
2147 <p>If you're just using the branch to "checkpoint" your code, and
2148 don't feel it's ready for review, please put some sort of notice at
2149 the top of the log message, such as:</p>
2151 <pre>
2152 *** checkpoint commit -- please don't waste your time reviewing it ***
2153 </pre>
2155 <p>And if a later commit on that branch <em>should</em> be reviewed,
2156 then please supply, in the log message, the appropriate 'svn diff'
2157 command, since the diff would likely involve two non-adjacent commits
2158 on that branch, and reviewers shouldn't have to spend time figuring
2159 out which ones they are.</p>
2161 <p>When you're done with the branch&nbsp;&mdash;&nbsp;when you've
2162 either merged it to trunk or given up on it&nbsp;&mdash;&nbsp;please
2163 remember to remove it.</p>
2165 <p>See also the <a href="#partial-commit-access" >section on partial
2166 commit access</a> for our policy on offering commit access to
2167 experimental branches.</p>
2169 </div>
2171 <div class="h2" id="configury" title="configury">
2172 <h2>The configuration/build system under unix</h2>
2174 <p>Greg Stein wrote a custom build system for Subversion, which had
2175 been using `automake' and recursive Makefiles. Now it uses a single,
2176 top-level Makefile, generated from Makefile.in (which is kept under
2177 revision control). `Makefile.in' in turn includes `build-outputs.mk',
2178 which is automatically generated from `build.conf' by the
2179 `gen-make.py' script. Thus, the latter two are under revision
2180 control, but `build-outputs.mk' is not.</p>
2182 <p>Here is Greg's original mail describing the system, followed by
2183 some advice about hacking it:</p>
2185 <pre>
2186 From: Greg Stein &lt;gstein@lyra.org&gt;
2187 Subject: new build system (was: Re: CVS update: MODIFIED: ac-helpers ...)
2188 To: dev@subversion.tigris.org
2189 Date: Thu, 24 May 2001 07:20:55 -0700
2190 Message-ID: &lt;20010524072055.F5402@lyra.org&gt;
2192 On Thu, May 24, 2001 at 01:40:17PM -0000, gstein@tigris.org wrote:
2193 &gt; User: gstein
2194 &gt; Date: 01/05/24 06:40:17
2195 &gt;
2196 &gt; Modified: ac-helpers .cvsignore svn-apache.m4
2197 &gt; Added: . Makefile.in
2198 &gt; Log:
2199 &gt; Switch over to the new non-recursive build system.
2200 &gt;...
2202 Okay... this is it. We're now on the build system.
2204 "It works on my machine."
2206 I suspect there may be some tweaks to make on different OSs. I'd be
2207 interested to hear if Ben can really build with normal BSD make. It
2208 should be possible.
2210 The code supports building, installation, checking, and
2211 dependencies. It does *NOT* yet deal with the doc/ subdirectory. That
2212 is next; I figured this could be rolled out and get the kinks worked
2213 out while I do the doc/ stuff. Oh, it doesn't build Neon or APR yet
2214 either. I also saw a problem where libsvn_fs wasn't getting built
2215 before linking one of the test proggies (see below).
2217 Basic operation: same as before.
2219 $ ./autogen.sh
2220 $ ./configure OPTIONS
2221 $ make
2222 $ make check
2223 $ make install
2225 There are some "make check" scripts that need to be fixed up. That'll
2226 happen RSN. Some of them create their own log, rather than spewing to
2227 stdout (where the top-level make will place the output into
2228 [TOP]/tests.log).
2230 The old Makefile.am files are still around, but I'll be tossing those
2231 along with a bunch of tweaks to all the .cvsignore files. There are a
2232 few other cleanups, too. But that can happen as a step two.
2234 [ $ cvs rm -f `find . -name Makefile.rm`
2236 See the mistake in that line? I didn't when I typed it. The find
2237 returned nothing, so cvs rm -f proceeded to delete my entire
2238 tree. And the -f made sure to delete all my source files, too. Good
2239 fugging thing that I had my mods in some Emacs buffers, or I'd be
2240 bitching.
2242 I am *so* glad that Ben coded SVN to *not* delete locally modified
2243 files *and* that we have an "undel" command. I had to go and tweak a
2244 bazillion Entries files to undo the delete...
2247 The top-level make has a number of shortcuts in it (well, actually in
2248 build-outputs.mk):
2250 $ make subversion/libsvn_fs/libsvn_fs.la
2254 $ make libsvn_fs
2256 The two are the same. So... when your test proggie fails to link
2257 because libsvn_fs isn't around, just run "make libsvn_fs" to build it
2258 immediately, then go back to the regular "make".
2260 Note that the system still conditionally builds the FS stuff based
2261 on whether DB (See 'Building on Unix' below) is available, and
2262 mod_dav_svn if Apache is available.
2264 Handy hint: if you don't like dependencies, then you can do:
2266 $ ./autogen.sh -s
2268 That will skip the dependency generation that goes into
2269 build-outputs.mk. It makes the script run quite a bit faster (48 secs
2270 vs 2 secs on my poor little Pentium 120).
2272 Note that if you change build.conf, you can simply run:
2274 $ ./gen-make.py build.conf
2276 to regen build-outputs.mk. You don't have to go back through the whole
2277 autogen.sh / configure process.
2279 You should also note that autogen.sh and configure run much faster now
2280 that we don't have the automake crap. Oh, and our makefiles never
2281 re-run configure on you out of the blue (gawd, I hated when automake
2282 did that to me).
2284 Obviously, there are going to be some tweaky things going on. I also
2285 think that the "shadow" builds or whatever they're called (different
2286 source and build dirs) are totally broken. Something tweaky will have
2287 to happen there. But, thankfully, we only have one Makefile to deal
2288 with.
2290 Note that I arrange things so that we have one generated file
2291 (build-outputs.mk), and one autoconf-generated file (Makefile from
2292 .in). I also tried to shove as much logic/rules into
2293 Makefile.in. Keeping build-outputs.mk devoid of rules (thus, implying
2294 gen-make.py devoid of rules in its output generation) manes that
2295 tweaking rules in Makefile.in is much more approachable to people.
2297 I think that is about it. Send problems to the dev@ list and/or feel
2298 free to dig in and fix them yourself. My next steps are mostly
2299 cleanup. After that, I'm going to toss out our use of libtool and rely
2300 on APR's libtool setup (no need for us to replicate what APR already
2301 did).
2303 Cheers,
2307 Greg Stein, http://www.lyra.org/
2308 </pre>
2310 <p>And here is some advice for those changing or testing the
2311 configuration/build system:</p>
2313 <pre>
2314 From: Karl Fogel &lt;kfogel@collab.net&gt;
2315 To: dev@subversion.tigris.org
2316 Subject: when changing build/config stuff, always do this first
2317 Date: Wed 28 Nov 2001
2319 Yo everyone: if you change part of the configuration/build system,
2320 please make sure to clean out any old installed Subversion libs
2321 *before* you try building with your changes. If you don't do this,
2322 your changes may appear to work fine, when in fact they would fail if
2323 run on a truly pristine system.
2325 This script demonstrates what I mean by "clean out". This is
2326 `/usr/local/cleanup.sh' on my system. It cleans out the Subversion
2327 libs (and the installed httpd-2.0 libs, since I'm often reinstalling
2328 that too):
2330 #!/bin/sh
2332 # Take care of libs
2333 cd /usr/local/lib
2334 rm -f APRVARS
2335 rm -f libapr*
2336 rm -f libexpat*
2337 rm -f libneon*
2338 rm -f libsvn*
2340 # Take care of headers
2341 cd /usr/local/include
2342 rm -f apr*
2343 rm -f svn*
2344 rm -f neon/*
2346 # Take care of headers
2347 cd /usr/local/apache2/lib
2348 rm -f *
2350 When someone reports a configuration bug and you're trying to
2351 reproduce it, run this first. :-)
2353 The voice of experience,
2354 -Karl
2355 </pre>
2357 </div>
2360 <div class="h2" id="releasing" title="releasing">
2361 <h2>How to release a distribution tarball</h2>
2363 <p>See <a href="release-process.html">The Subversion Release Procedure</a>.</p>
2365 </div>
2368 <div class="h2" id="release-numbering" title="release-numbering">
2369 <h2>Release numbering, compatibility, and deprecation</h2>
2371 <p>Subversion uses "MAJOR.MINOR.PATCH" release numbers, with the same
2372 guidelines as APR (see <a href="http://apr.apache.org/versioning.html"
2373 >http://apr.apache.org/versioning.html</a>), plus a few extensions,
2374 described later. The general idea is:</p>
2376 <ol>
2378 <li><p>Upgrading/downgrading between different patch releases in the
2379 same MAJOR.MINOR line never breaks code. It may cause bugfixes
2380 to disappear/reappear, but API signatures and semantics remain
2381 the same. (Of course, the semantics may change in the trivial
2382 ways appropriate for bugfixes, just not in ways that would
2383 force adjustments in calling code.)</p>
2384 </li>
2386 <li><p>Upgrading to a new minor release in the same major line may
2387 cause new APIs to appear, but not remove any APIs. Any code
2388 written to the old minor number will work with any later minor
2389 number in that line. However, downgrading afterwards may not
2390 work, if new code has been written that takes advantage of the
2391 new APIs.</p>
2392 </li>
2394 <li><p>When the major number changes, all bets are off. This is the
2395 only opportunity for a full reset of the APIs, and while we try
2396 not to gratuitously remove interfaces, we will use it to clean
2397 house a bit.</p>
2398 </li>
2400 </ol>
2402 <p>Subversion extends the APR guidelines to cover client/server
2403 compatibility questions:</p>
2405 <ol>
2407 <li><p>A patch or minor number release of a server (or client) never
2408 breaks compatibility with a client (or server) in the same
2409 major line. However, new features offered by the release might
2410 be unsupported without a corresponding upgrade to the other
2411 side of the connection. For updating ra_svn code specifically,
2412 please observe these principles:</p>
2414 <ol>
2416 <li><p>Fields can be added to any tuple; old clients will simply
2417 ignore them. (Right now, the marshalling implementation
2418 does not let you put number or boolean values in the
2419 optional part of a tuple, but changing that will not affect
2420 the protocol.)</p>
2422 <p>We can use this mechanism when information is added to an
2423 API call.</p>
2424 </li>
2426 <li><p>At connection establishment time, clients and servers exchange
2427 a list of capability keywords.</p>
2429 <p>We can use this mechanism for more complicated changes,
2430 like introducing pipelining or removing information from
2431 API calls.</p>
2432 </li>
2434 <li><p>New commands can be added; trying to use an unsupported
2435 command will result in an error which can be checked and dealt
2436 with.</p>
2437 </li>
2439 <li><p>The protocol version number can be bumped to allow graceful
2440 refusal of old clients or servers, or to allow a client or
2441 server to detect when it has to do things the old way.</p>
2443 <p>This mechanism is a last resort, to be used when capability
2444 keywords would be too hard to manage.</p>
2445 </li>
2447 </ol>
2448 </li>
2450 <li><p>Working copy and repository formats are backward- and
2451 forward-compatible for all patch releases in the same minor
2452 series. They are forward-compatible for all minor releases in
2453 the same major series; however, a minor release is allowed to
2454 make a working copy or repository that doesn't work with
2455 previous minor releases, where "make" could mean "upgrade" as
2456 well as "create".</p>
2457 </li>
2459 </ol>
2461 <p>Subversion does not use the "even==stable, odd==unstable"
2462 convention; any unqualified triplet indicates a stable release:</p>
2464 <pre>
2465 1.0.1 --&gt; first stable patch release of 1.0
2466 1.1.0 --&gt; next stable minor release of 1.x after 1.0.x
2467 1.1.1 --&gt; first stable patch release of 1.1.x
2468 1.1.2 --&gt; second stable patch release of 1.1.x
2469 1.2.0 --&gt; next stable minor release after that
2470 </pre>
2472 <p>The order of releases is semi-nonlinear&nbsp;&mdash;&nbsp;a 1.0.3
2473 <em>might</em> come out after a 1.1.0. But it's only "semi"-nonlinear
2474 because eventually we declare a patch line defunct and tell people to
2475 upgrade to the next minor release, so over the long run the numbering
2476 is basically linear.</p>
2478 <p>Non-stable releases are qualified with "alphaN" or "betaN"
2479 suffixes, and release candidates with "-rcN". For example, the
2480 prereleases leading to 1.3.7 might look like this:</p>
2482 <pre>
2483 subversion-1.3.7-rc1.tar.gz
2484 subversion-1.3.7-rc2.tar.gz
2485 subversion-1.3.7-rc3.tar.gz
2486 subversion-1.3.7.tar.gz
2487 </pre>
2489 <p>The output of 'svn --version' corresponds in the obvious way:</p>
2491 <pre>
2492 version 1.3.7 (Release Candidate 1)
2493 version 1.3.7 (Release Candidate 2)
2494 version 1.3.7 (Release Candidate 3)
2495 version 1.3.7
2496 </pre>
2498 <p>When you 'make install' subversion-1.3.7-rc1, it still installs as
2499 though it were "1.3.7", of course. The qualifiers are metadata on the
2500 release; we want each subsequent prerelease release to overwrite the
2501 previous one, and the final release to overwrite the last
2502 prerelease.</p>
2504 <p>For working copy builds, there is no tarball name to worry about,
2505 but 'svn --version' still produces special output:</p>
2507 <pre>
2508 version 1.3.7 (dev build)
2509 </pre>
2511 <p>The version number is the next version that the development was
2512 working towards. The important thing is to say "dev build". This
2513 indicates that the build came from a working copy, which is useful in
2514 bug reports.</p>
2516 <p>We have no mechanism for releasing dated snapshots. If we want
2517 code to get wider distribution than just those who build from working
2518 copies, we put out a prerelease.</p>
2520 <div class="h3" id="name-reuse" title="name-reuse">
2521 <h3>Reuse of release names</h3>
2523 <p>If a release or candidate release needs to be quickly re-issued due
2524 to some non-code problem (say, a packaging glitch), it's okay to reuse
2525 the same name, as long as the tarball hasn't been
2526 <a href="#tarball-signing">blessed by signing</a> yet. But if it has
2527 been uploaded to the standard distribution area with signatures, or if
2528 the re-issue was due to a change in code a user might run, then the
2529 old name must be tossed and the next name used.</p>
2531 </div>
2533 <div class="h3" id="deprecation" title="deprecation">
2534 <h3>Deprecation</h3>
2536 <p>When a new, improved version of an API is introduced, the old one
2537 remains for compatibility, at least until the next major release.
2538 However, we mark the old one as deprecated and point to the new one,
2539 so people know to write to the new API if at all possible. When
2540 deprecating, mention the release after which the deprecation was
2541 introduced, and point to the new API. If possible, replace the old
2542 API documentation with a diff to the new one. For example:</p>
2544 <pre>
2546 * @deprecated Provided for backward compatibility with the 1.0.0 API.
2548 * Similar to svn_repos_dump_fs2(), but with the @a use_deltas
2549 * parameter always set to @c FALSE.
2551 svn_error_t *svn_repos_dump_fs(svn_repos_t *repos,
2552 svn_stream_t *dumpstream,
2553 svn_stream_t *feedback_stream,
2554 svn_revnum_t start_rev,
2555 svn_revnum_t end_rev,
2556 svn_boolean_t incremental,
2557 svn_cancel_func_t cancel_func,
2558 void *cancel_baton,
2559 apr_pool_t *pool);
2560 </pre>
2562 <p>When the major release number changes, the "best" new API in a
2563 series generally replaces all the previous ones (assuming it subsumes
2564 their functionality), and it will take the name of the original API.
2565 Thus, marking 'svn_repos_dump_fs' as deprecated in 1.1.x doesn't mean
2566 that 2.0.0 doesn't have 'svn_repos_dump_fs', it just means the
2567 function's signature will be different: it will have the signature
2568 held by svn_repos_dump_fs2 (or svn_repos_dump_fs3, or whatever) in
2569 1.1.x. The numbered-suffix names disappear, and there is a single
2570 (shiny, new) svn_repos_dump_fs again.</p>
2572 <p>One exception to this replacement strategy is when the old function
2573 has a totally unsatisfying name anyway. Deprecation is a chance to
2574 fix that: we give the new API a totally new name, mark the old API as
2575 deprecated, point to the new API; then at the major version change, we
2576 remove the old API, but don't rename the new one to the old name,
2577 because its new name is fine.</p>
2579 </div>
2581 </div>
2584 <div class="h2" id="release-stabilization" title="release-stabilization">
2585 <h2>Stabilizing and maintaining releases</h2>
2587 <p>Minor and major number releases go through a stabilization period
2588 before release, and remain in maintenance (bugfix) mode after release.
2589 To start the release process, we create an "A.B.x" branch based on the
2590 latest trunk, for example:</p>
2592 <pre>
2593 $ svn cp http://svn.collab.net/repos/svn/trunk \
2594 http://svn.collab.net/repos/svn/branches/A.B.x
2595 </pre>
2597 <p>The stabilization period for a new A.B.0 release normally lasts
2598 four weeks, and allows us to make conservative bugfixes and discover
2599 showstopper issues. The stabilization period begins with a release
2600 candidate tarball with the version A.B.0-rc1. Further release
2601 candidate tarballs may be made as blocking bugs are fixed; for
2602 example, if a set of language bindings is found to be broken, it is
2603 prudent to make a new release candidate when they are fixed so that
2604 those language bindings may be tested.</p>
2606 <p>At the beginning of the final week of the stabilization period, a
2607 new release candidate tarball should be made if there are any changes
2608 pending since the last one. The final week of the stabilization
2609 period is reserved for critical bugfixes; fixes for minor bugs should
2610 be deferred to the A.B.1 release. A critical bug is a non-edge-case
2611 crash, a data corruption problem, a major security hole, or something
2612 equally serious.</p>
2614 <p>Under some circumstances, the stabilization period will be
2615 extended:</p>
2617 <ul>
2618 <li><p>If a potentially destabilizing change must be made in order to
2619 fix a bug, the entire four-week stabilization period is
2620 restarted. A potentially destabilizing change is one which
2621 could affect many parts of Subversion in unpredictable ways, or
2622 which involves adding a substantial amount of new code. Any
2623 incompatible API change (only allowable in the first place if
2624 the new release is an A.0.0 release) should be considered a
2625 potentially destabilizing change.</p>
2626 </li>
2628 <li><p>If a critical bugfix is made during the final week of the
2629 stabilization period, the final week is restarted. The final
2630 A.B.0 release is always identical to the release candidate made
2631 one week before (with the exceptions discussed below).</p>
2632 </li>
2634 </ul>
2636 <p>If there are disagreements over whether a change is potentially
2637 destabilizing or over whether a bug is critical, they may be settled
2638 with a committer vote.</p>
2640 <p>After the A.B.0 release is out, patch releases (A.B.1, A.B.2, etc.)
2641 follow when bugfixes warrant them. Patch releases do not require a
2642 four week soak, because only conservative changes go into the
2643 line.</p>
2645 <p>Certain kinds of commits can go into A.B.0 without restarting the
2646 soak period, or into a later release without affecting the testing
2647 schedule or release date:</p>
2649 <ul>
2650 <li><p>Without voting:</p>
2651 <ul>
2652 <li><p>Changes to the STATUS file.</p></li>
2653 <li><p>Documentation file changes, including to the book, README,
2654 INSTALL, www/, etc.</p></li>
2655 <li><p>Changes that are a normal part of release bookkeeping, for
2656 example, the steps listed in notes/releases.txt.</p></li>
2657 <li><p>Changes to dist.sh by, or approved by, the release manager.</p></li>
2658 <li><p>Changes to message translations in .po files or additions of
2659 new .po files.</p></li>
2660 </ul>
2661 </li>
2663 <li><p>With voting:</p>
2664 <ul>
2665 <li><p>Anything affecting only tools/, packages/, or bindings/.</p></li>
2666 <li><p>Doc fixes in core code header or source files.</p></li>
2667 <li><p>Changes to printed output, such as error and usage messages, as
2668 long as format string "%" codes and their args are not
2669 touched.</p></li>
2670 </ul>
2671 </li>
2673 </ul>
2675 <p>NOTE: The requirements on message translation changes are looser
2676 than for text messages in C code. Changing format specifiers in .po
2677 files is allowed because their validity can be checked mechanically
2678 (with the -c flag on msgfmt of GNU gettext). This is done at build
2679 time if GNU gettext is in use.</p>
2681 <p>Core code changes, of course, require voting, and restart the soak
2682 or test period, since otherwise the change could be undertested.</p>
2684 <p>The voting system works like this:</p>
2686 <p>A change to the A.B.x line must be first proposed in the
2687 A.B.x/STATUS file. Each proposal consists of a short identifying
2688 block (e.g., the revision number of a trunk or related-line commit, or
2689 perhaps an issue number), a brief description of the change, an
2690 at-most-one-line justification of why it should be in A.B.x, perhaps
2691 some notes/concerns, and finally the votes. The notes and concerns
2692 are meant to be brief summaries to help a reader get oriented; please
2693 don't use the STATUS file for actual discussion, use dev@ instead.</p>
2695 <p>Here's an example, probably as complex as an entry would ever
2696 get:</p>
2698 <pre>
2699 * r98765 (issue #56789)
2700 Make commit editor take a closure object for future mindreading.
2701 Justification: API stability, as prep for future enhancement.
2702 Notes: There was consensus on the desirability of this feature in
2703 the near future; see thread at http://... (Message-Id: blahblah).
2704 Concerns: Vetoed by jerenkrantz due to privacy concerns with the
2705 implementation; see thread at http://... (Message-Id: blahblah)
2706 Votes:
2707 +1: ghudson, bliss
2708 +0: cmpilato
2709 -0: gstein
2710 -1: jerenkrantz
2711 </pre>
2713 <p>A change needs three +1 votes from full committers (or partial
2714 committers for the involved areas), and no vetoes, to go into
2715 A.B.x.</p>
2717 <p>If you cast a veto (i.e. -1), please state the reason in the
2718 concerns field, and include a url / message-id for the list discussion
2719 if any. You can go back and add the link later if the thread isn't
2720 available at the time you commit the veto.</p>
2722 <p>Voting +1 on a change doesn't just mean you approve of it in
2723 principle. It means you have thoroughly reviewed the change, and find
2724 it correct and as nondisruptive as possible. When it is committed to
2725 the release branch, the log message will include the names of all who
2726 voted for it, as well as the original author and the person making the
2727 commit. All of these people are considered equally answerable for
2728 bugs.</p>
2730 <p>If you've reviewed a patch, and like it but have some reservations,
2731 you can write "+1 (concept)" and then ask questions on the list about
2732 your concerns. You can write "+0" if you like the general idea but
2733 haven't reviewed the patch carefully. Neither of these votes counts
2734 toward the total, but they can be useful for tracking down people who
2735 are following the change and might be willing to spend more time on
2736 it.</p>
2738 <p>There is a somewhat looser voting system for areas that are not
2739 core code, and that may have fewer experts available to review changes
2740 (for example, tools/, packages/, bindings/, test scripts, etc.). A
2741 change in these areas can go in with a +1 from a full committer or a
2742 partial committer for that area, at least one +0 or "concept +1" from
2743 any other committer, and no vetoes. (If a change affects the build
2744 system, however, it is considered a core change, and needs three
2745 +1's.) Use your judgment and don't review changes unless you have
2746 some competence to do so, of course. The goal is to get at least two
2747 pairs of eyes on the change, without demanding that every reviewer
2748 have the same amount of expertise as the area maintainer. This way
2749 one can review for general sanity, accurate comments, obvious
2750 mistakes, etc, without being forced to assert "Yes, I understand these
2751 changes in every detail and have tested them."</p>
2753 <p>Before proposing a change in STATUS, you should try merging it onto
2754 the branch to ensure that it doesn't produce merge conflicts. If
2755 conflicts occur, please create a new temporary branch from the release
2756 branch with your changes merged and the conflicts resolved. The
2757 branch should be named A.B.x-rYYYY, where YYYY is the first revision
2758 of your change in the STATUS file. Add a note in the STATUS file
2759 about the existence of the temporary branch. If the change involves
2760 further work, you can merge those revisions to the branch. When the
2761 entry for this change is removed from STATUS, this temporary branch
2762 should also be removed to avoid cluttering the /branches
2763 directory.</p>
2765 <p>NOTE: Changes to STATUS regarding the temporary branch, including
2766 voting, are always kept on the main release branch.</p>
2768 </div>
2771 <div class="h2" id="tarball-signing">
2772 <h2>Signing source distribution packages (a.k.a tarballs)</h2>
2774 <p>Before a release or release candidate is officially made public, it is
2775 made available in a temporary location for committers to test and sign.
2776 The point is to have the tarballs tested on more systems than just that of the
2777 person who rolled the release. When there are three signatures from full
2778 committers for each of the <tt>.tar.bz2</tt>, <tt>.tar.gz</tt> and
2779 <tt>.zip</tt> files, the release (candidate) can go public.</p>
2781 <p>Signing a tarball means that you assert certain things about it. When
2782 sending your signature (see below), indicate in the mail what steps
2783 you've taken to verify that the tarball is correct. Running
2784 <tt>make check</tt> over all RA layers and FS backends is a good idea,
2785 as well as building and testing the bindings.</p>
2787 <p>After having extracted and tested the tarball, you should sign it using
2788 <a href="http://www.gnupg.org">gpg</a>. To do so, use a command like:</p>
2790 <pre>
2791 gpg -ba subversion-1.3.0-rc4.tar.bz2
2792 </pre>
2794 <p>This will result in a file with the same name as the signed file, but with
2795 a <tt>.asc</tt> extension in the appropriate format for inclusion in the
2796 release announcement. Include this file in a mail, typically in reply
2797 to the announcement of the unofficial tarball.</p>
2799 <p>If you've downloaded and tested a <tt>.tar.bz2</tt> file, it is possible to
2800 sign a <tt>.tar.gz</tt> file with the same contents without having
2801 to download and test it separately. The trick is to extract the
2802 <tt>.bz2</tt> file, and pack it using <tt>gzip</tt> like this:</p>
2804 <pre>
2805 bzip2 -cd subversion-1.3.0-rc4.tar.bz2 \
2806 | gzip -9n > subversion-1.3.0-rc4.tar.gz
2807 </pre>
2809 <p>The resulting file should be identical to the file generated by the
2810 release manager, and thus can be signed as described above.
2811 To verify that the files are identical, you may use either the MD5 checksums
2812 or the release manager's signature, both of which should be provided with the
2813 tarballs.
2814 </p>
2815 </div>
2817 <div class="h2" id="l10n" title="l10n">
2818 <h2>Localization (l10n)</h2>
2820 <p>Translation has been divided into two domains. First, there is the
2821 translation of server messages sent to connecting clients. This issue
2822 has been <a
2823 href="http://svn.collab.net/repos/svn/trunk/notes/l10n-problems">punted
2824 for now</a>. Second there is the translation of the client and its
2825 libraries.</p>
2827 <p>The gettext package provides services for translating messages. It
2828 uses the xgettext tool to extract strings from the sources for
2829 translation. This works by extracting the arguments of the _() and
2830 N_() macros. The former is used in context where function calls are
2831 allowed (typically anything except static initializers). The latter
2832 is used whenever _() isn't. Strings marked with N_() need to be
2833 passed to gettext translation routines whenever referenced in the
2834 code. For an example, look at how the header and footer are handled
2835 in subversion/svn/help-cmd.c.</p>
2837 <p>When using direct calls to gettext routines (*gettext or
2838 *dgettext), keep in mind that most of Subversion code is library code.
2839 Therefore the default domain is not necessarily Subversion's own
2840 domain. In library code you should use the dgettext versions of the
2841 gettext functions. The domain name is defined in the PACKAGE_NAME
2842 define.</p>
2844 <p>All required setup for localization is controlled by the ENABLE_NLS
2845 conditional in svn_private_config.h (for *nix) and
2846 svn_private_config.hw (for Windows). Be sure to put</p>
2848 <pre>
2849 #include "svn_private_config.h"
2850 </pre>
2852 <p>as the last include in any file which requires localization.</p>
2854 <p>Also note that return values of _() and *gettext() calls are UTF-8
2855 encoded; this means that they should be translated to the current
2856 locale being written as any form of program output.</p>
2858 <p>The GNU gettext manual
2860 href="http://www.gnu.org/software/gettext/manual/html_node/gettext_toc.html"
2861 >http://www.gnu.org/software/gettext/manual/html_node/gettext_toc.html</a>)
2862 provides additional information on writing translatable programs in
2863 its section "Preparing Program Sources". Its hints mainly apply to
2864 string composition.</p>
2866 </div>
2868 </div>
2869 </body>
2870 </html>