Fossil SCM

fossil-scm / www / branching.wiki
Source Blame History 767 lines
169a10d… drh 1 <title>Branching, Forking, Merging, and Tagging</title>
169a10d… drh 2 <h2>Background</h2>
2e275c1… drh 3
2e275c1… drh 4 In a simple and perfect world, the development of a project would proceed
b882c62… wyoung 5 linearly, as shown in Figure 1.
2e275c1… drh 6
01f6ed9… wyoung 7 <verbatim type="pikchr center toggle">
239fb5b… wyoung 8 ALL: [circle rad 0.1in thickness 1.5px "1"
0b2f838… drh 9 arrow right 40%
0b2f838… drh 10 circle same "2"
0b2f838… drh 11 arrow same
0b2f838… drh 12 circle same "3"
0b2f838… drh 13 arrow same
299e064… drh 14 circle same "4"]
299e064… drh 15 box invis "Figure 1" big fit with .n at .3cm below ALL.s
0b2f838… drh 16 </verbatim>
2e275c1… drh 17
2e275c1… drh 18 Each circle represents a check-in. For the sake of clarity, the check-ins
2e275c1… drh 19 are given small consecutive numbers. In a real system, of course, the
796db89… drh 20 check-in numbers would be long hexadecimal hashes since it is not possible
d06396d… drh 21 to allocate collision-free sequential numbers in a distributed system.
d06396d… drh 22 But as sequential numbers are easier to read, we will substitute them for
796db89… drh 23 the long hashes in this document.
2e275c1… drh 24
b882c62… wyoung 25 The arrows in Figure 1 show the evolution of a project. The initial
2e275c1… drh 26 check-in is 1. Check-in 2 is derived from 1. In other words, check-in 2
2e275c1… drh 27 was created by making edits to check-in 1 and then committing those edits.
2e275c1… drh 28 We say that 2 is a <i>child</i> of 1
aafcf6c… jan.nijtmans 29 and that 1 is a <i>parent</i> of 2.
2e275c1… drh 30 Check-in 3 is derived from check-in 2, making
2e275c1… drh 31 3 a child of 2. We say that 3 is a <i>descendant</i> of both 1 and 2 and that 1
aafcf6c… jan.nijtmans 32 and 2 are both <i>ancestors</i> of 3.
d06396d… drh 33
b882c62… wyoung 34 <h2 id="dag">DAGs</h2>
d06396d… drh 35
aafcf6c… jan.nijtmans 36 The graph of check-ins is a
f8d210a… wyoung 37 [http://en.wikipedia.org/wiki/Directed_acyclic_graph | directed acyclic graph],
d06396d… drh 38 commonly shortened to <i>DAG</i>. Check-in 1 is the <i>root</i> of the DAG
c1c18b7… drh 39 since it has no ancestors. Check-in 4 is a <i>leaf</i> of the DAG since
d06396d… drh 40 it has no descendants. (We will give a more precise definition later of
d06396d… drh 41 "leaf.")
2e275c1… drh 42
2e275c1… drh 43 Alas, reality often interferes with the simple linear development of a
2e275c1… drh 44 project. Suppose two programmers make independent modifications to check-in 2.
b882c62… wyoung 45 After both changes are committed, the check-in graph looks like Figure 2:
b882c62… wyoung 46
01f6ed9… wyoung 47 <verbatim type="pikchr center toggle">
239fb5b… wyoung 48 ALL: [circle rad 0.1in thickness 1.5px "1"
0b2f838… drh 49 arrow right 40%
0b2f838… drh 50 circle same "2"
0b2f838… drh 51 circle same "3" at 2nd circle+(.4,.3)
0b2f838… drh 52 arrow from 2nd circle to 3rd circle chop
0b2f838… drh 53 circle same "4" at 2nd circle+(.4,-.3)
299e064… drh 54 arrow from 2nd circle to 4th circle chop]
299e064… drh 55 box invis "Figure 2" big fit with .n at .3cm below ALL.s
0b2f838… drh 56 </verbatim>
b882c62… wyoung 57
b882c62… wyoung 58 The graph in Figure 2 has two leaves: check-ins 3 and 4. Check-in 2 has
d06396d… drh 59 two children, check-ins 3 and 4. We call this state a <i>fork</i>.
d06396d… drh 60
f8d210a… wyoung 61 Fossil tries to prevent forks, primarily through its
f8d210a… wyoung 62 "[./concepts.wiki#workflow | autosync]" mechanism.
f8d210a… wyoung 63
f8d210a… wyoung 64 Suppose two programmers named Alice and
aafcf6c… jan.nijtmans 65 Bob are each editing check-in 2 separately. Alice finishes her edits
f8d210a… wyoung 66 and commits her changes first, resulting in check-in 3. When Bob later
b882c62… wyoung 67 attempts to commit his changes, Fossil verifies that check-in 2 is still
aafcf6c… jan.nijtmans 68 a leaf. Fossil sees that check-in 3 has occurred and aborts Bob's commit
aafcf6c… jan.nijtmans 69 attempt with a message "would fork." This allows Bob to do a "fossil
f8d210a… wyoung 70 update" to pull in Alice's changes, merging them into his own
aafcf6c… jan.nijtmans 71 changes. After merging, Bob commits check-in 4 as a child of check-in 3.
b882c62… wyoung 72 The result is a linear graph as shown in Figure 1. This is how CVS
f8d210a… wyoung 73 works. This is also how Fossil works in autosync mode.
f8d210a… wyoung 74
f8d210a… wyoung 75 But perhaps Bob is off-network when he does his commit, so he has no way
f8d210a… wyoung 76 of knowing that Alice has already committed her changes. Or, it could
f8d210a… wyoung 77 be that Bob has turned off "autosync" mode in Fossil. Or, maybe Bob
f8d210a… wyoung 78 just doesn't want to merge in Alice's changes before he has saved his
f8d210a… wyoung 79 own, so he forces the commit to occur using the "--allow-fork" option to
c64f28d… drh 80 the <b>[/help/commit | fossil commit]</b> command. For any of these
f8d210a… wyoung 81 reasons, two commits against check-in 2 have occurred, so the DAG now
f8d210a… wyoung 82 has two leaves.
f8d210a… wyoung 83
f8d210a… wyoung 84 In such a condition, a person working with this repository has a
f8d210a… wyoung 85 dilemma: which version of the project is the "latest" in the sense of
f8d210a… wyoung 86 having the most features and the most bug fixes? When there is more
f8d210a… wyoung 87 than one leaf in the graph, you don't really know, which is why we
f8d210a… wyoung 88 would ideally prefer to have linear check-in graphs.
b882c62… wyoung 89
b882c62… wyoung 90 Fossil resolves such problems using the check-in time on the leaves to
b882c62… wyoung 91 decide which leaf to use as the parent of new leaves. When a branch is
b882c62… wyoung 92 forked as in Figure 2, Fossil will choose check-in 4 as the parent for a
b882c62… wyoung 93 later check-in 5, but <i>only</i> if it has sync'd that check-in down
b882c62… wyoung 94 into the local repository. If autosync is disabled or the user is
f8d210a… wyoung 95 off-network when that fifth check-in occurs so that check-in 3 is the
b882c62… wyoung 96 latest on that branch at the time within that clone of the repository,
f8d210a… wyoung 97 Fossil will make check-in 3 the parent of check-in 5! We show practical
f8d210a… wyoung 98 consequences of this [#bad-fork | later in this article].
b882c62… wyoung 99
b882c62… wyoung 100 Fossil also uses a forked branch's leaf check-in timestamps when
b882c62… wyoung 101 checking out that branch: it gives you the fork with the latest
b882c62… wyoung 102 check-in, which in turn selects which parent your next check-in will be
b882c62… wyoung 103 a child of. This situation means development on that branch can fork
b882c62… wyoung 104 into two independent lines of development, based solely on which branch
f8d210a… wyoung 105 tip is newer at the time the next user starts his work on it.
f8d210a… wyoung 106
f8d210a… wyoung 107 Because of these potential problems, we strongly recommend that you do
f8d210a… wyoung 108 not intentionally create forks on long-lived shared working branches
f8d210a… wyoung 109 with "--allow-fork". (Prime example: trunk.) The inverse case —
f8d210a… wyoung 110 intentional forks on short-lived single-developer branches — is far
f8d210a… wyoung 111 easier to justify, since presumably the lone developer is never confused
f8d210a… wyoung 112 about why there are two or more leaves on that branch. Further
f8d210a… wyoung 113 justifications for intentional forking are [#forking | given below].
b882c62… wyoung 114
b882c62… wyoung 115 Let us return to Figure 2. To resolve such situations before they can
c64f28d… drh 116 become a real problem, Alice can use the <b>[/help/merge | fossil
f8d210a… wyoung 117 merge]</b> command to merge Bob's changes into her local copy of
f8d210a… wyoung 118 check-in 3. Without arguments, that command merges all leaves on the
f8d210a… wyoung 119 current branch. Alice can then verify that the merge is sensible and if
f8d210a… wyoung 120 so, commit the results as check-in 5. This results in a DAG as shown in
b882c62… wyoung 121 Figure 3.
b882c62… wyoung 122
01f6ed9… wyoung 123 <verbatim type="pikchr center toggle">
239fb5b… wyoung 124 ALL: [circle rad 0.1in thickness 1.5px "1"
0b2f838… drh 125 arrow right 40%
0b2f838… drh 126 circle same "2"
0b2f838… drh 127 circle same "3" at 2nd circle+(.4,.3)
0b2f838… drh 128 arrow from 2nd circle to 3rd circle chop
0b2f838… drh 129 circle same "4" at 2nd circle+(.4,-.3)
0b2f838… drh 130 arrow from 2nd circle to 4th circle chop
0b2f838… drh 131 circle same "5" at 3rd circle+(.4,-.3)
0b2f838… drh 132 arrow from 3rd circle to 5th circle chop
299e064… drh 133 arrow dashed .03 from 4th circle to 5th circle chop]
299e064… drh 134 box invis "Figure 3" big fit with .n at .2cm below ALL.s
0b2f838… drh 135 </verbatim>
766bec0… drh 136
766bec0… drh 137 Check-in 5 is a child of check-in 3 because it was created by editing
f8d210a… wyoung 138 check-in 3, but since check-in 5 also inherits the changes from check-in 4 by
f8d210a… wyoung 139 virtue of the merge, we say that check-in 5 is a <i>merge child</i>
aafcf6c… jan.nijtmans 140 of check-in 4 and that it is a <i>direct child</i> of check-in 3.
b882c62… wyoung 141 The graph is now back to a single leaf, check-in 5.
766bec0… drh 142
b882c62… wyoung 143 We have already seen that if Fossil is in autosync mode then Bob would
2e275c1… drh 144 have been warned about the potential fork the first time he tried to
2e275c1… drh 145 commit check-in 4. If Bob had updated his local check-out to merge in
f8d210a… wyoung 146 Alice's check-in 3 changes, then committed, the fork would have
2e275c1… drh 147 never occurred. The resulting graph would have been linear, as shown
b882c62… wyoung 148 in Figure 1.
b882c62… wyoung 149
f8d210a… wyoung 150 Realize that the graph of Figure 1 is a subset of Figure 3. If you hold your
f8d210a… wyoung 151 hand over the ④ in Figure 3, it looks
f8d210a… wyoung 152 exactly like Figure 1 except that the leaf has a different check-in
f8d210a… wyoung 153 number. That is just a notational difference: the two check-ins
f8d210a… wyoung 154 have exactly the same content.
f8d210a… wyoung 155
f8d210a… wyoung 156 Inversely, Figure 3 is a
b882c62… wyoung 157 superset of Figure 1. The check-in 4 of Figure 3 captures additional
b882c62… wyoung 158 state which is omitted from Figure 1. Check-in 4 of Figure 3 holds a
b882c62… wyoung 159 copy of Bob's local checkout before he merged in Alice's changes. That
b882c62… wyoung 160 snapshot of Bob's changes, which is independent of Alice's changes, is
f8d210a… wyoung 161 omitted from Figure 1.
f8d210a… wyoung 162
f8d210a… wyoung 163 Some people say that the development approach taken in
b882c62… wyoung 164 Figure 3 is better because it preserves this extra intermediate state.
b882c62… wyoung 165 Others say that the approach taken in Figure 1 is better because it is
f8d210a… wyoung 166 much easier to visualize linear development and because the
b882c62… wyoung 167 merging happens automatically instead of as a separate manual step. We
b882c62… wyoung 168 will not take sides in that debate. We will simply point out that
b882c62… wyoung 169 Fossil enables you to do it either way.
b882c62… wyoung 170
b882c62… wyoung 171 <h2 id="branching">The Alternative to Forking: Branching</h2>
aafcf6c… jan.nijtmans 172
aafcf6c… jan.nijtmans 173 Having more than one leaf in the check-in DAG is called a "fork." This
d06396d… drh 174 is usually undesirable and either avoided entirely,
b882c62… wyoung 175 as in Figure 1, or else quickly resolved as shown in Figure 3.
2e275c1… drh 176 But sometimes, one does want to have multiple leaves. For example, a project
2e275c1… drh 177 might have one leaf that is the latest version of the project under
2e275c1… drh 178 development and another leaf that is the latest version that has been
2e275c1… drh 179 tested.
d06396d… drh 180 When multiple leaves are desirable, we call this <i>branching</i>
1e0cf46… wyoung 181 instead of <i>forking</i>:
1e0cf46… wyoung 182
2e275c1… drh 183 Figure 4 shows an example of a project where there are two branches, one
2e275c1… drh 184 for development work and another for testing.
2e275c1… drh 185
01f6ed9… wyoung 186 <verbatim type="pikchr center toggle">
239fb5b… wyoung 187 ALL: [circle rad 0.1in thickness 1.5px fill white "1"
0b2f838… drh 188 arrow 40%
0b2f838… drh 189 C2: circle same "2"
0b2f838… drh 190 arrow same
0b2f838… drh 191 circle same "3"
0b2f838… drh 192 arrow same
0b2f838… drh 193 C5: circle same "5"
0b2f838… drh 194 arrow same
0b2f838… drh 195 C7: circle same "7"
0b2f838… drh 196 arrow same
0b2f838… drh 197 C8: circle same "8"
0b2f838… drh 198 arrow same
0b2f838… drh 199 C10: circle same "10"
0b2f838… drh 200 C4: circle same at 3rd circle-(0,.35) "4"
0b2f838… drh 201 C6: circle same at (1/2 way between C5 and C7,C4) "6"
0b2f838… drh 202 C9: circle same at (1/2 way between C8 and C10,C4) "9"
0b2f838… drh 203 arrow from C2 to C4 chop
0b2f838… drh 204 arrow from C4 to C6 chop
0b2f838… drh 205 arrow from C6 to C9 chop
0b2f838… drh 206 arrow dashed 0.03 from C6 to C7 chop
0b2f838… drh 207 arrow same from C9 to C10
0b2f838… drh 208 layer = 0
0b2f838… drh 209 box fill 0x9bcdfc color 0x9bcdfc wid (C10.e.x - C2.w.x) ht C6.height*1.5 at C6.c
299e064… drh 210 box invis "test" fit with .sw at last box.sw]
299e064… drh 211 box invis "Figure 4" big with .n at 0 below ALL.s
0b2f838… drh 212 </verbatim>
aafcf6c… jan.nijtmans 213
f8d210a… wyoung 214 Figure 4 diagrams the following scenario: the project starts and
aafcf6c… jan.nijtmans 215 progresses to a point where (at check-in 2)
2e275c1… drh 216 it is ready to enter testing for its first release.
2e275c1… drh 217 In a real project, of course, there might be hundreds or thousands of
2e275c1… drh 218 check-ins before a project reaches this point, but for simplicity of
2e275c1… drh 219 presentation we will say that the project is ready after check-in 2.
2e275c1… drh 220 The project then splits into two branches that are used by separate
2e275c1… drh 221 teams. The testing team, using the blue branch, finds and fixes a few
f8d210a… wyoung 222 bugs with check-ins 6 and 9. Meanwhile, the development
aafcf6c… jan.nijtmans 223 team, working on the top uncolored branch,
dc1a5cf… drh 224 is busy adding features for the second
2e275c1… drh 225 release. Of course, the development team would like to take advantage of
f8d210a… wyoung 226 the bug fixes implemented by the testing team, so periodically the
2e275c1… drh 227 changes in the test branch are merged into the dev branch. This is
2e275c1… drh 228 shown by the dashed merge arrows between check-ins 6 and 7 and between
2e275c1… drh 229 check-ins 9 and 10.
2e275c1… drh 230
b882c62… wyoung 231 In both Figures 2 and 4, check-in 2 has two children. In Figure 2,
d06396d… drh 232 we call this a "fork." In diagram 4, we call it a "branch." What is
b882c62… wyoung 233 the difference? As far as the internal Fossil data structures are
2e275c1… drh 234 concerned, there is no difference. The distinction is in the intent.
b882c62… wyoung 235 In Figure 2, the fact that check-in 2 has multiple children is an
b882c62… wyoung 236 accident that stems from concurrent development. In Figure 4, giving
f8d210a… wyoung 237 check-in 2 multiple children is a deliberate act. To a good
dc1a5cf… drh 238 approximation, we define forking to be by accident and branching to
2e275c1… drh 239 be by intent. Apart from that, they are the same.
f8d210a… wyoung 240
f8d210a… wyoung 241 When the fork is intentional, it helps humans to understand what is
f8d210a… wyoung 242 going on if we <i>name</i> the forks. This is not essential to Fossil's
f8d210a… wyoung 243 internal data model, but humans have trouble working with long-lived
f8d210a… wyoung 244 branches identified only by the commit ID currently at its tip, being a
f8d210a… wyoung 245 long string of hex digits. Therefore, Fossil conflates two concepts:
f8d210a… wyoung 246 branching as intentional forking and the naming of forks as branches.
f8d210a… wyoung 247 They are in fact separate concepts, but since Fossil is intended to be
f8d210a… wyoung 248 used primarily by humans, we combine them in Fossil's human user
f8d210a… wyoung 249 interfaces.
f8d210a… wyoung 250
8a1ba49… wyoung 251 <p class="blockquote">
f8d210a… wyoung 252 <b>Key Distinction:</b> A branch is a <i>named, intentional</i> fork.
8a1ba49… wyoung 253 </p>
f8d210a… wyoung 254
f8d210a… wyoung 255 Unnamed forks <i>may</i> be intentional, but most of the time, they're
f8d210a… wyoung 256 accidental and left unnamed.
2da1099… wyoung 257
2da1099… wyoung 258 Fossil offers two primary ways to create named, intentional forks,
7391166… wyoung 259 a.k.a. branches. First:
7391166… wyoung 260
7391166… wyoung 261 <pre>
ccd880e… wyoung 262 $ fossil commit --branch my-new-branch-name
7391166… wyoung 263 </pre>
7391166… wyoung 264
7391166… wyoung 265 This is the method we recommend for most cases: it creates a branch as
f8d210a… wyoung 266 part of a check-in using the version in the current checkout directory
2da1099… wyoung 267 as its basis. (This is normally the tip of the current branch, though
f8d210a… wyoung 268 it doesn't have to be. You can create a branch from an ancestor check-in
2da1099… wyoung 269 on a branch as well.) After making this branch-creating
f8d210a… wyoung 270 check-in, your local working directory is switched to that branch, so
f8d210a… wyoung 271 that further check-ins occur on that branch as well, as children of the
f8d210a… wyoung 272 tip check-in on that branch.
7391166… wyoung 273
7391166… wyoung 274 The second, more complicated option is:
1e0cf46… wyoung 275
1e0cf46… wyoung 276 <pre>
ccd880e… wyoung 277 $ fossil branch new my-new-branch-name trunk
ccd880e… wyoung 278 $ fossil update my-new-branch-name
ccd880e… wyoung 279 $ fossil commit
1e0cf46… wyoung 280 </pre>
1e0cf46… wyoung 281
2da1099… wyoung 282 Not only is this three commands instead of one, the first of which is
2da1099… wyoung 283 longer than the entire simpler command above, you must give the second command
f8d210a… wyoung 284 before creating any check-ins, because until you do, your local working
7391166… wyoung 285 directory remains on the same branch it was on at the time you issued
2da1099… wyoung 286 the command, so that the commit would otherwise put the new material on
2da1099… wyoung 287 the original branch instead of the new one.
7391166… wyoung 288
7391166… wyoung 289 In addition to those problems, the second method is a violation of the
1e0cf46… wyoung 290 [https://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it|YAGNI
1e0cf46… wyoung 291 Principle]. We recommend that you wait until you actually need the
f8d210a… wyoung 292 branch before you create it using the first command above.
7391166… wyoung 293
f8d210a… wyoung 294 The "trunk" is just another named branch in Fossil. It is simply
f8d210a… wyoung 295 the default branch name for the first check-in and every check-in made as
7391166… wyoung 296 one of its direct descendants. It is special only in that it is Fossil's
f8d210a… wyoung 297 default when it has no better idea of which branch you mean.
1e0cf46… wyoung 298
1e0cf46… wyoung 299
b882c62… wyoung 300 <h2 id="forking">Justifications For Forking</h2>
b882c62… wyoung 301
bf048cd… wyoung 302 The primary cases where forking is justified over branching are all when
bf048cd… wyoung 303 it is done purely in software in order to avoid losing information:
b882c62… wyoung 304
b882c62… wyoung 305 <ol>
862b77b… wyoung 306 <li><p id="offline">By Fossil itself when two users check in children to the same
f8d210a… wyoung 307 leaf of a branch, as in Figure 2.
f8d210a… wyoung 308 <br><br>
f8d210a… wyoung 309 If the fork occurs because
bf048cd… wyoung 310 autosync is disabled on one or both of the repositories or because
bf048cd… wyoung 311 the user doing the check-in has no network connection at the moment
bf048cd… wyoung 312 of the commit, Fossil has no way of knowing that it is creating a
0996347… wyoung 313 fork until the two repositories are later synchronized.</p></li>
862b77b… wyoung 314
862b77b… wyoung 315 <li><p id="dist-clone">By Fossil when the cloning hierarchy is more
862b77b… wyoung 316 than 2 levels deep.
862b77b… wyoung 317 <br><br>
79c2cb0… wyoung 318 [./sync.wiki|Fossil's synchronization protocol] is a two-party
862b77b… wyoung 319 negotiation; syncs don't automatically propagate up the clone tree
862b77b… wyoung 320 beyond that. Because of that, if you have a master repository and
862b77b… wyoung 321 Alice clones it, then Bobby clones from Alice's repository, a
862b77b… wyoung 322 check-in by Bobby that autosyncs with Alice's repo will <i>not</i>
862b77b… wyoung 323 also autosync with the master repo. The master doesn't get a copy of
f8d210a… wyoung 324 Bobby's check-in until Alice <i>separately</i> syncs with the master.
862b77b… wyoung 325 If Carol cloned from the master repo and checks something in that
862b77b… wyoung 326 creates a fork relative to Bobby's check-in, the master repo won't
862b77b… wyoung 327 know about that fork until Alice syncs her repo with the master.
862b77b… wyoung 328 Even then, realize that Carol still won't know about the fork until
862b77b… wyoung 329 she subsequently syncs with the master repo.
862b77b… wyoung 330 <br><br>
862b77b… wyoung 331 One way to deal with this is to just accept it as a fact of using a
862b77b… wyoung 332 [https://en.wikipedia.org/wiki/Distributed_version_control|Distributed
862b77b… wyoung 333 Version Control System] like Fossil.
862b77b… wyoung 334 <br><br>
862b77b… wyoung 335 Another option, which we recommend you consider carefully, is to
f8d210a… wyoung 336 make it a local policy that check-ins be made only directly against the master
862b77b… wyoung 337 repo or one of its immediate child clones so that the autosync
f8d210a… wyoung 338 algorithm can do its job most effectively. Any clones deeper than
862b77b… wyoung 339 that should be treated as read-only and thus get a copy of the new
862b77b… wyoung 340 state of the world only once these central repos have negotiated
862b77b… wyoung 341 that new state. This policy avoids a class of inadvertent fork you
862b77b… wyoung 342 might not need to tolerate. Since [#bad-fork|forks on long-lived
862b77b… wyoung 343 shared working branches can end up dividing a team's development
862b77b… wyoung 344 effort], a team may easily justify this restriction on distributed
862b77b… wyoung 345 cloning.</p></li>
862b77b… wyoung 346
f8d210a… wyoung 347 <li><p id="automation">You've automated Fossil, so you use
f8d210a… wyoung 348 <b>fossil commit --allow-fork</b> commands to prevent Fossil from
f8d210a… wyoung 349 refusing the check-in simply because it would create a fork.
f8d210a… wyoung 350 <br><br>
f8d210a… wyoung 351 If you are writing such a tool — e.g. a shell script to make
f8d210a… wyoung 352 multiple manipulations on a Fossil repo — it's better to make it
f8d210a… wyoung 353 smart enough to detect this condition and cope with it, such as
c64f28d… drh 354 by making a call to <b>[/help/update | fossil update]</b>
f8d210a… wyoung 355 and checking for a merge conflict. That said, if the alternative is
f8d210a… wyoung 356 losing information, you may feel justified in creating forks that an
f8d210a… wyoung 357 interactive user must later manually clean up with <b>fossil merge</b>
f8d210a… wyoung 358 commands.</p></li>
b882c62… wyoung 359 </ol>
b882c62… wyoung 360
b882c62… wyoung 361 That leaves only one case where we can recommend use of "--allow-fork"
f8d210a… wyoung 362 by interactive users: when you're working on a personal branch so that
f8d210a… wyoung 363 creating a dual-tipped branch isn't going to cause any other user an
f8d210a… wyoung 364 inconvenience or risk [#bad-fork | inadvertently forking the development
f8d210a… wyoung 365 effort]. In such a case, the lone developer working on that branch is
f8d210a… wyoung 366 not confused, since the fork in development is intentional. Sometimes it
f8d210a… wyoung 367 simply makes no sense to bother creating a name, cluttering the global
f8d210a… wyoung 368 branch namespace, simply to convert an intentional fork into a "branch."
f8d210a… wyoung 369 This is especially the case when the fork is short-lived.
3cc437a… wyoung 370
3cc437a… wyoung 371 There's a common generalization of that case: you're a solo developer,
184cf20… wyoung 372 so that the problems with branching vs forking simply don't matter. In
3cc437a… wyoung 373 that case, feel free to use "--allow-fork" as much as you like.
2686bad… wyoung 374
2686bad… wyoung 375
2686bad… wyoung 376 <h2 id="fix">Fixing Forks</h2>
2686bad… wyoung 377
2686bad… wyoung 378 If your local checkout is on a forked branch, you can usually fix a fork
2686bad… wyoung 379 automatically with:
2686bad… wyoung 380
2686bad… wyoung 381 <pre>
ccd880e… wyoung 382 $ fossil merge
2686bad… wyoung 383 </pre>
2686bad… wyoung 384
2686bad… wyoung 385 Normally you need to pass arguments to <b>fossil merge</b> to tell it
2686bad… wyoung 386 what you want to merge into the current basis view of the repository,
2686bad… wyoung 387 but without arguments, the command seeks out and fixes forks.
b882c62… wyoung 388
b882c62… wyoung 389
b882c62… wyoung 390 <h2 id="tags">Tags And Properties</h2>
2e275c1… drh 391
b882c62… wyoung 392 Tags and properties are used in Fossil to help express the intent, and
2e275c1… drh 393 thus to distinguish between forks and branches. Figure 5 shows the
b882c62… wyoung 394 same scenario as Figure 4 but with tags and properties added:
2e275c1… drh 395
01f6ed9… wyoung 396 <verbatim type="pikchr center toggle">
299e064… drh 397 ALL: [arrowht = 0.07
239fb5b… wyoung 398 C1: circle rad 0.1in thickness 1.5px fill white "1"
9ec0cce… drh 399 arrow 40%
9ec0cce… drh 400 C2: circle same "2"
9ec0cce… drh 401 arrow same
9ec0cce… drh 402 circle same "3"
9ec0cce… drh 403 arrow same
9ec0cce… drh 404 C5: circle same "5"
9ec0cce… drh 405 arrow same
9ec0cce… drh 406 C7: circle same "7"
9ec0cce… drh 407 arrow same
9ec0cce… drh 408 C8: circle same "8"
9ec0cce… drh 409 arrow same
9ec0cce… drh 410 C10: circle same "10"
9ec0cce… drh 411 C4: circle same at 3rd circle-(0,.35) "4"
9ec0cce… drh 412 C6: circle same at (1/2 way between C5 and C7,C4) "6"
9ec0cce… drh 413 C9: circle same at (1/2 way between C8 and C10,C4) "9"
9ec0cce… drh 414 arrow from C2 to C4 chop
9ec0cce… drh 415 arrow from C4 to C6 chop
9ec0cce… drh 416 arrow from C6 to C9 chop
9ec0cce… drh 417 arrow dashed 0.03 from C6 to C7 chop
9ec0cce… drh 418 arrow same from C9 to C10
9ec0cce… drh 419 layer = 0
9ec0cce… drh 420 box fill 0x9bcdfc color 0x9bcdfc wid (C10.e.x - C2.w.x) ht C6.height*1.5 at C6.c
9ec0cce… drh 421 text " test" above ljust at last box.sw
9ec0cce… drh 422 box fill lightgray "branch=trunk" "sym-trunk" fit with .ne at C1-(0.05,0.3);
9ec0cce… drh 423 line color gray from last box.ne to C1 chop
9ec0cce… drh 424 box same "branch=test" "sym-test" "bgcolor=blue" "cancel=sym-trunk" fit \
9ec0cce… drh 425 with .n at C4-(0,0.3)
9ec0cce… drh 426 line color gray from last box.n to C4 chop
9ec0cce… drh 427 box same "sym-release-1.0" "closed" fit with .n at C9-(0,0.3)
299e064… drh 428 line color gray from last box.n to C9 chop]
239fb5b… wyoung 429 box invis "Figure 5" big fit with .n at 0.2cm below ALL.s
9ec0cce… drh 430 </verbatim>
2e275c1… drh 431
2e275c1… drh 432 A <i>tag</i> is a name that is attached to a check-in. A
b882c62… wyoung 433 <i>property</i> is a name/value pair. Internally, Fossil implements
2e275c1… drh 434 tags as properties with a NULL value. So, tags and properties really
2e275c1… drh 435 are much the same thing, and henceforth we will use the word "tag"
aafcf6c… jan.nijtmans 436 to mean either a tag or a property.
2e275c1… drh 437
aafcf6c… jan.nijtmans 438 A tag can be a one-time tag, a propagating tag or a cancellation tag.
dc1a5cf… drh 439 A one-time tag only applies to the check-in to which it is attached. A
2e275c1… drh 440 propagating tag applies to the check-in to which it is attached and also
2e275c1… drh 441 to all direct descendants of that check-in. A <i>direct descendant</i>
bdc892f… drh 442 is a descendant through direct children. Tag propagation does not
2e275c1… drh 443 cross merges. Tag propagation also stops as soon
2e275c1… drh 444 as it encounters another check-in with the same tag. A cancellation tag
2e275c1… drh 445 is attached to a single check-in in order to either override a one-time
766bec0… drh 446 tag that was previously placed on that same check-in, or to block
766bec0… drh 447 tag propagation from an ancestor.
2e275c1… drh 448
fe38a76… drh 449 The initial check-in of every repository has two propagating tags. In
b882c62… wyoung 450 Figure 5, that initial check-in is check-in 1. The <b>branch</b> tag
aafcf6c… jan.nijtmans 451 tells (by its value) what branch the check-in is a member of.
d06396d… drh 452 The default branch is called "trunk." All tags that begin with "<b>sym-</b>"
2e275c1… drh 453 are symbolic name tags. When a symbolic name tag is attached to a
2e275c1… drh 454 check-in, that allows you to refer to that check-in by its symbolic
796db89… drh 455 name rather than by its hexadecimal hash name. When a symbolic name
2e275c1… drh 456 tag propagates (as does the <b>sym-trunk</b> tag) then referring to that
2e275c1… drh 457 name is the same as referring to the most recent check-in with that name.
d06396d… drh 458 Thus the two tags on check-in 1 cause all descendants to be in the
d06396d… drh 459 "trunk" branch and to have the symbolic name "trunk."
2e275c1… drh 460
2e275c1… drh 461 Check-in 4 has a <b>branch</b> tag which changes the name of the branch
d06396d… drh 462 to "test." The branch tag on check-in 4 propagates to check-ins 6 and 9.
2e275c1… drh 463 But because tag propagation does not follow merge links, the <b>branch=test</b>
5e4b163… eric 464 tag does not propagate to check-ins 7, 8, or 10. Note also that the
2e275c1… drh 465 <b>branch</b> tag on check-in 4 blocks the propagation of <b>branch=trunk</b>
2e275c1… drh 466 so that it cannot reach check-ins 6 or 9. This causes check-ins 4, 6, and
2e275c1… drh 467 9 to be in the "test" branch and all others to be in the "trunk" branch.
2e275c1… drh 468
2e275c1… drh 469 Check-in 4 also has a <b>sym-test</b> tag, which gives the symbolic name
2e275c1… drh 470 "test" to check-ins 4, 6, and 9. Because tags do not propagate across
5e4b163… eric 471 merges, check-ins 7, 8, and 10 do not inherit the <b>sym-test</b> tag and
d06396d… drh 472 are hence not known by the name "test."
aafcf6c… jan.nijtmans 473 To prevent the <b>sym-trunk</b> tag from propagating from check-in 1
aafcf6c… jan.nijtmans 474 into check-ins 4, 6, and 9, there is a cancellation tag for
d06396d… drh 475 <b>sym-trunk</b> on check-in 4. The net effect is that
2e275c1… drh 476 check-ins on the trunk go by the symbolic name of "trunk" and check-ins
d06396d… drh 477 on the test branch go by the symbolic name "test."
2e275c1… drh 478
2e275c1… drh 479 The <b>bgcolor=blue</b> tag on check-in 4 causes the background color
766bec0… drh 480 of timelines to be blue for check-in 4 and its direct descendants.
2e275c1… drh 481
2e275c1… drh 482 Figure 5 also shows two one-time tags on check-in 9. (The diagram does
2e275c1… drh 483 not make a graphical distinction between one-time and propagating tags.)
2e275c1… drh 484 The <b>sym-release-1.0</b> tag means that check-in 9 can be referred to
d06396d… drh 485 using the more meaningful name "release-1.0." The <b>closed</b> tag means
aafcf6c… jan.nijtmans 486 that check-in 9 is a "closed leaf." A closed leaf is a leaf that should
d06396d… drh 487 never have direct children.
aafcf6c… jan.nijtmans 488
efb104b… wyoung 489 <h2 id="bad-fork">How Can Forks Divide Development Effort?</h2>
efb104b… wyoung 490
862b77b… wyoung 491 [#dist-clone|Above], we stated that forks carry a risk that development
efb104b… wyoung 492 effort on a branch can be divided among the forks. It might not be
efb104b… wyoung 493 immediately obvious why this is so. To see it, consider this swim lane
efb104b… wyoung 494 diagram:
efb104b… wyoung 495
b3d99d9… wyoung 496 <verbatim type="pikchr center toggle">
0b2f838… drh 497 $laneh = 0.75
0b2f838… drh 498
299e064… drh 499 ALL: [
0b2f838… drh 500 # Draw the lanes
0b2f838… drh 501 down
0b2f838… drh 502 box width 3.5in height $laneh fill 0xacc9e3
0b2f838… drh 503 box same fill 0xc5d8ef
0b2f838… drh 504 box same as first box
0b2f838… drh 505 box same as 2nd box
0b2f838… drh 506 line from 1st box.sw+(0.2,0) up until even with 1st box.n \
0b2f838… drh 507 "Alan" above aligned
0b2f838… drh 508 line from 2nd box.sw+(0.2,0) up until even with 2nd box.n \
0b2f838… drh 509 "Betty" above aligned
0b2f838… drh 510 line from 3rd box.sw+(0.2,0) up until even with 3rd box.n \
0b2f838… drh 511 "Charlie" above aligned
0b2f838… drh 512 line from 4th box.sw+(0.2,0) up until even with 4th box.n \
0b2f838… drh 513 "Darlene" above aligned
0b2f838… drh 514
0b2f838… drh 515 # fill in content for the Alice lane
0b2f838… drh 516 right
0b2f838… drh 517 A1: circle rad 0.1in at end of first line + (0.2,-0.2) \
0b2f838… drh 518 fill white thickness 1.5px "1"
0b2f838… drh 519 arrow right 50%
0b2f838… drh 520 circle same "2"
0b2f838… drh 521 arrow right until even with first box.e - (0.65,0.0)
0b2f838… drh 522 ellipse "future" fit fill white height 0.2 width 0.5 thickness 1.5px
0b2f838… drh 523 A3: circle same at A1+(0.8,-0.3) "3" fill 0xc0c0c0
0b2f838… drh 524 arrow from A1 to last circle chop "fork!" below aligned
0b2f838… drh 525
0b2f838… drh 526 # content for the Betty lane
0b2f838… drh 527 B1: circle same as A1 at A1-(0,$laneh) "1"
0b2f838… drh 528 arrow right 50%
0b2f838… drh 529 circle same "2"
0b2f838… drh 530 arrow right until even with first ellipse.w
0b2f838… drh 531 ellipse same "future"
0b2f838… drh 532 B3: circle same at A3-(0,$laneh) "3"
0b2f838… drh 533 arrow right 50%
0b2f838… drh 534 circle same as A3 "4"
0b2f838… drh 535 arrow from B1 to 2nd last circle chop
0b2f838… drh 536
0b2f838… drh 537 # content for the Charlie lane
0b2f838… drh 538 C1: circle same as A1 at B1-(0,$laneh) "1"
0b2f838… drh 539 arrow 50%
0b2f838… drh 540 circle same "2"
0b2f838… drh 541 arrow right 0.8in "goes" "offline"
0b2f838… drh 542 C5: circle same as A3 "5"
c3bb7cd… drh 543 arrow right until even with first ellipse.w \
c3bb7cd… drh 544 "back online" above "pushes 5" below "pulls 3 &amp; 4" below
0b2f838… drh 545 ellipse same "future"
0b2f838… drh 546
0b2f838… drh 547 # content for the Darlene lane
0b2f838… drh 548 D1: circle same as A1 at C1-(0,$laneh) "1"
0b2f838… drh 549 arrow 50%
0b2f838… drh 550 circle same "2"
0b2f838… drh 551 arrow right until even with C5.w
0b2f838… drh 552 circle same "5"
0b2f838… drh 553 arrow 50%
0b2f838… drh 554 circle same as A3 "6"
0b2f838… drh 555 arrow right until even with first ellipse.w
0b2f838… drh 556 ellipse same "future"
0b2f838… drh 557 D3: circle same as B3 at B3-(0,2*$laneh) "3"
0b2f838… drh 558 arrow 50%
0b2f838… drh 559 circle same "4"
0b2f838… drh 560 arrow from D1 to D3 chop
299e064… drh 561 ]
299e064… drh 562 box invis "Figure 6" big fit with .n at 0.2cm below ALL.s
0b2f838… drh 563 </verbatim>
862b77b… wyoung 564
862b77b… wyoung 565 This is a happy, cooperating team. That is an important restriction on
862b77b… wyoung 566 our example, because you must understand that this sort of problem can
862b77b… wyoung 567 arise without any malice, selfishness, or willful ignorance in sight.
862b77b… wyoung 568 All users on this diagram start out with the same view of the
862b77b… wyoung 569 repository, cloned from the same master repo, and all of them are
862b77b… wyoung 570 working toward their shared vision of a unified future.
862b77b… wyoung 571
862b77b… wyoung 572 All users, except possibly Alan, start out with the same two initial
f8d210a… wyoung 573 check-ins in their local working clones, 1 & 2. It might be that Alan
862b77b… wyoung 574 starts out with only check-in 1 in his local clone, but we'll deal with
862b77b… wyoung 575 that detail later.
862b77b… wyoung 576
862b77b… wyoung 577 It doesn't matter which branch this happy team is working on, only that
cdd5e57… wyoung 578 our example makes the most sense if you think of it as a long-lived shared
cdd5e57… wyoung 579 working branch like trunk. Each user makes
862b77b… wyoung 580 only one check-in, shaded light gray in the diagram.
862b77b… wyoung 581
862b77b… wyoung 582 <h3 id="bf-alan">Step 1: Alan</h3>
862b77b… wyoung 583
862b77b… wyoung 584 Alan sets the stage for this problem by creating a
862b77b… wyoung 585 fork from check-in 1 as check-in 3. How and why Alan did this doesn't
862b77b… wyoung 586 affect what happens next, though we will walk through the possible cases
862b77b… wyoung 587 and attempt to assign blame [#post-mortem|in the <i>post mortem</i>].
862b77b… wyoung 588 For now, you can assume that Alan did this out of unavoidable ignorance.
862b77b… wyoung 589
862b77b… wyoung 590 <h3 id="bf-betty">Step 2: Betty</h3>
862b77b… wyoung 591
862b77b… wyoung 592 Because Betty's local clone is autosyncing with
70a7db8… wyoung 593 the same upstream repository as Alan's clone, there are a number of ways
70a7db8… wyoung 594 she can end up seeing Alan's check-in 3 as the latest on that branch:
70a7db8… wyoung 595
70a7db8… wyoung 596 <ol>
70a7db8… wyoung 597 <li><p>The working check-out directory she's using at the moment was
70a7db8… wyoung 598 on a different branch at the time Alan made check-in 3, so Fossil
70a7db8… wyoung 599 sees that as the tip at the time she switches her working directory
862b77b… wyoung 600 to that branch with a <b>fossil update $BRANCH</b> command. (There is an
862b77b… wyoung 601 implicit autosync in that command, if the option was enabled at the
862b77b… wyoung 602 time of the update.)</p></li>
70a7db8… wyoung 603
70a7db8… wyoung 604 <li><p>The same thing, only in a fresh checkout directory with a
c64f28d… drh 605 <b>[/help/open | fossil open $REPO $BRANCH]</b> command.</p></li>
70a7db8… wyoung 606
70a7db8… wyoung 607 <li><p>Alan makes his check-in 3 while Betty has check-in 1 or 2 as
70a7db8… wyoung 608 the tip in her local clone, but because she's working with an
70a7db8… wyoung 609 autosync'd connection to the same upstream repository as Alan, on
70a7db8… wyoung 610 attempting what will become check-in 4, she gets the "would fork"
f8d210a… wyoung 611 message from <b>fossil commit</b>, so she dutifully updates her clone
70a7db8… wyoung 612 and tries again, moving her work to be a child of the new tip,
70a7db8… wyoung 613 check-in 3. (If she doesn't update, she creates a <i>second</i>
70a7db8… wyoung 614 fork, which simply complicates matters beyond what we need here for
70a7db8… wyoung 615 our illustration.)</p></li>
70a7db8… wyoung 616 </ol>
70a7db8… wyoung 617
70a7db8… wyoung 618 For our purposes here, it doesn't really matter which one happened. All
862b77b… wyoung 619 that matters is that Alan's check-in 3 becomes the parent of Betty's
862b77b… wyoung 620 check-in 4 because it was the newest tip of the working branch at the
862b77b… wyoung 621 time Betty does her check-in.
862b77b… wyoung 622
862b77b… wyoung 623 <h3 id="bf-charlie">Step 3: Charlie</h3>
70a7db8… wyoung 624
862b77b… wyoung 625 Meanwhile, Charlie went offline after syncing
70a7db8… wyoung 626 his repo with check-in 2 as the latest on that branch. When he checks
70a7db8… wyoung 627 his changes in, it is as a child of 2, not of 4, because Charlie doesn't
70a7db8… wyoung 628 know about check-ins 3 & 4 yet. He does this at an absolute wall clock
70a7db8… wyoung 629 time <i>after</i> Alan and Betty made their check-ins, so when Charlie
70a7db8… wyoung 630 comes back online and pushes his check-in 5 to the master repository and
70a7db8… wyoung 631 learns about check-ins 3 and 4 during Fossil sync, Charlie inadvertently
70a7db8… wyoung 632 revives the other side of the fork.
70a7db8… wyoung 633
862b77b… wyoung 634 <h3 id="bf-darlene">Step 4: Darlene</h3>
862b77b… wyoung 635
862b77b… wyoung 636 Darlene sees all of this, because she joins in
70a7db8… wyoung 637 on the work on this branch after Alan, Betty, and Charlie made their
70a7db8… wyoung 638 check-ins and pushed them to the master repository. She's taking one of
70a7db8… wyoung 639 the same three steps as we [#bf-betty|outlined for Betty above].
70a7db8… wyoung 640 Regardless of her path to this view, it happens after Charlie pushed his
70a7db8… wyoung 641 check-in 5 to the master repo, so Darlene sees that as the latest on the
70a7db8… wyoung 642 branch, causing her work to be saved as a child of check-in 5, not of
70a7db8… wyoung 643 check-in 4, as it would if Charlie didn't come back online and sync
cdd5e57… wyoung 644 before Darlene started work on that branch.
2ac5bc3… wyoung 645
2ac5bc3… wyoung 646 <h3 id="post-mortem">Post Mortem</h3>
2ac5bc3… wyoung 647
862b77b… wyoung 648 The end result of all of this is that even though everyone makes only one check-in
862b77b… wyoung 649 and no one disables autosync without genuine need,
862b77b… wyoung 650 half of the check-ins end up on one side of the fork and half on
862b77b… wyoung 651 the other.
862b77b… wyoung 652
862b77b… wyoung 653 A future user — his mother calls him Edward, but please call him Eddie —
70a7db8… wyoung 654 can then join in on the work on this branch and end up on <i>either</i> side of
70a7db8… wyoung 655 the fork. If Eddie joins in with the state of the repository as drawn
2ac5bc3… wyoung 656 above, he'll end up on the top side of the fork, because check-in 6 is
2ac5bc3… wyoung 657 the latest, but if Alan or Betty makes a seventh check-in to that branch
2ac5bc3… wyoung 658 first, it will be as a child of check-in 4 since that's the version in
2ac5bc3… wyoung 659 their local check-out directories. Since that check-in 7 will then be the latest,
2ac5bc3… wyoung 660 Eddie will end up on the bottom side of the fork instead.
c16f7cb… wyoung 661
c16f7cb… wyoung 662 In all of this, realize that neither side of the fork is obviously
efb104b… wyoung 663 "correct." Every participant was doing the right thing by their own
70a7db8… wyoung 664 lights at the time they made their lone check-in.
70a7db8… wyoung 665
70a7db8… wyoung 666 Who, then, is to blame?
70a7db8… wyoung 667
70a7db8… wyoung 668 We can only blame the consequences of creating the fork on Alan if he
70a7db8… wyoung 669 did so on purpose, as by passing "--allow-fork" when creating a check-in
70a7db8… wyoung 670 on a shared working branch. Alan might have created it inadvertently by
70a7db8… wyoung 671 going offline while check-in 1 was the tip of the branch in his local
70a7db8… wyoung 672 clone, so that by the time he made his check-in 3, check-in 2 had
70a7db8… wyoung 673 arrived at the shared parent repository from someone else. (Francine?)
70a7db8… wyoung 674 When Alan rejoins the network and does an autosync, he learns about
70a7db8… wyoung 675 check-in 2. Since his #3 is already checked into his local clone because
70a7db8… wyoung 676 autosync was off or blocked, the sync creates an unavoidable fork. We
70a7db8… wyoung 677 can't blame either Alan or Francine here: they were both doing the right
70a7db8… wyoung 678 thing given their imperfect view of the state of the global situation.
70a7db8… wyoung 679
70a7db8… wyoung 680 The same is true of Betty, Charlie, and Darlene. None of them tried to
70a7db8… wyoung 681 create a fork, and none of them chose a side in this fork to participate
70a7db8… wyoung 682 in. They just took Fossil's default and assumed it was correct.
70a7db8… wyoung 683
70a7db8… wyoung 684 The only blame I can assign here is on any of these users who believed
862b77b… wyoung 685 forks couldn't happen before this did occur, and I blame them only for
862b77b… wyoung 686 their avoidable ignorance. (You, dear reader, have been ejected from
862b77b… wyoung 687 that category by reading this very document.) Any time someone can work
862b77b… wyoung 688 without getting full coordination from every other clone of the repo,
862b77b… wyoung 689 forks are possible. Given enough time, they're all but inevitable. This
862b77b… wyoung 690 is a general property of DVCSes, not just of Fossil.
70a7db8… wyoung 691
70a7db8… wyoung 692 This sort of consequence is why forks on shared working branches are
862b77b… wyoung 693 bad, which is why [./concepts.wiki#workflow|Fossil tries so hard to avoid them], why it warns you
862b77b… wyoung 694 about it when they do occur, and why it makes it relatively [#fix|quick and
862b77b… wyoung 695 painless to fix them] when they do occur.
efb104b… wyoung 696
efb104b… wyoung 697
2e275c1… drh 698 <h2>Review Of Terminology</h2>
2e275c1… drh 699
8a1ba49… wyoung 700 <dl>
2e275c1… drh 701 <dt><b>Branch</b></dt>
d06396d… drh 702 <dd><p>A branch is a set of check-ins with the same value for their
c1c18b7… drh 703 "branch" property.</p></dd>
2e275c1… drh 704 <dt><b>Leaf</b></dt>
d06396d… drh 705 <dd><p>A leaf is a check-in with no children in the same branch.</p></dd>
2e275c1… drh 706 <dt><b>Closed Leaf</b></dt>
d06396d… drh 707 <dd><p>A closed leaf is any leaf with the <b>closed</b> tag. These leaves
d06396d… drh 708 are intended to never be extended with descendants and hence are omitted
2e275c1… drh 709 from lists of leaves in the command-line and web interface.</p></dd>
2e275c1… drh 710 <dt><b>Open Leaf</b></dt>
2e275c1… drh 711 <dd><p>A open leaf is a leaf that is not closed.</p></dd>
2e275c1… drh 712 <dt><b>Fork</b></dt>
d06396d… drh 713 <dd><p>A fork is when a check-in has two or more direct (non-merge)
2e275c1… drh 714 children in the same branch.</p></dd>
2e275c1… drh 715 <dt><b>Branch Point</b></dt>
2e275c1… drh 716 <dd><p>A branch point occurs when a check-in has two or more direct (non-merge)
d06396d… drh 717 children in different branches. A branch point is similar to a fork,
2e275c1… drh 718 except that the children are in different branches.</p></dd>
8a1ba49… wyoung 719 </dl>
2e275c1… drh 720
b882c62… wyoung 721 Check-in 4 of Figure 3 is not a leaf because it has a child (check-in 5)
b882c62… wyoung 722 in the same branch. Check-in 9 of Figure 5 also has a child (check-in 10)
2e275c1… drh 723 but that child is in a different branch, so check-in 9 is a leaf. Because
d06396d… drh 724 of the <b>closed</b> tag on check-in 9, it is a closed leaf.
2e275c1… drh 725
b882c62… wyoung 726 Check-in 2 of Figure 3 is considered a "fork"
b882c62… wyoung 727 because it has two children in the same branch. Check-in 2 of Figure 5
2e275c1… drh 728 also has two children, but each child is in a different branch, hence in
b882c62… wyoung 729 Figure 5, check-in 2 is considered a "branch point."
c1c18b7… drh 730
c1c18b7… drh 731 <h2>Differences With Other DVCSes</h2>
b882c62… wyoung 732
42bfe93… wyoung 733 <h3 id="single">Single DAG</h3>
42bfe93… wyoung 734
c1c18b7… drh 735 Fossil keeps all check-ins on a single DAG. Branches are identified with
c1c18b7… drh 736 tags. This means that check-ins can be freely moved between branches
d06396d… drh 737 simply by altering their tags.
c1c18b7… drh 738
c1c18b7… drh 739 Most other DVCSes maintain a separate DAG for each branch.
42bfe93… wyoung 740
42bfe93… wyoung 741 <h3 id="unique">Branch Names Need Not Be Unique</h3>
42bfe93… wyoung 742
42bfe93… wyoung 743 Fossil does not require that branch names be unique, as in some VCSes,
42bfe93… wyoung 744 most notably Git. Just as with unnamed branches (which we call forks)
42bfe93… wyoung 745 Fossil resolves such ambiguities using the timestamps on the latest
f8d210a… wyoung 746 check-in in each branch. If you have two branches named "foo" and you say
f8d210a… wyoung 747 <b>fossil update foo</b>, you get the tip of the "foo" branch with the most
f8d210a… wyoung 748 recent check-in.
42bfe93… wyoung 749
42bfe93… wyoung 750 This fact is helpful because it means you can reuse branch names, which
42bfe93… wyoung 751 is especially useful with utility branches. There are several of these
42bfe93… wyoung 752 in the SQLite and Fossil repositories: "broken-build," "declined,"
42bfe93… wyoung 753 "mistake," etc. As you might guess from these names, such branch names
42bfe93… wyoung 754 are used in renaming the tip of one branch to shunt it off away from the
f8d210a… wyoung 755 mainline of that branch due to some human error. (See
c64f28d… drh 756 <b>[/help/amend | fossil
f8d210a… wyoung 757 amend]</b> and the Fossil UI check-in amendment features.) This is a
42bfe93… wyoung 758 workaround for Fossil's [./shunning.wiki|normal inability to forget
42bfe93… wyoung 759 history]: we usually don't want to actually <i>remove</i> history, but
42bfe93… wyoung 760 would like to sometimes set some of it aside under a new label.
42bfe93… wyoung 761
42bfe93… wyoung 762 Because some VCSes can't cope with duplicate branch names, Fossil
0996347… wyoung 763 collapses such names down on export using the same time stamp based
f8d210a… wyoung 764 arbitration logic, so that only the branch with the newest check-in gets
42bfe93… wyoung 765 the branch name in the export.
42bfe93… wyoung 766
42bfe93… wyoung 767 All of the above is true of tags in general, not just branches.

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button