Fossil SCM
Assorted improvements to the new material in www/branching.wiki, mainly in the way of clarifications and moderation of tone.
Commit
862b77b69aae9e0b1c7eb49135342a982b51e9840b84bf759894c6a981dd8b89
Parent
5050132815737a5…
1 file changed
+88
-55
+88
-55
| --- www/branching.wiki | ||
| +++ www/branching.wiki | ||
| @@ -234,37 +234,50 @@ | ||
| 234 | 234 | |
| 235 | 235 | The primary cases where forking is justified over branching are all when |
| 236 | 236 | it is done purely in software in order to avoid losing information: |
| 237 | 237 | |
| 238 | 238 | <ol> |
| 239 | - <li><p>By Fossil itself when two users check in children to the same | |
| 239 | + <li><p id="offline">By Fossil itself when two users check in children to the same | |
| 240 | 240 | leaf of a branch, as in Figure 2. If the fork occurs because |
| 241 | 241 | autosync is disabled on one or both of the repositories or because |
| 242 | 242 | the user doing the check-in has no network connection at the moment |
| 243 | 243 | of the commit, Fossil has no way of knowing that it is creating a |
| 244 | 244 | fork until the two repositories are later sync'd.</p></li> |
| 245 | 245 | |
| 246 | - <li><p>By Fossil when the cloning hierarchy is more than 2 levels | |
| 247 | - deep. If your master repository is cloned by user A and then user B | |
| 248 | - clones from user A's repository, a check-in by user B will cause | |
| 249 | - that repo to attempt an autosync with user A's repo before allowing | |
| 250 | - the checkin, but it will <i>not</i> check with the master repo as | |
| 251 | - well. It isn't until user A syncs her repo with the | |
| 252 | - master repo that an inadvertent fork can be detected. | |
| 246 | + <li><p id="dist-clone">By Fossil when the cloning hierarchy is more | |
| 247 | + than 2 levels deep. | |
| 248 | + <br><br> | |
| 249 | + [./sync.wiki|Fossil's synchronication protocol] is a two-party | |
| 250 | + negotiation; syncs don't automatically propagate up the clone tree | |
| 251 | + beyond that. Because of that, if you have a master repository and | |
| 252 | + Alice clones it, then Bobby clones from Alice's repository, a | |
| 253 | + check-in by Bobby that autosyncs with Alice's repo will <i>not</i> | |
| 254 | + also autosync with the master repo. The master doesn't get a copy of | |
| 255 | + Bobby's checkin until Alice <i>separately</i> syncs with the master. | |
| 256 | + If Carol cloned from the master repo and checks something in that | |
| 257 | + creates a fork relative to Bobby's check-in, the master repo won't | |
| 258 | + know about that fork until Alice syncs her repo with the master. | |
| 259 | + Even then, realize that Carol still won't know about the fork until | |
| 260 | + she subsequently syncs with the master repo. | |
| 261 | + <br><br> | |
| 262 | + One way to deal with this is to just accept it as a fact of using a | |
| 263 | + [https://en.wikipedia.org/wiki/Distributed_version_control|Distributed | |
| 264 | + Version Control System] like Fossil. | |
| 253 | 265 | <br><br> |
| 254 | - Because of this, we recommend that if you're using Fossil in a | |
| 255 | - distributed way like this, that check-ins be made only to the master | |
| 256 | - or its immediate child repos, and that those further down the chain | |
| 257 | - be read-only clones. This is not to say that we repudiate Fossil's | |
| 258 | - use as a | |
| 259 | - [https://en.wikipedia.org/wiki/Distributed_version_control|Distributed Version Control System], | |
| 260 | - just that such use is | |
| 261 | - prone to creating inadvertent forks by the very nature of distributed development. | |
| 262 | - We make a more complete argument that [#bad-fork|forks on long-lived | |
| 263 | - shared working branches are a problem] below.</p></li> | |
| 264 | - | |
| 265 | - <li><p>You've automated Fossil (e.g. with a shell script) and | |
| 266 | + Another option, which we recommend you consider carefully, is to | |
| 267 | + make it a local policy that checkins be made only against the master | |
| 268 | + repo or one of its immediate child clones so that the autosync | |
| 269 | + algorithm can do its job most effectively; any clones deeper than | |
| 270 | + that should be treated as read-only and thus get a copy of the new | |
| 271 | + state of the world only once these central repos have negotiated | |
| 272 | + that new state. This policy avoids a class of inadvertent fork you | |
| 273 | + might not need to tolerate. Since [#bad-fork|forks on long-lived | |
| 274 | + shared working branches can end up dividing a team's development | |
| 275 | + effort], a team may easily justify this restriction on distributed | |
| 276 | + cloning.</p></li> | |
| 277 | + | |
| 278 | + <li><p id="automation">You've automated Fossil (e.g. with a shell script) and | |
| 266 | 279 | forking is a possibility, so you write <b>fossil commit |
| 267 | 280 | --allow-fork</b> commands to prevent Fossil from refusing the |
| 268 | 281 | check-in because it would create a fork. It's better to write such |
| 269 | 282 | a script to detect this condition and cope with it (e.g. <b>fossil |
| 270 | 283 | update</b>) but if the alternative is losing information, you may |
| @@ -370,11 +383,11 @@ | ||
| 370 | 383 | that check-in 9 is a "closed leaf." A closed leaf is a leaf that should |
| 371 | 384 | never have direct children. |
| 372 | 385 | |
| 373 | 386 | <h2 id="bad-fork">How Can Forks Divide Development Effort?</h2> |
| 374 | 387 | |
| 375 | -[#forking|Above], we stated that forks carry a risk that development | |
| 388 | +[#dist-clone|Above], we stated that forks carry a risk that development | |
| 376 | 389 | effort on a branch can be divided among the forks. It might not be |
| 377 | 390 | immediately obvious why this is so. To see it, consider this swim lane |
| 378 | 391 | diagram: |
| 379 | 392 | |
| 380 | 393 | <table border=1 cellpadding=10 hspace=10 vspace=10 align="center"> |
| @@ -381,36 +394,47 @@ | ||
| 381 | 394 | <tr><td align="center"> |
| 382 | 395 | <img src="branch06.svg"><br> |
| 383 | 396 | Figure 6 |
| 384 | 397 | </td></tr></table> |
| 385 | 398 | |
| 386 | -All users in this diagram start off with the same two checkins at the | |
| 387 | -tip of the working branch, 1 and 2, they're all cloned directly from the | |
| 388 | -same master repository, and they're all working towards some indefinite, | |
| 389 | -unified future. This is a happy, cooperating team, with no malice or | |
| 390 | -selfishness in sight. This is all happening on some long-lived, shared | |
| 391 | -working branch, such as trunk, though it could be anything else that | |
| 392 | -matches those same qualifiers. Each user makes only one check-in, shaded | |
| 393 | -light gray. | |
| 394 | - | |
| 395 | -<a name="bf-alan"></a>Alan sets the stage for this problem by creating a | |
| 396 | -fork from check-in 1 as check-in 3. This has consequences which will | |
| 397 | -occur regardless of how or why that fork occurred, so we can ignore both | |
| 398 | -questions for now. We'll come back to these questions later in | |
| 399 | -[#post-mortem|the <i>post mortem</i> below]. | |
| 400 | - | |
| 401 | -<a name="bf-betty"></a>Because Betty's local clone is autosyncing with | |
| 399 | +This is a happy, cooperating team. That is an important restriction on | |
| 400 | +our example, because you must understand that this sort of problem can | |
| 401 | +arise without any malice, selfishness, or willful ignorance in sight. | |
| 402 | +All users on this diagram start out with the same view of the | |
| 403 | +repository, cloned from the same master repo, and all of them are | |
| 404 | +working toward their shared vision of a unified future. | |
| 405 | + | |
| 406 | +All users, except possibly Alan, start out with the same two initial | |
| 407 | +checkins in their local working clones, 1 & 2. It might be that Alan | |
| 408 | +starts out with only check-in 1 in his local clone, but we'll deal with | |
| 409 | +that detail later. | |
| 410 | + | |
| 411 | +It doesn't matter which branch this happy team is working on, only that | |
| 412 | +it be a long-lived shared working branch like trunk. Each user makes | |
| 413 | +only one check-in, shaded light gray in the diagram. | |
| 414 | + | |
| 415 | +<h3 id="bf-alan">Step 1: Alan</h3> | |
| 416 | + | |
| 417 | +Alan sets the stage for this problem by creating a | |
| 418 | +fork from check-in 1 as check-in 3. How and why Alan did this doesn't | |
| 419 | +affect what happens next, though we will walk through the possible cases | |
| 420 | +and attempt to assign blame [#post-mortem|in the <i>post mortem</i>]. | |
| 421 | +For now, you can assume that Alan did this out of unavoidable ignorance. | |
| 422 | + | |
| 423 | +<h3 id="bf-betty">Step 2: Betty</h3> | |
| 424 | + | |
| 425 | +Because Betty's local clone is autosyncing with | |
| 402 | 426 | the same upstream repository as Alan's clone, there are a number of ways |
| 403 | 427 | she can end up seeing Alan's check-in 3 as the latest on that branch: |
| 404 | 428 | |
| 405 | 429 | <ol> |
| 406 | 430 | <li><p>The working check-out directory she's using at the moment was |
| 407 | 431 | on a different branch at the time Alan made check-in 3, so Fossil |
| 408 | 432 | sees that as the tip at the time she switches her working directory |
| 409 | - to that branch with a <b>fossil update</b> command. (There is an | |
| 410 | - implicit autosync before <b>update</b> if that option is enabled at | |
| 411 | - the time.)</p></li> | |
| 433 | + to that branch with a <b>fossil update $BRANCH</b> command. (There is an | |
| 434 | + implicit autosync in that command, if the option was enabled at the | |
| 435 | + time of the update.)</p></li> | |
| 412 | 436 | |
| 413 | 437 | <li><p>The same thing, only in a fresh checkout directory with a |
| 414 | 438 | <b>fossil open $REPO $BRANCH</b> command.</p></li> |
| 415 | 439 | |
| 416 | 440 | <li><p>Alan makes his check-in 3 while Betty has check-in 1 or 2 as |
| @@ -423,23 +447,28 @@ | ||
| 423 | 447 | fork, which simply complicates matters beyond what we need here for |
| 424 | 448 | our illustration.)</p></li> |
| 425 | 449 | </ol> |
| 426 | 450 | |
| 427 | 451 | For our purposes here, it doesn't really matter which one happened. All |
| 428 | -that matters is that this new branch tip becomes the parent of Betty's | |
| 429 | -check-in 4. | |
| 452 | +that matters is that Alan's check-in 3 becomes the parent of Betty's | |
| 453 | +check-in 4 because it was the newest tip of the working branch at the | |
| 454 | +time Betty does her check-in. | |
| 455 | + | |
| 456 | +<h3 id="bf-charlie">Step 3: Charlie</h3> | |
| 430 | 457 | |
| 431 | -<a name="bf-charlie"></a>Meanwhile, Charlie went offline after syncing | |
| 458 | +Meanwhile, Charlie went offline after syncing | |
| 432 | 459 | his repo with check-in 2 as the latest on that branch. When he checks |
| 433 | 460 | his changes in, it is as a child of 2, not of 4, because Charlie doesn't |
| 434 | 461 | know about check-ins 3 & 4 yet. He does this at an absolute wall clock |
| 435 | 462 | time <i>after</i> Alan and Betty made their check-ins, so when Charlie |
| 436 | 463 | comes back online and pushes his check-in 5 to the master repository and |
| 437 | 464 | learns about check-ins 3 and 4 during Fossil sync, Charlie inadvertently |
| 438 | 465 | revives the other side of the fork. |
| 439 | 466 | |
| 440 | -<a name="bf-darlene"></a>Darlene sees all of this, because she joins in | |
| 467 | +<h3 id="bf-darlene">Step 4: Darlene</h3> | |
| 468 | + | |
| 469 | +Darlene sees all of this, because she joins in | |
| 441 | 470 | on the work on this branch after Alan, Betty, and Charlie made their |
| 442 | 471 | check-ins and pushed them to the master repository. She's taking one of |
| 443 | 472 | the same three steps as we [#bf-betty|outlined for Betty above]. |
| 444 | 473 | Regardless of her path to this view, it happens after Charlie pushed his |
| 445 | 474 | check-in 5 to the master repo, so Darlene sees that as the latest on the |
| @@ -447,13 +476,16 @@ | ||
| 447 | 476 | check-in 4, as it would if Charlie didn't come back online and sync |
| 448 | 477 | before Darlene started work on that branch up. |
| 449 | 478 | |
| 450 | 479 | <h3 id="post-mortem">Post Mortem</h3> |
| 451 | 480 | |
| 452 | -The end result of all of this is that everyone makes only one check-in, | |
| 453 | -but half of the check-ins are on one side of the fork, and half are on | |
| 454 | -the other. A future user — his mother calls him Edward, but please call him Eddie — | |
| 481 | +The end result of all of this is that even though everyone makes only one check-in | |
| 482 | +and no one disables autosync without genuine need, | |
| 483 | +half of the check-ins end up on one side of the fork and half on | |
| 484 | +the other. | |
| 485 | + | |
| 486 | +A future user — his mother calls him Edward, but please call him Eddie — | |
| 455 | 487 | can then join in on the work on this branch and end up on <i>either</i> side of |
| 456 | 488 | the fork. If Eddie joins in with the state of the repository as drawn |
| 457 | 489 | above, he'll end up on the top side of the fork, because check-in 6 is |
| 458 | 490 | the latest, but if Alan or Betty makes a seventh check-in to that branch |
| 459 | 491 | first, it will be as a child of check-in 4 since that's the version in |
| @@ -481,20 +513,21 @@ | ||
| 481 | 513 | The same is true of Betty, Charlie, and Darlene. None of them tried to |
| 482 | 514 | create a fork, and none of them chose a side in this fork to participate |
| 483 | 515 | in. They just took Fossil's default and assumed it was correct. |
| 484 | 516 | |
| 485 | 517 | The only blame I can assign here is on any of these users who believed |
| 486 | -forks couldn't happen before this did occur, and that's for their | |
| 487 | -ignorance. (Which isn't you, dear reader, now.) Any time someone can | |
| 488 | -work without getting full coordination from every other clone of the | |
| 489 | -repo, forks are possible. Given enough time, they're all but | |
| 490 | -inevitable. | |
| 518 | +forks couldn't happen before this did occur, and I blame them only for | |
| 519 | +their avoidable ignorance. (You, dear reader, have been ejected from | |
| 520 | +that category by reading this very document.) Any time someone can work | |
| 521 | +without getting full coordination from every other clone of the repo, | |
| 522 | +forks are possible. Given enough time, they're all but inevitable. This | |
| 523 | +is a general property of DVCSes, not just of Fossil. | |
| 491 | 524 | |
| 492 | 525 | This sort of consequence is why forks on shared working branches are |
| 493 | -bad, which is why Fossil tries so hard to avoid them, why it warns you | |
| 494 | -about it when they do occur, and why it makes it relatively quick and | |
| 495 | -painless to fix them when they do occur. | |
| 526 | +bad, which is why [./concepts.wiki#workflow|Fossil tries so hard to avoid them], why it warns you | |
| 527 | +about it when they do occur, and why it makes it relatively [#fix|quick and | |
| 528 | +painless to fix them] when they do occur. | |
| 496 | 529 | |
| 497 | 530 | |
| 498 | 531 | <h2>Review Of Terminology</h2> |
| 499 | 532 | |
| 500 | 533 | <blockquote><dl> |
| 501 | 534 |
| --- www/branching.wiki | |
| +++ www/branching.wiki | |
| @@ -234,37 +234,50 @@ | |
| 234 | |
| 235 | The primary cases where forking is justified over branching are all when |
| 236 | it is done purely in software in order to avoid losing information: |
| 237 | |
| 238 | <ol> |
| 239 | <li><p>By Fossil itself when two users check in children to the same |
| 240 | leaf of a branch, as in Figure 2. If the fork occurs because |
| 241 | autosync is disabled on one or both of the repositories or because |
| 242 | the user doing the check-in has no network connection at the moment |
| 243 | of the commit, Fossil has no way of knowing that it is creating a |
| 244 | fork until the two repositories are later sync'd.</p></li> |
| 245 | |
| 246 | <li><p>By Fossil when the cloning hierarchy is more than 2 levels |
| 247 | deep. If your master repository is cloned by user A and then user B |
| 248 | clones from user A's repository, a check-in by user B will cause |
| 249 | that repo to attempt an autosync with user A's repo before allowing |
| 250 | the checkin, but it will <i>not</i> check with the master repo as |
| 251 | well. It isn't until user A syncs her repo with the |
| 252 | master repo that an inadvertent fork can be detected. |
| 253 | <br><br> |
| 254 | Because of this, we recommend that if you're using Fossil in a |
| 255 | distributed way like this, that check-ins be made only to the master |
| 256 | or its immediate child repos, and that those further down the chain |
| 257 | be read-only clones. This is not to say that we repudiate Fossil's |
| 258 | use as a |
| 259 | [https://en.wikipedia.org/wiki/Distributed_version_control|Distributed Version Control System], |
| 260 | just that such use is |
| 261 | prone to creating inadvertent forks by the very nature of distributed development. |
| 262 | We make a more complete argument that [#bad-fork|forks on long-lived |
| 263 | shared working branches are a problem] below.</p></li> |
| 264 | |
| 265 | <li><p>You've automated Fossil (e.g. with a shell script) and |
| 266 | forking is a possibility, so you write <b>fossil commit |
| 267 | --allow-fork</b> commands to prevent Fossil from refusing the |
| 268 | check-in because it would create a fork. It's better to write such |
| 269 | a script to detect this condition and cope with it (e.g. <b>fossil |
| 270 | update</b>) but if the alternative is losing information, you may |
| @@ -370,11 +383,11 @@ | |
| 370 | that check-in 9 is a "closed leaf." A closed leaf is a leaf that should |
| 371 | never have direct children. |
| 372 | |
| 373 | <h2 id="bad-fork">How Can Forks Divide Development Effort?</h2> |
| 374 | |
| 375 | [#forking|Above], we stated that forks carry a risk that development |
| 376 | effort on a branch can be divided among the forks. It might not be |
| 377 | immediately obvious why this is so. To see it, consider this swim lane |
| 378 | diagram: |
| 379 | |
| 380 | <table border=1 cellpadding=10 hspace=10 vspace=10 align="center"> |
| @@ -381,36 +394,47 @@ | |
| 381 | <tr><td align="center"> |
| 382 | <img src="branch06.svg"><br> |
| 383 | Figure 6 |
| 384 | </td></tr></table> |
| 385 | |
| 386 | All users in this diagram start off with the same two checkins at the |
| 387 | tip of the working branch, 1 and 2, they're all cloned directly from the |
| 388 | same master repository, and they're all working towards some indefinite, |
| 389 | unified future. This is a happy, cooperating team, with no malice or |
| 390 | selfishness in sight. This is all happening on some long-lived, shared |
| 391 | working branch, such as trunk, though it could be anything else that |
| 392 | matches those same qualifiers. Each user makes only one check-in, shaded |
| 393 | light gray. |
| 394 | |
| 395 | <a name="bf-alan"></a>Alan sets the stage for this problem by creating a |
| 396 | fork from check-in 1 as check-in 3. This has consequences which will |
| 397 | occur regardless of how or why that fork occurred, so we can ignore both |
| 398 | questions for now. We'll come back to these questions later in |
| 399 | [#post-mortem|the <i>post mortem</i> below]. |
| 400 | |
| 401 | <a name="bf-betty"></a>Because Betty's local clone is autosyncing with |
| 402 | the same upstream repository as Alan's clone, there are a number of ways |
| 403 | she can end up seeing Alan's check-in 3 as the latest on that branch: |
| 404 | |
| 405 | <ol> |
| 406 | <li><p>The working check-out directory she's using at the moment was |
| 407 | on a different branch at the time Alan made check-in 3, so Fossil |
| 408 | sees that as the tip at the time she switches her working directory |
| 409 | to that branch with a <b>fossil update</b> command. (There is an |
| 410 | implicit autosync before <b>update</b> if that option is enabled at |
| 411 | the time.)</p></li> |
| 412 | |
| 413 | <li><p>The same thing, only in a fresh checkout directory with a |
| 414 | <b>fossil open $REPO $BRANCH</b> command.</p></li> |
| 415 | |
| 416 | <li><p>Alan makes his check-in 3 while Betty has check-in 1 or 2 as |
| @@ -423,23 +447,28 @@ | |
| 423 | fork, which simply complicates matters beyond what we need here for |
| 424 | our illustration.)</p></li> |
| 425 | </ol> |
| 426 | |
| 427 | For our purposes here, it doesn't really matter which one happened. All |
| 428 | that matters is that this new branch tip becomes the parent of Betty's |
| 429 | check-in 4. |
| 430 | |
| 431 | <a name="bf-charlie"></a>Meanwhile, Charlie went offline after syncing |
| 432 | his repo with check-in 2 as the latest on that branch. When he checks |
| 433 | his changes in, it is as a child of 2, not of 4, because Charlie doesn't |
| 434 | know about check-ins 3 & 4 yet. He does this at an absolute wall clock |
| 435 | time <i>after</i> Alan and Betty made their check-ins, so when Charlie |
| 436 | comes back online and pushes his check-in 5 to the master repository and |
| 437 | learns about check-ins 3 and 4 during Fossil sync, Charlie inadvertently |
| 438 | revives the other side of the fork. |
| 439 | |
| 440 | <a name="bf-darlene"></a>Darlene sees all of this, because she joins in |
| 441 | on the work on this branch after Alan, Betty, and Charlie made their |
| 442 | check-ins and pushed them to the master repository. She's taking one of |
| 443 | the same three steps as we [#bf-betty|outlined for Betty above]. |
| 444 | Regardless of her path to this view, it happens after Charlie pushed his |
| 445 | check-in 5 to the master repo, so Darlene sees that as the latest on the |
| @@ -447,13 +476,16 @@ | |
| 447 | check-in 4, as it would if Charlie didn't come back online and sync |
| 448 | before Darlene started work on that branch up. |
| 449 | |
| 450 | <h3 id="post-mortem">Post Mortem</h3> |
| 451 | |
| 452 | The end result of all of this is that everyone makes only one check-in, |
| 453 | but half of the check-ins are on one side of the fork, and half are on |
| 454 | the other. A future user — his mother calls him Edward, but please call him Eddie — |
| 455 | can then join in on the work on this branch and end up on <i>either</i> side of |
| 456 | the fork. If Eddie joins in with the state of the repository as drawn |
| 457 | above, he'll end up on the top side of the fork, because check-in 6 is |
| 458 | the latest, but if Alan or Betty makes a seventh check-in to that branch |
| 459 | first, it will be as a child of check-in 4 since that's the version in |
| @@ -481,20 +513,21 @@ | |
| 481 | The same is true of Betty, Charlie, and Darlene. None of them tried to |
| 482 | create a fork, and none of them chose a side in this fork to participate |
| 483 | in. They just took Fossil's default and assumed it was correct. |
| 484 | |
| 485 | The only blame I can assign here is on any of these users who believed |
| 486 | forks couldn't happen before this did occur, and that's for their |
| 487 | ignorance. (Which isn't you, dear reader, now.) Any time someone can |
| 488 | work without getting full coordination from every other clone of the |
| 489 | repo, forks are possible. Given enough time, they're all but |
| 490 | inevitable. |
| 491 | |
| 492 | This sort of consequence is why forks on shared working branches are |
| 493 | bad, which is why Fossil tries so hard to avoid them, why it warns you |
| 494 | about it when they do occur, and why it makes it relatively quick and |
| 495 | painless to fix them when they do occur. |
| 496 | |
| 497 | |
| 498 | <h2>Review Of Terminology</h2> |
| 499 | |
| 500 | <blockquote><dl> |
| 501 |
| --- www/branching.wiki | |
| +++ www/branching.wiki | |
| @@ -234,37 +234,50 @@ | |
| 234 | |
| 235 | The primary cases where forking is justified over branching are all when |
| 236 | it is done purely in software in order to avoid losing information: |
| 237 | |
| 238 | <ol> |
| 239 | <li><p id="offline">By Fossil itself when two users check in children to the same |
| 240 | leaf of a branch, as in Figure 2. If the fork occurs because |
| 241 | autosync is disabled on one or both of the repositories or because |
| 242 | the user doing the check-in has no network connection at the moment |
| 243 | of the commit, Fossil has no way of knowing that it is creating a |
| 244 | fork until the two repositories are later sync'd.</p></li> |
| 245 | |
| 246 | <li><p id="dist-clone">By Fossil when the cloning hierarchy is more |
| 247 | than 2 levels deep. |
| 248 | <br><br> |
| 249 | [./sync.wiki|Fossil's synchronication protocol] is a two-party |
| 250 | negotiation; syncs don't automatically propagate up the clone tree |
| 251 | beyond that. Because of that, if you have a master repository and |
| 252 | Alice clones it, then Bobby clones from Alice's repository, a |
| 253 | check-in by Bobby that autosyncs with Alice's repo will <i>not</i> |
| 254 | also autosync with the master repo. The master doesn't get a copy of |
| 255 | Bobby's checkin until Alice <i>separately</i> syncs with the master. |
| 256 | If Carol cloned from the master repo and checks something in that |
| 257 | creates a fork relative to Bobby's check-in, the master repo won't |
| 258 | know about that fork until Alice syncs her repo with the master. |
| 259 | Even then, realize that Carol still won't know about the fork until |
| 260 | she subsequently syncs with the master repo. |
| 261 | <br><br> |
| 262 | One way to deal with this is to just accept it as a fact of using a |
| 263 | [https://en.wikipedia.org/wiki/Distributed_version_control|Distributed |
| 264 | Version Control System] like Fossil. |
| 265 | <br><br> |
| 266 | Another option, which we recommend you consider carefully, is to |
| 267 | make it a local policy that checkins be made only against the master |
| 268 | repo or one of its immediate child clones so that the autosync |
| 269 | algorithm can do its job most effectively; any clones deeper than |
| 270 | that should be treated as read-only and thus get a copy of the new |
| 271 | state of the world only once these central repos have negotiated |
| 272 | that new state. This policy avoids a class of inadvertent fork you |
| 273 | might not need to tolerate. Since [#bad-fork|forks on long-lived |
| 274 | shared working branches can end up dividing a team's development |
| 275 | effort], a team may easily justify this restriction on distributed |
| 276 | cloning.</p></li> |
| 277 | |
| 278 | <li><p id="automation">You've automated Fossil (e.g. with a shell script) and |
| 279 | forking is a possibility, so you write <b>fossil commit |
| 280 | --allow-fork</b> commands to prevent Fossil from refusing the |
| 281 | check-in because it would create a fork. It's better to write such |
| 282 | a script to detect this condition and cope with it (e.g. <b>fossil |
| 283 | update</b>) but if the alternative is losing information, you may |
| @@ -370,11 +383,11 @@ | |
| 383 | that check-in 9 is a "closed leaf." A closed leaf is a leaf that should |
| 384 | never have direct children. |
| 385 | |
| 386 | <h2 id="bad-fork">How Can Forks Divide Development Effort?</h2> |
| 387 | |
| 388 | [#dist-clone|Above], we stated that forks carry a risk that development |
| 389 | effort on a branch can be divided among the forks. It might not be |
| 390 | immediately obvious why this is so. To see it, consider this swim lane |
| 391 | diagram: |
| 392 | |
| 393 | <table border=1 cellpadding=10 hspace=10 vspace=10 align="center"> |
| @@ -381,36 +394,47 @@ | |
| 394 | <tr><td align="center"> |
| 395 | <img src="branch06.svg"><br> |
| 396 | Figure 6 |
| 397 | </td></tr></table> |
| 398 | |
| 399 | This is a happy, cooperating team. That is an important restriction on |
| 400 | our example, because you must understand that this sort of problem can |
| 401 | arise without any malice, selfishness, or willful ignorance in sight. |
| 402 | All users on this diagram start out with the same view of the |
| 403 | repository, cloned from the same master repo, and all of them are |
| 404 | working toward their shared vision of a unified future. |
| 405 | |
| 406 | All users, except possibly Alan, start out with the same two initial |
| 407 | checkins in their local working clones, 1 & 2. It might be that Alan |
| 408 | starts out with only check-in 1 in his local clone, but we'll deal with |
| 409 | that detail later. |
| 410 | |
| 411 | It doesn't matter which branch this happy team is working on, only that |
| 412 | it be a long-lived shared working branch like trunk. Each user makes |
| 413 | only one check-in, shaded light gray in the diagram. |
| 414 | |
| 415 | <h3 id="bf-alan">Step 1: Alan</h3> |
| 416 | |
| 417 | Alan sets the stage for this problem by creating a |
| 418 | fork from check-in 1 as check-in 3. How and why Alan did this doesn't |
| 419 | affect what happens next, though we will walk through the possible cases |
| 420 | and attempt to assign blame [#post-mortem|in the <i>post mortem</i>]. |
| 421 | For now, you can assume that Alan did this out of unavoidable ignorance. |
| 422 | |
| 423 | <h3 id="bf-betty">Step 2: Betty</h3> |
| 424 | |
| 425 | Because Betty's local clone is autosyncing with |
| 426 | the same upstream repository as Alan's clone, there are a number of ways |
| 427 | she can end up seeing Alan's check-in 3 as the latest on that branch: |
| 428 | |
| 429 | <ol> |
| 430 | <li><p>The working check-out directory she's using at the moment was |
| 431 | on a different branch at the time Alan made check-in 3, so Fossil |
| 432 | sees that as the tip at the time she switches her working directory |
| 433 | to that branch with a <b>fossil update $BRANCH</b> command. (There is an |
| 434 | implicit autosync in that command, if the option was enabled at the |
| 435 | time of the update.)</p></li> |
| 436 | |
| 437 | <li><p>The same thing, only in a fresh checkout directory with a |
| 438 | <b>fossil open $REPO $BRANCH</b> command.</p></li> |
| 439 | |
| 440 | <li><p>Alan makes his check-in 3 while Betty has check-in 1 or 2 as |
| @@ -423,23 +447,28 @@ | |
| 447 | fork, which simply complicates matters beyond what we need here for |
| 448 | our illustration.)</p></li> |
| 449 | </ol> |
| 450 | |
| 451 | For our purposes here, it doesn't really matter which one happened. All |
| 452 | that matters is that Alan's check-in 3 becomes the parent of Betty's |
| 453 | check-in 4 because it was the newest tip of the working branch at the |
| 454 | time Betty does her check-in. |
| 455 | |
| 456 | <h3 id="bf-charlie">Step 3: Charlie</h3> |
| 457 | |
| 458 | Meanwhile, Charlie went offline after syncing |
| 459 | his repo with check-in 2 as the latest on that branch. When he checks |
| 460 | his changes in, it is as a child of 2, not of 4, because Charlie doesn't |
| 461 | know about check-ins 3 & 4 yet. He does this at an absolute wall clock |
| 462 | time <i>after</i> Alan and Betty made their check-ins, so when Charlie |
| 463 | comes back online and pushes his check-in 5 to the master repository and |
| 464 | learns about check-ins 3 and 4 during Fossil sync, Charlie inadvertently |
| 465 | revives the other side of the fork. |
| 466 | |
| 467 | <h3 id="bf-darlene">Step 4: Darlene</h3> |
| 468 | |
| 469 | Darlene sees all of this, because she joins in |
| 470 | on the work on this branch after Alan, Betty, and Charlie made their |
| 471 | check-ins and pushed them to the master repository. She's taking one of |
| 472 | the same three steps as we [#bf-betty|outlined for Betty above]. |
| 473 | Regardless of her path to this view, it happens after Charlie pushed his |
| 474 | check-in 5 to the master repo, so Darlene sees that as the latest on the |
| @@ -447,13 +476,16 @@ | |
| 476 | check-in 4, as it would if Charlie didn't come back online and sync |
| 477 | before Darlene started work on that branch up. |
| 478 | |
| 479 | <h3 id="post-mortem">Post Mortem</h3> |
| 480 | |
| 481 | The end result of all of this is that even though everyone makes only one check-in |
| 482 | and no one disables autosync without genuine need, |
| 483 | half of the check-ins end up on one side of the fork and half on |
| 484 | the other. |
| 485 | |
| 486 | A future user — his mother calls him Edward, but please call him Eddie — |
| 487 | can then join in on the work on this branch and end up on <i>either</i> side of |
| 488 | the fork. If Eddie joins in with the state of the repository as drawn |
| 489 | above, he'll end up on the top side of the fork, because check-in 6 is |
| 490 | the latest, but if Alan or Betty makes a seventh check-in to that branch |
| 491 | first, it will be as a child of check-in 4 since that's the version in |
| @@ -481,20 +513,21 @@ | |
| 513 | The same is true of Betty, Charlie, and Darlene. None of them tried to |
| 514 | create a fork, and none of them chose a side in this fork to participate |
| 515 | in. They just took Fossil's default and assumed it was correct. |
| 516 | |
| 517 | The only blame I can assign here is on any of these users who believed |
| 518 | forks couldn't happen before this did occur, and I blame them only for |
| 519 | their avoidable ignorance. (You, dear reader, have been ejected from |
| 520 | that category by reading this very document.) Any time someone can work |
| 521 | without getting full coordination from every other clone of the repo, |
| 522 | forks are possible. Given enough time, they're all but inevitable. This |
| 523 | is a general property of DVCSes, not just of Fossil. |
| 524 | |
| 525 | This sort of consequence is why forks on shared working branches are |
| 526 | bad, which is why [./concepts.wiki#workflow|Fossil tries so hard to avoid them], why it warns you |
| 527 | about it when they do occur, and why it makes it relatively [#fix|quick and |
| 528 | painless to fix them] when they do occur. |
| 529 | |
| 530 | |
| 531 | <h2>Review Of Terminology</h2> |
| 532 | |
| 533 | <blockquote><dl> |
| 534 |