~svn/ubuntu/raring/subversion/ppa

« back to all changes in this revision

Viewing changes to doc/misc-docs/best_practices.xml

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-12-05 01:26:14 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051205012614-qom4xfypgtsqc2xq
Tags: 1.2.3dfsg1-3ubuntu1
Merge with the final Debian release of 1.2.3dfsg1-3, bringing in
fixes to the clean target, better documentation of the libdb4.3
upgrade and build fixes to work with swig1.3_1.3.27.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<chapter id="misc-docs-best_practices">
 
2
  <title>Best Practices</title>
 
3
 
 
4
<simplesect>
 
5
 
 
6
    <para>Tips to use Subversion more effectively.</para>
 
7
 
 
8
    <para>In this chapter, we'll focus on how to avoid some pitfalls
 
9
      of version control systems in general and Subversion
 
10
      specifically.</para>
 
11
 
 
12
  </simplesect>
 
13
 
 
14
  <!-- ================================================================= -->
 
15
  <!-- ======================== SECTION 1 ============================== -->
 
16
  <!-- ================================================================= -->
 
17
  <sect1 id="misc-docs-best_practices-sect-1">
 
18
    <title>Source Code Formatting</title>
 
19
 
 
20
    <para>Subversion diffs and merges text files work on a
 
21
      line-by-line basis. They don't understand the syntax of
 
22
      programming languages or even know when you've just reflowed
 
23
      text to a different line width.</para>
 
24
 
 
25
    <para>Given this design, it's important to avoid unnecessary
 
26
      reformatting. It creates unnecessary conflicts when merging
 
27
      branches, updating working copies, and applying patches. It also
 
28
      can drown you in noise when viewing differences between
 
29
      revisions.</para>
 
30
 
 
31
    <para>You can avoid these problems by following clearly-defined
 
32
      formatting rules.  The Subversion project's own HACKING document
 
33
      (<systemitem
 
34
      class="url">http://svn.collab.net/repos/svn/trunk/HACKING</systemitem>)
 
35
      and the Code Conventions for the Java Programming Language
 
36
      (<systemitem
 
37
      class="url">http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html</systemitem>),
 
38
      are good examples.</para>
 
39
    
 
40
    <para>Tabs are particularly important. Some projects, like
 
41
      Subversion, do not use tabs at all in the source tree. Others
 
42
      always use them and define a particular tab size.</para>
 
43
 
 
44
    <para>It can be very helpful to have an editor smart enough to
 
45
      help adhere to these rules. For example, <command>vim</command>
 
46
      can do this on a per-project basis with
 
47
      <filename>.vimrc</filename> commands like the following:</para>
 
48
 
 
49
    <screen>
 
50
autocmd BufRead,BufNewFile */rapidsvn/*.{cpp,h}
 
51
    setlocal ts=4 noexpandtab
 
52
autocmd BufRead,BufNewFile */subversion/*.[ch]
 
53
    setlocal sw=2 expandtab cinoptions=>2sn-s{s^-s:s
 
54
    </screen>
 
55
 
 
56
    <para>Check your favorite editor's documentation for more
 
57
      information.</para>
 
58
 
 
59
    <sect2 id="misc-docs-best_practices-sect-1.1">
 
60
      <title>When You Have To Reformat</title>
 
61
      
 
62
      <para>In the real world, we're not always so perfect. Formatting
 
63
        preferences may change over time, or we may just make
 
64
        mistakes. There are things you can do to minimize the problems
 
65
        of reformatting.</para>
 
66
      
 
67
      <para>These are good guidelines to follow:</para>
 
68
      
 
69
      <itemizedlist>
 
70
        
 
71
        <listitem>
 
72
          <para>If you're making a sweeping reformatting change, do it
 
73
            in a single commit with no semantic changes. Give precise
 
74
            directions on duplicating formatting changes.</para>
 
75
        </listitem>
 
76
        
 
77
        <listitem>
 
78
          <para>If you've made semantic changes to some area of code and
 
79
            see inconsistent formatting in the immediate context, it's
 
80
            okay to reformat.  Causing conflicts is not as great a
 
81
            concern because your semantic changes are likely to do that
 
82
            anyway.</para>
 
83
        </listitem>
 
84
        
 
85
      </itemizedlist>
 
86
      
 
87
      <para>Here's an example of a sweeping reformat:</para>
 
88
      
 
89
      <screen>
 
90
$ svn co file:///repo/path/trunk indent_wc
 
91
$ indent -gnu indent_wc/src/*.[ch]
 
92
$ svn commit -m 'Ran indent -gnu src/*.[ch]' indent_wc
 
93
        </screen>
 
94
      
 
95
      <para>This follows all rules: there were no semantic changes mixed
 
96
        in (no files were changed other than through
 
97
        <command>indent</command>). The <command>indent</command>
 
98
        commandline was given, so the changes can be very easily
 
99
        duplicated. All the reformatting was done in a single
 
100
        revision.</para>
 
101
      
 
102
      <para>Let's say these changes occurred to the trunk at revision
 
103
        26. The head revision is now 42. You created a branch at
 
104
        revision 13 and now want to merge it back into the
 
105
        trunk. Ordinarily you'd do this:</para>
 
106
      
 
107
      <screen>
 
108
$ svn co file://repo/path/trunk merge_wc
 
109
$ svn merge -r 13:head file://repo/path/branches/mybranch merge_wc
 
110
&hellip; # resolve conflicts
 
111
$ svn commit -m 'Merged branch'
 
112
      </screen>
 
113
      
 
114
      <para>But with the reformatting changes, there will be many, many
 
115
        conflicts. If you follow these rules, you can merge more
 
116
        easily:</para>
 
117
      
 
118
      <screen>
 
119
$ svn co -r 25 file://repo/path/trunk merge_wc
 
120
$ svn merge -r 13:head file://repo/path/branches/mybranch merge_wc
 
121
&hellip; # resolve conflicts
 
122
$ indent -gnu src/*.[ch]
 
123
$ svn up
 
124
&hellip; # resolve conflicts
 
125
$ svn commit -m 'Merged branch'
 
126
      </screen>
 
127
      
 
128
      <para>In English, the procedure is:</para>
 
129
      
 
130
      <itemizedlist>
 
131
        
 
132
        <listitem>
 
133
          <para> Check out a pre-reformatting trunk working copy.</para>
 
134
        </listitem>
 
135
        
 
136
        <listitem>
 
137
          <para> Merge all branch changes. Fix conflicts.</para>
 
138
        </listitem>
 
139
        
 
140
        <listitem>
 
141
          <para> Reformat in the same manner.</para>
 
142
        </listitem>
 
143
 
 
144
        <listitem>
 
145
          <para> Update to the head revision. Fix conflicts.</para>
 
146
        </listitem>
 
147
        
 
148
        <listitem>
 
149
          <para> Check in the merged working copy.</para>
 
150
        </listitem>
 
151
        
 
152
      </itemizedlist>
 
153
      
 
154
    </sect2>
 
155
    
 
156
    <sect2 id="misc-docs-best_practices-sect-1.2">
 
157
      <title>Ignoring Whitespace Differences</title>
 
158
      
 
159
      <para>When viewing differences between revisions, you can
 
160
        customize <command>svn diff</command> output to hide whitespace
 
161
        changes. The <option>-x</option> argument passes arguments
 
162
        through to GNU diff. Here are some useful arguments:</para>
 
163
      
 
164
      <table id="misc-docs-best_practices-table-1">
 
165
        <title></title>
 
166
        <tgroup cols="2">
 
167
          <thead>
 
168
            <row>
 
169
              <entry>Option</entry>
 
170
              <entry>Description</entry>
 
171
            </row>
 
172
          </thead>
 
173
          <tbody>
 
174
            
 
175
            <row>
 
176
              <entry><option>-b</option></entry> 
 
177
              <entry>Ignore differences in whitespace only.</entry>
 
178
            </row>
 
179
            
 
180
            <row>
 
181
              <entry><option>-B</option></entry>
 
182
              <entry>Ignore added/removed blank lines.</entry>
 
183
            </row>
 
184
            
 
185
            <row>
 
186
              <entry><option>-i</option></entry>
 
187
              <entry>Ignore changes in case.</entry>
 
188
            </row>
 
189
            
 
190
            <row>
 
191
              <entry><option>-t</option></entry>
 
192
              <entry>Expand tabs to spaces to preserve
 
193
                alignment.</entry>
 
194
            </row>
 
195
            
 
196
            <row>
 
197
              <entry><option>-T</option></entry>
 
198
              <entry>Output a tab rather than a space at the beginning
 
199
                of each line to start on a tab stop.</entry>
 
200
            </row>
 
201
            
 
202
          </tbody>
 
203
        </tgroup>
 
204
      </table>
 
205
      
 
206
      <para>The commit emails always show whitespace-only changes.
 
207
        <filename>commit-email.pl</filename> uses <command>svnlook diff</command> to get
 
208
        differences, which doesn't support the <option>-x</option>
 
209
        option.</para>
 
210
      
 
211
    </sect2>
 
212
 
 
213
    <sect2 id="misc-docs-best_practices-sect-1.3">
 
214
      <title>Line Endings</title>
 
215
      
 
216
      <para>Different platforms (Unix, Windows, Mac OS) have different
 
217
        conventions for marking the line endings of text files. Simple
 
218
        editors may rewrite line endings, causing problems with diff and
 
219
        merge. This is a subset of the formatting problems.</para>
 
220
      
 
221
      <para>Subversion has built-in support for normalizing line
 
222
        endings. To enable it, set the <command>svn:eol-style</command>
 
223
        property to ``native''. See Properties in the Subversion
 
224
        book for more information.</para>
 
225
 
 
226
    </sect2>
 
227
 
 
228
  </sect1>
 
229
 
 
230
  <!-- ================================================================= -->
 
231
  <!-- ======================== SECTION 2 ============================== -->
 
232
  <!-- ================================================================= -->
 
233
  <sect1 id="misc-docs-best_practices-sect-2">
 
234
    <title>When you commit</title>
 
235
 
 
236
    <para>It pays to take some time before you commit to review your
 
237
      changes and create an appropriate log message. You are
 
238
      publishing the newly changed project anew every time you
 
239
      commit. This is true in two senses:</para>
 
240
 
 
241
    <itemizedlist>
 
242
 
 
243
      <listitem>
 
244
        <para> When you commit, you are potentially destabilizing the
 
245
          head revision.  Many projects have a policy that the head
 
246
          revision is <quote>stable</quote>&mdash;it should always
 
247
          parse/compile, it should always pass unit tests, etc. If you
 
248
          don't get something right, you may be inconveniencing an
 
249
          arbitrary number of people until someone commits a fix.</para>
 
250
      </listitem>
 
251
 
 
252
      <listitem>
 
253
        <para> You cannot easily remove revisions. (There is no
 
254
          equivalent to <command>cvs admin -o</command>.) If you might
 
255
          not want something to be in the repository, make sure it is
 
256
          not included in your commit.  Check for sensitive
 
257
          information, autogenerated files, and unnecessary large
 
258
          files.</para>
 
259
      </listitem>
 
260
 
 
261
    </itemizedlist>
 
262
 
 
263
    <para>If you later don't like your log message, it is possible to
 
264
      change it. The <command>svnadmin setlog</command> command will
 
265
      do this locally. You can set up the script <systemitem
 
266
      class="url">http://svn.collab.net/repos/svn/trunk/tools/cgi/tweak-log.cgi,tweak-log.cgi</systemitem>
 
267
      to allow the same thing remotely. All the same, creating a good
 
268
      log message beforehand helps clarify your thoughts and avoid
 
269
      committing a mistake.</para>
 
270
 
 
271
    <para>You should run a <command>svn diff</command> before each
 
272
      commit and ask yourself:</para>
 
273
 
 
274
    <itemizedlist>
 
275
 
 
276
      <listitem>
 
277
        <para> do these changes belong together? It's best that each
 
278
          revision is a single logical change. It's very easy to
 
279
          forget that you've started another change.
 
280
        </para>
 
281
      </listitem>
 
282
 
 
283
      <listitem>
 
284
        <para> do I have a log entry for these changes?
 
285
        </para>
 
286
      </listitem>
 
287
 
 
288
    </itemizedlist>
 
289
 
 
290
    <para>Defining a log entry policy is also helpful --- the
 
291
      Subversion HACKING document <systemitem
 
292
      class="url">http://svn.collab.net/repos/svn/trunk/HACKING</systemitem>
 
293
      is a good model. If you always embed filenames, function names,
 
294
      etc. then you can easily search through the logs with
 
295
      search-svnlog.pl <systemitem
 
296
      class="url">http://svn.collab.net/repos/svn/trunk/tools/client-side/search-svnlog.pl</systemitem>.</para>
 
297
 
 
298
    <para>You may want to write the log entry as you go. It's common
 
299
      to create a file <filename>changes</filename> with your log
 
300
      entry in progress. When you commit, use <command>svn ci -F
 
301
      changes</command>.</para>
 
302
 
 
303
    <para>If you do not write log entries as you go, you can generate
 
304
      an initial log entry file using the output of <command>svn
 
305
      status</command> which contains a list of all modified files and
 
306
      directories and write a comment for each one.</para>
 
307
 
 
308
    <sect2 id="misc-docs-best_practices-sect-2.1">
 
309
      <title>Binary Files</title>
 
310
      
 
311
      <para>Subversion does not have any way to merge or view
 
312
        differences of binary files, so it's critical that these have
 
313
        accurate log messages. Since you can't review your changes
 
314
        with <command>svn diff</command> immediately before
 
315
        committing, it's a particularly good idea to write the log
 
316
        entry as you go.</para>
 
317
 
 
318
    </sect2>
 
319
 
 
320
  </sect1>
 
321
 
 
322
</chapter>
 
323
 
 
324
<!--
 
325
local variables: 
 
326
sgml-parent-document: ("misc-docs.xml" "chapter")
 
327
end:
 
328
-->