Fossil SCM

Added section "2.8 Test Before Commit" to the fossil-v-git doc.

wyoung 2019-09-13 10:46 trunk
Commit e5ba45788b9938487af172163908af04f1ef440ee4c07abd6f15df14ec74f1b8
1 file changed +85 -1
--- www/fossil-v-git.wiki
+++ www/fossil-v-git.wiki
@@ -52,10 +52,12 @@
5252
<td>Focus on the entire tree of changes</td></tr>
5353
<tr><td>One check-out per repository</td>
5454
<td>Many check-outs per repository</td></tr>
5555
<tr><td>Remembers what you should have done</td>
5656
<td>Remembers what you actually did</td></tr>
57
+<tr><td>Commit first</td>
58
+ <td>Test first</td></tr>
5759
<tr><td>SHA-2</td>
5860
<td>SHA-3</td></tr>
5961
</table></blockquote>
6062
6163
<h3 id="features">2.1 Featureful</h3>
@@ -593,11 +595,93 @@
593595
594596
We go into more detail on this topic in a separate article,
595597
[./rebaseharm.md | Rebase Considered Harmful].
596598
597599
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>
599683
600684
Fossil started out using 160-bit SHA-1 hashes to identify check-ins,
601685
just as in Git. That changed in early 2017 when news of the
602686
[https://shattered.io/|SHAttered attack] broke, demonstrating that SHA-1
603687
collisions were now practical to create. Two weeks later, the creator of
604688
--- 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

Keyboard Shortcuts

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