Check-in [2e275c1420]
Not logged in
Overview

SHA1 Hash:2e275c14202446fca2bb8a48a8d15ed82d9bbc33
Date: 2009-01-23 21:24:00
User: drh
Comment:First draft of the "branching" document.
Timelines: ancestors | descendants | both | trunk
Other Links: files | ZIP archive | manifest

Tags And Properties
Changes
[hide diffs]

Added art/branching.odp version [2b21dbbc28]

cannot compute difference between binary files

Added www/branch01.gif version [a288153196]

cannot compute difference between binary files

Added www/branch02.gif version [55c3567748]

cannot compute difference between binary files

Added www/branch03.gif version [3840bdbb5e]

cannot compute difference between binary files

Added www/branch04.gif version [908b4fc168]

cannot compute difference between binary files

Added www/branch05.gif version [4808cbf6e0]

cannot compute difference between binary files

Added www/branching.wiki version [55dd24e8cf]

@@ -1,1 +1,259 @@
+<h1 align="center">
+Branching, Forking, Merging, and Tagging
+</h1>
+
+In a simple and perfect world, the development of a project would proceed
+linearly, as shown in figure 1.
+
+<center><table border=1 cellpadding=10 hspace=10 vspace=10>
+<tr><td align="center">
+<img src="branch01.gif"><br>
+Figure 1
+</td></tr></table></center>
+
+Each circle represents a check-in.  For the sake of clarity, the check-ins
+are given small consecutive numbers.  In a real system, of course, the
+check-in numbers would be 40-character SHA1 hashes since it is not possible
+to allocate collision-free sequential numbers is a distributed system.
+But sequential numbers are easier to read, so we will substitute them for
+the 40-character SHA1 hashes in this document.
+
+The arrows in figure 1 show evolution of the project.  The initial
+check-in is 1.  Check-in 2 is derived from 1.  In other words, check-in 2
+was created by making edits to check-in 1 and then committing those edits.
+We say that 2 is a <i>child</i> of 1
+and that 1 is a <i>parent</i> of 2.
+Check-in 3 is derived from check-in 2, making
+3 a child of 2.  We say that 3 is a <i>descendant</i> of both 1 and 2 and that 1
+and 2 are both <i>ancestors</i> of 3.
+
+We call the graph of check-ins a <i>tree</i>.  Check-in 1 is the <i>root</i>
+since it has no ancestors.  Check-in 4 is a <i>leaf</i> of the tree since
+it has no descendants.
+
+Alas, reality often interferes with the simple linear development of a
+project.  Suppose two programmers make independent modifications to check-in 2.
+After both changes are checked in, we have a check-in graph that looks
+like figure 2:
+
+<center><table border=1 cellpadding=10 hspace=10 vspace=10>
+<tr><td align="center">
+<img src="branch02.gif"><br>
+Figure 2
+</td></tr></table></center>
+
+The graph in figure 2 has two leaves: check-ins 3 and 4.  Check-in 2 has
+two children, check-ins 3 and 4.  We call this stituation a <i>fork</i>.
+
+Fossil tries to prevent forks.  Suppose the two programmers who were
+editing check-in 2 are named Alice and Bob.  Suppose Alice finished her
+edits first and did a commit, resulting in check-in 3.  Later, when Bob
+tried to commit his changes, fossil would try to verify that check-in 2
+was still a leaf.  Fossil would see that check-in 3 had occurred and would
+abort Bob's commit attempt with a message "would fork".  This allows Bob
+to do a "fossil update" which would pull in Alices changes and merge them
+together with his own changes.  After merging, Bob could then commit
+check-in 4 as a child of check-in 3 and the result would be a linear graph
+as shown in figure 1.  This is how CVS works.  This is also how fossil
+works in "autosync" mode.
+
+But it might be that Bob is off-network when he does his commit, so he
+has no way of knowing that Alice has already committed her changes.
+Or, it could be that Bob has turned of "autosync" mode in SQLite.  Or,
+maybe Bob just doesn't want to merge in Alices changes before he has
+saved his own, so he forces the commit to occur using the "--force" option
+to the fossil <b>commit</b> command.  For whatever reason, two commits against
+check-in 2 have occurred and now the tree has two leaves.
+
+So which version of the project is the "latest" in the sense of having
+the most features and the most bug fixes?  When there is more than
+one leaf in the graph, you don't really know.  So we like to have
+graphs with a single leaf.
+
+To resolve this situation, Alice can use the fossil <b>merge</b> command
+to me merge in Bob's changes in here local copy of check-in 3.  Then she
+can commit the results as check-in 5.  This results in a tree as shown
+in figure 3.
+
+<center><table border=1 cellpadding=10 hspace=10 vspace=10>
+<tr><td align="center">
+<img src="branch03.gif"><br>
+Figure 3
+</td></tr></table></center>
+
+Check-in 5 is a direct child of check-in 3 because it was created by editing
+check-in 3.  But check-in 5 also inherits the changes from check-in 4 by
+virtual of the merge.  So we say that check-in 5 is a <i>merge child</i>
+of check-in 4 and that it is a <i>direct child</i> of check-in 3.
+The graph is now back to a single leaf (check-in 5).
+
+We have already seen that if fossil is in autosync mode then Bob would
+have been warned about the potential fork the first time he tried to
+commit check-in 4.  If Bob had updated his local check-out to merge in
+Alice's check-in 3 changes, then committed, then the fork would have
+never occurred.  The resulting graph would have been linear, as shown
+in figure 1.  Really the graph of figure 1 is a subset of figure 3.
+Hold your hand over the check-in 4 circle of figure 3 and then figure
+3 looks exactly like figure 1 (except that the leaf has a different check-in
+number, but that is just a notational difference - the two check-ins have
+exactly the same content).  In other words, figure 3 is really a superset
+of figure 1.  The check-in 4 of figure 3 captures addition state which
+is omitted from figure 1.  In check-in 4 of figure 3 is a copy
+of Bob's local checkout before he merged in Alices changes.  That snapshot
+of Bob's changes independent of Alice's changes is omitted from figure 1.
+Some people say that the approach taken in figure 3 is better because it
+preserves this extra intermediate state.  Others say that the approach
+taken in figure 1 is better because it is much easier to visualize a
+linear line of development and because the the merging happens automatically
+instead of as a separate manual step.  We will not take sides in this
+debate.  We will simply point out that fossil enables you to do it either way.
+
+<h2>Forking Versus Branching</h2>
+
+Forking and having more than one leaf in the check-in tree is usually
+considered undesirable, and so forks are usually quickly resolved as
+shown in figure 3 above.
+But sometimes, one does want to have multiple leaves.  For example, a project
+might have one leaf that is the latest version of the project under
+development and another leaf that is the latest version that has been
+tested.
+When multiple leaves are desirable, we call the phenomenon <i>branching</i>
+instead of <i>forking</i>.
+Figure 4 shows an example of a project where there are two branches, one
+for development work and another for testing.
+
+<center><table border=1 cellpadding=10 hspace=10 vspace=10>
+<tr><td align="center">
+<img src="branch04.gif"><br>
+Figure 4
+</td></tr></table></center>
+
+The hypothetical scenario of figure 4 is this:  The project starts and
+progresses to a point where (at check-in 2)
+it is ready to enter testing for its first release.
+In a real project, of course, there might be hundreds or thousands of
+check-ins before a project reaches this point, but for simplicity of
+presentation we will say that the project is ready after check-in 2.
+The project then splits into two branches that are used by separate
+teams.  The testing team, using the blue branch, finds and fixes a few
+bugs.  This is shown by check-ins 6 and 9.  Meanwhile the development
+team, working on the red branch, is busy adding features for the second
+release.  Of course, the development team would like to take advantage of
+the bug fixes implemented by the testing team.  So periodically, the
+changes in the test branch are merged into the dev branch.  This is
+shown by the dashed merge arrows between check-ins 6 and 7 and between
+check-ins 9 and 10.
+
+In both figures 2 and 4, check-in 2 has two children.  In figure 2,
+we called this a "fork".  In diagram 4, we call it a "branch".  What is
+the difference?  As far as the internal fossil data structure are
+concerned, there is no difference.  The distinction is in the intent.
+In figure 2, the fact that check-in 2 has multiple children is an
+accident that stems from concurrent development.  In figure 4, giving
+check-in 2 multiple children is a deliberate act.  So, to a good
+approximating, we define forking to be by accident and branching to
+be by intent.  Apart from that, they are the same.
+
+<h2>Tags And Properties</h2>
+
+Tags and properties are used in fossil to help express the intent, and
+thus to distinguish between forks and branches.  Figure 5 shows the
+same scenario as figure 4 but with tags and properties added:
+
+<center><table border=1 cellpadding=10 hspace=10 vspace=10>
+<tr><td align="center">
+<img src="branch05.gif"><br>
+Figure 5
+</td></tr></table></center>
+
+A <i>tag</i> is a name that is attached to a check-in.  A
+<i>property</i> is a name/value pair.  Internally, fossil implements
+tags as properties with a NULL value.  So, tags and properties really
+are much the same thing, and henceforth we will use the word "tag"
+to mean either a tag or a property.
+
+A tag can be either a one-time tag or an propagating tag or a cancellation.
+A one-time tag only applies to the check-in to which it is attached.  An
+propagating tag applies to the check-in to which it is attached and also
+to all direct descendants of that check-in.  A <i>direct descendant</i>
+is a descendant through direct children.  Tags propagation does not
+cross merges.  Tag propagation also stops as soon
+as it encounters another check-in with the same tag.  A cancellation tag
+is attached to a single check-in in order to either override a one-time
+tag that was placed on that same check-in, or to block tag propagation.
+
+Every repository is created with a single empty check-in that has two
+propagating tags.  In figure 5, that initial empty check-in is check-in 1.
+The <b>branch</b> tag tells (by its value)
+what branch the check-in is a member of.
+The default branch is called "trunk".  All tags that begin with "<b>sym-</b>"
+are symbolic name tags.  When a symbolic name tag is attached to a
+check-in, that allows you to refer to that check-in by its symbolic
+name rather than by its 40-character SHA1 hash name.  When a symbolic name
+tag propagates (as does the <b>sym-trunk</b> tag) then referring to that
+name is the same as referring to the most recent check-in with that name.
+Thus the two tags on check-in once cause all decendents to be in the
+"trunk" branch and to have the symbolic name "trunk".
+
+Check-in 4 has a <b>branch</b> tag which changes the name of the branch
+to "test".  The branch tag on check-in 4 propagates to check-ins 6 and 9.
+But because tag propagation does not follow merge links, the <b>branch=test</b>
+tag does not propagate to check-ins 7, 8, or 9.  Note also that the
+<b>branch</b> tag on check-in 4 blocks the propagation of <b>branch=trunk</b>
+so that it cannot reach check-ins 6 or 9.  This causes check-ins 4, 6, and
+9 to be in the "test" branch and all others to be in the "trunk" branch.
+
+Check-in 4 also has a <b>sym-test</b> tag, which gives the symbolic name
+"test" to check-ins 4, 6, and 9.  Because tags do not propagate across
+merges, check-ins 7, 8, and 9 do not inherit the <b>sym-test</b> tag and
+are hence not known by the name "test".
+To prevent the <b>sym-trunk</b> tag from propagating from check-in 1
+into check-ins 4, 6, and 9, there is a cancellation tag for
+<b>sym-trunk</b> on check-in 4.  The net effect of all of this is that
+check-ins on the trunk go by the symbolic name of "trunk" and check-ins
+that are on the test branch go by the symbolic name "test".
+
+The <b>bgcolor=blue</b> tag on check-in 4 causes the background color
+of timelines to be blue for check-in 4 and its descendants.
+
+Figure 5 also shows two one-time tags on check-in 9.  (The diagram does
+not make a graphical distinction between one-time and propagating tags.)
+The <b>sym-release-1.0</b> tag means that check-in 9 can be referred to
+using the more meaningful name "release-1.0".  The <b>closed</b> tag means
+that check-in 9 is a "closed leaf".  A closed leaf is a leaf that intended
+to never have any childred.
+
+<h2>Review Of Terminology</h2>
+
+Here is a list of definitions of key terms:
+
+
+<blockquote><dl>
+<dt><b>Branch</b></dt>
+<dd><p>A branch is a set of check-ins that have the same value for their
+<dt><b>Leaf</b></dt>
+<dd><p>A leaf is a check-in that has no children in the same branch.</p></dd>
+<dt><b>Closed Leaf</b></dt>
+<dd><p>A closed leaf is leaf that has the <b>closed</b> tag.  Such leaves
+are intented to never be extended with descendents and hence are omitted
+from lists of leaves in the command-line and web interface.</p></dd>
+<dt><b>Open Leaf</b></dt>
+<dd><p>A open leaf is a leaf that is not closed.</p></dd>
+<dt><b>Fork</b></dt>
+<dd><p>A fork occurs when a check-in has two or more direct (non-merge)
+children in the same branch.</p></dd>
+<dt><b>Branch Point</b></dt>
+<dd><p>A branch point occurs when a check-in has two or more direct (non-merge)
+children in the different branches.  A branch point is similar to a fork,
+except that the children are in different branches.</p></dd>
+</dl></blockquote>
+
+Check-in 4 of figure 3 is not a leaf because it has a child (check-in 5)
+in the same branch.  Check-in 9 of figure 5 also has a child (check-in 10)
+but that child is in a different branch, so check-in 9 is a leaf.  Because
+of the <b>closed</b> tag check-in 9, it is a closed leaf.
 
+Check-in 2 of figure 3 is considered a "fork"
+because it has two children in the same branch.  Check-in 2 of figure 5
+also has two children, but each child is in a different branch, hence in
+figure 5, check-in 2 is considered a "branch point".

Modified www/concepts.wiki from [414be747ce] to [e17c6aa709].

@@ -212,13 +212,13 @@
 <img src="concept2.gif" align="right" hspace="10">
 
 <p>Fossil has two modes of operation: "autosync" and "non-autosync".
 Autosync mode works something like CVS or SVN in that it automatically
 keeps your work in sync with the central server.  Non-autosync is
-more like GIT, or Bitkeeper in that your local repository develops
+more like GIT or Bitkeeper in that your local repository develops
 independently of your coworkers and you share your changes manually.
-The interesting thing about fossil is that it supports both autosync
+An interesting feature of fossil is that it supports both autosync
 and non-autosync work flows.</p>
 
 <p>The default setting for fossil is to be in autosync mode.  You
 can change the autosync setting or check the current autosync
 setting using commands like:</p>
@@ -382,10 +382,16 @@
 <p>A stand-alone server is a great way to set of transient connections
 between coworkers for doing quick pushes or pulls.  But you can also
 set up a permanent stand-alone server if you prefer.  Just make
 arrangements for fossil to be launched with appropriate arguments
 after every reboot.</p>
+
+<p>If you just want a server to browse the built-in fossil website
+locally, use the <b>ui</b> command in place of <b>server</b>.  The
+<b>ui</b> command starts up a local server too, but it also takes
+the additional step of automatically launching your webbrowser and
+pointing at the new server.</p>
 </li>
 
 <li><p><b>Setting up a CGI server</b></p>
 
 <p>If you have a webserver running on your machine already, you can

Modified www/index.wiki from [635e17dfd6] to [b5ddee628e].

@@ -58,10 +58,12 @@
   *  The [./concepts.wiki | concepts] behind fossil
   *  [./build.wiki | Building And Installing]
   *  [./quickstart.wiki | Quick Start] guide to using fossil
   *  Fossil supports [./embeddeddoc.wiki | embedded documentation]
      that is versioned along with project source code.
+  *  A tutorial on [./branching.wiki | branching], what it means and how
+     to do it using fossil.
   *  The [./selfcheck.wiki | automatic self-check] mechanism
      helps insure project integrity.
   *  Fossil contains a [./wikitheory.wiki | built-in wiki].
   *  There is a
     [http://lists.fossil-scm.org:8080/cgi-bin/mailman/listinfo/fossil-users | mailing list]