Date: Sun, 19 Feb 2012 12:17:43 GMT From: Rene Ladan <rene@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 206534 for review Message-ID: <201202191217.q1JCHhK2031901@skunkworks.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@206534?ac=10 Change 206534 by rene@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) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201202191217.q1JCHhK2031901>