228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
|
<h3 id="durable" name="database">2.3 Durable</h3>
The baseline data structures for Fossil and Git are the same, modulo
formatting details. Both systems manage a
[https://en.wikipedia.org/wiki/Directed_acyclic_graph | directed acyclic
graph] (DAG) of [https://en.wikipedia.org/wiki/Merkle_tree | Merkle
tree] / [./blockchain.md | block chain] structured check-in objects.
Check-ins are identified by a cryptographic hash of the check-in
contents, and each check-in refers to its parent via <i>its</i> hash.
The difference is that Git stores its objects as individual files in the
<tt>.git</tt> folder or compressed into bespoke
[https://git-scm.com/book/en/v2/Git-Internals-Packfiles|pack-files],
whereas Fossil stores its objects in a [https://www.sqlite.org/|SQLite]
|
|
|
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
|
<h3 id="durable" name="database">2.3 Durable</h3>
The baseline data structures for Fossil and Git are the same, modulo
formatting details. Both systems manage a
[https://en.wikipedia.org/wiki/Directed_acyclic_graph | directed acyclic
graph] (DAG) of [https://en.wikipedia.org/wiki/Merkle_tree | Merkle
tree] structured check-in objects.
Check-ins are identified by a cryptographic hash of the check-in
contents, and each check-in refers to its parent via <i>its</i> hash.
The difference is that Git stores its objects as individual files in the
<tt>.git</tt> folder or compressed into bespoke
[https://git-scm.com/book/en/v2/Git-Internals-Packfiles|pack-files],
whereas Fossil stores its objects in a [https://www.sqlite.org/|SQLite]
|
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
|
The prime example in Git is rebasing: the change happens to the local
repository immediately if successful, even though you haven't tested the
change yet. It's possible to argue for such a design in a tool like Git
which doesn't automatically push the change up to its parent, because
you can still test the change before pushing local changes to the parent
repo, but in the meantime you've made a durable change to your local Git
repository's blockchain. You must do something drastic like <tt>git
reset --hard</tt> to revert that rebase if it causes a problem. If you
push your rebased local repo up to the parent without testing first,
you've now committed the error on a public branch, effectively a
violation of
[https://www.atlassian.com/git/tutorials/merging-vs-rebasing#the-golden-rule-of-rebasing
| the golden rule of rebasing].
Lesser examples are the Git <tt>merge</tt>, <tt>cherry-pick</tt>, and
<tt>revert</tt> commands, all of which apply work from one branch onto
another, and all of which do their work immediately without giving you
an opportunity to test the change first locally unless you give the
<tt>--no-commit</tt> option.
Fossil cannot sensibly work that way because of its default-enabled
autosync feature. Instead of jumping straight to the commit step, Fossil
applies the proposed merge to the local working directory only,
requiring a separate check-in step before the change is committed to the
repository blockchain. This gives you a chance to test the change first,
either manually or by running your software's automatic tests. (Ideally,
both!)
Another difference is that because Fossil requires an explicit commit
for a merge, it makes you give an explicit commit <i>message</i> for
each merge, whereas Git writes that commit message itself by default
unless you give the optional <tt>--edit</tt> flag to override it.
|
|
|
|
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
|
The prime example in Git is rebasing: the change happens to the local
repository immediately if successful, even though you haven't tested the
change yet. It's possible to argue for such a design in a tool like Git
which doesn't automatically push the change up to its parent, because
you can still test the change before pushing local changes to the parent
repo, but in the meantime you've made a durable change to your local Git
repository. You must do something drastic like <tt>git
reset --hard</tt> to revert that rebase if it causes a problem. If you
push your rebased local repo up to the parent without testing first,
you've now committed the error on a public branch, effectively a
violation of
[https://www.atlassian.com/git/tutorials/merging-vs-rebasing#the-golden-rule-of-rebasing
| the golden rule of rebasing].
Lesser examples are the Git <tt>merge</tt>, <tt>cherry-pick</tt>, and
<tt>revert</tt> commands, all of which apply work from one branch onto
another, and all of which do their work immediately without giving you
an opportunity to test the change first locally unless you give the
<tt>--no-commit</tt> option.
Fossil cannot sensibly work that way because of its default-enabled
autosync feature. Instead of jumping straight to the commit step, Fossil
applies the proposed merge to the local working directory only,
requiring a separate check-in step before the change is committed to the
repository. This gives you a chance to test the change first,
either manually or by running your software's automatic tests. (Ideally,
both!)
Another difference is that because Fossil requires an explicit commit
for a merge, it makes you give an explicit commit <i>message</i> for
each merge, whereas Git writes that commit message itself by default
unless you give the optional <tt>--edit</tt> flag to override it.
|