[svnbook commit] r2910 - trunk/src/en/book

sussman noreply at red-bean.com
Mon Dec 10 16:32:12 CST 2007


Author: sussman
Date: Mon Dec 10 16:32:10 2007
New Revision: 2910

Log:
Keep filling out chapter 4.

* src/en/book/ch04-branching-and-merging.xml:  more work on TODO sections.


Modified:
   trunk/src/en/book/ch04-branching-and-merging.xml

Modified: trunk/src/en/book/ch04-branching-and-merging.xml
==============================================================================
--- trunk/src/en/book/ch04-branching-and-merging.xml	(original)
+++ trunk/src/en/book/ch04-branching-and-merging.xml	Mon Dec 10 16:32:10 2007
@@ -419,6 +419,7 @@
 
   </sect1>
 
+
   <!-- ================================================================= -->
   <!-- ================================================================= -->
   <!-- ================================================================= -->
@@ -465,6 +466,50 @@
       <xref linkend="svn.branchmerge.advanced"/>.)</para>
 
   <!-- =============================================================== -->
+    <sect2 id="svn.branchmerge.changesets">
+      <title>Changesets</title>
+
+      <para>Before we get too far in, we should warn you that there's
+        going to be a lot of discussion of <quote>changes</quote> in
+        the pages ahead.  A lot of people experienced with version
+        control systems use the terms <quote>change</quote>
+        and <quote>changeset</quote> interchangeably, and we should
+        clarify what Subversion understands as
+        a <firstterm>changeset</firstterm>.</para>
+
+      <para>Everyone seems to have a slightly different definition
+        of <quote>changeset</quote>, or at least a different
+        expectation of what it means for a version control system to
+        have them.  For our purpose, let's say that a changeset is
+        just a collection of changes with a unique name.  The changes
+        might include textual edits to file contents, modifications to
+        tree structure, or tweaks to metadata.  In more common speak,
+        a changeset is just a patch with a name you can refer
+        to.</para>
+
+      <para>In Subversion, a global revision number N names a tree in
+        the repository: it's the way the repository looked after the
+        Nth commit.  It's also the name of an implicit changeset: if
+        you compare tree N with tree N-1, you can derive the exact
+        patch that was committed.  For this reason, it's easy to think
+        of revision N as not just a tree, but a changeset as well.  If
+        you use an issue tracker to manage bugs, you can use the
+        revision numbers to refer to particular patches that fix
+        bugs—for example,
+        <quote>this issue was fixed by revision 9238.</quote>.
+        Somebody can then run <command>svn log -r9238</command> to
+        read about the exact changeset which fixed the bug, and run
+        <command>svn diff -c 9238</command> to see the patch itself.
+        And (as you'll see shortly)
+        Subversion's <command>merge</command> command is able to use
+        revision numbers.  You can merge specific changesets from one
+        branch to another by naming them in the merge
+        arguments: <command>svn merge -c 9238</command> would merge
+        changeset #9238 into your working copy.</para>
+
+      </sect2>
+
+  <!-- =============================================================== -->
     <sect2 id="svn.branchemerge.basicmerging.stayinsync">
       <title>Keeping a Branch in Sync</title>
 
@@ -585,11 +630,11 @@
 
       </sidebar>
 
-      <para>Suppose, now, that another week has passed.  You've
-        committed more changes to your branch, and your comrades have
-        continued to improve the trunk as well.  Once again, you'd
-        like to replicate the latest trunk changes to your branch and
-        bring yourself in sync.  Just run the same merge command
+      <para>Suppose that another week has passed.  You've committed
+        more changes to your branch, and your comrades have continued
+        to improve the trunk as well.  Once again, you'd like to
+        replicate the latest trunk changes to your branch and bring
+        yourself in sync.  Just run the same merge command
         again!</para>
 
       <screen>
@@ -634,15 +679,21 @@
         do this by either doing an <command>svn checkout</command>,
         dredging up an old trunk working copy from somewhere on your
         disk, or by using <command>svn switch</command> (see
-        <xref linkend="svn.branchmerge.switchwc"/>.)  Then
-        invoke <command>svn merge</command> within your trunk working
-        copy:</para>
+        <xref linkend="svn.branchmerge.switchwc"/>.) However you get a
+        trunk working copy, remember that it's a best practice to do
+        your merge into a working copy that
+        has <emphasis>no</emphasis> local edits and has been recently
+        updated.  If your working copy isn't <quote>clean</quote> in
+        these ways, you can run into some headaches.</para>
+
+      <para>Once you have a clean working copy of trunk,
+        you're ready merge your branch back into it:</para>
 
       <screen>
 $ pwd
 /home/user/calc-trunk
 
-$ svn merge http://svn.example.com/repos/calc/branches/my-calc-branch
+$ svn merge --reintegrate http://svn.example.com/repos/calc/branches/my-calc-branch
 --- Merging r341 through r390 into '.':
 U  button.c
 U  integer.c
@@ -659,9 +710,35 @@
 </screen>
 
       <para>Congratulations, your branch has now been re-merged back
-        into the main line of development.  You'll no longer need your
-        branch at this point anymore, so you can do some basic
-        housecleaning in the repository:</para>
+        into the main line of development.  Notice our use of
+        the <option>--reintegrate</option> option this time around.
+        The option is needed because this sort of <quote>merge
+        back</quote> is a different sort of work than what you've been
+        doing up until now.  Previously, we had been
+        asking <command>svn merge</command> to grab the <quote>next
+        set</quote> of changes one branch and duplicate them to
+        another branch.  This is fairly straightforward, and each time
+        Subversion knows how to pick up where it left off.  In our
+        prior examples, you can see that first it merges the ranges
+        345:356 from trunk to branch; later on, it continues by
+        merging the next contiguously available range, 357:380.  When
+        doing the final sync, it merges the range 381:385>.</para>
+
+      <para>When merging your branch back to the trunk, however, the
+        underlying mathematics is quite different.  Your feature
+        branch is now a mish-mosh of both duplicated trunk changes and
+        private branch changes, so there's no simple contiguous range
+        of revisions to copy over.  By specifying
+        the <option>--integrate</option> option, you're asking
+        Subversion to carefully replicate <emphasis>only</emphasis>
+        those changes unique to your branch.  (And in fact it does
+        this by comparing the latest trunk tree with the latest branch
+        tree:  the resulting difference is exactly your branch
+        changes!)</para>
+
+      <para>Now that your branch is merged to trunk, you'll no longer
+        need your branch.  You can do some basic housecleaning in the
+        repository:</para>
 
       <screen>
 $ svn delete http://svn.example.com/repos/calc/branches/my-calc-branch
@@ -686,51 +763,88 @@
     <sect2 id="svn.branchemerge.basicmerging.basicmergetracking">
       <title>Basic Merge Tracking</title>
 
-      <para>###TODO: set expectations on what gets tracked and what
-      doesn't.</para>
+      <para>Of course, there's a lot more detail to the story of
+        merging changes.  Subversion does its best to note where
+        changes have happened and where they've been duplicated, but
+        it's far from perfect.  In this section, we'll show you how
+        some of the magic works.</para>
 
       <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
       <sect3 id="svn.branchmerge.basicmerging.basicmergetracking.mergeinfo">
-        <title>Mergeinfo</title>
+        <title>Mergeinfo and Previews</title>
 
-        <para>###TODO: explain svn:mergeinfo prop and 'svn mergeinfo'
-          command, so users get a general sense of how the system is
-          tracking changes.</para>
+        <para>The basic mechanism Subversion uses to track
+          changesets—that is, which changes have been merged to
+          which branches—is by recording data in properties.
+          Specifically, merge data is tracked in
+          the <literal>svn:mergeinfo</literal> property attached to
+          files and directories.  (If you're not familiar with
+          Subversion properties, now is the time to go skim over
+          <xref linkend="svn.advanced.props"/>.)</para>
 
-      </sect3>
+        <para>You can examine the property, just like any
+          other:</para>
 
-      <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-      <sect3 id="svn.branchmerge.basicmerging.basicmergetracking.previews">
-        <title>Previewing Merges</title>
+        <screen>
+$ cd my-calc-branch
+
+$ svn propget svn:mergeinfo .
+/trunk:341-390
+</screen>
 
-        <para>It's a best practice to do your merge into a working
-          copy that has <emphasis>no</emphasis> local edits and has
-          been recently updated.  If your working copy
-          isn't <quote>clean</quote> in these ways, you can run into
-          some headaches.</para>
-
-        <para>Assuming your working copy is tidy, merging isn't a
-          particularly high-risk operation.  If you get the merge
-          wrong the first time, simply <command>svn revert</command>
-          the changes and try again.</para>
-
-        <para>If you've merged into a working copy that already has
-          local modifications, the changes applied by a merge will be
-          mixed with your pre-existing ones, and running
-          <command>svn revert</command> is no longer an option.  The
-          two sets of changes may be impossible to separate.</para>
-
-        <para>In cases like this, people take comfort in being able to
-          predict or examine merges before they happen.  One simple
-          way to do that is to run <command>svn diff</command> with
-          the same arguments you plan to pass to <command>svn
-          merge</command>, as we already showed in our first example
-          of merging.  Another method of previewing is to pass the
-          <option>--dry-run</option> option to the merge
-          command:</para>
+        <para>...but it is <emphasis>not</emphasis> recommended that
+          you change the value of this property yourself, unless you
+          really know what you're doing.  (An example of this comes up
+          in <xref linkend="svn.branchmerge.advanced.blockchanges"/>.)
+          In general, this property is automatically maintained by
+          Subversion whenever you run <command>svn merge</command>,
+          and its value indicates which changes have already been
+          replicated into a particular directory.</para>
+
+        <para>As we saw earlier, there's also a
+          subcommand <command>svn mergeinfo</command>, which can be
+          helpful in seeing not only which changesets a directory has
+          absorbed, but also which changesets it's still eligible to
+          receive.  This gives a sort of preview of the next set of
+          changes that <command>svn merge</command> will replicate to
+          your branch.</para>
 
         <screen>
-$ svn merge --dry-run http://svn.example.com/repos/calc/trunk
+$ svn mergeinfo .
+Path: .
+  Source path: /trunk
+    Merged ranges: r341:390
+    Eligible ranges: r391:395
+</screen>
+
+        <para>The <command>svn mergeinfo</command> command, by
+          default, looks back at the history of the thing you're
+          querying and tries to make a sane guess about
+          the <quote>source</quote> you want to be copying changes
+          from.  In our prior example, because we're querying our
+          branch working copy, the command assumes we're interested in
+          receiving changes from <filename>/trunk</filename> (since
+          that's where our branch was originally copied from.)
+          However, if another coworker had a different branch going on
+          that we wanted to merge changes from, we could have this
+          command tell us about eligible changesets from that source
+          too:</para>
+
+        <screen>
+$ svn mergeinfo --from-source \
+                http://svn.example.com/repos/calc/branches/other-branch  .
+Path: .
+  Source path: /branches/other-branch
+    Merged ranges:
+    Eligible ranges: r360:364
+</screen>
+
+        <para>Another way to get a more precise preview of a merge
+          operation is to use
+          the <option>--dry-run</option> option.</para>
+
+        <screen>
+$ svn merge http://svn.example.com/repos/calc/trunk --dry-run
 U  integer.c
 
 $ svn status
@@ -745,6 +859,32 @@
           times when running <command>svn diff</command> gives too
           much detail.</para>
 
+        <para>Of course, the best way to preview a merge operation is
+          to just do it!  Remember, running <command>svn
+          merge</command> isn't an inherently risky thing; if you
+          don't like the results, simply <command>svn revert -R</command>
+          the changes from your working copy and retry the command
+          with different options.  The merge isn't final until you
+          actually <command>svn commit</command> the results.</para>
+
+        <tip>
+          <para>While it's perfectly fine to experiment with merges by
+            running <command>svn merge</command> and <command>svn
+            revert</command> over and over, you may run into some
+            annoying (but easily bypassed) roadblocks.  For example,
+            if the merge operation adds a new file (i.e. schedules it
+            for addition), then <command>svn revert</command> won't
+            actually remove the file;  it simply unschedules the
+            addition.  You're left with an unversioned file.  If you
+            then attempt to run the merge again, you may get conflicts
+            due to the unversioned file <quote>being in the
+            way</quote>.  Solution?  After performing a revert, be
+            sure to clean up the working copy and remove unversioned
+            files and directories.  The output of <command>svn
+            status</command> should be as clean (read:  empty) as
+            possible!</para>
+        </tip>
+
       </sect3>
 
       <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
@@ -1060,9 +1200,8 @@
 Committed revision 350.
 </screen>
 
-      <para>One way to think about a repository revision is as a
-        specific group of changes (some version control systems call
-        these <firstterm>changesets</firstterm>).  By using the
+      <para>As we mentioned earlier, one way to think about a
+        repository revision is as a specific changeset.  By using the
         <option>-r</option> option, you can ask <command>svn
         merge</command> to apply a changeset, or whole range of
         changesets, to your working copy.  In our case of undoing a
@@ -1070,39 +1209,6 @@
         changeset #303 to our working copy
         <emphasis>backwards</emphasis>.</para>
 
-      <sidebar>
-        <title>Subversion and Changesets</title>
-
-        <para>Everyone seems to have a slightly different definition
-          of <quote>changeset</quote>, or at least a different
-          expectation of what it means for a version control system to
-          have <quote>changeset features</quote>.  For our purpose,
-          let's say that a changeset is just a collection of changes
-          with a unique name.  The changes might include textual edits
-          to file contents, modifications to tree structure, or tweaks
-          to metadata.  In more common speak, a changeset is just a
-          patch with a name you can refer to.</para>
-
-        <para>In Subversion, a global revision number N names a tree
-          in the repository: it's the way the repository looked after
-          the Nth commit.  It's also the name of an implicit
-          changeset: if you compare tree N with tree N-1, you can
-          derive the exact patch that was committed.  For this reason,
-          it's easy to think of <quote>revision N</quote> as not just
-          a tree, but a changeset as well.  If you use an issue
-          tracker to manage bugs, you can use the revision numbers to
-          refer to particular patches that fix bugs—for example,
-          <quote>this issue was fixed by revision 9238.</quote>.
-          Somebody can then run <command>svn log -r9238</command> to
-          read about the exact changeset which fixed the bug, and run
-          <command>svn diff -c 9238</command> to see the patch
-          itself.  And Subversion's <literal>merge</literal> command
-          also uses revision numbers.  You can merge specific changesets
-          from one branch to another by naming them in the merge
-          arguments: <command>svn merge -c 9238</command> would
-          merge changeset #9238 into your working copy.</para>
-      </sidebar>
-
       <para>Keep in mind that rolling back a change like this is just
         like any other <command>svn merge</command> operation, so you
         should use <command>svn status</command> and <command>svn




More information about the svnbook-dev mailing list