| <appendix id="svn-ap-a"> |
| <title>Subversion for CVS Users</title> |
| |
| <simplesect> |
| |
| <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 backreferences 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—ones that you forgot were odd to begin |
| with.</para> |
| |
| </simplesect> |
| |
| <!-- ================================================================= --> |
| <!-- ======================== SECTION 1 ============================== --> |
| <!-- ================================================================= --> |
| <sect1 id="svn-app-a-sect-1"> |
| <title>Revision Numbers Are Different Now</title> |
| |
| <para>In CVS, revision numbers are per-file. This is because CVS |
| uses RCS as a backend; 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>, they're 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>For more details on this topic, see <xref |
| linkend="svn-ch-2-sect-3.2" />.</para> |
| |
| </sect1> |
| |
| <!-- ================================================================= --> |
| <!-- ======================== SECTION 2 ============================== --> |
| <!-- ================================================================= --> |
| <sect1 id="svn-app-a-sect-2"> |
| <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 |
| rm</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 <command>svn |
| commit</command>.</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 <command>svn update</command>, |
| 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, because 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-ch-2-sect-3.4"/>.</para> |
| |
| </sect1> |
| |
| |
| <!-- ================================================================= --> |
| <!-- ======================== SECTION 3 ============================== --> |
| <!-- ================================================================= --> |
| <sect1 id="svn-app-a-sect-3"> |
| <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 off-line:</para> |
| |
| <variablelist> |
| |
| <varlistentry> |
| <term><command>svn status</command></term> |
| <listitem> |
| <para>Shows you any local changes you've made (see <xref |
| linkend="svn-ch-3-sect-4.3.1"/>)</para> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><command>svn diff</command></term> |
| <listitem> |
| <para>Shows you the details of your changes (see <xref |
| linkend="svn-ch-3-sect-4.3.2"/>)</para> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><command>svn revert</command></term> |
| <listitem> |
| <para>Removes your local changes (see <xref |
| linkend="svn-ch-3-sect-4.3.3"/>)</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 is new; it will not only |
| remove local mods, but it will un-schedule operations such as |
| adds and deletes. It's the preferred way to revert a file; |
| running <command>rm file; svn update</command> will still work, but |
| it blurs the purpose of updating. And, while we're on this |
| subject… |
| |
| </para> |
| |
| </sect1> |
| |
| <!-- ================================================================= --> |
| <!-- ======================== SECTION 4 ============================== --> |
| <!-- ================================================================= --> |
| <sect1 id="svn-app-a-sect-4"> |
| <title>Distinction Between Status and Update</title> |
| |
| <para>In Subversion, we've tried 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 <command>cvs up</command> |
| to quickly see their mods. Of course, this has the side effect |
| of merging repository changes that you may not be ready to deal |
| with!</para> |
| |
| <para>With Subversion, we've tried to remove this muddle by making |
| the output of <command>svn status</command> easy to read for |
| both humans and parsers. Also, <command>svn update</command> |
| only prints information about files that are updated, |
| <emphasis>not</emphasis> local modifications.</para> |
| |
| <para>Here's a quick guide to <command>svn status</command>. We |
| encourage all new Subversion users to use it early and often:</para> |
| |
| <variablelist> |
| <title><command>svn status</command> Prints All Files That Have |
| Local Modifications: The Network is not Accessed by |
| Default</title> |
| |
| <varlistentry> |
| <term><option>-u</option> switch</term> |
| <listitem> |
| <para>Add out-of-dateness information from repository.</para> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><option>-v</option> switch</term> |
| <listitem> |
| <para>Show <emphasis>all</emphasis> entries under |
| version control.</para> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><option>-N</option> switch</term> |
| <listitem> |
| <para>Nonrecursive.</para> |
| </listitem> |
| </varlistentry> |
| |
| </variablelist> |
| |
| <para>The status 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>) switch, 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 |
| Head 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 example above, 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 <command>-</command> next to bloo.png |
| means that it doesn't yet exist in the working copy.)</para> |
| |
| <!-- ###TODO describe -u here as well as -uv. -u and -v use |
| different "long" 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>Lastly, here's a quick summary of the most common status codes that |
| you may 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 (comes from another |
| repository. See <xref linkend="svn-ch-6-sect-2.3.6" />) |
| ? Resource is not under version control |
| ! Resource is missing or incomplete (removed by another tool than |
| Subversion) |
| </screen> |
| |
| <!-- ###TODO: This paragraph should be moved elsewhere. We are |
| talking about status codes here, and not update. |
| Although CVS uses update as a form of status... --> |
| <para>Subversion has combined the CVS <command>P</command> and |
| <command>U</command> codes into just <command>U</command>. When |
| a merge or conflict occurs, Subversion simply prints |
| <command>G</command> or <command>C</command>, rather than a |
| whole sentence about it.</para> |
| |
| <para>For a more detailed discussion of <command>svn |
| status</command>, see <xref linkend="svn-ch-3-sect-4.3.1" />.</para> |
| |
| |
| </sect1> |
| |
| <!-- ================================================================= --> |
| <!-- ======================== SECTION 5 ============================= --> |
| <!-- ================================================================= --> |
| <sect1 id="svn-app-a-sect-5"> |
| <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 a CVS user will need to climb. Read all |
| about it in <xref linkend="svn-ch-4"/></para> |
| |
| </sect1> |
| |
| |
| <!-- ================================================================= --> |
| <!-- ======================== SECTION 6 ============================== --> |
| <!-- ================================================================= --> |
| <sect1 id="svn-app-a-sect-6"> |
| <title>Meta-data Properties</title> |
| |
| <para>A new feature of Subversion is that you can attach arbitrary |
| metadata to files and directories. We refer to this data as |
| <firstterm>properties</firstterm>, and they can be thought of as |
| collections of arbitrary name/value pairs attached to each item |
| 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-ch-6-sect-2"/>.</para> |
| |
| </sect1> |
| |
| <!-- ================================================================= --> |
| <!-- ======================== SECTION 7 ============================== --> |
| <!-- ================================================================= --> |
| <sect1 id="svn-app-a-sect-7"> |
| <title>Conflict Resolution</title> |
| |
| <para>CVS marks conflicts with in-line <quote>conflict |
| markers</quote>, and prints a <command>C</command> during an |
| update. Historically, this has caused problems, because CVS |
| isn't doing enough. Many users forget about (or don't see) |
| the <command>C</command> after it whizzes by on their |
| terminal. They often forget that the conflict-markers are |
| even present, and then accidentally commit files containing |
| conflict-markers.</para> |
| |
| <para>Subversion solves this problem by making conflicts more |
| tangible. It remembers that a file is in a state of conflict, |
| and won't allow you to commit your changes until you run |
| <command>svn resolved</command>. See <xref |
| linkend="svn-ch-3-sect-4.4"/> for more details.</para> |
| </sect1> |
| |
| <!-- ================================================================= --> |
| <!-- ======================== SECTION 8 ============================== --> |
| <!-- ================================================================= --> |
| <sect1 id="svn-app-a-sect-8"> |
| <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. |
| But internally, Subversion expresses differences between files |
| using a binary-differencing algorithm, regardless of whether they |
| contain textual or binary data. That means that all files are |
| stored differentially (compressed) in the repository, and small |
| differences are always sent over the network.</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 do so (see <xref |
| linkend="svn-ch-6-sect-2.3.4"/> and <xref |
| linkend="svn-ch-6-sect-2.3.5"/> 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. text/*), |
| 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> |
| |
| <!-- ================================================================= --> |
| <!-- ======================== SECTION 9 ============================== --> |
| <!-- ================================================================= --> |
| <sect1 id="svn-app-a-sect-9"> |
| |
| <title>Versioned Modules</title> |
| |
| <para>Unlike CVS, a Subversion working copy is aware that it has |
| checked out a module. That means that if somebody changes the |
| definition of a module, then a call to <command>svn update</command> |
| will update the working copy appropriately.</para> |
| |
| <para>Subversion defines modules as a list of directories within a |
| directory property: see <xref linkend="svn-ch-6-sect-3"/>.</para> |
| |
| </sect1> |
| |
| </appendix> |
| |
| <!-- |
| local variables: |
| sgml-parent-document: ("book.xml" "appendix") |
| end: |
| --> |