Fossil SCM
More clarifications in the "How Can Forks Divide Development Effort?" section of branching.wiki, primarily in explaining how each user in the example arrives at the view shown in the swim lane diagram. There were multiple implicit possilibities before, and some were misinterpreting it.
Commit
70a7db80f577f963a5684e52940f92e7fd55576277ddbc76256a8d84be853380
Parent
2ac5bc3c3000288…
1 file changed
+95
-48
+95
-48
| --- www/branching.wiki | ||
| +++ www/branching.wiki | ||
| @@ -382,72 +382,119 @@ | ||
| 382 | 382 | <img src="branch06.svg"><br> |
| 383 | 383 | Figure 6 |
| 384 | 384 | </td></tr></table> |
| 385 | 385 | |
| 386 | 386 | All users in this diagram start off with the same two checkins at the |
| 387 | -tip of the working branch, 1 and 2, and they're all working towards some | |
| 388 | -indefinite, unified future. This is all happening on some long-lived, | |
| 389 | -shared working branch, such as trunk, though it could be anything else | |
| 390 | -that matches those same qualifiers. Each user makes only one check-in, | |
| 391 | -shaded light gray. | |
| 392 | - | |
| 393 | -Alan sets the stage for this problem by creating a fork from check-in 1 | |
| 394 | -as check-in 3. This has consequences which will occur regardless of how | |
| 395 | -that fork was created, so we can ignore the "how" here. <i>Why</i> that | |
| 396 | -fork was created will matter in [#post-mortem|the <i>post mortem</i> | |
| 397 | -below], but we can ignore that for now, too. | |
| 398 | - | |
| 399 | -Betty is sync'd with the same view of the repository as Alan, so her | |
| 400 | -check-in goes in as a child of the fork-creating check-in 3, that being the | |
| 401 | -latest check-in on the branch at the time. | |
| 402 | - | |
| 403 | -Meanwhile, Charlie went offline after syncing his repo with check-in 2 as | |
| 404 | -the latest on that branch. When he checks his changes in, it is as a | |
| 405 | -child of 2, not of 4, because Charlie doesn't know about check-ins 3 & 4 yet. | |
| 406 | -He does this at an absolute wall clock time <i>after</i> Alan and Betty | |
| 407 | -made their check-ins, so when Charlie comes back online and pushes his | |
| 408 | -check-in 5 to the master repository and learns about check-ins 3 and 4 | |
| 409 | -during Fossil sync, Charlie inadvertently revives the | |
| 410 | -other side of the fork. | |
| 411 | - | |
| 412 | -Darlene sees all of this, because she comes along after Alan, Betty, and Charlie | |
| 413 | -made their check-ins and pushed them to the master repository. Perhaps | |
| 414 | -Darlene is switching a working directory to this forked branch, or | |
| 415 | -perhaps Darlene is opening a Fossil repo clone into a new working | |
| 416 | -directory. Regardless, it happens after Charlie pushed his check-in 5 to | |
| 417 | -the master repo, so Darlene sees that as the latest on the branch, | |
| 418 | -causing her work to be saved as a child of check-in 5, not of check-in | |
| 419 | -4, as it would if Charlie didn't come back online and sync before Darlene | |
| 420 | -showed up. | |
| 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 | |
| 417 | + the tip in her local clone, but because she's working with an | |
| 418 | + autosync'd connection to the same upstream repository as Alan, on | |
| 419 | + attempting what will become check-in 4, she gets the "would fork" | |
| 420 | + message from <b>fossil ci</b>, so she dutifully updates her clone | |
| 421 | + and tries again, moving her work to be a child of the new tip, | |
| 422 | + check-in 3. (If she doesn't update, she creates a <i>second</i> | |
| 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 | |
| 446 | +branch, causing her work to be saved as a child of check-in 5, not of | |
| 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. | |
| 421 | 449 | |
| 422 | 450 | <h3 id="post-mortem">Post Mortem</h3> |
| 423 | 451 | |
| 424 | 452 | The end result of all of this is that everyone makes only one check-in, |
| 425 | 453 | but half of the check-ins are on one side of the fork, and half are on |
| 426 | 454 | the other. A future user — his mother calls him Edward, but please call him Eddie — |
| 427 | -can then show up and end up on <i>either</i> side of | |
| 428 | -the fork. If Eddie shows up with the state of the repository as drawn | |
| 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 | |
| 429 | 457 | above, he'll end up on the top side of the fork, because check-in 6 is |
| 430 | 458 | the latest, but if Alan or Betty makes a seventh check-in to that branch |
| 431 | 459 | first, it will be as a child of check-in 4 since that's the version in |
| 432 | 460 | their local check-out directories. Since that check-in 7 will then be the latest, |
| 433 | 461 | Eddie will end up on the bottom side of the fork instead. |
| 434 | 462 | |
| 435 | 463 | In all of this, realize that neither side of the fork is obviously |
| 436 | 464 | "correct." Every participant was doing the right thing by their own |
| 437 | -lights at the time they made their lone check-in. We can only blame | |
| 438 | -the consequences of creating the fork on Alan | |
| 439 | -if he did so on purpose, as by passing | |
| 440 | -"--allow-fork" when creating a check-in on a shared working branch. If | |
| 441 | -the fork was created inadvertently, it's no one's fault. | |
| 442 | - | |
| 443 | -(Or, perhaps it is <i>everyone's</i> fault for using a DVCS while having | |
| 444 | -an unrealistic expectation that forks should never occur.) | |
| 445 | - | |
| 446 | -This is why forks on shared working branches are bad, which is why | |
| 447 | -Fossil tries so hard to avoid them, and why it warns you about it when | |
| 448 | -they do occur. | |
| 465 | +lights at the time they made their lone check-in. | |
| 466 | + | |
| 467 | +Who, then, is to blame? | |
| 468 | + | |
| 469 | +We can only blame the consequences of creating the fork on Alan if he | |
| 470 | +did so on purpose, as by passing "--allow-fork" when creating a check-in | |
| 471 | +on a shared working branch. Alan might have created it inadvertently by | |
| 472 | +going offline while check-in 1 was the tip of the branch in his local | |
| 473 | +clone, so that by the time he made his check-in 3, check-in 2 had | |
| 474 | +arrived at the shared parent repository from someone else. (Francine?) | |
| 475 | +When Alan rejoins the network and does an autosync, he learns about | |
| 476 | +check-in 2. Since his #3 is already checked into his local clone because | |
| 477 | +autosync was off or blocked, the sync creates an unavoidable fork. We | |
| 478 | +can't blame either Alan or Francine here: they were both doing the right | |
| 479 | +thing given their imperfect view of the state of the global situation. | |
| 480 | + | |
| 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. | |
| 449 | 496 | |
| 450 | 497 | |
| 451 | 498 | <h2>Review Of Terminology</h2> |
| 452 | 499 | |
| 453 | 500 | <blockquote><dl> |
| 454 | 501 |
| --- www/branching.wiki | |
| +++ www/branching.wiki | |
| @@ -382,72 +382,119 @@ | |
| 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, and they're all working towards some |
| 388 | indefinite, unified future. This is all happening on some long-lived, |
| 389 | shared working branch, such as trunk, though it could be anything else |
| 390 | that matches those same qualifiers. Each user makes only one check-in, |
| 391 | shaded light gray. |
| 392 | |
| 393 | Alan sets the stage for this problem by creating a fork from check-in 1 |
| 394 | as check-in 3. This has consequences which will occur regardless of how |
| 395 | that fork was created, so we can ignore the "how" here. <i>Why</i> that |
| 396 | fork was created will matter in [#post-mortem|the <i>post mortem</i> |
| 397 | below], but we can ignore that for now, too. |
| 398 | |
| 399 | Betty is sync'd with the same view of the repository as Alan, so her |
| 400 | check-in goes in as a child of the fork-creating check-in 3, that being the |
| 401 | latest check-in on the branch at the time. |
| 402 | |
| 403 | Meanwhile, Charlie went offline after syncing his repo with check-in 2 as |
| 404 | the latest on that branch. When he checks his changes in, it is as a |
| 405 | child of 2, not of 4, because Charlie doesn't know about check-ins 3 & 4 yet. |
| 406 | He does this at an absolute wall clock time <i>after</i> Alan and Betty |
| 407 | made their check-ins, so when Charlie comes back online and pushes his |
| 408 | check-in 5 to the master repository and learns about check-ins 3 and 4 |
| 409 | during Fossil sync, Charlie inadvertently revives the |
| 410 | other side of the fork. |
| 411 | |
| 412 | Darlene sees all of this, because she comes along after Alan, Betty, and Charlie |
| 413 | made their check-ins and pushed them to the master repository. Perhaps |
| 414 | Darlene is switching a working directory to this forked branch, or |
| 415 | perhaps Darlene is opening a Fossil repo clone into a new working |
| 416 | directory. Regardless, it happens after Charlie pushed his check-in 5 to |
| 417 | the master repo, so Darlene sees that as the latest on the branch, |
| 418 | causing her work to be saved as a child of check-in 5, not of check-in |
| 419 | 4, as it would if Charlie didn't come back online and sync before Darlene |
| 420 | showed up. |
| 421 | |
| 422 | <h3 id="post-mortem">Post Mortem</h3> |
| 423 | |
| 424 | The end result of all of this is that everyone makes only one check-in, |
| 425 | but half of the check-ins are on one side of the fork, and half are on |
| 426 | the other. A future user — his mother calls him Edward, but please call him Eddie — |
| 427 | can then show up and end up on <i>either</i> side of |
| 428 | the fork. If Eddie shows up with the state of the repository as drawn |
| 429 | above, he'll end up on the top side of the fork, because check-in 6 is |
| 430 | the latest, but if Alan or Betty makes a seventh check-in to that branch |
| 431 | first, it will be as a child of check-in 4 since that's the version in |
| 432 | their local check-out directories. Since that check-in 7 will then be the latest, |
| 433 | Eddie will end up on the bottom side of the fork instead. |
| 434 | |
| 435 | In all of this, realize that neither side of the fork is obviously |
| 436 | "correct." Every participant was doing the right thing by their own |
| 437 | lights at the time they made their lone check-in. We can only blame |
| 438 | the consequences of creating the fork on Alan |
| 439 | if he did so on purpose, as by passing |
| 440 | "--allow-fork" when creating a check-in on a shared working branch. If |
| 441 | the fork was created inadvertently, it's no one's fault. |
| 442 | |
| 443 | (Or, perhaps it is <i>everyone's</i> fault for using a DVCS while having |
| 444 | an unrealistic expectation that forks should never occur.) |
| 445 | |
| 446 | This is why forks on shared working branches are bad, which is why |
| 447 | Fossil tries so hard to avoid them, and why it warns you about it when |
| 448 | they do occur. |
| 449 | |
| 450 | |
| 451 | <h2>Review Of Terminology</h2> |
| 452 | |
| 453 | <blockquote><dl> |
| 454 |
| --- www/branching.wiki | |
| +++ www/branching.wiki | |
| @@ -382,72 +382,119 @@ | |
| 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 |
| 417 | the tip in her local clone, but because she's working with an |
| 418 | autosync'd connection to the same upstream repository as Alan, on |
| 419 | attempting what will become check-in 4, she gets the "would fork" |
| 420 | message from <b>fossil ci</b>, so she dutifully updates her clone |
| 421 | and tries again, moving her work to be a child of the new tip, |
| 422 | check-in 3. (If she doesn't update, she creates a <i>second</i> |
| 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 |
| 446 | branch, causing her work to be saved as a child of check-in 5, not of |
| 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 |
| 460 | their local check-out directories. Since that check-in 7 will then be the latest, |
| 461 | Eddie will end up on the bottom side of the fork instead. |
| 462 | |
| 463 | In all of this, realize that neither side of the fork is obviously |
| 464 | "correct." Every participant was doing the right thing by their own |
| 465 | lights at the time they made their lone check-in. |
| 466 | |
| 467 | Who, then, is to blame? |
| 468 | |
| 469 | We can only blame the consequences of creating the fork on Alan if he |
| 470 | did so on purpose, as by passing "--allow-fork" when creating a check-in |
| 471 | on a shared working branch. Alan might have created it inadvertently by |
| 472 | going offline while check-in 1 was the tip of the branch in his local |
| 473 | clone, so that by the time he made his check-in 3, check-in 2 had |
| 474 | arrived at the shared parent repository from someone else. (Francine?) |
| 475 | When Alan rejoins the network and does an autosync, he learns about |
| 476 | check-in 2. Since his #3 is already checked into his local clone because |
| 477 | autosync was off or blocked, the sync creates an unavoidable fork. We |
| 478 | can't blame either Alan or Francine here: they were both doing the right |
| 479 | thing given their imperfect view of the state of the global situation. |
| 480 | |
| 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 |