Fossil SCM
Updates to the "branching.wiki" document.
Commit
d06396d31d361e13f361f6fa86b14c994973f32e
Parent
9301375f3e9a35e…
1 file changed
+48
-53
+48
-53
| --- www/branching.wiki | ||
| +++ www/branching.wiki | ||
| @@ -11,15 +11,15 @@ | ||
| 11 | 11 | </td></tr></table></center> |
| 12 | 12 | |
| 13 | 13 | Each circle represents a check-in. For the sake of clarity, the check-ins |
| 14 | 14 | are given small consecutive numbers. In a real system, of course, the |
| 15 | 15 | check-in numbers would be 40-character SHA1 hashes since it is not possible |
| 16 | -to allocate collision-free sequential numbers is a distributed system. | |
| 17 | -But sequential numbers are easier to read, so we will substitute them for | |
| 16 | +to allocate collision-free sequential numbers in a distributed system. | |
| 17 | +But as sequential numbers are easier to read, we will substitute them for | |
| 18 | 18 | the 40-character SHA1 hashes in this document. |
| 19 | 19 | |
| 20 | -The arrows in figure 1 show evolution of the project. The initial | |
| 20 | +The arrows in figure 1 show the evolution of a project. The initial | |
| 21 | 21 | check-in is 1. Check-in 2 is derived from 1. In other words, check-in 2 |
| 22 | 22 | was created by making edits to check-in 1 and then committing those edits. |
| 23 | 23 | We say that 2 is a <i>child</i> of 1 |
| 24 | 24 | and that 1 is a <i>parent</i> of 2. |
| 25 | 25 | Check-in 3 is derived from check-in 2, making |
| @@ -29,48 +29,46 @@ | ||
| 29 | 29 | <a name="dag"></a> |
| 30 | 30 | <h2>DAGs</h2> |
| 31 | 31 | |
| 32 | 32 | The graph of check-ins is a |
| 33 | 33 | [http://en.wikipedia.org/wiki/Directed_acyclic_graph | directed acyclic graph] |
| 34 | -and so we will | |
| 35 | -henceforth call it a <i>DAG</i>. Check-in 1 is the <i>root</i> of the DAG | |
| 34 | +commonly shortened to <i>DAG</i>. Check-in 1 is the <i>root</i> of the DAG | |
| 36 | 35 | since it has no ancestors. Check-in 4 is a <i>leaf</i> of the DAG since |
| 37 | -it has no descendants. (We will give a more precise in the definition of | |
| 38 | -"leaf" later.) | |
| 36 | +it has no descendants. (We will give a more precise definition later of | |
| 37 | +"leaf.") | |
| 39 | 38 | |
| 40 | 39 | Alas, reality often interferes with the simple linear development of a |
| 41 | 40 | project. Suppose two programmers make independent modifications to check-in 2. |
| 42 | -After both changes are checked in, we have a check-in graph that looks | |
| 43 | -like figure 2: | |
| 41 | +After both changes are committed, the check-in graph looks like figure 2: | |
| 44 | 42 | |
| 45 | 43 | <center><table border=1 cellpadding=10 hspace=10 vspace=10> |
| 46 | 44 | <tr><td align="center"> |
| 47 | 45 | <img src="branch02.gif" width=210 height=140><br> |
| 48 | 46 | Figure 2 |
| 49 | 47 | </td></tr></table></center> |
| 50 | 48 | |
| 51 | 49 | The graph in figure 2 has two leaves: check-ins 3 and 4. Check-in 2 has |
| 52 | -two children, check-ins 3 and 4. We call this stituation a <i>fork</i>. | |
| 53 | - | |
| 54 | -Fossil tries to prevent forks. Suppose the two programmers who were | |
| 55 | -editing check-in 2 are named Alice and Bob. Suppose Alice finished her | |
| 56 | -edits first and did a commit, resulting in check-in 3. Later, when Bob | |
| 57 | -tried to commit his changes, fossil would try to verify that check-in 2 | |
| 58 | -was still a leaf. Fossil would see that check-in 3 had occurred and would | |
| 59 | -abort Bob's commit attempt with a message "would fork". This allows Bob | |
| 60 | -to do a "fossil update" which would pull in Alice's changes and merge them | |
| 61 | -together with his own changes. After merging, Bob could then commit | |
| 62 | -check-in 4 as a child of check-in 3 and the result would be a linear graph | |
| 63 | -as shown in figure 1. This is how CVS works. This is also how fossil | |
| 64 | -works in [concepts.wiki#workflow | "autosync"] mode. | |
| 65 | - | |
| 66 | -But it might be that Bob is off-network when he does his commit, so he | |
| 50 | +two children, check-ins 3 and 4. We call this state a <i>fork</i>. | |
| 51 | + | |
| 52 | +Fossil tries to prevent forks. Suppose two programmers named Alice and | |
| 53 | +Bob are each editing check-in 2 separately. Alice finishes her edits | |
| 54 | +first and commits her changes, resulting in check-in 3. Later, when Bob | |
| 55 | +attempts to commit his changes, fossil verifies that check-in 2 is still | |
| 56 | +a leaf. Fossil sees that check-in 3 has occurred and aborts Bob's commit | |
| 57 | +attempt with a message "would fork." This allows Bob to do a "fossil | |
| 58 | +update" which pulls in Alice's changes, merging them into his own | |
| 59 | +changes. After merging, Bob commits check-in 4 as a child of check-in 3. | |
| 60 | +The result is a linear graph as shown in figure 1. This is how CVS | |
| 61 | +works. This is also how fossil works in [concepts.wiki#workflow | | |
| 62 | +"autosync"] mode. | |
| 63 | + | |
| 64 | +But perhaps Bob is off-network when he does his commit, so he | |
| 67 | 65 | has no way of knowing that Alice has already committed her changes. |
| 68 | 66 | Or, it could be that Bob has turned off "autosync" mode in Fossil. Or, |
| 69 | 67 | maybe Bob just doesn't want to merge in Alice's changes before he has |
| 70 | 68 | saved his own, so he forces the commit to occur using the "--force" option |
| 71 | -to the fossil <b>commit</b> command. For whatever reason, two commits against | |
| 69 | +to the fossil <b>commit</b> command. For any of these reasons, two commits against | |
| 72 | 70 | check-in 2 have occurred and now the DAG has two leaves. |
| 73 | 71 | |
| 74 | 72 | So which version of the project is the "latest" in the sense of having |
| 75 | 73 | the most features and the most bug fixes? When there is more than |
| 76 | 74 | one leaf in the graph, you don't really know. So we like to have |
| @@ -101,31 +99,31 @@ | ||
| 101 | 99 | in figure 1. Really the graph of figure 1 is a subset of figure 3. |
| 102 | 100 | Hold your hand over the check-in 4 circle of figure 3 and then figure |
| 103 | 101 | 3 looks exactly like figure 1 (except that the leaf has a different check-in |
| 104 | 102 | number, but that is just a notational difference - the two check-ins have |
| 105 | 103 | exactly the same content). In other words, figure 3 is really a superset |
| 106 | -of figure 1. The check-in 4 of figure 3 captures addition state which | |
| 104 | +of figure 1. The check-in 4 of figure 3 captures additional state which | |
| 107 | 105 | is omitted from figure 1. Check-in 4 of figure 3 holds a copy |
| 108 | 106 | of Bob's local checkout before he merged in Alice's changes. That snapshot |
| 109 | -of Bob's changes independent of Alice's changes is omitted from figure 1. | |
| 107 | +of Bob's changes, which is independent of Alice's changes, is omitted from figure 1. | |
| 110 | 108 | Some people say that the approach taken in figure 3 is better because it |
| 111 | 109 | preserves this extra intermediate state. Others say that the approach |
| 112 | 110 | taken in figure 1 is better because it is much easier to visualize a |
| 113 | 111 | linear line of development and because the merging happens automatically |
| 114 | 112 | instead of as a separate manual step. We will not take sides in that |
| 115 | 113 | debate. We will simply point out that fossil enables you to do it either way. |
| 116 | 114 | |
| 117 | 115 | <h2>Forking Versus Branching</h2> |
| 118 | 116 | |
| 119 | -Having more than one leaf in the check-in DAG is usually | |
| 120 | -considered undesirable, and so forks are usually either avoided entirely, | |
| 117 | +Having more than one leaf in the check-in DAG is called a "fork." This | |
| 118 | +is usually undesirable and either avoided entirely, | |
| 121 | 119 | as in figure 1, or else quickly resolved as shown in figure 3. |
| 122 | 120 | But sometimes, one does want to have multiple leaves. For example, a project |
| 123 | 121 | might have one leaf that is the latest version of the project under |
| 124 | 122 | development and another leaf that is the latest version that has been |
| 125 | 123 | tested. |
| 126 | -When multiple leaves are desirable, we call the phenomenon <i>branching</i> | |
| 124 | +When multiple leaves are desirable, we call this <i>branching</i> | |
| 127 | 125 | instead of <i>forking</i>. |
| 128 | 126 | Figure 4 shows an example of a project where there are two branches, one |
| 129 | 127 | for development work and another for testing. |
| 130 | 128 | |
| 131 | 129 | <center><table border=1 cellpadding=10 hspace=10 vspace=10> |
| @@ -150,11 +148,11 @@ | ||
| 150 | 148 | changes in the test branch are merged into the dev branch. This is |
| 151 | 149 | shown by the dashed merge arrows between check-ins 6 and 7 and between |
| 152 | 150 | check-ins 9 and 10. |
| 153 | 151 | |
| 154 | 152 | In both figures 2 and 4, check-in 2 has two children. In figure 2, |
| 155 | -we called this a "fork". In diagram 4, we call it a "branch". What is | |
| 153 | +we call this a "fork." In diagram 4, we call it a "branch." What is | |
| 156 | 154 | the difference? As far as the internal fossil data structures are |
| 157 | 155 | concerned, there is no difference. The distinction is in the intent. |
| 158 | 156 | In figure 2, the fact that check-in 2 has multiple children is an |
| 159 | 157 | accident that stems from concurrent development. In figure 4, giving |
| 160 | 158 | check-in 2 multiple children is a deliberate act. So, to a good |
| @@ -193,85 +191,82 @@ | ||
| 193 | 191 | |
| 194 | 192 | Every repository is created with a single empty check-in that has two |
| 195 | 193 | propagating tags. In figure 5, that initial empty check-in is check-in 1. |
| 196 | 194 | The <b>branch</b> tag tells (by its value) |
| 197 | 195 | what branch the check-in is a member of. |
| 198 | -The default branch is called "trunk". All tags that begin with "<b>sym-</b>" | |
| 196 | +The default branch is called "trunk." All tags that begin with "<b>sym-</b>" | |
| 199 | 197 | are symbolic name tags. When a symbolic name tag is attached to a |
| 200 | 198 | check-in, that allows you to refer to that check-in by its symbolic |
| 201 | 199 | name rather than by its 40-character SHA1 hash name. When a symbolic name |
| 202 | 200 | tag propagates (as does the <b>sym-trunk</b> tag) then referring to that |
| 203 | 201 | name is the same as referring to the most recent check-in with that name. |
| 204 | -Thus the two tags on check-in one cause all descendants to be in the | |
| 205 | -"trunk" branch and to have the symbolic name "trunk". | |
| 202 | +Thus the two tags on check-in 1 cause all descendants to be in the | |
| 203 | +"trunk" branch and to have the symbolic name "trunk." | |
| 206 | 204 | |
| 207 | 205 | Check-in 4 has a <b>branch</b> tag which changes the name of the branch |
| 208 | -to "test". The branch tag on check-in 4 propagates to check-ins 6 and 9. | |
| 206 | +to "test." The branch tag on check-in 4 propagates to check-ins 6 and 9. | |
| 209 | 207 | But because tag propagation does not follow merge links, the <b>branch=test</b> |
| 210 | 208 | tag does not propagate to check-ins 7, 8, or 10. Note also that the |
| 211 | 209 | <b>branch</b> tag on check-in 4 blocks the propagation of <b>branch=trunk</b> |
| 212 | 210 | so that it cannot reach check-ins 6 or 9. This causes check-ins 4, 6, and |
| 213 | 211 | 9 to be in the "test" branch and all others to be in the "trunk" branch. |
| 214 | 212 | |
| 215 | 213 | Check-in 4 also has a <b>sym-test</b> tag, which gives the symbolic name |
| 216 | 214 | "test" to check-ins 4, 6, and 9. Because tags do not propagate across |
| 217 | 215 | merges, check-ins 7, 8, and 10 do not inherit the <b>sym-test</b> tag and |
| 218 | -are hence not known by the name "test". | |
| 216 | +are hence not known by the name "test." | |
| 219 | 217 | To prevent the <b>sym-trunk</b> tag from propagating from check-in 1 |
| 220 | 218 | into check-ins 4, 6, and 9, there is a cancellation tag for |
| 221 | -<b>sym-trunk</b> on check-in 4. The net effect of all of this is that | |
| 219 | +<b>sym-trunk</b> on check-in 4. The net effect is that | |
| 222 | 220 | check-ins on the trunk go by the symbolic name of "trunk" and check-ins |
| 223 | -that are on the test branch go by the symbolic name "test". | |
| 221 | +on the test branch go by the symbolic name "test." | |
| 224 | 222 | |
| 225 | 223 | The <b>bgcolor=blue</b> tag on check-in 4 causes the background color |
| 226 | 224 | of timelines to be blue for check-in 4 and its direct descendants. |
| 227 | 225 | |
| 228 | 226 | Figure 5 also shows two one-time tags on check-in 9. (The diagram does |
| 229 | 227 | not make a graphical distinction between one-time and propagating tags.) |
| 230 | 228 | The <b>sym-release-1.0</b> tag means that check-in 9 can be referred to |
| 231 | -using the more meaningful name "release-1.0". The <b>closed</b> tag means | |
| 232 | -that check-in 9 is a "closed leaf". A closed leaf is a leaf that intended | |
| 233 | -to never have any direct children. | |
| 229 | +using the more meaningful name "release-1.0." The <b>closed</b> tag means | |
| 230 | +that check-in 9 is a "closed leaf." A closed leaf is a leaf that should | |
| 231 | +never have direct children. | |
| 234 | 232 | |
| 235 | 233 | <h2>Review Of Terminology</h2> |
| 236 | - | |
| 237 | -Here is a list of definitions of key terms: | |
| 238 | - | |
| 239 | 234 | |
| 240 | 235 | <blockquote><dl> |
| 241 | 236 | <dt><b>Branch</b></dt> |
| 242 | -<dd><p>A branch is a set of check-ins that have the same value for their | |
| 237 | +<dd><p>A branch is a set of check-ins with the same value for their | |
| 243 | 238 | "branch" property.</p></dd> |
| 244 | 239 | <dt><b>Leaf</b></dt> |
| 245 | -<dd><p>A leaf is a check-in that has no children in the same branch.</p></dd> | |
| 240 | +<dd><p>A leaf is a check-in with no children in the same branch.</p></dd> | |
| 246 | 241 | <dt><b>Closed Leaf</b></dt> |
| 247 | -<dd><p>A closed leaf is leaf that has the <b>closed</b> tag. Such leaves | |
| 248 | -are intented to never be extended with descendants and hence are omitted | |
| 242 | +<dd><p>A closed leaf is any leaf with the <b>closed</b> tag. These leaves | |
| 243 | +are intended to never be extended with descendants and hence are omitted | |
| 249 | 244 | from lists of leaves in the command-line and web interface.</p></dd> |
| 250 | 245 | <dt><b>Open Leaf</b></dt> |
| 251 | 246 | <dd><p>A open leaf is a leaf that is not closed.</p></dd> |
| 252 | 247 | <dt><b>Fork</b></dt> |
| 253 | -<dd><p>A fork occurs when a check-in has two or more direct (non-merge) | |
| 248 | +<dd><p>A fork is when a check-in has two or more direct (non-merge) | |
| 254 | 249 | children in the same branch.</p></dd> |
| 255 | 250 | <dt><b>Branch Point</b></dt> |
| 256 | 251 | <dd><p>A branch point occurs when a check-in has two or more direct (non-merge) |
| 257 | -children in the different branches. A branch point is similar to a fork, | |
| 252 | +children in different branches. A branch point is similar to a fork, | |
| 258 | 253 | except that the children are in different branches.</p></dd> |
| 259 | 254 | </dl></blockquote> |
| 260 | 255 | |
| 261 | 256 | Check-in 4 of figure 3 is not a leaf because it has a child (check-in 5) |
| 262 | 257 | in the same branch. Check-in 9 of figure 5 also has a child (check-in 10) |
| 263 | 258 | but that child is in a different branch, so check-in 9 is a leaf. Because |
| 264 | -of the <b>closed</b> tag check-in 9, it is a closed leaf. | |
| 259 | +of the <b>closed</b> tag on check-in 9, it is a closed leaf. | |
| 265 | 260 | |
| 266 | 261 | Check-in 2 of figure 3 is considered a "fork" |
| 267 | 262 | because it has two children in the same branch. Check-in 2 of figure 5 |
| 268 | 263 | also has two children, but each child is in a different branch, hence in |
| 269 | -figure 5, check-in 2 is considered a "branch point". | |
| 264 | +figure 5, check-in 2 is considered a "branch point." | |
| 270 | 265 | |
| 271 | 266 | <h2>Differences With Other DVCSes</h2> |
| 272 | 267 | |
| 273 | 268 | Fossil keeps all check-ins on a single DAG. Branches are identified with |
| 274 | 269 | tags. This means that check-ins can be freely moved between branches |
| 275 | -simply by altering the tags. | |
| 270 | +simply by altering their tags. | |
| 276 | 271 | |
| 277 | 272 | Most other DVCSes maintain a separate DAG for each branch. |
| 278 | 273 |
| --- www/branching.wiki | |
| +++ www/branching.wiki | |
| @@ -11,15 +11,15 @@ | |
| 11 | </td></tr></table></center> |
| 12 | |
| 13 | Each circle represents a check-in. For the sake of clarity, the check-ins |
| 14 | are given small consecutive numbers. In a real system, of course, the |
| 15 | check-in numbers would be 40-character SHA1 hashes since it is not possible |
| 16 | to allocate collision-free sequential numbers is a distributed system. |
| 17 | But sequential numbers are easier to read, so we will substitute them for |
| 18 | the 40-character SHA1 hashes in this document. |
| 19 | |
| 20 | The arrows in figure 1 show evolution of the project. The initial |
| 21 | check-in is 1. Check-in 2 is derived from 1. In other words, check-in 2 |
| 22 | was created by making edits to check-in 1 and then committing those edits. |
| 23 | We say that 2 is a <i>child</i> of 1 |
| 24 | and that 1 is a <i>parent</i> of 2. |
| 25 | Check-in 3 is derived from check-in 2, making |
| @@ -29,48 +29,46 @@ | |
| 29 | <a name="dag"></a> |
| 30 | <h2>DAGs</h2> |
| 31 | |
| 32 | The graph of check-ins is a |
| 33 | [http://en.wikipedia.org/wiki/Directed_acyclic_graph | directed acyclic graph] |
| 34 | and so we will |
| 35 | henceforth call it a <i>DAG</i>. Check-in 1 is the <i>root</i> of the DAG |
| 36 | since it has no ancestors. Check-in 4 is a <i>leaf</i> of the DAG since |
| 37 | it has no descendants. (We will give a more precise in the definition of |
| 38 | "leaf" later.) |
| 39 | |
| 40 | Alas, reality often interferes with the simple linear development of a |
| 41 | project. Suppose two programmers make independent modifications to check-in 2. |
| 42 | After both changes are checked in, we have a check-in graph that looks |
| 43 | like figure 2: |
| 44 | |
| 45 | <center><table border=1 cellpadding=10 hspace=10 vspace=10> |
| 46 | <tr><td align="center"> |
| 47 | <img src="branch02.gif" width=210 height=140><br> |
| 48 | Figure 2 |
| 49 | </td></tr></table></center> |
| 50 | |
| 51 | The graph in figure 2 has two leaves: check-ins 3 and 4. Check-in 2 has |
| 52 | two children, check-ins 3 and 4. We call this stituation a <i>fork</i>. |
| 53 | |
| 54 | Fossil tries to prevent forks. Suppose the two programmers who were |
| 55 | editing check-in 2 are named Alice and Bob. Suppose Alice finished her |
| 56 | edits first and did a commit, resulting in check-in 3. Later, when Bob |
| 57 | tried to commit his changes, fossil would try to verify that check-in 2 |
| 58 | was still a leaf. Fossil would see that check-in 3 had occurred and would |
| 59 | abort Bob's commit attempt with a message "would fork". This allows Bob |
| 60 | to do a "fossil update" which would pull in Alice's changes and merge them |
| 61 | together with his own changes. After merging, Bob could then commit |
| 62 | check-in 4 as a child of check-in 3 and the result would be a linear graph |
| 63 | as shown in figure 1. This is how CVS works. This is also how fossil |
| 64 | works in [concepts.wiki#workflow | "autosync"] mode. |
| 65 | |
| 66 | But it might be that Bob is off-network when he does his commit, so he |
| 67 | has no way of knowing that Alice has already committed her changes. |
| 68 | Or, it could be that Bob has turned off "autosync" mode in Fossil. Or, |
| 69 | maybe Bob just doesn't want to merge in Alice's changes before he has |
| 70 | saved his own, so he forces the commit to occur using the "--force" option |
| 71 | to the fossil <b>commit</b> command. For whatever reason, two commits against |
| 72 | check-in 2 have occurred and now the DAG has two leaves. |
| 73 | |
| 74 | So which version of the project is the "latest" in the sense of having |
| 75 | the most features and the most bug fixes? When there is more than |
| 76 | one leaf in the graph, you don't really know. So we like to have |
| @@ -101,31 +99,31 @@ | |
| 101 | in figure 1. Really the graph of figure 1 is a subset of figure 3. |
| 102 | Hold your hand over the check-in 4 circle of figure 3 and then figure |
| 103 | 3 looks exactly like figure 1 (except that the leaf has a different check-in |
| 104 | number, but that is just a notational difference - the two check-ins have |
| 105 | exactly the same content). In other words, figure 3 is really a superset |
| 106 | of figure 1. The check-in 4 of figure 3 captures addition state which |
| 107 | is omitted from figure 1. Check-in 4 of figure 3 holds a copy |
| 108 | of Bob's local checkout before he merged in Alice's changes. That snapshot |
| 109 | of Bob's changes independent of Alice's changes is omitted from figure 1. |
| 110 | Some people say that the approach taken in figure 3 is better because it |
| 111 | preserves this extra intermediate state. Others say that the approach |
| 112 | taken in figure 1 is better because it is much easier to visualize a |
| 113 | linear line of development and because the merging happens automatically |
| 114 | instead of as a separate manual step. We will not take sides in that |
| 115 | debate. We will simply point out that fossil enables you to do it either way. |
| 116 | |
| 117 | <h2>Forking Versus Branching</h2> |
| 118 | |
| 119 | Having more than one leaf in the check-in DAG is usually |
| 120 | considered undesirable, and so forks are usually either avoided entirely, |
| 121 | as in figure 1, or else quickly resolved as shown in figure 3. |
| 122 | But sometimes, one does want to have multiple leaves. For example, a project |
| 123 | might have one leaf that is the latest version of the project under |
| 124 | development and another leaf that is the latest version that has been |
| 125 | tested. |
| 126 | When multiple leaves are desirable, we call the phenomenon <i>branching</i> |
| 127 | instead of <i>forking</i>. |
| 128 | Figure 4 shows an example of a project where there are two branches, one |
| 129 | for development work and another for testing. |
| 130 | |
| 131 | <center><table border=1 cellpadding=10 hspace=10 vspace=10> |
| @@ -150,11 +148,11 @@ | |
| 150 | changes in the test branch are merged into the dev branch. This is |
| 151 | shown by the dashed merge arrows between check-ins 6 and 7 and between |
| 152 | check-ins 9 and 10. |
| 153 | |
| 154 | In both figures 2 and 4, check-in 2 has two children. In figure 2, |
| 155 | we called this a "fork". In diagram 4, we call it a "branch". What is |
| 156 | the difference? As far as the internal fossil data structures are |
| 157 | concerned, there is no difference. The distinction is in the intent. |
| 158 | In figure 2, the fact that check-in 2 has multiple children is an |
| 159 | accident that stems from concurrent development. In figure 4, giving |
| 160 | check-in 2 multiple children is a deliberate act. So, to a good |
| @@ -193,85 +191,82 @@ | |
| 193 | |
| 194 | Every repository is created with a single empty check-in that has two |
| 195 | propagating tags. In figure 5, that initial empty check-in is check-in 1. |
| 196 | The <b>branch</b> tag tells (by its value) |
| 197 | what branch the check-in is a member of. |
| 198 | The default branch is called "trunk". All tags that begin with "<b>sym-</b>" |
| 199 | are symbolic name tags. When a symbolic name tag is attached to a |
| 200 | check-in, that allows you to refer to that check-in by its symbolic |
| 201 | name rather than by its 40-character SHA1 hash name. When a symbolic name |
| 202 | tag propagates (as does the <b>sym-trunk</b> tag) then referring to that |
| 203 | name is the same as referring to the most recent check-in with that name. |
| 204 | Thus the two tags on check-in one cause all descendants to be in the |
| 205 | "trunk" branch and to have the symbolic name "trunk". |
| 206 | |
| 207 | Check-in 4 has a <b>branch</b> tag which changes the name of the branch |
| 208 | to "test". The branch tag on check-in 4 propagates to check-ins 6 and 9. |
| 209 | But because tag propagation does not follow merge links, the <b>branch=test</b> |
| 210 | tag does not propagate to check-ins 7, 8, or 10. Note also that the |
| 211 | <b>branch</b> tag on check-in 4 blocks the propagation of <b>branch=trunk</b> |
| 212 | so that it cannot reach check-ins 6 or 9. This causes check-ins 4, 6, and |
| 213 | 9 to be in the "test" branch and all others to be in the "trunk" branch. |
| 214 | |
| 215 | Check-in 4 also has a <b>sym-test</b> tag, which gives the symbolic name |
| 216 | "test" to check-ins 4, 6, and 9. Because tags do not propagate across |
| 217 | merges, check-ins 7, 8, and 10 do not inherit the <b>sym-test</b> tag and |
| 218 | are hence not known by the name "test". |
| 219 | To prevent the <b>sym-trunk</b> tag from propagating from check-in 1 |
| 220 | into check-ins 4, 6, and 9, there is a cancellation tag for |
| 221 | <b>sym-trunk</b> on check-in 4. The net effect of all of this is that |
| 222 | check-ins on the trunk go by the symbolic name of "trunk" and check-ins |
| 223 | that are on the test branch go by the symbolic name "test". |
| 224 | |
| 225 | The <b>bgcolor=blue</b> tag on check-in 4 causes the background color |
| 226 | of timelines to be blue for check-in 4 and its direct descendants. |
| 227 | |
| 228 | Figure 5 also shows two one-time tags on check-in 9. (The diagram does |
| 229 | not make a graphical distinction between one-time and propagating tags.) |
| 230 | The <b>sym-release-1.0</b> tag means that check-in 9 can be referred to |
| 231 | using the more meaningful name "release-1.0". The <b>closed</b> tag means |
| 232 | that check-in 9 is a "closed leaf". A closed leaf is a leaf that intended |
| 233 | to never have any direct children. |
| 234 | |
| 235 | <h2>Review Of Terminology</h2> |
| 236 | |
| 237 | Here is a list of definitions of key terms: |
| 238 | |
| 239 | |
| 240 | <blockquote><dl> |
| 241 | <dt><b>Branch</b></dt> |
| 242 | <dd><p>A branch is a set of check-ins that have the same value for their |
| 243 | "branch" property.</p></dd> |
| 244 | <dt><b>Leaf</b></dt> |
| 245 | <dd><p>A leaf is a check-in that has no children in the same branch.</p></dd> |
| 246 | <dt><b>Closed Leaf</b></dt> |
| 247 | <dd><p>A closed leaf is leaf that has the <b>closed</b> tag. Such leaves |
| 248 | are intented to never be extended with descendants and hence are omitted |
| 249 | from lists of leaves in the command-line and web interface.</p></dd> |
| 250 | <dt><b>Open Leaf</b></dt> |
| 251 | <dd><p>A open leaf is a leaf that is not closed.</p></dd> |
| 252 | <dt><b>Fork</b></dt> |
| 253 | <dd><p>A fork occurs when a check-in has two or more direct (non-merge) |
| 254 | children in the same branch.</p></dd> |
| 255 | <dt><b>Branch Point</b></dt> |
| 256 | <dd><p>A branch point occurs when a check-in has two or more direct (non-merge) |
| 257 | children in the different branches. A branch point is similar to a fork, |
| 258 | except that the children are in different branches.</p></dd> |
| 259 | </dl></blockquote> |
| 260 | |
| 261 | Check-in 4 of figure 3 is not a leaf because it has a child (check-in 5) |
| 262 | in the same branch. Check-in 9 of figure 5 also has a child (check-in 10) |
| 263 | but that child is in a different branch, so check-in 9 is a leaf. Because |
| 264 | of the <b>closed</b> tag check-in 9, it is a closed leaf. |
| 265 | |
| 266 | Check-in 2 of figure 3 is considered a "fork" |
| 267 | because it has two children in the same branch. Check-in 2 of figure 5 |
| 268 | also has two children, but each child is in a different branch, hence in |
| 269 | figure 5, check-in 2 is considered a "branch point". |
| 270 | |
| 271 | <h2>Differences With Other DVCSes</h2> |
| 272 | |
| 273 | Fossil keeps all check-ins on a single DAG. Branches are identified with |
| 274 | tags. This means that check-ins can be freely moved between branches |
| 275 | simply by altering the tags. |
| 276 | |
| 277 | Most other DVCSes maintain a separate DAG for each branch. |
| 278 |
| --- www/branching.wiki | |
| +++ www/branching.wiki | |
| @@ -11,15 +11,15 @@ | |
| 11 | </td></tr></table></center> |
| 12 | |
| 13 | Each circle represents a check-in. For the sake of clarity, the check-ins |
| 14 | are given small consecutive numbers. In a real system, of course, the |
| 15 | check-in numbers would be 40-character SHA1 hashes since it is not possible |
| 16 | to allocate collision-free sequential numbers in a distributed system. |
| 17 | But as sequential numbers are easier to read, we will substitute them for |
| 18 | the 40-character SHA1 hashes in this document. |
| 19 | |
| 20 | The arrows in figure 1 show the evolution of a project. The initial |
| 21 | check-in is 1. Check-in 2 is derived from 1. In other words, check-in 2 |
| 22 | was created by making edits to check-in 1 and then committing those edits. |
| 23 | We say that 2 is a <i>child</i> of 1 |
| 24 | and that 1 is a <i>parent</i> of 2. |
| 25 | Check-in 3 is derived from check-in 2, making |
| @@ -29,48 +29,46 @@ | |
| 29 | <a name="dag"></a> |
| 30 | <h2>DAGs</h2> |
| 31 | |
| 32 | The graph of check-ins is a |
| 33 | [http://en.wikipedia.org/wiki/Directed_acyclic_graph | directed acyclic graph] |
| 34 | commonly shortened to <i>DAG</i>. Check-in 1 is the <i>root</i> of the DAG |
| 35 | since it has no ancestors. Check-in 4 is a <i>leaf</i> of the DAG since |
| 36 | it has no descendants. (We will give a more precise definition later of |
| 37 | "leaf.") |
| 38 | |
| 39 | Alas, reality often interferes with the simple linear development of a |
| 40 | project. Suppose two programmers make independent modifications to check-in 2. |
| 41 | After both changes are committed, the check-in graph looks like figure 2: |
| 42 | |
| 43 | <center><table border=1 cellpadding=10 hspace=10 vspace=10> |
| 44 | <tr><td align="center"> |
| 45 | <img src="branch02.gif" width=210 height=140><br> |
| 46 | Figure 2 |
| 47 | </td></tr></table></center> |
| 48 | |
| 49 | The graph in figure 2 has two leaves: check-ins 3 and 4. Check-in 2 has |
| 50 | two children, check-ins 3 and 4. We call this state a <i>fork</i>. |
| 51 | |
| 52 | Fossil tries to prevent forks. Suppose two programmers named Alice and |
| 53 | Bob are each editing check-in 2 separately. Alice finishes her edits |
| 54 | first and commits her changes, resulting in check-in 3. Later, when Bob |
| 55 | attempts to commit his changes, fossil verifies that check-in 2 is still |
| 56 | a leaf. Fossil sees that check-in 3 has occurred and aborts Bob's commit |
| 57 | attempt with a message "would fork." This allows Bob to do a "fossil |
| 58 | update" which pulls in Alice's changes, merging them into his own |
| 59 | changes. After merging, Bob commits check-in 4 as a child of check-in 3. |
| 60 | The result is a linear graph as shown in figure 1. This is how CVS |
| 61 | works. This is also how fossil works in [concepts.wiki#workflow | |
| 62 | "autosync"] mode. |
| 63 | |
| 64 | But perhaps Bob is off-network when he does his commit, so he |
| 65 | has no way of knowing that Alice has already committed her changes. |
| 66 | Or, it could be that Bob has turned off "autosync" mode in Fossil. Or, |
| 67 | maybe Bob just doesn't want to merge in Alice's changes before he has |
| 68 | saved his own, so he forces the commit to occur using the "--force" option |
| 69 | to the fossil <b>commit</b> command. For any of these reasons, two commits against |
| 70 | check-in 2 have occurred and now the DAG has two leaves. |
| 71 | |
| 72 | So which version of the project is the "latest" in the sense of having |
| 73 | the most features and the most bug fixes? When there is more than |
| 74 | one leaf in the graph, you don't really know. So we like to have |
| @@ -101,31 +99,31 @@ | |
| 99 | in figure 1. Really the graph of figure 1 is a subset of figure 3. |
| 100 | Hold your hand over the check-in 4 circle of figure 3 and then figure |
| 101 | 3 looks exactly like figure 1 (except that the leaf has a different check-in |
| 102 | number, but that is just a notational difference - the two check-ins have |
| 103 | exactly the same content). In other words, figure 3 is really a superset |
| 104 | of figure 1. The check-in 4 of figure 3 captures additional state which |
| 105 | is omitted from figure 1. Check-in 4 of figure 3 holds a copy |
| 106 | of Bob's local checkout before he merged in Alice's changes. That snapshot |
| 107 | of Bob's changes, which is independent of Alice's changes, is omitted from figure 1. |
| 108 | Some people say that the approach taken in figure 3 is better because it |
| 109 | preserves this extra intermediate state. Others say that the approach |
| 110 | taken in figure 1 is better because it is much easier to visualize a |
| 111 | linear line of development and because the merging happens automatically |
| 112 | instead of as a separate manual step. We will not take sides in that |
| 113 | debate. We will simply point out that fossil enables you to do it either way. |
| 114 | |
| 115 | <h2>Forking Versus Branching</h2> |
| 116 | |
| 117 | Having more than one leaf in the check-in DAG is called a "fork." This |
| 118 | is usually undesirable and either avoided entirely, |
| 119 | as in figure 1, or else quickly resolved as shown in figure 3. |
| 120 | But sometimes, one does want to have multiple leaves. For example, a project |
| 121 | might have one leaf that is the latest version of the project under |
| 122 | development and another leaf that is the latest version that has been |
| 123 | tested. |
| 124 | When multiple leaves are desirable, we call this <i>branching</i> |
| 125 | instead of <i>forking</i>. |
| 126 | Figure 4 shows an example of a project where there are two branches, one |
| 127 | for development work and another for testing. |
| 128 | |
| 129 | <center><table border=1 cellpadding=10 hspace=10 vspace=10> |
| @@ -150,11 +148,11 @@ | |
| 148 | changes in the test branch are merged into the dev branch. This is |
| 149 | shown by the dashed merge arrows between check-ins 6 and 7 and between |
| 150 | check-ins 9 and 10. |
| 151 | |
| 152 | In both figures 2 and 4, check-in 2 has two children. In figure 2, |
| 153 | we call this a "fork." In diagram 4, we call it a "branch." What is |
| 154 | the difference? As far as the internal fossil data structures are |
| 155 | concerned, there is no difference. The distinction is in the intent. |
| 156 | In figure 2, the fact that check-in 2 has multiple children is an |
| 157 | accident that stems from concurrent development. In figure 4, giving |
| 158 | check-in 2 multiple children is a deliberate act. So, to a good |
| @@ -193,85 +191,82 @@ | |
| 191 | |
| 192 | Every repository is created with a single empty check-in that has two |
| 193 | propagating tags. In figure 5, that initial empty check-in is check-in 1. |
| 194 | The <b>branch</b> tag tells (by its value) |
| 195 | what branch the check-in is a member of. |
| 196 | The default branch is called "trunk." All tags that begin with "<b>sym-</b>" |
| 197 | are symbolic name tags. When a symbolic name tag is attached to a |
| 198 | check-in, that allows you to refer to that check-in by its symbolic |
| 199 | name rather than by its 40-character SHA1 hash name. When a symbolic name |
| 200 | tag propagates (as does the <b>sym-trunk</b> tag) then referring to that |
| 201 | name is the same as referring to the most recent check-in with that name. |
| 202 | Thus the two tags on check-in 1 cause all descendants to be in the |
| 203 | "trunk" branch and to have the symbolic name "trunk." |
| 204 | |
| 205 | Check-in 4 has a <b>branch</b> tag which changes the name of the branch |
| 206 | to "test." The branch tag on check-in 4 propagates to check-ins 6 and 9. |
| 207 | But because tag propagation does not follow merge links, the <b>branch=test</b> |
| 208 | tag does not propagate to check-ins 7, 8, or 10. Note also that the |
| 209 | <b>branch</b> tag on check-in 4 blocks the propagation of <b>branch=trunk</b> |
| 210 | so that it cannot reach check-ins 6 or 9. This causes check-ins 4, 6, and |
| 211 | 9 to be in the "test" branch and all others to be in the "trunk" branch. |
| 212 | |
| 213 | Check-in 4 also has a <b>sym-test</b> tag, which gives the symbolic name |
| 214 | "test" to check-ins 4, 6, and 9. Because tags do not propagate across |
| 215 | merges, check-ins 7, 8, and 10 do not inherit the <b>sym-test</b> tag and |
| 216 | are hence not known by the name "test." |
| 217 | To prevent the <b>sym-trunk</b> tag from propagating from check-in 1 |
| 218 | into check-ins 4, 6, and 9, there is a cancellation tag for |
| 219 | <b>sym-trunk</b> on check-in 4. The net effect is that |
| 220 | check-ins on the trunk go by the symbolic name of "trunk" and check-ins |
| 221 | on the test branch go by the symbolic name "test." |
| 222 | |
| 223 | The <b>bgcolor=blue</b> tag on check-in 4 causes the background color |
| 224 | of timelines to be blue for check-in 4 and its direct descendants. |
| 225 | |
| 226 | Figure 5 also shows two one-time tags on check-in 9. (The diagram does |
| 227 | not make a graphical distinction between one-time and propagating tags.) |
| 228 | The <b>sym-release-1.0</b> tag means that check-in 9 can be referred to |
| 229 | using the more meaningful name "release-1.0." The <b>closed</b> tag means |
| 230 | that check-in 9 is a "closed leaf." A closed leaf is a leaf that should |
| 231 | never have direct children. |
| 232 | |
| 233 | <h2>Review Of Terminology</h2> |
| 234 | |
| 235 | <blockquote><dl> |
| 236 | <dt><b>Branch</b></dt> |
| 237 | <dd><p>A branch is a set of check-ins with the same value for their |
| 238 | "branch" property.</p></dd> |
| 239 | <dt><b>Leaf</b></dt> |
| 240 | <dd><p>A leaf is a check-in with no children in the same branch.</p></dd> |
| 241 | <dt><b>Closed Leaf</b></dt> |
| 242 | <dd><p>A closed leaf is any leaf with the <b>closed</b> tag. These leaves |
| 243 | are intended to never be extended with descendants and hence are omitted |
| 244 | from lists of leaves in the command-line and web interface.</p></dd> |
| 245 | <dt><b>Open Leaf</b></dt> |
| 246 | <dd><p>A open leaf is a leaf that is not closed.</p></dd> |
| 247 | <dt><b>Fork</b></dt> |
| 248 | <dd><p>A fork is when a check-in has two or more direct (non-merge) |
| 249 | children in the same branch.</p></dd> |
| 250 | <dt><b>Branch Point</b></dt> |
| 251 | <dd><p>A branch point occurs when a check-in has two or more direct (non-merge) |
| 252 | children in different branches. A branch point is similar to a fork, |
| 253 | except that the children are in different branches.</p></dd> |
| 254 | </dl></blockquote> |
| 255 | |
| 256 | Check-in 4 of figure 3 is not a leaf because it has a child (check-in 5) |
| 257 | in the same branch. Check-in 9 of figure 5 also has a child (check-in 10) |
| 258 | but that child is in a different branch, so check-in 9 is a leaf. Because |
| 259 | of the <b>closed</b> tag on check-in 9, it is a closed leaf. |
| 260 | |
| 261 | Check-in 2 of figure 3 is considered a "fork" |
| 262 | because it has two children in the same branch. Check-in 2 of figure 5 |
| 263 | also has two children, but each child is in a different branch, hence in |
| 264 | figure 5, check-in 2 is considered a "branch point." |
| 265 | |
| 266 | <h2>Differences With Other DVCSes</h2> |
| 267 | |
| 268 | Fossil keeps all check-ins on a single DAG. Branches are identified with |
| 269 | tags. This means that check-ins can be freely moved between branches |
| 270 | simply by altering their tags. |
| 271 | |
| 272 | Most other DVCSes maintain a separate DAG for each branch. |
| 273 |