PERFORCE change 206534 for review
Rene Ladan
rene at FreeBSD.org
Sun Feb 19 12:17:44 UTC 2012
http://p4web.freebsd.org/@@206534?ac=10
Change 206534 by rene at rene_acer on 2012/02/19 12:17:32
IFC
Affected files ...
.. //depot/projects/docproj_nl/en_US.ISO8859-1/articles/committers-guide/article.sgml#48 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/articles/contributors/contrib.additional.sgml#126 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/articles/contributors/contrib.committers.sgml#76 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/articles/contributors/contrib.develalumni.sgml#11 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/articles/explaining-bsd/article.sgml#6 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/books/developers-handbook/testing/chapter.sgml#3 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/books/faq/book.sgml#42 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/books/fdp-primer/doc-build/chapter.sgml#2 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/books/fdp-primer/psgml-mode/chapter.sgml#3 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/books/handbook/audit/chapter.sgml#5 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/books/handbook/basics/chapter.sgml#9 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/books/handbook/bsdinstall/chapter.sgml#13 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/books/handbook/config/chapter.sgml#20 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/books/handbook/cutting-edge/chapter.sgml#32 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/books/handbook/desktop/chapter.sgml#34 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/books/handbook/disks/chapter.sgml#25 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/books/handbook/eresources/chapter.sgml#31 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/books/handbook/filesystems/chapter.sgml#11 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/books/handbook/firewalls/chapter.sgml#18 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/books/handbook/install/chapter.sgml#27 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/books/handbook/jails/chapter.sgml#10 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/books/handbook/kernelconfig/chapter.sgml#17 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/books/handbook/l10n/chapter.sgml#13 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/books/handbook/linuxemu/chapter.sgml#13 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/books/handbook/mac/chapter.sgml#11 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/books/handbook/mail/chapter.sgml#10 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/books/handbook/mirrors/chapter.sgml#42 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/books/handbook/ports/chapter.sgml#15 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/books/handbook/security/chapter.sgml#22 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/books/handbook/serialcomms/chapter.sgml#14 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/books/handbook/users/chapter.sgml#3 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/books/handbook/virtualization/chapter.sgml#13 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/books/handbook/x11/chapter.sgml#23 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/books/porters-handbook/book.sgml#130 integrate
.. //depot/projects/docproj_nl/en_US.ISO8859-1/share/sgml/authors.ent#69 integrate
.. //depot/projects/docproj_nl/nl_NL.ISO8859-1/books/handbook/book.sgml#23 integrate
.. //depot/projects/docproj_nl/nl_NL.ISO8859-1/books/handbook/boot/chapter.sgml#16 integrate
.. //depot/projects/docproj_nl/nl_NL.ISO8859-1/books/handbook/config/chapter.sgml#36 integrate
.. //depot/projects/docproj_nl/nl_NL.ISO8859-1/books/handbook/desktop/chapter.sgml#56 integrate
.. //depot/projects/docproj_nl/nl_NL.ISO8859-1/books/handbook/disks/chapter.sgml#35 integrate
.. //depot/projects/docproj_nl/nl_NL.ISO8859-1/books/handbook/geom/chapter.sgml#21 integrate
.. //depot/projects/docproj_nl/nl_NL.ISO8859-1/books/handbook/install/chapter.sgml#36 integrate
.. //depot/projects/docproj_nl/nl_NL.ISO8859-1/books/handbook/kernelconfig/chapter.sgml#29 integrate
.. //depot/projects/docproj_nl/nl_NL.ISO8859-1/books/handbook/linuxemu/chapter.sgml#21 integrate
.. //depot/projects/docproj_nl/nl_NL.ISO8859-1/books/handbook/mac/chapter.sgml#19 integrate
.. //depot/projects/docproj_nl/nl_NL.ISO8859-1/books/handbook/mail/chapter.sgml#19 integrate
.. //depot/projects/docproj_nl/nl_NL.ISO8859-1/books/handbook/printing/chapter.sgml#13 integrate
.. //depot/projects/docproj_nl/nl_NL.ISO8859-1/books/handbook/security/chapter.sgml#33 integrate
.. //depot/projects/docproj_nl/nl_NL.ISO8859-1/books/handbook/x11/chapter.sgml#42 integrate
.. //depot/projects/docproj_nl/www/en/developers.sgml#70 integrate
.. //depot/projects/docproj_nl/www/en/releases/8.3R/schedule.sgml#2 integrate
.. //depot/projects/docproj_nl/www/en/releng/index.sgml#49 integrate
.. //depot/projects/docproj_nl/www/share/sgml/commercial.isp.xml#28 integrate
.. //depot/projects/docproj_nl/www/share/sgml/commercial.software.xml#14 integrate
.. //depot/projects/docproj_nl/www/share/sgml/news.xml#131 integrate
.. //depot/projects/docproj_nl/www/share/sgml/usergroups.xml#30 integrate
Differences ...
==== //depot/projects/docproj_nl/en_US.ISO8859-1/articles/committers-guide/article.sgml#48 (text+ko) ====
@@ -9,7 +9,7 @@
<corpauthor>The &os; Documentation Project</corpauthor>
- <pubdate>$FreeBSD: doc/en_US.ISO8859-1/articles/committers-guide/article.sgml,v 1.309 2012/01/14 11:48:00 crees Exp $</pubdate>
+ <pubdate>$FreeBSD: doc/en_US.ISO8859-1/articles/committers-guide/article.sgml,v 1.310 2012/02/17 22:34:05 gjb Exp $</pubdate>
<copyright>
<year>1999</year>
@@ -1049,6 +1049,1313 @@
</sect1>
+ <sect1 id="subversion-primer">
+ <title>Subversion Primer</title>
+
+ <sect2 id="svn-intro">
+ <title>Introduction</title>
+
+ <para>The &os; source repository switched from
+ <acronym>CVS</acronym> to Subversion on May 31st, 2008. The
+ first real <acronym>SVN</acronym> commit is
+ <emphasis>r179447</emphasis>.</para>
+
+ <para>There are mechanisms in place to automatically merge
+ changes back from the Subversion repository to the
+ <acronym>CVS</acronym> one, so regular users should not notice
+ a difference, however developers most certainly will.</para>
+
+ <para>Subversion is not that different from
+ <acronym>CVS</acronym> when it comes to daily use, but there
+ are differences. Subversion has a number of features that
+ should make developers' lives easier. The most important
+ advantage to Subversion (and the reason why &os; switched) is
+ that it handles branches and merging much better than CVS
+ does. Some of the principal differences are:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Commits are atomic.</para>
+ </listitem>
+ <listitem>
+ <para>Revision numbers apply across the repository—all
+ files that were modified in the same commit have the same
+ revision number.</para>
+ </listitem>
+ <listitem>
+ <para>Branching and tagging are namespace operations.</para>
+ </listitem>
+ <listitem>
+ <para>Directories are versioned.</para>
+ </listitem>
+ <listitem>
+ <para>Files and directories can have arbitrary, versioned
+ metadata attached to them.</para>
+ </listitem>
+ <listitem>
+ <para>Files and directories can be copied, with full history
+ tracking.</para>
+ </listitem>
+ <listitem>
+ <para>No more contortions due to <acronym>CVS</acronym>
+ weakness such as applying &man.patch.1; files at compile
+ time in order to avoid touching vendor branch code.</para>
+ </listitem>
+ <listitem>
+ <para>No more repo-copies.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Subversion can be installed from the &os; Ports
+ Collection, by issuing the following commands:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/devel/subversion</userinput>
+&prompt.root; <userinput>make clean install</userinput></screen>
+ </sect2>
+
+ <sect2 id="svn-getting-started">
+ <title>Getting Started</title>
+
+ <para>There are three ways to obtain a working copy of the tree
+ from Subversion. This section will explain them.</para>
+
+ <sect3>
+ <title>Direct Checkout</title>
+
+ <para>The first is to check out directly from the main
+ repository:</para>
+
+ <screen>&prompt.user; <userinput>svn checkout svn+ssh://svn.freebsd.org/base/head /usr/src</userinput></screen>
+
+ <para>The above command will check out a
+ <literal>CURRENT</literal> source tree as <filename
+ class="directory"><replaceable>/usr/src/</replaceable></filename>,
+ which can be any target directory on the local filesystem.
+ Omitting the final argument of that command causes the
+ working copy, in this case, to be named <quote>head</quote>,
+ but that can be renamed safely.</para>
+
+ <para><literal>svn+ssh</literal> means the
+ <acronym>SVN</acronym> protocol tunnelled over
+ <acronym>SSH</acronym>. The name of the server is
+ <literal>svn.freebsd.org</literal>, <literal>base</literal>
+ is the path to the repository, and <literal>head</literal>
+ is the subdirectory within the repository.</para>
+
+ <para>If your &os; login name is different from your login
+ name on your local machine, you must either include it in
+ the <acronym>URL</acronym> (for example
+ <literal>svn+ssh://jarjar@svn.freebsd.org/base/head</literal>),
+ or add an entry to your <filename>~/.ssh/config</filename>
+ in the form:</para>
+
+ <programlisting>Host svn.freebsd.org
+ User jarjar</programlisting>
+
+ <para>This is the simplest method, but it's hard to tell just
+ yet how much load it will place on the repository.
+ Subversion is much faster than <acronym>CVS</acronym>,
+ however.</para>
+
+ <note>
+ <para>The <command>svn diff</command> does not require
+ access to the server as <acronym>SVN</acronym> stores a
+ reference copy of every file in the working copy. This,
+ however, means that Subversion working copies are very
+ large in size.</para>
+ </note>
+ </sect3>
+
+ <sect3>
+ <title>Checkout from a Mirror</title>
+
+ <para>You can check out a working copy from a mirror by simply
+ substituting the mirror's <acronym>URL</acronym> for
+ <literal>svn+ssh://svn.freebsd.org/base</literal>. This can
+ be an official mirror or a mirror you maintain yourself
+ using <command>svnsync</command> or similar.</para>
+
+ <para>There is a serious disadvantage to this method: every
+ time something is to be committed, a <command>svn switch
+ --relocate</command> to the master repository has to be
+ done, remembering to <command>svn switch</command> back to
+ the mirror after the commit. Also, since <command>svn
+ switch</command> only works between repositories that have
+ the same UUID, some hacking of the local repository's UUID
+ has to occur before it is possible to start using it.</para>
+
+ <para>Unlike with <acronym>CVS</acronym> and
+ <acronym>csup</acronym>, the hassle of a local
+ <command>svnsync</command> mirror probably is not worth it
+ unless the network connectivity situation or other factors
+ demand it. If it is needed, see the end of this chapter for
+ information on how to set one up.</para>
+ </sect3>
+
+ <sect3>
+ <title>Checkout from a Local Mirror Using
+ <acronym>SVK</acronym></title>
+
+ <para>The third alternative is to use <acronym>SVK</acronym>
+ to maintain a local mirror. It is a version control system
+ build on top of Subversion's storage engine. It is
+ identical to Subversion in most respects, except that it
+ allows for setting up parts of repositories as mirrors of
+ other repositories, and keeping local branches for merging
+ back into the upstream repositories. There are extensions
+ that allow <acronym>SVK</acronym> to mirror
+ <acronym>CVS</acronym> and Perforce repositories in addition
+ to Subversion ones.</para>
+
+ <para>Like everything, <acronym>SVK</acronym> has its
+ disadvantages, one being that local revision numbers will
+ not match upstream revision numbers. This makes it
+ difficult to <command>svk log</command>, <command>svk
+ diff</command>, or <command>svk update</command> to an
+ arbitrary upstream revision.</para>
+
+ <para>To set up a mirror of the &os; repository, do:</para>
+
+ <screen>&prompt.user; <userinput>svk mirror svn+ssh://svn.freebsd.org/base //freebsd/base</userinput></screen>
+
+ <para>The local <acronym>SVK</acronym> repository will be
+ stored in <filename
+ class="directory">~/.svk/local/</filename>, but can be
+ moved to whereever suits. If it is moved,
+ <filename>~/.svk/config</filename> should be amended
+ manually to reflect the move.</para>
+
+ <para>Any path can be used, not just the one in the example
+ above. A common pattern is to place mirrors under
+ <literal>//mirror</literal>, e.g.
+ <filename
+ class="directory">//mirror/freebsd/base/</filename>, and
+ local branches under <literal>//local</literal>.</para>
+
+ <para>To pull down the contents of the repository to the
+ mirror:</para>
+
+ <screen>&prompt.user; <userinput>svk sync //freebsd/base</userinput></screen>
+
+ <note>
+ <para><command>svk sync</command> will take a very long
+ time, possibly several days over a slow network
+ connection. &a.peter; has a tarball that can be used to
+ jumpstart the mirror, but only if one does not exist
+ already.</para>
+ </note>
+
+ <para>To use &a.peter;'s tarball mentioned in the note
+ above:</para>
+
+ <screen>&prompt.user; <userinput>cd ~</userinput>
+&prompt.user; <userinput>scp freefall:/home/peter/dot_svk_r179646.tbz2 .</userinput>
+&prompt.user; <userinput>tar xf dot_svk_r179646.tbz2</userinput></screen>
+
+ <para>Then edit <filename>~/.svk/config</filename> and replace
+ <filename
+ class="directory">/scratch/tmp/peter/.svk/local/</filename>
+ with the equivalent of <filename
+ class="directory">/home/<replaceable>jarjar</replaceable>/.svk/local/</filename>.</para>
+
+ <para>You can check out files directly from your mirror, once
+ it has been created:</para>
+
+ <screen>&prompt.user; <userinput>svk checkout //freebsd/base/head /usr/src</userinput></screen>
+
+ <para>Unlike <acronym>SVN</acronym>, <acronym>SVK</acronym>
+ does not store metadata or reference copies in the working
+ copy. All metadata is recorded in
+ <filename>~/.svk/config</filename>; reference copies are not
+ used at all because <acronym>SVK</acronym> always operates
+ on a local repository.</para>
+
+ <para>When committing from a working copy like the one above,
+ <acronym>SVN</acronym> will commit directly to the upstream
+ repository, then syncronise the mirror.</para>
+
+ <para>However, the <quote>killer app</quote> for
+ <acronym>SVK</acronym> is the ability to work without a
+ network connection. To do that, a local branch must be set
+ up:</para>
+
+ <screen>&prompt.user; <userinput>svk mkdir //local/freebsd</userinput>
+&prompt.user; <userinput>svk copy //freebsd/base/head //local/freebsd/head</userinput></screen>
+
+ <para>Once again, any path can be used, it does not have to
+ specifically be the one in the example.</para>
+
+ <para>Before use, the local branch has to be synchronised,
+ like so:</para>
+
+ <screen>&prompt.user; <userinput>svk pull //local/freebsd/head</userinput></screen>
+
+ <para>Then check out from the newly created local
+ branch:</para>
+
+ <screen>&prompt.user; <userinput>svk checkout //local/freebsd/head /usr/src</userinput></screen>
+
+ <para>The point of this exercise is showing that it is
+ possible to commit work-in-progress to a local branch, and
+ only push it to the upstream repository when work is
+ complete. The easy way to push is with <command>svk
+ push</command>, but there is a serious disadvantage to it:
+ it will push every single commit made to the local branch
+ incrementally instead of lumping them all into a single
+ commit. Therefore, using <command>svk smerge</command> is
+ preferable.</para>
+ </sect3>
+
+ <sect3>
+ <title><literal>RELENG_*</literal> Branches and General
+ Layout</title>
+
+ <para>In <literal>svn+ssh://svn.freebsd.org/base</literal>,
+ <emphasis>base</emphasis> refers to the source tree.
+ Similarly, <emphasis>ports</emphasis> refers to the ports
+ tree, and so on. These are separate repositories with their
+ own change number sequences, access controls and commit
+ mail.</para>
+
+ <para>For the base repository, HEAD refers to the -CURRENT
+ tree. For example, <filename>head/bin/ls</filename> is what
+ would go into <filename>/usr/src/bin/ls</filename> in a
+ release. Some other key locations are:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis>/stable/<replaceable>n</replaceable></emphasis>
+ which corresponds to
+ <literal>RELENG_<replaceable>n</replaceable></literal>.</para>
+ </listitem>
+ <listitem>
+ <para><emphasis>/releng/<replaceable>n.n</replaceable></emphasis>
+ which corresponds to
+ <literal>RELENG_<replaceable>n_n</replaceable></literal>.</para>
+ </listitem>
+ <listitem>
+ <para><emphasis>/release/<replaceable>n.n.n</replaceable></emphasis>
+ which corresponds to
+ <literal>RELENG_<replaceable>n_n_n</replaceable>_RELEASE</literal>.</para>
+ </listitem>
+ <listitem>
+ <para><emphasis>/vendor*</emphasis> is the vendor branch
+ import work area. This directory itself does not
+ contain branches, however its subdirectories do. This
+ contrasts with the <emphasis>stable</emphasis>,
+ <emphasis>releng</emphasis> and
+ <emphasis>release</emphasis> directories.</para>
+ </listitem>
+ <listitem>
+ <para><emphasis>/projects</emphasis> and
+ <emphasis>/user</emphasis> feature a branch work area,
+ like in Perforce. As above, the
+ <emphasis>/user</emphasis> directory does not contain
+ branches itself.</para>
+ </listitem>
+ </itemizedlist>
+ </sect3>
+ </sect2>
+
+ <sect2 id="svn-daily-use">
+ <title>Daily Use</title>
+
+ <para>This section will explain how to perform common day-to-day
+ operations with Subversion. There should be no difference
+ between <acronym>SVN</acronym> and <acronym>SVK</acronym> in
+ daily use, except for the revision renumbering mentioned
+ earlier.</para>
+
+ <note>
+ <para><acronym>SVN</acronym> and <acronym>SVK</acronym>
+ commands that have direct <acronym>CVS</acronym> equivalents
+ usually have the same name and abbreviations. For example:
+ <emphasis>checkout</emphasis> and <emphasis>co</emphasis>,
+ <emphasis>update</emphasis> and <emphasis>up</emphasis>, and
+ <emphasis>commit</emphasis> and
+ <emphasis>ci</emphasis>.</para>
+ </note>
+
+ <sect3>
+ <title>Help</title>
+
+ <para>Both <acronym>SVN</acronym> and <acronym>SVK</acronym>
+ have built in help documentation. It can be accessed by
+ typing the following command:</para>
+
+ <screen>&prompt.user; <userinput>svn help</userinput></screen>
+ </sect3>
+
+ <sect3>
+ <title>Checkout</title>
+
+ <para>As seen earlier, to check out the &os; head
+ branch:</para>
+
+ <screen>&prompt.user; <userinput>svn checkout svn+ssh://svn.freebsd.org/base/head /usr/src</userinput></screen>
+
+ <para>At some point, more than just <literal>HEAD</literal>
+ will probably be useful, for instance when merging changes
+ to stable/7. Therefore, it may be useful to have a partial
+ checkout of the complete tree (a full checkout would be very
+ painful).</para>
+
+ <para>To do this, first check out the root of the
+ repository:</para>
+
+ <screen>&prompt.user; <userinput>svn checkout --depth=immediates svn+ssh://svn.freebsd.org/base</userinput></screen>
+
+ <para>This will give <literal>base</literal> with all the
+ files it contains (at the time of writing, just
+ <filename>ROADMAP.txt</filename>) and empty subdirectories
+ for <literal>head</literal>, <literal>stable</literal>,
+ <literal>vendor</literal> and so on.</para>
+
+ <para>Expanding the working copy is possible. Just change the
+ depth of the various subdirectories:</para>
+
+ <screen>&prompt.user; <userinput>svn up --set-depth=infinity base/head</userinput>
+&prompt.user; <userinput>svn up --set-depth=immediates base/release base/releng base/stable</userinput></screen>
+
+ <para>The above command will pull down a full copy of
+ <literal>head</literal>, plus empty copies of every
+ <literal>release</literal> tag, every
+ <literal>releng</literal> branch, and every
+ <literal>stable</literal> branch.</para>
+
+ <para>If at a later date merging to
+ <literal>7-STABLE</literal> is required, expand the working
+ copy:</para>
+
+ <screen>&prompt.user; <userinput>svn up --set-depth=infinity base/stable/7</userinput></screen>
+
+ <para>Subtrees do not have to be expanded completely. For
+ instance, expanding only <literal>stable/7/sys</literal> and
+ then later expand the rest of
+ <literal>stable/7</literal>:</para>
+
+ <screen>&prompt.user; <userinput>svn up --set-depth=infinity base/stable/7/sys</userinput>
+&prompt.user; <userinput>svn up --set-depth=infinity base/stable/7</userinput></screen>
+
+ <para>Updating the tree with <command>svn update</command>
+ will only update what was previously asked for (in this
+ case, <literal>head</literal> and
+ <literal>stable/7</literal>; it will not pull down the whole
+ tree.</para>
+
+ <para>It is useful to note that decreasing the depth of a
+ working copy is not possible.</para>
+ </sect3>
+
+ <sect3>
+ <title>Anonymous Checkout</title>
+
+ <para>It is possible to anonymously check out the &os;
+ repository with Subversion. This will give access to a
+ read-only tree that can be updated, but not committed
+ to. To do this, use one of the following commands:</para>
+
+ <screen>&prompt.user; <userinput>svn co svn://svn.freebsd.org/base/head /usr/src</userinput>
+&prompt.user; <userinput>svn co http://svn.freebsd.org/base/head /usr/src</userinput></screen>
+ </sect3>
+
+ <sect3>
+ <title>Updating the Tree</title>
+
+ <para>To update a working copy to either the latest revision,
+ or a specific revision:</para>
+
+ <screen>&prompt.user; <userinput>svn update</userinput>
+&prompt.user; <userinput>svn update -<replaceable>r12345</replaceable></userinput></screen>
+ </sect3>
+
+ <sect3>
+ <title>Status</title>
+
+ <para>To view the local changes that have been made to the
+ working copy:</para>
+
+ <screen>&prompt.user; <userinput>svn status</userinput></screen>
+
+ <para><acronym>CVS</acronym> has no direct equivalent of this
+ command. The nearest would be <command>cvs up -N</command>
+ which shows local changes and files that are out-of-date.
+ Doing this in <acronym>SVN</acronym> is possible too,
+ however:</para>
+
+ <screen>&prompt.user; <userinput>svn status --show-updates</userinput></screen>
+ </sect3>
+
+ <sect3>
+ <title>Editing and Committing</title>
+
+ <para>Like <acronym>CVS</acronym> but unlike Perforce,
+ <acronym>SVN</acronym> and <acronym>SVK</acronym> do not
+ need to be told in advance about file editing.</para>
+
+ <para><command>svn commit</command>works like the equivalent
+ <acronym>CVS</acronym> command. To commit all changes in
+ the current directory and all subdirectories:</para>
+
+ <screen>&prompt.user; <userinput>svn commit</userinput></screen>
+
+ <para>To commit all changes in, for example, the <filename
+ class="directory"><replaceable>lib/libfetch/</replaceable></filename>
+ and <filename
+ class="directory"><replaceable>usr/bin/fetch/</replaceable></filename>
+ in a single operation:</para>
+
+ <screen>&prompt.user; <userinput>svn commit <replaceable>lib/libfetch</replaceable> <replaceable>usr/bin/fetch</replaceable></userinput></screen>
+ </sect3>
+
+ <sect3>
+ <title>Adding and Removing Files</title>
+
+ <note>
+ <para>Before adding files, get a copy of <ulink
+ url="http://people.freebsd.org/~peter/auto-props.txt">auto-props.txt</ulink>
+ and add it to <filename>~/.subversion/config</filename>
+ according to the instructions in the file. If you added
+ something before you've read this, you may use
+ <command>svn rm --keep-local</command> for just added
+ files, fix your config file and re-add them again. The
+ initial config file is created when you first run a svn
+ command, even something as simple as <command>svn
+ help</command>.</para>
+ </note>
+
+ <para>As with <acronym>CVS</acronym>, files are added to a
+ <acronym>SVN</acronym> repository with <command>svn
+ add</command>. To add a file named
+ <emphasis>foo</emphasis>, edit it, then:</para>
+
+ <screen>&prompt.user; <userinput>svn add <replaceable>foo</replaceable></userinput></screen>
+
+ <para>Files can be removed with <command>svn
+ remove</command>:</para>
+
+ <screen>&prompt.user; <userinput>svn remove <replaceable>foo</replaceable></userinput></screen>
+
+ <para>Subversion does not require <command>rm</command>ing the
+ file before <command>svn rm</command>ing it, and indeed
+ complains if that happens.</para>
+
+ <para>It is possible to add directories with <command>svn
+ add</command>:</para>
+
+ <screen>&prompt.user; <userinput>mkdir <replaceable>bar</replaceable></userinput>
+&prompt.user; <userinput>svn add <replaceable>bar</replaceable></userinput></screen>
+
+ <para>Although <command>svn mkdir</command> makes this
+ easier by combining the creation of the directory and the
+ adding of it:</para>
+
+ <screen>&prompt.user; <userinput>svn mkdir <replaceable>bar</replaceable></userinput></screen>
+
+ <para>In <acronym>CVS</acronym>, the directory is immediately
+ created in the repository when you <command>cvs
+ add</command> it; this is not the case in Subversion.
+ Furthermore, unlike <acronym>CVS</acronym>, Subversion
+ allows directories to be removed using <command>svn
+ rm</command>, however there is no <command>svn
+ rmdir</command>:</para>
+
+ <screen>&prompt.user; <userinput>svn rm <replaceable>bar</replaceable></userinput></screen>
+ </sect3>
+
+ <sect3>
+ <title>Copying and Moving Files</title>
+
+ <para>The following (obviously) creates a copy of
+ <filename>foo.c</filename>, named
+ <filename>bar.c</filename>:</para>
+
+ <screen>&prompt.user; <userinput>svn copy <replaceable>foo.c</replaceable> <replaceable>bar.c</replaceable></userinput></screen>
+
+ <para>To move and rename a file:</para>
+
+ <screen>&prompt.user; <userinput>svn move <replaceable>foo.c</replaceable> <replaceable>bar.c</replaceable></userinput></screen>
+
+ <para>The above command is the exact equivalent of:</para>
+
+ <screen>&prompt.user; <userinput>svn copy <replaceable>foo.c</replaceable> <replaceable>bar.c</replaceable></userinput>
+&prompt.user; <userinput>svn remove <replaceable>foo.c</replaceable></userinput></screen>
+
+ <para>Neither of these operations have equivalents in
+ <acronym>CVS</acronym>.</para>
+ </sect3>
+
+ <sect3>
+ <title>Log and Annotate</title>
+
+ <para><command>svn log</command> will show all the
+ revisions that affect a directory and files within that
+ directory in reverse chronological order, if run on a
+ directory. This contrasts with <command>cvs log</command>
+ in that <acronym>CVS</acronym> shows the complete log for
+ each file in the directory, including duplicate entries for
+ revisions that affect multiple files.</para>
+
+ <para><command>svn annotate</command>, or equally <command>svn
+ praise</command> or <command>svn blame</command>, is
+ equivalent to <command>cvs annotate</command> in everything
+ but output format.</para>
+ </sect3>
+
+ <sect3>
+ <title>Diffs</title>
+
+ <para>The <command>svn diff</command> displays changes to the
+ working copy of the repository. <acronym>SVN</acronym>'s
+ diffs are unified by default, unlike
+ <acronym>CVS</acronym>'s, and <acronym>SVN</acronym>'s
+ include new files by default in the diff output.</para>
+
+ <para>Like <command>cvs diff</command>, <command>svn
+ diff</command> can show the changes between two revisions
+ of the same file:</para>
+
+ <screen>&prompt.user; <userinput>svn diff -r179453:179454 ROADMAP.txt</userinput></screen>
+
+ <para>It can also show all changes for a specific changeset.
+ The following will show what changes were made to the
+ current directory and all subdirectories in changeset
+ 179454:</para>
+
+ <screen>&prompt.user; <userinput>svn diff -c179454 .</userinput></screen>
+ </sect3>
+
+ <sect3>
+ <title>Reverting</title>
+
+ <para>Local changes (including additions and deletions) can be
+ reverted using <command>svn revert</command>. Unlike
+ <command>cvs up -C</command>, it does not update out-of-date
+ files—it just replaces them with pristine copies of
+ the original version.</para>
+ </sect3>
+
+ <sect3>
+ <title>Conflicts</title>
+
+ <para>If a <command>svn update</command> resulted in a merge
+ conflict, Subversion will remember which files have
+ conflicts and refuse to commit any changes to those files
+ until explicitly told that the conflicts have been resolved.
+ The simple, not yet deprecated procedure is the
+ following:</para>
+
+ <screen>&prompt.user; <userinput>svn resolved <replaceable>foo</replaceable></userinput></screen>
+
+ <para>However, the preferred procedure is:</para>
+
+ <screen>&prompt.user; <userinput>svn resolve --accept=working <replaceable>foo</replaceable></userinput></screen>
+
+ <para>The two examples are equivalent. Possible values for
+ <literal>--accept</literal> are:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><literal>working</literal>: use the version in your
+ working directory (which one presumes has been edited to
+ resolve the conflicts).</para>
+ </listitem>
+ <listitem>
+ <para><literal>base</literal>: use a pristine copy of the
+ version you had before <command>svn update</command>,
+ discarding your own changes, the conflicting changes,
+ and possibly other intervening changes as well.</para>
+ </listitem>
+ <listitem>
+ <para><literal>mine-full</literal>: use what you had
+ before <command>svn update</command>, including your own
+ changes, but discarding the conflicting changes, and
+ possibly other intervening changes as well.</para>
+ </listitem>
+ <listitem>
+ <para><literal>theirs-full</literal>: use the version that
+ was retrieved when you did <command>svn
+ update</command>, discarding your own changes.</para>
+ </listitem>
+ </itemizedlist>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Advanced Use</title>
+
+ <sect3>
+ <title>Sparse Checkouts</title>
+
+ <para>The equivalent to <command>cvs checkout -l</command>,
+ which checks out a directory without its subdirectories, is
+ <command>svn checkout -N</command>. Unlike
+ <acronym>CVS</acronym>, <acronym>SVN</acronym> remembers the
+ <literal>-N</literal> so that a <command>svn
+ update</command> does not end up pulling down the
+ subdirectories. In Subversion 1.5 and newer,
+ <literal>-N</literal> has been deprecated in favour of the
+ <literal>--depth</literal> option which allows for precise
+ control. Therefore:</para>
+
+ <screen>&prompt.user; <userinput>svn checkout -N svn+ssh://svn.freebsd.org/base ~/freebsd</userinput></screen>
+
+ <para>is equivalent to:</para>
+
+ <screen>&prompt.user; <userinput>svn checkout --depth=empty svn+ssh://svn.freebsd.org/base ~/freebsd</userinput></screen>
+
+ <para>Valid arguments to <literal>--depth</literal>
+ are:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><literal>empty</literal>: the directory itself
+ without any of its contents.</para>
+ </listitem>
+ <listitem>
+ <para><literal>files</literal>: the directory and any
+ files it contains.</para>
+ </listitem>
+ <listitem>
+ <para><literal>immediates</literal>: the directory and any
+ files and directories it contains, but none of the
+ subdirectories' contents.</para>
+ </listitem>
+ <listitem>
+ <para><literal>infinity</literal>: anything.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>The <literal>--depth</literal> option applies to many
+ other commands, including <command>svn commit</command>,
+ <command>svn revert</command>, and <command>svn
+ diff</command>.</para>
+
+ <para>Since <literal>--depth</literal> is sticky, there is a
+ <literal>--set-depth</literal> option for <command>svn
+ update</command> that will change the selected depth.
+ Thus, given the working copy produced by the previous
+ example:</para>
+
+ <screen>&prompt.user; <userinput>cd <replaceable>~/freebsd</replaceable></userinput>
+&prompt.user; <userinput>svn update --set-depth=immediates .</userinput></screen>
+
+ <para>The above command will populate the working copy in
+ <replaceable>~/freebsd</replaceable> with
+ <filename>ROADMAP.txt</filename> and empty subdirectories,
+ and nothing will happen when <command>svn update</command>
+ is executed on the subdirectories. However, the following
+ command will set the depth for head (in this case) to
+ infinity, and fully populate it:</para>
+
+ <screen>&prompt.user; <userinput>svn update --set-depth=infinity <replaceable>head</replaceable></userinput></screen>
+ </sect3>
+
+ <sect3>
+ <title>Direct Operation</title>
+
+ <para>Certain operations can be performed directly on the
+ repository, without touching the working copy.
+ Specifically, this applies to any operation that does not
+ require editing a file, including:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><literal>log</literal>,
+ <literal>diff</literal>.</para>
+ </listitem>
+ <listitem>
+ <para><literal>mkdir</literal>.</para>
+ </listitem>
+ <listitem>
+ <para><literal>remove</literal>, <literal>copy</literal>,
+ <literal>rename</literal>.</para>
+ </listitem>
+ <listitem>
+ <para><literal>propset</literal>,
+ <literal>propedit</literal>,
+ <literal>propdel</literal>.</para>
+ </listitem>
+ <listitem>
+ <para><literal>merge</literal>.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Branching is very fast. The following command would be
+ used to branch <literal>RELENG_8</literal>:</para>
+
+ <screen>&prompt.user; <userinput>svn copy svn+ssh://svn.freebsd.org/base/head svn+ssh://svn.freebsd.org/base/stable/8</userinput></screen>
+
+ <para>This is equivalent to the following set of
+ commands which take minutes and hours as opposed to seconds,
+ depending on your network connection:</para>
+
+ <screen>&prompt.user; <userinput>svn checkout --depth=immediates svn+ssh://svn.freebsd.org/base</userinput>
+&prompt.user; <userinput>cd base</userinput>
+&prompt.user; <userinput>svn update --depth=infinity head</userinput>
+&prompt.user; <userinput>svn copy head stable/8</userinput>
+&prompt.user; <userinput>svn commit stable/8</userinput></screen>
+ </sect3>
+
+ <sect3>
+ <title>Merging with <acronym>SVN</acronym></title>
+
+ <para>This section deals with merging code from one branch to
+ another (typically, from head to a stable branch). For
+ information about vendor imports, see the next section in
+ this primer.</para>
+
+ <note>
+ <para>In all examples below, <literal>$FSVN</literal>
+ refers to the location of the &os; Subversion repository,
+ <literal>svn+ssh://svn.freebsd.org/base/</literal>.</para>
+ </note>
+
+ <sect4>
+ <title>About Merge Tracking</title>
+
+ <para>From the user's perspective, merge tracking
+ information (or mergeinfo) is stored in a property called
+ <literal>svn:mergeinfo</literal>, which is a
+ comma-separated list of revisions and ranges of revisions
+ that have been merged. When set on a file, it applies
+ only to that file. When set on a directory, it applies to
+ that directory and its descendants (files and directories)
+ except for those that have their own
+ <literal>svn:mergeinfo</literal>.</para>
+
+ <para>It is <emphasis>not</emphasis> inherited. For
+ instance, <filename
+ class="directory">stable/6/contrib/openpam/</filename>
+ does not implicitly inherit mergeinfo from <filename
+ class="directory">stable/6/</filename>, or <filename
+ class="directory">stable/6/contrib/</filename>. Doing
+ so would make partial checkouts very hard to manage.
+ Instead, mergeinfo is explicitly propagated down the tree.
+ For merging something into <filename
+ class="directory">branch/foo/bar/</filename>, the
+ following rules apply:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>If <filename
+ class="directory">branch/foo/bar/</filename> doesn't
+ already have a mergeinfo record, but a direct ancestor
+ (for instance, <filename
+ class="directory">branch/foo/</filename>) does,
+ then that record will be propagated down to
+ <filename class="directory">branch/foo/bar/</filename>
+ before information
+ about the current merge is recorded.</para>
+ </listitem>
+ <listitem>
+ <para>Information about the current merge will
+ <emphasis>not</emphasis> be propagated back up that
+ ancestor.</para>
+ </listitem>
+ <listitem>
+ <para>If a direct descendant of <filename
+ class="directory">branch/foo/bar/</filename> (for
+ instance, <filename
+ class="directory">branch/foo/bar/baz/</filename>)
+ already has a mergeinfo record, information about the
+ current merge will be propagated down to it.</para>
+ </listitem>
+ </orderedlist>
+
+ <para>If you consider the case where a revision changes
+ several separate parts of the tree (for example, <filename
+ class="directory">branch/foo/bar/</filename> and
+ <filename class="directory">branch/foo/quux/</filename>),
+ but you only want to merge some of it (for example,
+ <filename class="directory">branch/foo/bar/</filename>),
+ you will see that these rules make sense. If mergeinfo
+ was propagated up, it would seem like that revision had
+ also been merged to <filename
+ class="directory">branch/foo/quux/</filename>, when in
+ fact it had not been.</para>
+ </sect4>
+
+ <sect4>
+ <title>Selecting the Source and Target</title>
+
+ <para>Because of mergeinfo propagation, it is important to
+ choose the source and target for the merge carefully to
+ minimise property changes on unrelated directories.</para>
+
+ <para>The rules for selecting the merge target (the
+ directory that you will merge the changes to) can be
+ summarised as follows:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>Never merge directly to a file.</para>
+ </listitem>
+ <listitem>
+ <para>Never, ever merge directly to a file.</para>
+ </listitem>
+ <listitem>
+ <para><emphasis>Never, ever, ever</emphasis> merge
+ directly to a file.</para>
+ </listitem>
+ <listitem>
+ <para>Changes to kernel code should be merged to
+ <filename class="directory">sys/</filename>. For
+ instance, a change to the &man.ichwd.4; driver should
+ be merged to <filename
+ class="directory">sys/</filename>, not <filename
+ class="directory">sys/dev/ichwd/</filename>.
+ Likewise, a change to the TCP/IP stack should be
+ merged to <filename class="directory">sys/</filename>,
+ not <filename
+ class="directory">sys/netinet/</filename>.</para>
+ </listitem>
+ <listitem>
+ <para>Changes to code under <filename
+ class="directory">etc/</filename> should be merged
+ at <filename class="directory">etc/</filename>, not
+ below it.</para>
+ </listitem>
+ <listitem>
+ <para>Changes to vendor code (code in <filename
+ class="directory">contrib/</filename>, <filename
+ class="directory">crypto/</filename> and so on)
+ should be merged to the directory where vendor imports
+ happen. For instance, a change to <filename
+ class="directory">crypto/openssl/util/</filename>
+ should be merged to <filename
+ class="directory">crypto/openssl/</filename>. This
+ is rarely an issue, however, since changes to vendor
+ code are usually merged wholesale.</para>
+ </listitem>
+ <listitem>
+ <para>Changes to userland programs should as a general
+ rule be merged to the directory that contains the
+ Makefile for that program. For instance, a change to
+ <filename
+ class="directory">usr.bin/xlint/arch/i386/</filename>
+ should be merged to <filename
+ class="directory">usr.bin/xlint/</filename>.</para>
+ </listitem>
+ <listitem>
+ <para>Changes to userland libraries should as a general
+ rule be merged to the directory that contains the
+ Makefile for that library. For instance, a change to
+ <filename class="directory">lib/libc/gen/</filename>
+ should be merged to <filename
+ class="directory">lib/libc/</filename>.</para>
+ </listitem>
+ <listitem>
+ <para>There may be cases where it makes sense to deviate
+ from the rules for userland programs and libraries.
+ For instance, everything under <filename
+ class="directory">lib/libpam/</filename> is merged
+ to <filename class="directory">lib/libpam/</filename>,
+ even though the library itself and all of the modules
+ each have their own Makefile.</para>
+ </listitem>
+ <listitem>
+ <para>Changes to man pages should be merged to <filename
+ class="directory">share/man/man<replaceable>N</replaceable>/</filename>,
+ for the appropriate value of
+ <literal>N</literal>.</para>
+ </listitem>
+ <listitem>
+ <para>Changes to a top-level file in the source tree
+ such as <filename>UPDATING</filename> or
+ <filename>Makefile.inc1</filename> should be merged
+ directly to that file rather than to the root of the
+ whole tree. Yes, this is an exception to the first
+ three rules.</para>
+ </listitem>
+ <listitem>
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the p4-projects
mailing list