Fossil SCM
Added section "2.8 Test Before Commit" to the fossil-v-git doc.
Commit
e5ba45788b9938487af172163908af04f1ef440ee4c07abd6f15df14ec74f1b8
Parent
924bf44d398461d…
1 file changed
+85
-1
+85
-1
| --- www/fossil-v-git.wiki | ||
| +++ www/fossil-v-git.wiki | ||
| @@ -52,10 +52,12 @@ | ||
| 52 | 52 | <td>Focus on the entire tree of changes</td></tr> |
| 53 | 53 | <tr><td>One check-out per repository</td> |
| 54 | 54 | <td>Many check-outs per repository</td></tr> |
| 55 | 55 | <tr><td>Remembers what you should have done</td> |
| 56 | 56 | <td>Remembers what you actually did</td></tr> |
| 57 | +<tr><td>Commit first</td> | |
| 58 | + <td>Test first</td></tr> | |
| 57 | 59 | <tr><td>SHA-2</td> |
| 58 | 60 | <td>SHA-3</td></tr> |
| 59 | 61 | </table></blockquote> |
| 60 | 62 | |
| 61 | 63 | <h3 id="features">2.1 Featureful</h3> |
| @@ -593,11 +595,93 @@ | ||
| 593 | 595 | |
| 594 | 596 | We go into more detail on this topic in a separate article, |
| 595 | 597 | [./rebaseharm.md | Rebase Considered Harmful]. |
| 596 | 598 | |
| 597 | 599 | |
| 598 | -<h3 id="hash">2.8 Hash Algorithm: SHA-3 vs SHA-2 vs SHA-1</h3> | |
| 600 | +<h3 id="testing">2.8 Test Before Commit</h3> | |
| 601 | + | |
| 602 | +One of the things that falls out of Git's default separation of commit | |
| 603 | +from push is that there are several Git sub-commands that jump straight | |
| 604 | +to the commit step before a change could possibly be tested. Fossil, by | |
| 605 | +contrast, makes the equivalent change to the local working check-out | |
| 606 | +only, requiring a separate check-in step to commit the change. This | |
| 607 | +design difference falls naturally out of Fossil's default-enabled | |
| 608 | +autosync feature. | |
| 609 | + | |
| 610 | +The prime example in Git is rebasing: the change happens to the local | |
| 611 | +repository immediately if successful, even though you haven't tested the | |
| 612 | +change yet. It's possible to argue for such a design in a tool like Git | |
| 613 | +which doesn't automatically push the change up to its parent, because | |
| 614 | +you can still test the change before pushing local changes to the parent | |
| 615 | +repo, but in the meantime you've made a durable change to your local Git | |
| 616 | +repository's blockchain. You must do something drastic like <tt>git | |
| 617 | +reset --hard</tt> to revert that rebase if it causes a problem. If you | |
| 618 | +push your rebased local repo up to the parent without testing first, | |
| 619 | +you've now committed the error on a public branch, effectively a | |
| 620 | +violation of | |
| 621 | +[https://www.atlassian.com/git/tutorials/merging-vs-rebasing#the-golden-rule-of-rebasing | |
| 622 | +| the golden rule of rebasing]. | |
| 623 | + | |
| 624 | +Lesser examples are the Git <tt>merge</tt>, <tt>cherry-pick</tt>, and | |
| 625 | +<tt>revert</tt> commands, all of which apply work from one branch onto | |
| 626 | +another, and all of which do their work immediately without giving you | |
| 627 | +an opportunity to test the change first locally unless you give the | |
| 628 | +<tt>--no-commit</tt> option. | |
| 629 | + | |
| 630 | +Fossil cannot sensibly work that way because of its default-enabled | |
| 631 | +autosync feature. Instead of jumping straight to the commit step, Fossil | |
| 632 | +applies the proposed merge to the local working directory only, | |
| 633 | +requiring a separate check-in step before the change is committed to the | |
| 634 | +repository blockchain. This gives you a chance to test the change, | |
| 635 | +whether manually, or by running your software's automatic tests, or | |
| 636 | +both. | |
| 637 | + | |
| 638 | +Another difference is that because Fossil requires an explicit commit | |
| 639 | +for a merge, it makes you give an explicit commit <i>message</i> for | |
| 640 | +each merge, whereas Git writes that commit message itself by default | |
| 641 | +unless you give the optional <tt>--edit</tt> flag to override it. | |
| 642 | + | |
| 643 | +We don't look at this difference as a workaround in Fossil for autosync, | |
| 644 | +but instead as a test-first philosophical difference. When every commit | |
| 645 | +is pushed to the parent repo by default, it encourages a working style | |
| 646 | +in which every commit is tested first. We think this is an inherently | |
| 647 | +good thing. | |
| 648 | + | |
| 649 | +Incidentally, this is a good example of Git's messy command design. | |
| 650 | +These three commands: | |
| 651 | + | |
| 652 | +<pre> | |
| 653 | + $ git merge HASH | |
| 654 | + $ git cherry-pick HASH | |
| 655 | + $ git revert HASH | |
| 656 | +</pre> | |
| 657 | + | |
| 658 | +...are all the same command in Fossil: | |
| 659 | + | |
| 660 | +<pre> | |
| 661 | + $ fossil merge HASH | |
| 662 | + $ fossil merge --cherrypick HASH | |
| 663 | + $ fossil merge --backout HASH | |
| 664 | +</pre> | |
| 665 | + | |
| 666 | +If you think about it, they're all the same function: apply work done on | |
| 667 | +one branch to another. All that changes between these commands is how | |
| 668 | +much work gets applied — just one check-in or a whole branch — and the | |
| 669 | +merge direction. This is the sort of thing we mean when we point out | |
| 670 | +that Fossil's command interface is simpler than Git's: there are fewer | |
| 671 | +concepts to keep track of in your mental model of Fossil's internal | |
| 672 | +operation. | |
| 673 | + | |
| 674 | +Fossil's implementation of the feature is also simpler to describe. The | |
| 675 | +online help for <tt> [/help?cmd=merge | fossil merge]</tt> is currently | |
| 676 | +41 lines long, whereas the aggregate man page length for the above three | |
| 677 | +Git commands is over 1000 lines, much of it mutually redundant. (e.g. | |
| 678 | +the <tt>--edit</tt> and <tt>--no-commit</tt> options get described three | |
| 679 | +different times, each time differently.) | |
| 680 | + | |
| 681 | + | |
| 682 | +<h3 id="hash">2.9 Hash Algorithm: SHA-3 vs SHA-2 vs SHA-1</h3> | |
| 599 | 683 | |
| 600 | 684 | Fossil started out using 160-bit SHA-1 hashes to identify check-ins, |
| 601 | 685 | just as in Git. That changed in early 2017 when news of the |
| 602 | 686 | [https://shattered.io/|SHAttered attack] broke, demonstrating that SHA-1 |
| 603 | 687 | collisions were now practical to create. Two weeks later, the creator of |
| 604 | 688 |
| --- www/fossil-v-git.wiki | |
| +++ www/fossil-v-git.wiki | |
| @@ -52,10 +52,12 @@ | |
| 52 | <td>Focus on the entire tree of changes</td></tr> |
| 53 | <tr><td>One check-out per repository</td> |
| 54 | <td>Many check-outs per repository</td></tr> |
| 55 | <tr><td>Remembers what you should have done</td> |
| 56 | <td>Remembers what you actually did</td></tr> |
| 57 | <tr><td>SHA-2</td> |
| 58 | <td>SHA-3</td></tr> |
| 59 | </table></blockquote> |
| 60 | |
| 61 | <h3 id="features">2.1 Featureful</h3> |
| @@ -593,11 +595,93 @@ | |
| 593 | |
| 594 | We go into more detail on this topic in a separate article, |
| 595 | [./rebaseharm.md | Rebase Considered Harmful]. |
| 596 | |
| 597 | |
| 598 | <h3 id="hash">2.8 Hash Algorithm: SHA-3 vs SHA-2 vs SHA-1</h3> |
| 599 | |
| 600 | Fossil started out using 160-bit SHA-1 hashes to identify check-ins, |
| 601 | just as in Git. That changed in early 2017 when news of the |
| 602 | [https://shattered.io/|SHAttered attack] broke, demonstrating that SHA-1 |
| 603 | collisions were now practical to create. Two weeks later, the creator of |
| 604 |
| --- www/fossil-v-git.wiki | |
| +++ www/fossil-v-git.wiki | |
| @@ -52,10 +52,12 @@ | |
| 52 | <td>Focus on the entire tree of changes</td></tr> |
| 53 | <tr><td>One check-out per repository</td> |
| 54 | <td>Many check-outs per repository</td></tr> |
| 55 | <tr><td>Remembers what you should have done</td> |
| 56 | <td>Remembers what you actually did</td></tr> |
| 57 | <tr><td>Commit first</td> |
| 58 | <td>Test first</td></tr> |
| 59 | <tr><td>SHA-2</td> |
| 60 | <td>SHA-3</td></tr> |
| 61 | </table></blockquote> |
| 62 | |
| 63 | <h3 id="features">2.1 Featureful</h3> |
| @@ -593,11 +595,93 @@ | |
| 595 | |
| 596 | We go into more detail on this topic in a separate article, |
| 597 | [./rebaseharm.md | Rebase Considered Harmful]. |
| 598 | |
| 599 | |
| 600 | <h3 id="testing">2.8 Test Before Commit</h3> |
| 601 | |
| 602 | One of the things that falls out of Git's default separation of commit |
| 603 | from push is that there are several Git sub-commands that jump straight |
| 604 | to the commit step before a change could possibly be tested. Fossil, by |
| 605 | contrast, makes the equivalent change to the local working check-out |
| 606 | only, requiring a separate check-in step to commit the change. This |
| 607 | design difference falls naturally out of Fossil's default-enabled |
| 608 | autosync feature. |
| 609 | |
| 610 | The prime example in Git is rebasing: the change happens to the local |
| 611 | repository immediately if successful, even though you haven't tested the |
| 612 | change yet. It's possible to argue for such a design in a tool like Git |
| 613 | which doesn't automatically push the change up to its parent, because |
| 614 | you can still test the change before pushing local changes to the parent |
| 615 | repo, but in the meantime you've made a durable change to your local Git |
| 616 | repository's blockchain. You must do something drastic like <tt>git |
| 617 | reset --hard</tt> to revert that rebase if it causes a problem. If you |
| 618 | push your rebased local repo up to the parent without testing first, |
| 619 | you've now committed the error on a public branch, effectively a |
| 620 | violation of |
| 621 | [https://www.atlassian.com/git/tutorials/merging-vs-rebasing#the-golden-rule-of-rebasing |
| 622 | | the golden rule of rebasing]. |
| 623 | |
| 624 | Lesser examples are the Git <tt>merge</tt>, <tt>cherry-pick</tt>, and |
| 625 | <tt>revert</tt> commands, all of which apply work from one branch onto |
| 626 | another, and all of which do their work immediately without giving you |
| 627 | an opportunity to test the change first locally unless you give the |
| 628 | <tt>--no-commit</tt> option. |
| 629 | |
| 630 | Fossil cannot sensibly work that way because of its default-enabled |
| 631 | autosync feature. Instead of jumping straight to the commit step, Fossil |
| 632 | applies the proposed merge to the local working directory only, |
| 633 | requiring a separate check-in step before the change is committed to the |
| 634 | repository blockchain. This gives you a chance to test the change, |
| 635 | whether manually, or by running your software's automatic tests, or |
| 636 | both. |
| 637 | |
| 638 | Another difference is that because Fossil requires an explicit commit |
| 639 | for a merge, it makes you give an explicit commit <i>message</i> for |
| 640 | each merge, whereas Git writes that commit message itself by default |
| 641 | unless you give the optional <tt>--edit</tt> flag to override it. |
| 642 | |
| 643 | We don't look at this difference as a workaround in Fossil for autosync, |
| 644 | but instead as a test-first philosophical difference. When every commit |
| 645 | is pushed to the parent repo by default, it encourages a working style |
| 646 | in which every commit is tested first. We think this is an inherently |
| 647 | good thing. |
| 648 | |
| 649 | Incidentally, this is a good example of Git's messy command design. |
| 650 | These three commands: |
| 651 | |
| 652 | <pre> |
| 653 | $ git merge HASH |
| 654 | $ git cherry-pick HASH |
| 655 | $ git revert HASH |
| 656 | </pre> |
| 657 | |
| 658 | ...are all the same command in Fossil: |
| 659 | |
| 660 | <pre> |
| 661 | $ fossil merge HASH |
| 662 | $ fossil merge --cherrypick HASH |
| 663 | $ fossil merge --backout HASH |
| 664 | </pre> |
| 665 | |
| 666 | If you think about it, they're all the same function: apply work done on |
| 667 | one branch to another. All that changes between these commands is how |
| 668 | much work gets applied — just one check-in or a whole branch — and the |
| 669 | merge direction. This is the sort of thing we mean when we point out |
| 670 | that Fossil's command interface is simpler than Git's: there are fewer |
| 671 | concepts to keep track of in your mental model of Fossil's internal |
| 672 | operation. |
| 673 | |
| 674 | Fossil's implementation of the feature is also simpler to describe. The |
| 675 | online help for <tt> [/help?cmd=merge | fossil merge]</tt> is currently |
| 676 | 41 lines long, whereas the aggregate man page length for the above three |
| 677 | Git commands is over 1000 lines, much of it mutually redundant. (e.g. |
| 678 | the <tt>--edit</tt> and <tt>--no-commit</tt> options get described three |
| 679 | different times, each time differently.) |
| 680 | |
| 681 | |
| 682 | <h3 id="hash">2.9 Hash Algorithm: SHA-3 vs SHA-2 vs SHA-1</h3> |
| 683 | |
| 684 | Fossil started out using 160-bit SHA-1 hashes to identify check-ins, |
| 685 | just as in Git. That changed in early 2017 when news of the |
| 686 | [https://shattered.io/|SHAttered attack] broke, demonstrating that SHA-1 |
| 687 | collisions were now practical to create. Two weeks later, the creator of |
| 688 |