~ubuntu-branches/ubuntu/trusty/subversion/trusty-proposed

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Andy Whitcroft
  • Date: 2012-06-21 15:36:36 UTC
  • mfrom: (0.4.13 sid)
  • Revision ID: package-import@ubuntu.com-20120621153636-amqqmuidgwgxz1ly
Tags: 1.7.5-1ubuntu1
* Merge from Debian unstable.  Remaining changes:
  - Create pot file on build.
  - Build a python-subversion-dbg package.
  - Build-depend on python-dbg.
  - Build-depend on default-jre-headless/-jdk.
  - Do not apply java-build patch.
  - debian/rules: Manually create the doxygen output directory, otherwise
    we get weird build failures when running parallel builds.

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
33
 
      <filename>hacking.html</filename> document (<systemitem
34
 
      class="url">http://svn.collab.net/repos/svn/trunk/www/hacking.html</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>Some useful GNU diff arguments</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 <filename>hacking.html</filename> document
292
 
      <systemitem
293
 
      class="url">http://svn.collab.net/repos/svn/trunk/www/hacking.html</systemitem>
294
 
      is a good model. If you always embed filenames, function names,
295
 
      etc. then you can easily search through the logs with
296
 
      search-svnlog.pl <systemitem
297
 
      class="url">http://svn.collab.net/repos/svn/trunk/tools/client-side/search-svnlog.pl</systemitem>.</para>
298
 
 
299
 
    <para>You may want to write the log entry as you go. It's common
300
 
      to create a file <filename>changes</filename> with your log
301
 
      entry in progress. When you commit, use <command>svn ci -F
302
 
      changes</command>.</para>
303
 
 
304
 
    <para>If you do not write log entries as you go, you can generate
305
 
      an initial log entry file using the output of <command>svn
306
 
      status</command> which contains a list of all modified files and
307
 
      directories and write a comment for each one.</para>
308
 
 
309
 
    <sect2 id="misc-docs-best_practices-sect-2.1">
310
 
      <title>Binary Files</title>
311
 
      
312
 
      <para>Subversion does not have any way to merge or view
313
 
        differences of binary files, so it's critical that these have
314
 
        accurate log messages. Since you can't review your changes
315
 
        with <command>svn diff</command> immediately before
316
 
        committing, it's a particularly good idea to write the log
317
 
        entry as you go.</para>
318
 
 
319
 
    </sect2>
320
 
 
321
 
  </sect1>
322
 
 
323
 
</chapter>
324
 
 
325
 
<!--
326
 
local variables: 
327
 
sgml-parent-document: ("misc-docs.xml" "chapter")
328
 
end:
329
 
-->