1<title>Fossil Versus Git</title>
2
3<h2>1.0 Don't Stress!</h2>
4
5The feature sets of Fossil and [http://git-scm.com | Git] overlap in
6many ways. Both are
7[https://en.wikipedia.org/wiki/Distributed_version_control | distributed
8version control systems] which store a tree of check-in objects to a
9local repository clone. In both systems, the local clone starts out as a
10full copy of the remote parent. New content gets added to the local
11clone and then later optionally pushed up to the remote, and changes to
12the remote can be pulled down to the local clone at will. Both systems
13offer diffing, patching, branching, merging, cherry-picking, bisecting,
14private branches, a stash, etc.
15
16Fossil has inbound and outbound Git conversion features, so if you start
17out using one DVCS and later decide you like the other better, you can
18easily [./inout.wiki | move your version-controlled file content].¹
19
20In this document, we set all of that similarity and interoperability
21aside and focus on the important differences between the two, especially
22those that impact the user experience.
23
24Keep in mind that you are reading this on a Fossil website, and though
25we try to be fair, the information here
26might be biased in favor of Fossil, if only because we spend most of our
27time using Fossil, not Git.  Ask around for second opinions from
28people who have used <em>both</em> Fossil and Git.
29
30If you want a more practical, less philosophical guide to moving from
31Git to Fossil, see our [./gitusers.md | Git to Fossil Translation Guide].
32
33
34<h2>2.0 Differences Between Fossil And Git</h2>
35
36Differences between Fossil and Git are summarized by the following table,
37with further description in the text that follows.
38
39<blockquote><table border=1 cellpadding=5 align=center>
40<tr><th width="49%">GIT</th><th width="49%">FOSSIL</th><th width="2%">more</th></tr>
41<tr>
42    <td>File versioning only</td>
43    <td>VCS, tickets, wiki, docs, notes, forum, chat, UI,
44    [https://en.wikipedia.org/wiki/Role-based_access_control|RBAC]</td>
45    <td><a href="#features">2.1&nbsp;&darr;</a></td>
46</tr>
47<tr>
48    <td>A federation of many small programs</td>
49    <td>One self-contained, stand-alone executable</td>
50    <td><a href="#selfcontained">2.2&nbsp;&darr;</a></td>
51</tr>
52<tr>
53    <td>Custom key/value data store</td>
54    <td>[https://sqlite.org/mostdeployed.html|The most used SQL database in the world]</td>
55    <td><a href="#durable">2.3&nbsp;&darr;</a></td>
56</tr>
57<tr>
58    <td>Runs natively on POSIX systems</td>
59    <td>Runs natively on both POSIX and Windows</td>
60    <td><a href="#portable">2.4&nbsp;&darr;</a></td>
61</tr>
62<tr>
63    <td>Bazaar-style development</td>
64    <td>Cathedral-style development</td>
65    <td><a href="#devorg">2.5.1&nbsp;&darr;</a></td>
66</tr>
67<tr>
68    <td>Designed for Linux kernel development</td>
69    <td>Designed for SQLite development</td>
70    <td><a href="#scale">2.5.2&nbsp;&darr;</a></td>
71</tr>
72<tr>
73    <td>Many contributors</td>
74    <td>Select contributors</td>
75    <td><a href="#contrib">2.5.3&nbsp;&darr;</a></td>
76</tr>
77<tr>
78    <td>Focus on individual branches</td>
79    <td>Focus on the entire tree of changes</td>
80    <td><a href="#branches">2.5.4&nbsp;&darr;</a></td>
81</tr>
82<tr>
83    <td>One check-out per repository</td>
84    <td>Many check-outs per repository</td>
85    <td><a href="#checkouts">2.6&nbsp;&darr;</a></td>
86</tr>
87<tr>
88    <td>Remembers what you should have done</td>
89    <td>Remembers what you actually did</td>
90    <td><a href="#history">2.7&nbsp;&darr;</a></td>
91</tr>
92<tr>
93    <td>Commit first</td>
94    <td>Test first</td>
95    <td><a href="#testing">2.8&nbsp;&darr;</a></td>
96</tr>
97<tr>
98    <td>SHA-1 or SHA-2</td>
99    <td>SHA-1 and/or SHA-3, in the same repository</td>
100    <td><a href="#hash">2.9&nbsp;&darr;</a></td>
101</tr>
102</table></blockquote>
103
104<h3 id="features">2.1 Featureful</h3>
105
106Git provides file versioning services only, whereas Fossil adds
107an integrated [./wikitheory.wiki | wiki],
108[./bugtheory.wiki | ticketing &amp; bug tracking],
109[./embeddeddoc.wiki | embedded documentation],
110[./event.wiki | technical notes], a [./forum.wiki | web forum],
111and a [./chat.md | chat service],
112all within a single nicely-designed [./customskin.md|skinnable] web
113[/help?cmd=ui|UI],
114protected by [./caps/ | a fine-grained role-based
115access control system].
116These additional capabilities are available for Git as 3rd-party
117add-ons, but with Fossil they are integrated into
118the design.  One way to describe Fossil is that it is
119"[https://github.com/ | GitHub]-in-a-box."
120
121Fossil can do operations over all local repo clones and check-out
122directories with a single command. For example, Fossil lets you say
123"<tt>fossil all sync</tt>" on a laptop prior to taking it off the network
124hosting those repos. You can sync up to all of the private repos on your
125company network plus those public Internet-hosted repos you use. Whether
126going out for a working lunch or on a transoceanic airplane trip, one
127command gets you in sync. This works with several other Fossil
128sub-commands, such as "<tt>fossil all changes</tt>" to get a list of files
129that you forgot to commit prior to the end of your working day, across
130all repos.
131
132Whenever Fossil is told to modify the local checkout in some destructive
133way ([/help?cmd=rm|fossil rm], [/help?cmd=update|fossil update],
134[/help?cmd=revert|fossil revert], etc.) Fossil remembers the prior state
135and is able to return the check-out directory to that state with a
136<tt>fossil undo</tt> command. You cannot undo a commit in Fossil
137([#history | on purpose!]) but as long as the change remains confined to
138the local check-out directory only, Fossil makes undo
139[https://git-scm.com/book/en/v2/Git-Basics-Undoing-Things|easier than in
140Git].
141
142For developers who choose to self-host projects (rather than using a
1433rd-party service such as GitHub) Fossil is much easier to set up, since
144the stand-alone Fossil executable together with a [./server/any/cgi.md|2-line CGI script]
145suffice to instantiate a full-featured developer website.  To accomplish
146the same using Git requires locating, installing, configuring, integrating,
147and managing a wide assortment of separate tools.  Standing up a developer
148website using Fossil can be done in minutes, whereas doing the same using
149Git requires hours or days.
150
151Fossil is small, complete, and self-contained.  If you clone
152[https://github.com/git/git|Git's self-hosting repository], you get just
153Git's source code.  If you clone Fossil's self-hosting repository, you
154get the entire Fossil website — source code, documentation, ticket
155history, and so forth.² That means you get a copy of this very article
156and all of its historical versions, plus the same for all of the other
157public content on this site.
158
159
160<h3 id="selfcontained" name="selfcontained">2.2 Self Contained</h3>
161
162Git is actually a collection of many small tools, each doing one small
163part of the job, which can be recombined (by experts) to perform
164powerful operations. Git has a lot of complexity and many dependencies,
165so that most people end up installing it via some kind of package
166manager, simply because the creation of complicated binary packages is
167best delegated to people skilled in their creation. Normal Git users are
168not expected to build Git from source and install it themselves.
169
170Fossil is a single self-contained stand-alone executable which by default
171depends only on common platform libraries.  You can statically link
172to get an executable with no external dependencies at all &mdash; a useful
173feature for running inside a restrictive
174[https://en.wikipedia.org/wiki/Chroot|chroot jail].
175
176The precompiled Fossil binaries are delivered as just a single
177executable.  The precompiled Windows deliveries are just a ZIP archive
178containing only "<tt>fossil.exe</tt>".  There is no "<tt>setup.exe</tt>"
179to run.  Linux and Mac precompiled binaries are a tarball containing
180just the "<tt>fossil</tt>" executable.  To install, just put the
181executable on your PATH.  To uninstall, just delete the executable.
182To upgrade (or downgrade) simply replace the executable.
183
184A typical Fossil executable is between 5 and 7 megabytes uncompressed
185(as of 2020-12-12),
186assuming that the executable is statically linked against OpenSSL.
187
188Fossil is easy to build from sources. Just run
189"<tt>./configure && make</tt>" on POSIX systems and
190"<tt>nmake /f Makefile.msc</tt>" on Windows.
191
192Contrast a basic installation of Git, which takes up about
19315&nbsp;MiB on Debian 10 across 230 files, not counting the contents of
194<tt>/usr/share/doc</tt> or <tt>/usr/share/locale</tt>. If you need to
195deploy to any platform where you cannot count facilities like the POSIX
196shell, Perl interpreter, and Tcl/Tk platform needed to fully use Git
197as part of the base platform, the full footprint of a Git installation
198extends to more like 45&nbsp;MiB and thousands of files. This complicates
199several common scenarios: Git for Windows, chrooted Git servers,
200Docker images...
201
202Some say that Git more closely adheres to the Unix philosophy,
203summarized as "many small tools, loosely joined," but we have many
204examples of other successful Unix software that violates that principle
205to good effect, from Apache to Python to ZFS. We can infer from that
206that this is not an absolute principle of good software design.
207Sometimes "many features, tightly-coupled" works better. What actually
208matters is effectiveness and efficiency. We believe Fossil achieves
209this.
210
211The above size comparisons aren't apples-to-apples anyway. We've
212compared the size of Fossil with all of its [#features | many built-in
213features] to a fairly minimal Git installation. You must add a lot
214of third-party
215software to Git to give it a Fossil-equivalent feature set. Consider
216[https://about.gitlab.com/|GitLab], a third-party extension to Git
217wrapping it in many features, making it roughly Fossil-equivalent,
218though [https://docs.gitlab.com/ee/install/requirements.html|much more
219resource hungry] and hence more costly to run than the equivalent
220Fossil setup. GitLab's basic requirements are easy to accept when you're dedicating
221a local rack server or blade to it, since its minimum requirements are
222more or less a description of the smallest
223thing you could call a "server" these days, but when you go to host that
224in the cloud, you can expect to pay about 8 times as much to comfortably host
225GitLab as for Fossil.³ This difference is largely due to basic
226technology choices: Ruby and PostgreSQL vs C and SQLite.
227
228The Fossil project itself is [./selfhost.wiki|hosted on a small and
229inexpensive VPS].  A bare-bones $5/month VPS or a
230spare Raspberry Pi is sufficient to run a full-up project
231site, complete with tickets, wiki, chat, and forum, in addition to
232being a code repository.
233
234<h3 id="durable" name="database">2.3 Query Language</h3>
235
236The baseline data structures for Fossil and Git are the same, modulo
237formatting details. Both systems manage a
238[https://en.wikipedia.org/wiki/Directed_acyclic_graph | directed acyclic
239graph] (DAG) of [https://en.wikipedia.org/wiki/Merkle_tree | Merkle
240tree] structured check-in objects.
241Check-ins are identified by a cryptographic hash of the check-in
242contents, and each check-in refers to its parent via the parent's hash.
243
244The difference is that Git stores its objects as individual files in the
245<tt>.git</tt> folder or compressed into bespoke key/value
246[https://git-scm.com/book/en/v2/Git-Internals-Packfiles|pack-files],
247whereas Fossil stores its objects in a [https://www.sqlite.org/|SQLite]
248database file which provides ACID transactions and a high-level query
249language.
250This difference is more than an implementation detail. It has important
251practical consequences.
252
253One notable consequence is that it is difficult to find the descendants
254of check-ins in Git.
255One can easily locate the ancestors of a particular Git check-in
256by following the pointers embedded in the check-in object, but it is
257difficult to go the other direction and locate the descendants of a
258check-in.  It is so difficult, in fact, that neither native Git nor
259GitHub provide this capability short of crawling the
260[https://www.git-scm.com/docs/git-log|commit log].  With Fossil,
261on the other hand, finding descendants is a simple SQL query.
262It is common in Fossil to ask to see
263[/timeline?df=release&y=ci|all check-ins since the last release].
264Git lets you see "what came before".  Fossil makes it just as
265easy to also see "what came after".
266
267Leaf check-ins in Git that lack a "ref" become "detached," making them
268difficult to locate and subject to garbage collection. This
269[http://gitfaq.org/articles/what-is-a-detached-head.html|detached head
270state] problem has caused grief for
271[https://www.google.com/search?q=git+detached+head+state | many
272of Git users]. With
273Fossil, detached heads are simply impossible because we can always find
274our way back into the Merkle tree using one or more of the relations
275in the SQL database.
276
277The SQL query capabilities of Fossil make it easier to track the
278changes for one particular file within a project.  For example,
279you can easily find
280[/finfo/www/fossil-v-git.wiki|the complete edit history of this one document],
281or even
282[/finfo/www/fossil-v-git.wiki?ubg|the same history color-coded by committer],
283Both questions are simple SQL query in Fossil, with procedural code
284only being used to format the result for display.
285The same result could be obtained from Git, but because the data is
286in a key/value store, much more procedural code has to be written to
287walk the data and compute the result. And since that is a lot more
288work, the question is seldom asked.
289
290The ease of querying Fossil data using SQL means that status or
291history information about the project under management is easier
292to obtain.  And being easier means that it is more likely to happen.
293Fossil reports tend to be more detailed and useful.
294Consider the [/timeline?c=6df7a853ec16865b|this Fossil timeline]
295compared to its
296[https://github.com/drhsqlite/fossil-mirror/commits/master?after=f720c106d297ca1f61bccb30c5c191b88a626d01+34|its
297closest equivalent in GitHub].  Judge for yourself: Which of those
298reports is more useful to a developer trying to understand what happened?
299
300The bottom line is that even though Fossil and Git are built around
301the same low-level data structure, the use of SQL
302to query this data makes the data more accessible in Fossil, resulting
303in more detailed information being available to the user.  This
304improves situational awareness and makes working on the project
305easier.
306
307<h3 id="portable">2.4 Portable</h3>
308
309Fossil is largely written in ISO C, almost purely conforming to the
310original 1989 standard. We make very little use of
311[https://en.wikipedia.org/wiki/C99|C99], and we do not knowingly make
312any use of
313[https://en.wikipedia.org/wiki/C11_(C_standard_revision)|C11]. Fossil
314does call POSIX and Windows APIs where necessary, but it's about
315as portable as you can ask given that ISO C doesn't define all of the
316facilities Fossil needs to do its thing. (Network sockets, file locking,
317etc.) There are certainly well-known platforms Fossil hasn't been ported
318to yet, but that's most likely due to lack of interest rather than
319inherent difficulties in doing the port. We believe the most stringent
320limit on its portability is that it assumes at least a 32-bit CPU and
321several megs of flat-addressed memory.⁴ Fossil isn't quite as
322[https://www.sqlite.org/custombuild.html|portable as SQLite], but it's
323close.
324
325Over half of the C code in Fossil is actually an embedded copy of the
326current version of SQLite. Much of what is Fossil-specific after you set
327SQLite itself aside is SQL code calling into SQLite. The number of lines
328of SQL code in Fossil isn't large by percentage, but since SQL is such
329an expressive, declarative language, it has an outsized contribution to
330Fossil's user-visible functionality.
331
332Fossil isn't entirely C and SQL code. Its web UI [./javascript.md |
333uses JavaScript where
334necessary]. The server-side
335UI scripting uses a custom minimal
336[https://en.wikipedia.org/wiki/Tcl|Tcl] dialect called
337[https://fossil-scm.org/xfer/doc/trunk/www/th1.md|TH1], which is
338embedded into Fossil itself. Fossil's build system and test suite are
339largely based on Tcl.⁵ All of this is quite portable.
340
341About half of Git's code is POSIX C, and about a third is POSIX shell
342code. This is largely why the so-called "Git for Windows" distributions
343(both [https://git-scm.com/download/win|first-party] and
344[https://gitforwindows.org/|third-party]) are actually an
345[http://mingw.org/wiki/msys|MSYS POSIX portability environment] bundled
346with all of the Git stuff, because it would be too painful to port Git
347natively to Windows. Git is a foreign citizen on Windows, speaking to it
348only through a translator.⁶
349
350While Fossil does lean toward POSIX norms when given a choice — LF-only
351line endings are treated as first-class citizens over CR+LF, for example
352— the Windows build of Fossil is truly native.
353
354The third-party extensions to Git tend to follow this same pattern.
355[http://mingw.org/wiki/msys|GitLab isn't portable to Windows at all],
356for example. For that matter, GitLab isn't even officially supported on
357macOS, the BSDs, or uncommon Linuxes! We have many users who regularly
358build and run Fossil on all of these systems.
359
360
361<h3 id="vs-linux">2.5 Linux vs. SQLite</h3>
362
363Fossil and Git promote different development styles because each one was
364specifically designed to support the creator's main software
365development project: [https://en.wikipedia.org/wiki/Linus_Torvalds|Linus
366Torvalds] designed Git to support development of
367[https://www.kernel.org/|the Linux kernel], and
368[https://en.wikipedia.org/wiki/D._Richard_Hipp|D. Richard Hipp] designed
369Fossil to support the development of [https://sqlite.org/|SQLite].
370Both projects must rank high on any objective list of "most
371important FOSS projects," yet these two projects are almost entirely unlike
372one another, so it is natural that the DVCSes created to support these
373projects also differ in many ways.
374
375In the following sections, we will explain how four key differences
376between the Linux and SQLite software development projects dictated the
377design of each DVCS's low-friction usage path.
378
379When deciding between these two DVCSes, you should ask yourself, "Is my
380project more like Linux or more like SQLite?"
381
382
383<h4 id="devorg">2.5.1 Development Organization</h4>
384
385Eric S. Raymond's seminal essay-turned-book
386"[https://en.wikipedia.org/wiki/The_Cathedral_and_the_Bazaar|The
387Cathedral and the Bazaar]" details the two major development
388organization styles found in
389[https://en.wikipedia.org/wiki/Free_and_open-source_software|FOSS]
390projects. As it happens, Linux and SQLite fall on opposite sides of this
391dichotomy. Differing development organization styles dictate a different
392design and low-friction usage path in the tools created to support each
393project.
394
395Git promotes the Linux kernel's bazaar development style, in which a
396loosely-associated mass of developers contribute their work through
397[https://git-scm.com/book/en/v2/Distributed-Git-Distributed-Workflows#_dictator_and_lieutenants_workflow|a
398hierarchy of lieutenants] who manage and clean up these contributions
399for consideration by Linus Torvalds, who has the power to cherry-pick
400individual contributions into his version of the Linux kernel. Git
401allows an anonymous developer to rebase and push specific locally-named
402private branches, so that a Git repo clone often isn't really a clone at
403all: it may have an arbitrary number of differences relative to the
404repository it originally cloned from. Git encourages siloed development.
405Select work in a developer's local repository may remain private
406indefinitely.
407
408The Git preference for siloed development has been strongly adopted by GitHub,
409who say
410"[https://guides.github.com/activities/forking|Forking is at the core of social coding at GitHub]".
411As of September 2021,
412[https://github.com/search?q=is:public|Github hosts 46 million distinct software projects],
413most of them created by forking a previously-existing project. Since
414this is [https://evansdata.com/reports/viewRelease.php?reportID=9 |
415roughly twice the number of developers in the world], it beggars belief
416that most of these forks are still under active development. We expect
417that the vast bulk of these are abandoned one-off efforts.
418
419All of this is exactly what one wants when doing bazaar-style
420development.
421
422Fossil's normal mode of operation differs on every one of these points,
423with the specific designed-in goal of promoting SQLite's cathedral
424development model:
425
426<ul>
427    <li><p><b>Personal engagement:</b> SQLite's developers know each
428    other by name and work together daily on the project.</p></li>
429
430    <li><p><b>Trust over hierarchy:</b> SQLite's developers check
431    changes into their local repository, and these are immediately and
432    automatically synchronized up to the central repository; there is no
433    "[https://git-scm.com/book/en/v2/Distributed-Git-Distributed-Workflows#_dictator_and_lieutenants_workflow|dictator
434    and lieutenants]" hierarchy as with Linux kernel contributions.  D.
435    Richard Hipp rarely overrides decisions made by those he has trusted
436    with commit access on his repositories. Fossil allows you to give
437    [./caps/admin-v-setup.md|some users] more power over what
438    they can do with the repository, but Fossil [./caps/index.md#ucap |
439    only loosely supports] the enforcement of a development organization's
440    social and power hierarchies. Fossil is a great fit for
441    [https://en.wikipedia.org/wiki/Flat_organization|flat
442    organizations].</p></li>
443
444    <li><p><b>No easy drive-by contributions:</b> Git
445    [https://www.git-scm.com/docs/git-request-pull|pull requests] offer
446    a low-friction path to accepting
447    [https://www.jonobacon.com/2012/07/25/building-strong-community-structural-integrity/|drive-by
448    contributions]. Fossil's closest equivalents are its unique
449    [/help?cmd=bundle|bundle] and [/help?cmd=patch|patch] features, which require higher engagement
450    than firing off a PR.⁷ This difference comes directly from the
451    initial designed purpose for each tool: the SQLite project doesn't
452    accept outside contributions from previously-unknown developers, but
453    the Linux kernel does.</p></li>
454
455    <li><p><b>No rebasing:</b> When your local repo clone syncs changes
456    up to its parent, those changes are sent exactly as they were
457    committed locally. [#history|There is no rebasing mechanism in
458    Fossil, on purpose.]</p></li>
459
460    <li><p><b>Sync over push:</b> Explicit pushes are uncommon in
461    Fossil-based projects: the default is to rely on
462    [/help?cmd=autosync|autosync mode] instead, in which each commit
463    syncs immediately to its parent repository. This is a mode so you
464    can turn it off temporarily when needed, such as when working
465    offline. Fossil is still a truly distributed version control system;
466    it's just that its starting default is to assume you're rarely out
467    of communication with the parent repo.
468    <br><br>
469    This is not merely a reflection of modern always-connected computing
470    environments. It is a conscious decision in direct support of
471    SQLite's cathedral development model: we don't want developers going
472    dark, then showing up weeks later with a massive bolus of changes
473    for us to integrate all at once.
474    [https://en.wikipedia.org/wiki/Jim_McCarthy_(author)|Jim McCarthy]
475    put it well in his book on software project management,
476    <i>[https://www.amazon.com/dp/0735623198/|Dynamics of Software
477    Development]</i>: "[https://www.youtube.com/watch?v=oY6BCHqEbyc|Beware
478    of a guy in a room]."</p></li>
479
480    <li><p><b>Branch names sync:</b> Unlike in Git, branch names in
481    Fossil are not purely local labels. They sync along with everything
482    else, so everyone sees the same set of branch names. Fossil's design
483    choice here is a direct reflection of the Linux vs. SQLite project
484    outlook: SQLite's developers collaborate closely on a single
485    coherent project, whereas Linux's developers go off on tangents and
486    occasionally send selected change sets to each other.</p></li>
487
488    <li><p><b>Private branches are rare:</b>
489    [/doc/trunk/www/private.wiki|Private branches exist in Fossil], but
490    they're normally used to handle rare exception cases, whereas in
491    many Git projects, they're part of the straight-line development
492    process.</p></li>
493
494    <li><p><b>Identical clones:</b> Fossil's autosync system tries to
495    keep each local clone identical to the repository it cloned
496    from.</p></li>
497</ul>
498
499Where Git encourages siloed development, Fossil fights against it.
500Fossil places a lot of emphasis on synchronizing everyone's work and on
501reporting on the state of the project and the work of its developers, so
502that everyone — especially the project leader — can maintain a better
503mental picture of what is happening, leading to better situational
504awareness.
505
506You can think about this difference in terms of
507[https://en.wikipedia.org/wiki/Feedback | feedback loop size], which we
508know from the mathematics of
509[https://en.wikipedia.org/wiki/Control_theory | control theory] to
510directly affect the speed at which any system can safely make changes.
511The larger the feedback loop, the slower the whole system must run in
512order to avoid loss of control. The same concept shows up in other
513contexts, such as in the [https://en.wikipedia.org/wiki/OODA_loop | OODA
514loop] concept.
515Committing your changes to private branches in order to delay a public
516push to the parent repo increases the size of your collaborators'
517control loops, either causing them to slow their work in order to safely
518react to your work, or to overcorrect in response to each change.
519
520Each DVCS can be used in the opposite style, but doing so works against
521their low-friction paths.
522
523
524<h4 id="scale">2.5.2 Scale</h4>
525
526The Linux kernel has a far bigger developer community than that of
527SQLite: there are thousands and thousands of contributors to Linux, most
528of whom do not know each others names. These thousands are responsible
529for producing roughly 89⨉ more code than is in SQLite. (10.7
530[https://en.wikipedia.org/wiki/Source_lines_of_code|MLOC] vs. 0.12 MLOC
531according to [https://dwheeler.com/sloccount/|SLOCCount].) The Linux
532kernel and its development process were already uncommonly large back in
5332005 when Git was designed, specifically to support the consequences of
534having such a large set of developers working on such a large code base.
535
53695% of the code in SQLite comes from just four programmers, and 64% of
537it is from the lead developer alone. The SQLite developers know each
538other well and interact daily. Fossil was designed for this development
539model.
540
541We think you should ask yourself whether you have Linus Torvalds scale
542software configuration management problems or D. Richard Hipp scale
543problems when choosing your DVCS. An
544[https://en.wikipedia.org/wiki/Impact_wrench|automotive air impact
545wrench] running at 8000 RPM driving an M8 socket-cap bolt at 16 cm/s is
546not the best way to hang a picture on the living room wall.
547
548
549<h4 id="branches">2.5.3 Individual Branches vs. The Entire Change History</h4>
550
551Both Fossil and Git store history as a directed acyclic graph (DAG)
552of changes, but Git tends to focus more on individual branches of
553the DAG, whereas Fossil puts more emphasis on the entire DAG.
554
555For example, the default behavior in Git is to only synchronize
556a single branch, whereas with Fossil the only sync option is to
557sync the entire DAG.  Git commands,
558GitHub, and GitLab tend to show only a single branch at
559a time, whereas Fossil usually shows all parallel branches at
560once.  Git has commands like "rebase" that help keep all relevant
561changes on a single branch, whereas Fossil encourages a style of
562many concurrent branches constantly springing into existence,
563undergoing active development in parallel for a few days or weeks, then
564merging back into the main line and disappearing.
565
566This difference in emphasis arises from the different purposes of
567the two systems.  Git focuses on individual branches, because that
568is exactly what you want for a highly-distributed bazaar-style project
569such as Linux.  Linus Torvalds does not want to see every check-in
570by every contributor to Linux, as such extreme visibility does not scale
571well.  But Fossil was written for the cathedral-style SQLite project
572with just a handful of active committers.  Seeing all
573changes on all branches all at once helps keep the whole team
574up-to-date with what everybody else is doing, resulting in a more
575tightly focused and cohesive implementation.
576
577
578<h3 id="checkouts">2.6 One vs. Many Check-outs per Repository</h3>
579
580Because Git commingles the repository data with the initial checkout of
581that repository, the default mode of operation in Git is to stick to that
582single work/repo tree, even when that's a shortsighted way of working.
583
584Fossil doesn't work that way. A Fossil repository is a SQLite database
585file which is normally stored outside the working checkout directory. You can
586[/help?cmd=open | open] a Fossil repository any number of times into
587any number of working directories. A common usage pattern is to have one
588working directory per active working branch, so that switching branches
589is done with a <tt>cd</tt> command rather than by checking out the
590branches successively in a single working directory.
591
592Fossil does allow you to switch branches within a working checkout
593directory, and this is also often done. It is simply that there is no
594inherent penalty to either choice in Fossil as there is in Git. The
595standard advice is to use a switch-in-place workflow in Fossil when
596the disturbance from switching branches is small, and to use multiple
597checkouts when you have long-lived working branches that are different
598enough that switching in place is disruptive.
599
600While you can [./gitusers.md#worktree | use Git in the Fossil style],
601Git's default tie between working directory and
602repository means the standard method for working with a Git repo is to
603have one working directory only. Most Git tutorials teach this style, so
604it is how most people learn to use Git. Because relatively few people
605use Git with multiple working directories per repository, there are
606[https://duckduckgo.com/?q=git+worktree+problem | several known
607problems] with that way of working, problems which don't happen in Fossil because of
608the clear [./ckout-workflows.md | separation] between a Fossil repository and
609each working directory.
610
611This distinction matters because switching branches inside a single working directory loses local context
612on each switch.
613
614For instance, in any software project where the runnable program must be
615built from source files, you invalidate build objects on each switch,
616artificially increasing the time required to switch versions. Most obviously, this
617affects software written in statically-compiled programming languages
618such as C, Java, and Haskell, but it can even affect programs written in
619dynamic languages like JavaScript. A typical
620[https://en.wikipedia.org/wiki/Single-page_application | SPA] build
621process involves several passes: [http://browserify.org/ | Browserify] to convert
622[https://nodejs.org/ | Node] packages so they'll run in a web browser,
623[https://sass-lang.com | SASS] to CSS translation,
624transpilation of [https://www.typescriptlang.org | Typescript] to JavaScript,
625[https://github.com/mishoo/UglifyJS | uglification], etc.
626Once all that processing work is done for a given input
627file in a given working directory, why re-do that work just to switch
628versions? If most of the files that differ between versions don't change
629very often, you can save substantial time by switching branches with
630<tt>cd</tt> rather than swapping versions in-place within a working
631checkout directory.
632
633For another example, you might have an active long-running test grinding
634away in a working directory, then get a call from a customer requiring
635that you switch to a stable branch to answer questions in terms of the
636version that customer is running. You don't want to stop the test in
637order to switch your lone working directory to the stable branch.
638
639Disk space is cheap. Having several working directories, each with its
640own local state, makes switching versions cheap and fast. Plus,
641<tt>cd</tt> is faster to type than <tt>git checkout</tt> or <tt>fossil
642update</tt>.
643
644
645<h3 id="history">2.7 What you should have done vs. What you actually did</h3>
646
647Git puts a lot of emphasis on maintaining
648a "clean" check-in history.  Extraneous and experimental branches by
649individual developers often never make it into the main repository.
650Branches may be rebased before being pushed to make
651it appear as if development had been linear, or "squashed" to make it
652appear that multiple commits were made as a single commit.
653There are [https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History |
654other history rewriting mechanisms in Git] as well. Git strives to record what
655the development of a project should have looked like had there been no
656mistakes.
657
658Fossil, in contrast, puts more emphasis on recording exactly what happened,
659including all of the messy errors, dead-ends, experimental branches, and
660so forth.  One might argue that this
661makes the history of a Fossil project "messy," but another point of view
662is that this makes the history "accurate."  In actual practice, the
663superior reporting tools available in Fossil mean that the added "mess"
664is not a factor.
665
666Like Git, Fossil has an [/help?cmd=amend|amend command] for modifying
667prior commits, but unlike in Git, this works not by replacing data in
668the repository, but by adding a correction record to the repository that
669affects how later Fossil operations present the corrected data. The old
670information is still there in the repository, it is just overridden from
671the amendment point forward.
672
673Fossil lacks almost every other history rewriting mechanism listed on
674the Git documentation page linked above. [./rebaseharm.md | There is no
675rebase] in Fossil, on purpose, thus no way to reorder or copy commits
676around in the commit hash tree. There is no commit squashing, dropping,
677or interactive patch-based cherry-picking of commit elements in Fossil.
678There is nothing like Git's <tt>filter-branch</tt> in Fossil.
679
680The lone exception is deleting commits. Fossil has two methods for doing
681that, both of which have stringent limitations, on purpose.
682
683The first is [/doc/trunk/www/shunning.wiki | shunning]. See that
684document for details, but briefly, you only get mandatory compliance
685for shun requests within a single repository. Shun requests do not
686propagate automatically between repository clones. A Fossil repository
687administrator can <i>cooperatively</i> pull another repo's shun requests
688across a sync boundary, so that two admins can get together and agree to
689shun certain committed artifacts, but a person cannot force their local
690shun requests into another repo without having admin-level control over
691the receiving repo as well. Fossil's shun feature isn't for fixing up
692everyday bad commits, it's for dealing with extreme situations: public
693commits of secret material, ticket/wiki/forum spam, law enforcement
694takedown demands, etc.
695
696There is also the experimental [/help?cmd=purge | <tt>purge</tt>
697command], which differs from shunning in ways that aren't especially
698important in the context of this document. At a 30000 foot level, you
699can think of purging as useful only when you've turned off Fossil's
700autosync feature and want to pluck artifacts out of its hash tree before
701they get pushed. In that sense, it's approximately the same as
702<tt>git rebase -i, drop</tt>. However, given that Fossil defaults to
703having autosync enabled [#devorg | for good reason], the purge command
704isn't very useful in practice: once a commit has been pushed into
705another repo, shunning is more useful if you need to delete it from
706history.
707
708If these accommodations strike you as incoherent with respect to
709Fossil's philosophy of durable, unchanging commits, realize that if
710shunning and purging were removed from Fossil, you could still remove
711artifacts from the repository with SQL <tt>DELETE</tt> statements; the
712repository database file is, after all, directly modifiable, being
713writable by your user. Where the Fossil philosophy really takes hold is
714in making it difficult to violate the integrity of the hash tree.
715It's somewhat tangential, but the document [./blockchain.md | "Is Fossil
716a Blockchain?"] touches on this and related topics.
717
718One commentator characterized Git as recording history according to
719the victors, whereas Fossil records history as it actually happened.
720
721
722<h3 id="testing">2.8 Test Before Commit</h3>
723
724One of the things that falls out of Git's default separation of commit
725from push is that there are several Git sub-commands that jump straight
726to the commit step before a change could possibly be tested. Fossil, by
727contrast, makes the equivalent change to the local working check-out
728only, requiring a separate check-in step to commit the change. This
729design difference falls naturally out of Fossil's default-enabled
730autosync feature and its philosophy of [#history | not offering history
731rewriting features].
732
733The prime example in Git is rebasing: the change happens to the local
734repository immediately if successful, even though you haven't tested the
735change yet. It's possible to argue for such a design in a tool like Git
736since it lacks an autosync feature, because you can still test the
737change before pushing local changes to the parent repo, but in the
738meantime you've made a durable change to your local Git repository. You
739must do something drastic like <tt>git reset --hard</tt> to revert that
740rebase or rewrite history before pushing it if the rebase causes a
741problem. If you push your rebased local repo up to the parent without
742testing first, you cannot fix it without violating
743[https://www.atlassian.com/git/tutorials/merging-vs-rebasing#the-golden-rule-of-rebasing
744| the golden rule of rebasing].
745
746Lesser examples are the Git <tt>merge</tt>, <tt>cherry-pick</tt>, and
747<tt>revert</tt> commands, all of which apply work from one branch onto
748another, and all of which commit their change to the local repository
749immediately without giving you
750an opportunity to test the change first unless you give the
751<tt>--no-commit</tt> option. Otherwise, you're back in the same boat:
752reset the local repository or rewrite history to fix things, then maybe
753retry.
754
755Fossil cannot sensibly work that way because of its default-enabled
756autosync feature and its purposeful paucity of commands for modifying
757commits, as discussed in [#history | the prior section].
758
759Instead of jumping straight to the commit step, Fossil
760applies the proposed merge to the local working directory only,
761requiring a separate check-in step before the change is committed to the
762repository. This gives you a chance to test the change first,
763either manually or by running your software's automatic tests. (Ideally,
764both!) Thus, Fossil doesn't need rebase, squashing,
765<tt>reset --hard</tt>, or other Git commit mutating mechanisms.
766
767Because Fossil requires an explicit commit for a merge, it has the nice
768side benefit that it makes you give an explicit commit <i>message</i>
769for each merge, whereas Git writes that commit message itself by default
770unless you give the optional <tt>--edit</tt> flag to override it.
771
772We don't look at this difference as a workaround in Fossil for autosync,
773but instead as a test-first philosophical difference:
774<tt>fossil commit</tt> is a <i>commitment</i>. When every commit is
775pushed to the parent repo by default, it encourages a working style in
776which every commit is tested first. It encourages thinking before
777acting. We believe this is an inherently good thing.
778
779Incidentally, this is a good example of Git's messy command design.
780These three commands:
781
782<pre>
783    $ git merge HASH
784    $ git cherry-pick HASH
785    $ git revert HASH
786</pre>
787
788...are all the same command in Fossil:
789
790<pre>
791    $ fossil merge HASH
792    $ fossil merge --cherrypick HASH
793    $ fossil merge --backout HASH
794</pre>
795
796If you think about it, they're all the same function: apply work done on
797one branch to another. All that changes between these commands is how
798much work gets applied — just one check-in or a whole branch — and the
799merge direction.  This is the sort of thing we mean when we point out
800that Fossil's command interface is simpler than Git's: there are fewer
801concepts to keep track of in your mental model of Fossil's internal
802operation.
803
804Fossil's implementation of the feature is also simpler to describe. The
805brief online help for <tt>[/help?cmd=merge | fossil merge]</tt> is
806currently 41 lines long, to which you want to add the 600 lines of
807[./branching.wiki | the branching document]. The equivalent
808documentation in Git is the aggregation of the man pages for the above
809three commands, which is over 1000 lines, much of it mutually redundant.
810(e.g.  Git's <tt>--edit</tt> and <tt>--no-commit</tt> options get
811described three times, each time differently.) Fossil's
812documentation is not only more concise, it gives a nice split of brief
813online help and full online documentation.
814
815
816<h3 id="hash">2.9 Hash Algorithm: SHA-3 vs SHA-2 vs SHA-1</h3>
817
818Fossil started out using 160-bit SHA-1 hashes to identify check-ins,
819just as in Git. That changed in early 2017 when news of the
820[https://shattered.io/|SHAttered attack] broke, demonstrating that SHA-1
821collisions were now practical to create. Two weeks later, the creator of
822Fossil delivered a new release allowing a clean migration to
823[https://en.wikipedia.org/wiki/SHA-3|256-bit SHA-3] with
824[./hashpolicy.wiki|full backwards compatibility] to old SHA-1 based
825repositories.
826
827In October 2019, after the last of the major binary
828package repos offering Fossil upgraded to Fossil 2.<i>x</i>,
829we switched the default hash mode so that from
830Fossil 2.10 forward, the conversion to SHA-3 is fully automatic.
831This not
832only solves the SHAttered problem, it should prevent a reoccurrence of
833similar problems for the foreseeable future.
834
835Meanwhile, the Git community took until August 2018 to publish
836[https://git-scm.com/docs/hash-function-transition/|their first plan]
837for solving the same problem by moving to SHA-256, a variant of the
838[https://en.wikipedia.org/wiki/SHA-2 | older SHA-2 algorithm].  As of
839this writing in February 2020, that plan hasn't been implemented, as far
840as this author is aware, but there is now
841[https://lwn.net/ml/git/20200113124729.3684846-1-sandals@crustytoothpaste.net/
842| a competing SHA-256 based plan] which requires complete repository
843conversion from SHA-1 to SHA-256, breaking all public hashes in the
844repo. One way to characterize such a massive upheaval in Git terms is a
845whole-project rebase, which violates
846[https://blog.axosoft.com/golden-rule-of-rebasing-in-git/ | Git's own
847Golden Rule of Rebasing].
848
849Regardless of the eventual implementation details, we fully expect Git
850to move off SHA-1 eventually and for the changes to take years more to
851percolate through the community.
852
853Almost three years after Fossil solved this problem, the
854[https://sha-mbles.github.io/ | SHAmbles attack] was published, further
855weakening the case for continuing to use SHA-1.
856
857The practical impact of attacks like SHAttered and SHAmbles on the
858Git and Fossil Merkle trees isn't clear, but you want to have your repositories
859moved over to a stronger hash algorithm before someone figures out how
860to make use of the weaknesses in the old one. Fossil has had this covered
861for years now, so that the solution is now almost universally deployed.
862
863<hr/>
864
865<h3>Asides and Digressions</h3>
866
867<i><small><ol>
868    <li><p>[./mirrorlimitations.md|Many
869    things are lost] in making a Git mirror of a Fossil repo due to
870    limitations of Git relative to Fossil. GitHub adds some of these
871    missing features to stock
872    Git, but because they're not part of Git proper,
873    [./mirrortogithub.md|exporting a Fossil repository to GitHub] will
874    still not include them; Fossil tickets do not become GitHub issues,
875    for example.
876
877    <li><p>The <tt>fossil-scm.org</tt> web site is actually hosted in
878    several parts, so that it is not strictly true that "everything" on
879    it is in the self-hosting Fossil project repo. The web forum is
880    hosted as [https://fossil-scm.org/forum/|a separate Fossil repo]
881    from the [https://fossil-scm.org/home/|main Fossil self-hosting
882    repo] for administration reasons, and the Download page content
883    isn't normally synchronized with a "<tt>fossil clone</tt>" command unless
884    you add the "-u" option.  (See "[./aboutdownload.wiki|How the
885    Download Page Works]" for details.)
886    Chat history is deliberately not synced as
887    chat messages are intended to be ephemeral.
888    There may also be some purely
889    static elements of the web site served via D. Richard Hipp's own
890    lightweight web server,
891    <tt>[https://sqlite.org/althttpd/|althttpd]</tt>,
892    which is configured as a front end to Fossil running in CGI mode on
893    these sites.
894
895    <li><p>That estimate is based on pricing at Digital Ocean in
896    mid-2019: Fossil will run just fine on the smallest instance they
897    offer, at US $5/month, but the closest match to GitLab's minimum
898    requirements among Digital Ocean's offerings currently costs
899    $40/month.
900
901    <li><p>This means you can give up waiting for Fossil to be ported to
902    the PDP-11, but we remain hopeful that someone may eventually port
903    it to [https://en.wikipedia.org/wiki/Z/OS|z/OS].
904
905    <li><p>"Why is there all this Tcl in and around Fossil?" you may
906    ask. It is because D. Richard Hipp is a long-time Tcl user and
907    contributor. SQLite started out as an embedded database for Tcl
908    specifically. ([https://sqlite.org/tclsqlite.html | [Reference]])
909    When he then created Fossil to manage the development of SQLite, it
910    was natural for him to use Tcl-based tools for its scripting, build
911    system, test system, etc. It came full circle in 2011 when
912    [https://www.reddit.com/r/programming/comments/fwrx5/tcl_and_tk_move_away_from_cvs_to_fossil/
913    | the Tcl and Tk projects moved from CVS to Fossil].
914
915    <li><p>A minority of the pieces of the Git core software suite are
916    written in other languages, primarily Perl, Python, and Tcl. (e.g.
917    <tt>git-send-mail</tt>, <tt>git-p4</tt>, and <tt>gitk</tt>,
918    respectively.)  Although these interpreters are quite portable, they
919    aren't installed by default everywhere, and on some platforms you
920    can't count on them at all. (Not just Windows, but also the BSDs and
921    many other non-Linux platforms.) This expands the dependency
922    footprint of Git considerably. It is why the current Git for Windows
923    distribution is 44.7&nbsp;MiB but the current <tt>fossil.exe</tt>
924    zip file for Windows is 2.24&nbsp;MiB. Fossil is much smaller
925    despite using a roughly similar amount of high-level scripting code
926    because its interpreters are compact and built into Fossil itself.
927
928    <li><p>Both Fossil and Git support
929    [https://en.wikipedia.org/wiki/Patch_(Unix)|<tt>patch(1)</tt>
930    files] — unified diff formatted output — for accepting drive-by contributions, but it's a
931    lossy contribution path for both systems. Unlike Git PRs and Fossil
932    bundles, patch files collapse multiple checkins together, they don't
933    include check-in comments, and they cannot encode changes made above
934    the individual file content layer: you lose branching decisions,
935    tag changes, file renames, and more when using patch files. Fossil
936    2.16 adds [./patchcmd.md | a <tt>fossil patch</tt> command] that
937    also solves these problems, but it is because it works like a Fossil
938    bundle, only for uncommitted changes; it doesn't use Larry Wall's
939    <tt>patch</tt> tool to apply unified diff output to the receiving
940    Fossil checkout.</p></li>
941</ol></i></small>
942