My favorites | Sign in
Logo
          
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
<appendix id="svn.forcvs">
<title>Subversion for CVS Users</title>

<para>This appendix is a guide for CVS users new to Subversion.
It's essentially a list of differences between the two systems
as <quote>viewed from 10,000 feet.</quote> For each section, we
provide references to relevant chapters when
possible.</para>

<para>Although the goal of Subversion is to take over the current
and future CVS user base, some new features and design changes
were required to fix certain <quote>broken</quote> behaviors
that CVS had. This means that, as a CVS user, you may need to
break habits&mdash;ones that you forgot were odd to begin
with.</para>


<!-- ================================================================= -->
<!-- ================================================================= -->
<!-- ================================================================= -->
<sect1 id="svn.forcvs.revnums">
<title>Revision Numbers Are Different Now</title>

<para>In CVS, revision numbers are per file. This is because CVS
stores its data in RCS files; each file has a corresponding RCS
file in the repository, and the repository is roughly laid out
according to the structure of your project tree.</para>

<para>In Subversion, the repository looks like a single
filesystem. Each commit results in an entirely new filesystem
tree; in essence, the repository is an array of trees. Each of
these trees is labeled with a single revision number. When
someone talks about <quote>revision 54</quote>, he's talking
about a particular tree (and indirectly, the way the filesystem
looked after the 54th commit).</para>

<para>Technically, it's not valid to talk about <quote>revision 5
of <filename>foo.c</filename>.</quote> Instead, one would say
<quote><filename>foo.c</filename> as it appears in revision
5.</quote> Also, be careful when making assumptions about the
evolution of a file. In CVS, revisions 5 and 6 of
<filename>foo.c</filename> are always different. In Subversion,
it's most likely that <filename>foo.c</filename> did
<emphasis>not</emphasis> change between revisions 5 and
6.</para>

<para>Similarly, in CVS, a tag or branch is an annotation on the
file or on the version information for that individual file,
whereas in Subversion, a tag or branch is a copy of an entire
tree (by convention, into the <filename>/branches</filename>
or <filename>/tags</filename> directories that appear at the top
level of the repository, beside <filename>/trunk</filename>). In
the repository as a whole, many versions of each file may be
visible: the latest version on each branch, every tagged
version, and of course the latest version on the trunk
itself. So, to refine the terms even further, one would often
say <quote><filename>foo.c</filename> as it appears in
<filename>/branches/REL1</filename> in revision
5.</quote></para>

<para>For more details on this topic, see <xref
linkend="svn.basic.in-action.revs" />.</para>

</sect1>

<!-- ================================================================= -->
<!-- ================================================================= -->
<!-- ================================================================= -->
<sect1 id="svn.forcvs.directories">
<title>Directory Versions</title>

<para>Subversion tracks tree structures, not just file contents.
It's one of the biggest reasons Subversion was written to
replace CVS.</para>

<para>Here's what this means to you, as a former CVS user:</para>

<itemizedlist>
<listitem>
<para>The <command>svn add</command> and <command>svn
delete</command> commands work on directories now, just as
they work on files. So do <command>svn copy</command> and
<command>svn move</command>. However, these commands do
<emphasis>not</emphasis> cause any kind of immediate change
in the repository. Instead, the working items are simply
<quote>scheduled</quote> for addition or deletion. No
repository changes happen until you run <userinput>svn
commit</userinput>.</para>
</listitem>
<listitem>
<para>Directories aren't dumb containers anymore; they have
revision numbers like files. (Or more properly, it's
correct to talk about <quote>directory
<filename>foo/</filename> in revision 5.</quote>)</para>
</listitem>
</itemizedlist>

<para>Let's talk more about that last point. Directory versioning
is a hard problem; because we want to allow mixed-revision
working copies, there are some limitations on how far we can
abuse this model.</para>

<para>From a theoretical point of view, we define <quote>revision
5 of directory <filename>foo</filename></quote> to mean a
specific collection of directory entries and properties. Now
suppose we start adding and removing files from
<filename>foo</filename>, and then commit. It would be a lie
to say that we still have revision 5 of
<filename>foo</filename>. However, if we bumped
<filename>foo</filename>'s revision number after the commit,
that would be a lie too; there may be other changes to
<filename>foo</filename> we haven't yet received, because we
haven't updated yet.</para>

<para>Subversion deals with this problem by quietly tracking
committed adds and deletes in the <filename>.svn</filename>
area. When you eventually run <userinput>svn update</userinput>,
all accounts are settled with the repository, and the
directory's new revision number is set correctly.
<emphasis>Therefore, only after an update is it truly safe to
say that you have a <quote>perfect</quote> revision of a
directory.</emphasis> Most of the time, your working copy will
contain <quote>imperfect</quote> directory revisions.</para>

<para>Similarly, a problem arises if you attempt to commit
property changes on a directory. Normally, the commit would
bump the working directory's local revision number. But again,
that would be a lie, as there may be adds or deletes that
the directory doesn't yet have, because no update has happened.
<emphasis>Therefore, you are not allowed to commit
property changes on a directory unless the directory is
up to date.</emphasis></para>

<para>For more discussion about the limitations of directory
versioning, see <xref linkend="svn.basic.in-action.mixedrevs"/>.</para>

</sect1>


<!-- ================================================================= -->
<!-- ================================================================= -->
<!-- ================================================================= -->
<sect1 id="svn.forcvs.disconnected">
<title>More Disconnected Operations</title>

<para>In recent years, disk space has become outrageously cheap
and abundant, but network bandwidth has not. Therefore, the
Subversion working copy has been optimized around the scarcer
resource.</para>

<para>The <filename>.svn</filename> administrative directory
serves the same purpose as the <filename>CVS</filename>
directory, except that it also stores read-only,
<quote>pristine</quote> copies of your files. This allows you
to do many things offline:</para>

<variablelist>

<varlistentry>
<term><command>svn status</command></term>
<listitem>
<para>Shows you any local changes you've made (see <xref
linkend="svn.tour.cycle.examine.status"/>)</para>
</listitem>
</varlistentry>

<varlistentry>
<term><command>svn diff</command></term>
<listitem>
<para>Shows you the details of your changes (see <xref
linkend="svn.tour.cycle.examine.diff"/>)</para>
</listitem>
</varlistentry>

<varlistentry>
<term><command>svn revert</command></term>
<listitem>
<para>Removes your local changes (see <xref
linkend="svn.tour.cycle.revert"/>)</para>
</listitem>
</varlistentry>

</variablelist>

<para>Also, the cached pristine files allow the Subversion client
to send differences when committing, which CVS cannot do.</para>

<para>The last subcommand in the list&mdash;<command>svn
revert</command>&mdash;is new. It will not only remove local
changes, but also unschedule operations such as adds and
deletes. Although deleting the file and then running <userinput>svn
update</userinput> will still work, doing so distorts the true
purpose of updating. And, while we're on this subject&hellip;

</para>

</sect1>

<!-- ================================================================= -->
<!-- ================================================================= -->
<!-- ================================================================= -->
<sect1 id="svn.forcvs.status-vs-update">
<title>Distinction Between Status and Update</title>

<para>Subversion attempts to erase a lot of the confusion
between the <command>cvs status</command> and
<command>cvs update</command> commands.</para>

<para>The <command>cvs status</command> command has two purposes:
first, to show the user any local modifications in the working
copy, and second, to show the user which files are out of date.
Unfortunately, because of CVS's hard-to-read status output, many
CVS users don't take advantage of this command at all. Instead,
they've developed a habit of running <userinput>cvs
update</userinput> or <userinput>cvs -n update</userinput> to quickly
see their changes. If users forget to use
the <option>-n</option> option, this has the side effect of
merging repository changes they may not be ready to deal
with.</para>

<para>Subversion removes this muddle by making the output of
<command>svn status</command> easy to read for both humans and
parsers. Also, <command>svn update</command> prints only
information about files that are updated,
<emphasis>not</emphasis> local modifications.</para>

<sect2 id="svn.forcvs.status-vs-update.status">
<title>Status</title>

<para><command>svn status</command> prints all files that have
local modifications. By default, the repository is not
contacted. While this subcommand accepts a fair number of
options, the following are the most commonly used ones:</para>

<variablelist>
<varlistentry>
<term><option>-u</option></term>
<listitem>
<para>Contact the repository to determine, and then display,
out-of-dateness information.</para>
</listitem>
</varlistentry>

<varlistentry>
<term><option>-v</option></term>
<listitem>
<para>Show <emphasis>all</emphasis> entries under
version control.</para>
</listitem>
</varlistentry>

<varlistentry>
<term><option>-N</option></term>
<listitem>
<para>Run nonrecursively (do not descend into
subdirectories).</para>
</listitem>
</varlistentry>
</variablelist>

<para>The <command>svn status</command> command has two output
formats. In the default <quote>short</quote> format, local
modifications look like this:</para>

<screen>
$ svn status
M foo.c
M bar/baz.c
</screen>

<para>If you specify the <option>--show-updates</option>
(<option>-u</option>) option, a longer output format is
used:</para>

<screen>
$ svn status -u
M 1047 foo.c
* 1045 faces.html
* bloo.png
M 1050 bar/baz.c
Status against revision: 1066
</screen>

<para>In this case, two new columns appear. The second column
contains an asterisk if the file or directory is out of date.
The third column shows the working copy's revision number of the
item. In the previous example, the asterisk indicates that
<filename>faces.html</filename> would be patched if we updated,
and that <filename>bloo.png</filename> is a newly added file in
the repository. (The absence of any revision number next to
<filename>bloo.png</filename> means that it doesn't yet exist in
the working copy.)</para>

<!-- ###TODO describe -v here as well as -uv. -u and -v use
different <quote>long</quote> formats and need to be
documented separately. Moreover, as you can combine -u and
-v, it needs to be explained what each of them does. As -u is
much more important than -v, and the example following that
paragraph *is* about -u, not -v, my patch concentrated on
that. -->

<para>At this point, you should take a quick look at the list of
all possible status codes in
<xref linkend="svn.ref.svn.c.status"/>. Here are a few of the
more common status codes you'll see:</para>

<screen>
A Resource is scheduled for Addition
D Resource is scheduled for Deletion
M Resource has local Modifications
C Resource has Conflicts (changes have not been completely merged
between the repository and working copy version)
X Resource is eXternal to this working copy (may come from another
repository). See <xref linkend="svn.advanced.externals" />
? Resource is not under version control
! Resource is missing or incomplete (removed by a tool other than
Subversion)
</screen>

<para>For a more detailed discussion of <command>svn
status</command>, see <xref linkend="svn.tour.cycle.examine.status" />.</para>

</sect2>

<sect2 id="svn.forcvs.status-vs-update.update">
<title>Update</title>

<para><command>svn update</command> updates your working copy,
and prints only information about files that it updates.</para>

<para>Subversion has combined CVS's <literal>P</literal> and
<literal>U</literal> codes into just <literal>U</literal>. When
a merge or conflict occurs, Subversion simply prints
<literal>G</literal> or <literal>C</literal>, rather than a
whole sentence about it.</para>

<para>For a more detailed discussion of <command>svn
update</command>, see <xref linkend="svn.tour.cycle.update" />.</para>

</sect2>

</sect1>

<!-- ================================================================= -->
<!-- ================================================================= -->
<!-- ================================================================= -->
<sect1 id="svn.forcvs.branches-and-tags">
<title>Branches and Tags</title>

<para>Subversion doesn't distinguish between filesystem space and
<quote>branch</quote> space; branches and tags are ordinary
directories within the filesystem. This is probably the single
biggest mental hurdle that a CVS user will need to cross. Read
all about it in <xref linkend="svn.branchmerge"/>.</para>

<warning>

<para>Since Subversion treats branches and tags as ordinary
directories, your project's various lines of development
probably live in subdirectories of the main project directory.
So remember to check out using the URL of the subdirectory
that contains the particular line of development you want, not
the project's root URL. If you make the mistake of checking
out the root of the project, you may very well wind up with a
working copy that contains a complete copy of your project's
content for each and every one of its branches and tags.
<footnote>
<para>That is, providing you don't run out of disk space
before your checkout finishes.</para>
</footnote>
</para>
</warning>

</sect1>


<!-- ================================================================= -->
<!-- ================================================================= -->
<!-- ================================================================= -->
<sect1 id="svn.forcvs.properties">
<title>Metadata Properties</title>

<para>A new feature of Subversion is that you can attach arbitrary
metadata (or <quote>properties</quote>) to files and
directories. Properties are arbitrary name/value pairs
associated with files and directories in your working
copy.</para>

<para>To set or get a property name, use the <command>svn
propset</command> and <command>svn propget</command>
subcommands. To list all properties on an object, use
<command>svn proplist</command>.</para>

<para>For more information, see <xref linkend="svn.advanced.props"/>.</para>

</sect1>

<!-- ================================================================= -->
<!-- ================================================================= -->
<!-- ================================================================= -->
<sect1 id="svn.forcvs.conflicts">
<title>Conflict Resolution</title>

<para>CVS marks conflicts with inline <quote>conflict
markers,</quote> and then prints a <literal>C</literal> during
an update or merge operation. Historically, this has caused
problems, because CVS isn't doing enough. Many users forget
about (or don't see) the <literal>C</literal> after it whizzes
by on their terminal. They often forget that the conflict
markers are even present, and then accidentally commit files
containing those conflict markers.</para>

<para>Subversion solves this problem in a pair of ways. First,
when a conflict occurs in a file, Subversion records the fact
that the file is in a state of conflict, and won't allow you to
commit changes to that file until you explicitly resolve the
conflict. Second, Subversion 1.5 provides interactive
conflict resolution, which allows you to resolve conflicts as
they happen instead of having to go back and do so after the
update or merge operation completes. See <xref
linkend="svn.tour.cycle.resolve" /> for more about conflict
resolution in Subversion.</para>

</sect1>

<!-- ================================================================= -->
<!-- ================================================================= -->
<!-- ================================================================= -->
<sect1 id="svn.forcvs.binary-and-trans">
<title>Binary Files and Translation</title>

<para>In the most general sense, Subversion handles binary files
more gracefully than CVS does. Because CVS uses RCS, it can
only store successive full copies of a changing binary file.
Subversion, however, expresses differences between files using a
binary differencing algorithm, regardless of whether they
contain textual or binary data. That means all files are
stored differentially (compressed) in the repository.</para>

<para>CVS users have to mark binary files with
<option>-kb</option> flags to prevent data from being
garbled (due to keyword expansion and line-ending translations).
They sometimes forget to do this.</para>

<para>Subversion takes the more paranoid route. First, it never
performs any kind of keyword or line-ending translation unless
you explicitly ask it to do so (see <xref
linkend="svn.advanced.props.special.keywords"/> and <xref
linkend="svn.advanced.props.special.eol-style"/> for more details). By default,
Subversion treats all file data as literal byte strings, and
files are always stored in the repository in an untranslated
state.</para>

<para>Second, Subversion maintains an internal notion of whether a
file is <quote>text</quote> or <quote>binary</quote> data, but
this notion is <emphasis>only</emphasis> extant in the working
copy. During an <command>svn update</command>, Subversion will
perform contextual merges on locally modified text files, but
will not attempt to do so for binary files.</para>

<para>To determine whether a contextual merge is possible,
Subversion examines the <literal>svn:mime-type</literal>
property. If the file has no <literal>svn:mime-type</literal>
property, or has a MIME type that is textual (e.g.,
<literal>text/*</literal>),
Subversion assumes it is text. Otherwise, Subversion assumes
the file is binary. Subversion also helps users by running a
binary-detection algorithm in the <command>svn import</command>
and <command>svn add</command> commands. These commands will
make a good guess and then (possibly) set a binary
<literal>svn:mime-type</literal> property on the file being
added. (If Subversion guesses wrong, the user can always remove
or hand-edit the property.)</para>

</sect1>

<!-- ================================================================= -->
<!-- ================================================================= -->
<!-- ================================================================= -->
<sect1 id="svn.forcvs.modules">

<title>Versioned Modules</title>

<para>Unlike CVS, a Subversion working copy is aware that it has
checked out a module. That means if somebody changes the
definition of a module (e.g., adds or removes components), a
call to <command>svn update</command> will update the working
copy appropriately, adding and removing components.</para>

<para>Subversion defines modules as a list of directories within a
directory property; see <xref linkend="svn.advanced.externals"/>.</para>

</sect1>

<!-- ================================================================= -->
<!-- ================================================================= -->
<!-- ================================================================= -->
<sect1 id="svn.forcvs.auth">

<title>Authentication</title>

<para>With CVS's pserver, you are required to log in to the server
(using the <command>cvs login</command> command) before
performing any read or write operation&mdash;you sometimes even
have to log in for anonymous operations. With a Subversion
repository using Apache <command>httpd</command> or
<command>svnserve</command> as the server, you don't provide any
authentication credentials at the outset&mdash;if an operation
that you perform requires authentication, the server will
challenge you for your credentials (whether those credentials
are username and password, a client certificate, or even both).
So if your repository is world-readable, you will not be
required to authenticate at all for read operations.</para>

<para>As with CVS, Subversion still caches your credentials on
disk (in your <filename>~/.subversion/auth/</filename>
directory) unless you tell it not to by using the
<option>--no-auth-cache</option> option.</para>

<para>The exception to this behavior, however, is in the case of
accessing an <command>svnserve</command> server over an SSH
tunnel, using the <literal>svn+ssh://</literal> URL scheme. In
that case, the <command>ssh</command> program unconditionally
demands authentication just to start the tunnel.</para>

</sect1>

<!-- ================================================================= -->
<!-- ================================================================= -->
<!-- ================================================================= -->
<sect1 id="svn.forcvs.convert">

<title>Converting a Repository from CVS to Subversion</title>

<para>Perhaps the most important way to familiarize CVS users with
Subversion is to let them continue to work on their projects
using the new system. And while that can be somewhat
accomplished using a flat import into a Subversion repository of
an exported CVS repository, the more thorough solution involves
transferring not just the latest snapshot of their data, but all
the history behind it as well, from one system to another. This
is an extremely difficult problem to solve; it involves
deducing changesets in the absence of atomicity and translating
between the systems' completely orthogonal branching policies,
among other complications. Still, a handful of tools claim
to at least partially support the ability to convert
existing CVS repositories into Subversion ones.</para>

<para>The most popular (and mature) conversion tool is
cvs2svn (<ulink url="http://cvs2svn.tigris.org/"/>), a Python
program originally created by members of Subversion's own
development community. This tool is meant to run exactly once:
it scans your CVS repository multiple times and attempts to
deduce commits, branches, and tags as best it can. When it
finishes, the result is either a Subversion repository or a
portable Subversion dump file representing your code's history.
See the web site for detailed instructions and caveats.</para>

</sect1>

</appendix>

<!--
local variables:
sgml-parent-document: ("book.xml" "appendix")
end:
-->
Show details Hide details

Change log

r3524 by julianf...@btopenworld.com on May 26, 2009   Diff
Stylistic changes across a few files...

* src/en/book/appb-svn-for-cvs-users.xml,
  src/en/book/appc-webdav.xml,
  src/en/book/ch00-preface.xml,
  src/en/book/ch02-basic-usage.xml,
  src/en/book/ch03-advanced-topics.xml,
  src/en/book/ch04-branching-and-
merging.xml,
  src/en/book/ch05-repository-admin.xml,
  src/en/book/ch06-server-
configuration.xml,
...
Go to: 

Older revisions

r3292 by cmpilato on Sep 03, 2008   Diff
* src/en/book/ch09-reference.xml,
* src/en/book/ch03-advanced-
topics.xml,
* src/en/book/appb-svn-for-cvs-
users.xml,
...
r3247 by cmpilato on Aug 06, 2008   Diff
* src/en/book/ch09-reference.xml
* src/en/book/appb-svn-for-cvs-
users.xml
* src/en/book/ch05-repository-
admin.xml
...
r3239 by cmpilato on Aug 04, 2008   Diff
Fix various buglets found by a search
for "mime" (lowercase) in the text.
All revisions of this file

File info

Size: 25862 bytes, 567 lines

File properties

svn:mime-type
text/xml
svn:eol-style
native
Hosted by Google Code