summaryrefslogtreecommitdiff
path: root/www/fossil-v-git.wiki
diff options
context:
space:
mode:
authorcashmere <cashmere@autistici.org>2026-09-04 09:05:24 +0200
committercashmere <cashmere@autistici.org>2026-09-04 09:05:24 +0200
commit4f49b16079b27d7ce633619e4cddfdf2bffbc952 (patch)
treec296c1e7f3c3e2f6859c6d3a1b1b208779b89679 /www/fossil-v-git.wiki
downloadrelic-master.tar.gz
initial commitHEADmaster
Diffstat (limited to 'www/fossil-v-git.wiki')
-rw-r--r--www/fossil-v-git.wiki984
1 files changed, 984 insertions, 0 deletions
diff --git a/www/fossil-v-git.wiki b/www/fossil-v-git.wiki
new file mode 100644
index 0000000..7c64c7f
--- /dev/null
+++ b/www/fossil-v-git.wiki
@@ -0,0 +1,984 @@
+<title>Fossil Versus Git</title>
+
+<h2>1.0 Don't Stress!</h2>
+
+The feature sets of Fossil and [http://git-scm.com | Git] overlap in
+many ways. Both are
+[https://en.wikipedia.org/wiki/Distributed_version_control | distributed
+version control systems] which store a tree of check-in objects to a
+local repository clone. In both systems, the local clone starts out as a
+full copy of the remote parent. New content gets added to the local
+clone and then later optionally pushed up to the remote, and changes to
+the remote can be pulled down to the local clone at will. Both systems
+offer diffing, patching, branching, merging, cherry-picking, bisecting,
+private branches, a stash, etc.
+
+Fossil has inbound and outbound Git conversion features, so if you start
+out using one DVCS and later decide you like the other better, you can
+easily [./inout.wiki | move your version-controlled file content].¹
+
+In this document, we set all of that similarity and interoperability
+aside and focus on the important differences between the two, especially
+those that impact the user experience.
+
+Keep in mind that you are reading this on a Fossil website, and though
+we try to be fair, the information here will inevitably
+be biased in favor of Fossil purely because we spend most of our
+time using Fossil, not Git. Ask around for second opinions from
+people who have used <em>both</em> Fossil and Git.
+
+If you want a more practical, less philosophical guide to moving from
+Git to Fossil, see our [./gitusers.md | Git to Fossil Translation Guide].
+
+
+<h2>2.0 Differences Between Fossil And Git</h2>
+
+Differences between Fossil and Git are summarized by the following table,
+with further description in the text that follows.
+
+<table style="width: fit-content">
+<tr><th>GIT</th><th>FOSSIL</th><th>more</th></tr>
+<tr>
+ <td>File versioning only</td>
+ <td>
+ VCS, tickets, wiki, docs, notes, forum, chat, UI,
+ [https://en.wikipedia.org/wiki/Role-based_access_control|RBAC]
+ </td>
+ <td><a href="#features">2.1&nbsp;&darr;</a></td>
+</tr>
+<tr>
+ <td>A federation of many small programs</td>
+ <td>One self-contained, stand-alone executable</td>
+ <td><a href="#selfcontained">2.2&nbsp;&darr;</a></td>
+</tr>
+<tr>
+ <td>Custom key/value data store</td>
+ <td>[https://sqlite.org/mostdeployed.html|The most used SQL database in the world]</td>
+ <td><a href="#durable">2.3&nbsp;&darr;</a></td>
+</tr>
+<tr>
+ <td>Runs natively on POSIX systems</td>
+ <td>Runs natively on both POSIX and Windows</td>
+ <td><a href="#portable">2.4&nbsp;&darr;</a></td>
+</tr>
+<tr>
+ <td>Bazaar-style development</td>
+ <td>Cathedral-style development</td>
+ <td><a href="#devorg">2.5.1&nbsp;&darr;</a></td>
+</tr>
+<tr>
+ <td>Designed for Linux kernel development</td>
+ <td>Designed for SQLite development</td>
+ <td><a href="#scale">2.5.2&nbsp;&darr;</a></td>
+</tr>
+<tr>
+ <td>Focus on individual branches</td>
+ <td>Focus on the entire tree of changes</td>
+ <td><a href="#branches">2.5.3&nbsp;&darr;</a></td>
+</tr>
+<tr>
+ <td>One check-out per repository</td>
+ <td>Many check-outs per repository</td>
+ <td><a href="#checkouts">2.6&nbsp;&darr;</a></td>
+</tr>
+<tr>
+ <td>Remembers what you should have done</td>
+ <td>Remembers what you actually did</td>
+ <td><a href="#history">2.7&nbsp;&darr;</a></td>
+</tr>
+<tr>
+ <td>Commit first</td>
+ <td>Test first</td>
+ <td><a href="#testing">2.8&nbsp;&darr;</a></td>
+</tr>
+<tr>
+ <td>SHA-1 or SHA-2</td>
+ <td>SHA-1 and/or SHA-3, in the same repository</td>
+ <td><a href="#hash">2.9&nbsp;&darr;</a></td>
+</tr>
+</table>
+
+<h3 id="features">2.1 Featureful</h3>
+
+Git provides file versioning services only, whereas Fossil adds
+an integrated [./wikitheory.wiki | wiki],
+[./bugtheory.wiki | ticketing &amp; bug tracking],
+[./embeddeddoc.wiki | embedded documentation],
+[./event.wiki | technical notes], a [./forum.wiki | web forum],
+and a [./chat.md | chat service],
+all within a single nicely-designed [./customskin.md|skinnable] web
+[/help/ui|UI],
+protected by [./caps/ | a fine-grained role-based
+access control system].
+These additional capabilities are available for Git as 3rd-party
+add-ons, but with Fossil they are integrated into
+the design, to the point that it approximates
+"[https://github.com/ | GitHub]-in-a-box."
+
+Even if you only want straight version control, Fossil has affordances
+not available in Git.
+
+For instance, Fossil can do operations over all local repo clones and
+check-out directories with a single command. You can say "<tt>fossil
+all sync</tt>" on a laptop prior to taking it off the network hosting
+those repos, as before going on a trip. It doesn't matter if those
+repos are private and restricted to your company network or public
+Internet-hosted repos, you get synced up with everything you need while
+off-network.
+
+You get the same capability with several other Fossil
+sub-commands as well, such as "<tt>fossil all changes</tt>" to get a list of files
+that you forgot to commit prior to the end of your working day, across
+all repos.
+
+Whenever Fossil is told to modify the local checkout in some destructive
+way ([/help/rm|fossil rm], [/help/update|fossil update],
+[/help/revert|fossil revert], etc.) Fossil remembers the prior state
+and is able to return the check-out directory to that state with a
+<tt>fossil undo</tt> command. While you cannot undo a commit in Fossil
+— [#history | on purpose!] — as long as the change remains confined to
+the local check-out directory only, Fossil makes undo
+[https://git-scm.com/book/en/v2/Git-Basics-Undoing-Things|easier than in
+Git].
+
+For developers who choose to self-host projects rather than rely on a
+3rd-party service such as GitHub, Fossil is much easier to set up:
+the stand-alone Fossil executable together with a [./server/any/cgi.md|2-line CGI script]
+suffice to instantiate a full-featured developer website. To accomplish
+the same using Git requires locating, installing, configuring, integrating,
+and managing a wide assortment of separate tools. Standing up a developer
+website using Fossil can be done in minutes, whereas doing the same using
+Git requires hours or days.
+
+Fossil is small, complete, and self-contained. If you clone
+[https://github.com/git/git|Git's self-hosting repository], you get just
+Git's source code. If you clone Fossil's self-hosting repository, you
+get the entire Fossil website — source code, documentation, ticket
+history, and so forth.² That means you get a copy of this very article
+and all of its historical versions, plus the same for all of the other
+public content on this site.
+
+
+<h3 id="selfcontained" name="selfcontained">2.2 Self Contained</h3>
+
+Git is actually a collection of many small tools, each doing one small
+part of the job, which can be recombined (by experts) to perform
+powerful operations. Git has a lot of complexity and many dependencies,
+so that most people end up installing it via some kind of package
+manager, simply because the creation of complicated binary packages is
+best delegated to people skilled in their creation. Normal Git users are
+not expected to build Git from source and install it themselves.
+
+Fossil is a single self-contained stand-alone executable which
+depends only on common platform libraries in its default configuration.
+To install one of [https://fossil-scm.org/home/uv/download.html | our
+precompiled binaries], unpack the executable from the archive and put it
+somewhere in your <tt>PATH</tt>. To uninstall it, delete the executable.
+
+This policy is particularly useful when running Fossil inside a
+restrictive container, anything from [./chroot.md | classic chroot
+jails] to modern [https://en.wikipedia.org/wiki/OS-level_virtualization
+| OS-level virtualization mechanisms] such as
+[https://en.wikipedia.org/wiki/Docker_(software) | Docker].
+Our [./containers.md | stock container image] is under 11&nbsp;MB when
+uncompressed and running because it contains nothing but a single
+statically-linked binary.
+
+If you build a dynamically linked binary instead, a Linux
+x86_64 build of Fossil drops to under 5&nbsp;MB on-disk, stripped.
+It will depend only on widespread
+platform libraries with stable ABIs such as glibc, zlib, and openssl.
+
+Much the same is true on Windows, where our precompiled static binaries
+are distributed inside a ZIP archive containing "<tt>fossil.exe</tt>"
+and not a thing else, with a size on-par that of the Linux container
+build. There is no "<tt>setup.exe</tt>" to run; just copy it into your
+<tt>%PATH%</tt>.
+
+Fossil is easy to build from sources. Just run
+"<tt>./configure && make</tt>" on POSIX systems and
+"<tt>nmake /f Makefile.msc</tt>" on Windows.
+
+Git, by contrast, takes 25&nbsp;MiB on Ubuntu 26.04 across 940 files.
+That doesn't count platform facilities like the POSIX shell and script
+interpreters its full feature set requires. A fairer comparison to
+Fossil's single static binary container is the Docker Hardened Image for
+[https://hub.docker.com/hardened-images/catalog/dhi/git |Git 2.x on
+Alpine], which presently weighs in at 36.3 megs unpacked and 607 files,
+if you count all the <tt>busybox</tt> symlinks which would otherwise be
+separate binaries on a more traditional Linux system. Worst of all are
+the "Git for Windows" packages where they end up needing to ship a large
+yet nerfed Linux-like userland to support Git's many loosely coupled
+pieces, approaching a hundred megs and thousands of files.
+
+Some say that Git more closely adheres to the Unix philosophy,
+summarized as "many small tools, loosely joined," but we have many
+examples of other successful Unix software that violates that principle
+to good effect, from Apache to Python to ZFS. We can infer from that
+that this is not an absolute principle of good software design.
+Sometimes "many features, tightly-coupled" works better. What actually
+matters is effectiveness and efficiency. We believe Fossil achieves
+this.
+
+The above size comparisons aren't apples-to-apples anyway. We've
+compared the size of Fossil with all of its [#features | many built-in
+features] to a relatively bare-bones Git installation. You must add a
+lot of third-party software to Git to give it a Fossil-equivalent
+feature set.
+
+Consider [https://about.gitlab.com/|GitLab], which wraps Git in enough
+features to bring it to a rough (very rough) parity with Fossil. While
+it is certainly ahead in some areas — automation comes to mind — it must
+be noted that GitLab's own forums are on Discourse, not self-hosted as
+with Fossil. You may then argue that Discourse is superior to the Fossil
+forum feature, but this merely brings us back to another of Fossil's
+advantages: when the posts are part of the repo, you can migrate your
+entire project to another host merely by standing that repo back up on
+other hardware. Choosing to assemble your project hosting from multiple
+pieces requires each to have their own backups, their own management
+processes, and their own migration strategies.
+
+Even then, these disparate services do not cooperate at the same level
+as in Fossil, where the ability to have a forum post linking to a wiki
+article linking to a trouble ticket linking to a commit falls out of the
+model nearly for free. These are all internal links, mind, potentially
+using nothing but repository artifact hashes, all backed by SQLite's
+referential integrity. With something like GitLab, its "internal
+references" are tacked on after the fact, not Git repo hashes at all,
+and when it comes to external services like Discourse, history tells us
+you're storing up tech debt which will come due at some future point in
+the form of piles of broken links when one piece or the other needs
+changing out.
+
+Furthermore, GitLab is far more resource hungry even in its
+[https://docs.gitlab.com/omnibus/settings/memory_constrained_envs/ |
+minimal configuration], hence more costly to run than the equivalent
+Fossil setup. [https://hub.docker.com/r/gitlab/gitlab-ce/ | The
+official GitLab Community Edition container] currently clocks in at
+3.44 GiB, independent of add-ons like Discourse. You can expect it to
+cost around 8× as much to host it on a cloud service. Even pared down
+to the minimum, there remain the consequences from the difference in
+basic technology choices: Ruby and PostgreSQL vs C and SQLite.
+
+The Fossil project itself is [./selfhost.wiki|hosted on a small and
+inexpensive VPS]. A bare-bones $5/month VPS or a
+spare Raspberry Pi is sufficient to run a full-up project
+site, complete with tickets, wiki, chat, and forum, in addition to
+being a code repository.
+
+<h3 id="durable" name="database">2.3 Query Language</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 the parent's hash.
+
+The difference is that Git stores its objects as individual files in the
+<tt>.git</tt> folder or compressed into bespoke key/value
+[https://git-scm.com/book/en/v2/Git-Internals-Packfiles|pack-files],
+whereas Fossil stores its objects in a [https://www.sqlite.org/|SQLite]
+database file which provides ACID transactions and a high-level query
+language.
+
+This difference is more than an implementation detail; it has important
+practical consequences.
+
+One notable example is that it is difficult to find the descendants
+of check-ins in Git.
+One can easily locate the ancestors of a particular Git check-in
+by following the pointers embedded in the check-in object, but
+going the other direction is difficult enough
+that neither native Git nor the big "forge" facilities
+like GitHub and GitLab provide this capability short of crawling the
+[https://www.git-scm.com/docs/git-log|commit log]. In Fossil,
+we can find descendants using a simple SQL query, which then allows
+us to see [/timeline?df=release&y=ci|all check-ins since the last release],
+as but one example.
+Git lets you see "what came before," but Fossil makes it just as
+easy to also see "what came after."
+
+Leaf check-ins in Git that lack a "ref" become "detached," making them
+difficult to locate and subject to garbage collection. This
+[https://stackoverflow.com/q/3965676 | detached head
+state] problem has caused grief for
+[https://www.google.com/search?q=git+detached+head+state |
+untold millions of Git users]. With
+Fossil, detached heads are simply impossible because we can always find
+our way back into the Merkle tree using one or more of the relations
+in the SQL database.
+
+The SQL query capabilities of Fossil make it easier to track the
+changes for one particular file within a project. For example,
+you can easily find
+[/finfo/www/fossil-v-git.wiki|the complete edit history of this one document],
+or even
+[/finfo/www/fossil-v-git.wiki?ubg|the same history color-coded by committer],
+Both come down to simple SQL queries in Fossil, with procedural code
+only being used to format the result for display.
+The same result could be obtained from Git, but because the data is
+in a key/value store, much more procedural code has to be written to
+walk the data and compute the result.
+
+The ease of querying Fossil data using SQL means that status or
+history information about the project under management is easier
+to obtain, hence more likely to happen, giving its developers better
+situational awareness.
+Fossil reports tend to be more detailed and useful.
+Compare [/timeline?c=6df7a853ec16865b|this Fossil timeline]
+to
+[https://github.com/drhsqlite/fossil-mirror/commits/master?after=f720c106d297ca1f61bccb30c5c191b88a626d01+34 |
+its closest equivalent in the GitHub mirror]. Judge for yourself: which of those
+reports is more useful to a developer trying to understand what happened?
+
+<h3 id="portable">2.4 Portable</h3>
+
+Fossil is largely written in ISO C, almost purely conforming to the
+original 1989 standard. We make very little use of
+[https://en.wikipedia.org/wiki/C99|C99], and we do not knowingly make
+any use of
+[https://en.wikipedia.org/wiki/C11_(C_standard_revision)|C11]. Fossil
+does call POSIX and Windows APIs where necessary, but it's about
+as portable as you can ask given that ISO C doesn't define all of the
+facilities Fossil needs to do its thing. (Network sockets, file locking,
+etc.) There are certainly well-known platforms Fossil hasn't been ported
+to yet, but that's most likely due to lack of interest rather than
+inherent difficulties in doing the port. We believe the most stringent
+limit on its portability is that it assumes at least a 32-bit CPU and
+several megs of flat-addressed memory.³ Fossil isn't quite as
+[https://www.sqlite.org/custombuild.html|portable as SQLite], but it's
+close.
+
+Over half of the C code in Fossil is actually an embedded copy of the
+current version of SQLite. Much of what is Fossil-specific after you set
+SQLite itself aside is SQL code calling into SQLite. The number of lines
+of SQL code in Fossil isn't large by percentage, but since SQL is such
+an expressive, declarative language, it has an outsized contribution to
+Fossil's user-visible functionality.
+
+Fossil isn't entirely C and SQL code. Its web UI [./javascript.md |
+uses JavaScript where
+necessary]. The server-side
+UI scripting uses a custom minimal
+[https://en.wikipedia.org/wiki/Tcl|Tcl] dialect called
+[./th1.md|TH1], which is
+embedded into Fossil itself. Fossil's build system and test suite are
+largely based on Tcl.⁴ All of this is quite portable.
+
+About half of Git's code is POSIX C, and about a third is POSIX shell
+code. This is largely why the so-called "Git for Windows" distributions
+(both [https://git-scm.com/download/win|first-party] and
+[https://gitforwindows.org/|third-party]) are actually an
+[https://www.msys2.org/wiki/Home/|MSYS POSIX portability environment] bundled
+with all of the Git stuff, because it would be too painful to port Git
+natively to Windows. Git is a foreign citizen on Windows, speaking to it
+only through a translator.⁵
+
+While Fossil does lean toward POSIX norms when given a choice — LF-only
+line endings are treated as first-class citizens over CR+LF, for example
+— the Windows build of Fossil is truly native.
+
+The third-party extensions to Git tend to follow this same pattern.
+[https://docs.gitlab.com/ee/install/install_methods.html#microsoft-windows |
+GitLab isn't portable to Windows at all],
+for example. For that matter, GitLab isn't even officially supported on
+macOS, the BSDs, or uncommon Linuxes! We have many users who regularly
+build and run Fossil on all of these systems.
+
+
+<h3 id="vs-linux">2.5 Linux vs. SQLite</h3>
+
+Fossil and Git promote different development styles because each one was
+specifically designed to support the creator's main software
+development project: [https://en.wikipedia.org/wiki/Linus_Torvalds|Linus
+Torvalds] designed Git to support development of
+[https://www.kernel.org/|the Linux kernel], and
+[https://en.wikipedia.org/wiki/D._Richard_Hipp|D. Richard Hipp] designed
+Fossil to support the development of [https://sqlite.org/|SQLite].
+Both projects must rank high on any objective list of "most
+important FOSS projects," yet these two projects are almost entirely unlike
+one another, so it is natural that the DVCSes created to support these
+projects also differ in many ways.
+
+In the following sections, we will explain how four key differences
+between the Linux and SQLite software development projects dictated the
+design of each DVCS's low-friction usage path.
+
+When deciding between these two DVCSes, you should ask yourself, "Is my
+project more like Linux or more like SQLite?"
+
+
+<h4 id="devorg">2.5.1 Development Organization</h4>
+
+Eric S. Raymond's seminal essay-turned-book
+"[https://en.wikipedia.org/wiki/The_Cathedral_and_the_Bazaar|The
+Cathedral and the Bazaar]" details the two major development
+organization styles found in
+[https://en.wikipedia.org/wiki/Free_and_open-source_software|FOSS]
+projects. As it happens, Linux and SQLite fall on opposite sides of this
+dichotomy. Differing development organization styles dictate a different
+design and low-friction usage path in the tools created to support each
+project.
+
+Git promotes the Linux kernel's bazaar development style, in which a
+loosely-associated mass of developers contribute their work through
+[https://git-scm.com/book/en/v2/Distributed-Git-Distributed-Workflows#_dictator_and_lieutenants_workflow|a
+hierarchy of lieutenants] who manage and clean up these contributions
+for consideration by Linus Torvalds, who has the power to cherry-pick
+individual contributions into his version of the Linux kernel. Git
+allows an anonymous developer to rebase and push specific locally-named
+private branches, so that a Git repo clone often isn't really a clone at
+all: it may have an arbitrary number of differences relative to the
+repository it originally cloned from. Git encourages siloed development.
+Select work in a developer's local repository may remain private
+indefinitely.
+
+All of this is exactly what one wants when doing bazaar-style
+development.
+
+Fossil's normal mode of operation differs on every one of these points,
+with the specific designed-in goal of promoting SQLite's cathedral
+development model:
+
+ * <b>Personal engagement:</b> SQLite's developers know each
+ other by name and work together daily on the project.
+
+ * <b>Trust over hierarchy:</b> SQLite's developers check
+ changes into their local repository, and these are immediately and
+ automatically synchronized up to the central repository; there is no
+ "[https://git-scm.com/book/en/v2/Distributed-Git-Distributed-Workflows#_dictator_and_lieutenants_workflow|dictator
+ and lieutenants]" hierarchy as with Linux kernel contributions. D.
+ Richard Hipp rarely overrides decisions made by those he has trusted
+ with commit access on his repositories. Fossil allows you to give
+ [./caps/admin-v-setup.md|some users] more power over what
+ they can do with the repository, but Fossil [./caps/index.md#ucap |
+ only loosely supports] the enforcement of a development organization's
+ social and power hierarchies. Fossil is a great fit for
+ [https://en.wikipedia.org/wiki/Flat_organization|flat
+ organizations].
+
+ * <b>No easy drive-by contributions:</b> Git
+ [https://www.git-scm.com/docs/git-request-pull|pull requests] offer
+ a low-friction path to accepting
+ [https://www.jonobacon.com/2012/07/25/building-strong-community-structural-integrity/|drive-by
+ contributions]. Fossil's closest equivalents are its unique
+ [/help/bundle|bundle] and [/help/patch|patch] features, which require higher engagement
+ than firing off a PR.⁶ This difference comes directly from the
+ initial designed purpose for each tool: the SQLite project doesn't
+ accept outside contributions from previously-unknown developers, but
+ the Linux kernel does.
+
+ * <b>No rebasing:</b> When your local repo clone syncs changes
+ up to its parent, those changes are sent exactly as they were
+ committed locally. [#history|There is no rebasing mechanism in
+ Fossil, on purpose.]
+
+ * <b>Sync over push:</b> Explicit pushes are uncommon in
+ Fossil-based projects: the default is to rely on
+ [/help/autosync|autosync mode] instead, in which each commit
+ syncs immediately to its parent repository. This is a mode so you
+ can turn it off temporarily when needed, such as when working
+ offline. Fossil is still a truly distributed version control system;
+ it's just that its starting default is to assume you're rarely out
+ of communication with the parent repo.
+ <br><br>
+ This is not merely a reflection of modern always-connected computing
+ environments. It is a conscious decision in direct support of
+ SQLite's cathedral development model: we don't want developers going
+ dark, then showing up weeks later with a massive bolus of changes
+ for us to integrate all at once.
+ [https://en.wikipedia.org/wiki/Jim_McCarthy_(author)|Jim McCarthy]
+ put it well in his book on software project management,
+ <i>[https://www.amazon.com/dp/0735623198/|Dynamics of Software
+ Development]</i>: "[https://www.youtube.com/watch?v=oY6BCHqEbyc|Beware
+ of a guy in a room]."
+
+ * <b>Branch names sync:</b> Unlike in Git, branch names in
+ Fossil are not purely local labels. They sync along with everything
+ else, so everyone sees the same set of branch names. Fossil's design
+ choice here is a direct reflection of the Linux vs. SQLite project
+ outlook: SQLite's developers collaborate closely on a single
+ coherent project, whereas Linux's developers go off on tangents and
+ occasionally send selected change sets to each other.
+
+ * <b>Private branches are rare:</b>
+ [/doc/trunk/www/private.wiki|Private branches exist in Fossil], but
+ they're normally used to handle rare exception cases, whereas in
+ many Git projects, they're part of the straight-line development
+ process.
+
+ * <b>Identical clones:</b> Fossil's autosync system tries to
+ keep each local clone identical to the repository it cloned
+ from.
+
+Where Git encourages siloed development, Fossil fights against it.
+Fossil places a lot of emphasis on synchronizing everyone's work and on
+reporting on the state of the project and the work of its developers, so
+that everyone — especially the project leader — can maintain a better
+mental picture of what is happening, leading to better situational
+awareness.
+
+By contrast, "…[https://docs.github.com/en/get-started/quickstart/contributing-to-projects|forking is
+at the core of social coding at GitHub]". As of June 2026,
+[https://github.com/search?q=is:public|Github hosts 324 million distinct
+software projects], most of which were created by forking a
+previously-existing project. Since this is
+[https://www.griddynamics.com/blog/number-software-developers-world |
+~11× the number of developers in the world], it beggars belief that
+most of these forks are still under active development. The vast bulk
+of these must be abandoned one-off efforts. This is part of the nature
+of bazaar style development.
+
+You can think about this difference in terms of
+[https://en.wikipedia.org/wiki/Feedback | feedback loop size], which we
+know from the mathematics of
+[https://en.wikipedia.org/wiki/Control_theory | control theory] to
+directly affect the speed at which any system can safely make changes.
+The larger the feedback loop, the slower the whole system must run in
+order to avoid loss of control. The same concept shows up in other
+contexts, such as in the [https://en.wikipedia.org/wiki/OODA_loop | OODA
+loop] concept.
+Committing your changes to private branches in order to delay a public
+push to the parent repo increases the size of your collaborators'
+control loops, either causing them to slow their work in order to safely
+react to your work, or to over-correct in response to each change.
+
+Each DVCS can be used in the opposite style, but doing so works against
+their low-friction paths.
+
+
+<h4 id="scale">2.5.2 Scale</h4>
+
+The Linux kernel has a far bigger developer community than that of
+SQLite: there are thousands and thousands of contributors to Linux, most
+of whom do not know each other's names. These thousands are responsible
+for producing roughly 73× more code than is in SQLite. (32.0
+[https://en.wikipedia.org/wiki/Source_lines_of_code|MLOC] vs. 0.44 MLOC
+according to [https://github.com/boyter/scc | scc].) The Linux
+kernel and its development process were already uncommonly large back in
+2005 when Git was designed, specifically to support the consequences of
+having such a large set of developers working on such a large code base.
+
+95% of the code in SQLite comes from just six programmers, and 62% of
+it is from the lead developer alone. The SQLite developers know each
+other well and interact daily. Fossil was designed for this development
+model.
+
+When choosing your DVCS, we think you should ask yourself whether the
+scale of your software configuration management problems is closer to
+those Linus Torvalds designed Git to cope with or whether your work's
+scale is closer to that of SQLite, for which D. Richard Hipp designed
+Fossil. An [https://en.wikipedia.org/wiki/Impact_wrench|automotive air
+impact wrench] running at 8000 RPM driving an M8 socket-cap bolt at 16
+cm/s is not the best way to hang a picture on the living room wall.
+
+Fossil works well for projects several times the size of SQLite,
+[https://core.tcl-lang.org/tcl/ | such as Tcl], with a repository over
+twice the size and with many more core committers.
+
+
+<h4 id="branches">2.5.3 Individual Branches vs. The Entire Change History</h4>
+
+Both Fossil and Git store history as a directed acyclic graph (DAG)
+of changes, but Git tends to focus more on individual branches of
+the DAG, whereas Fossil puts more emphasis on the entire DAG.
+
+While a common usage pattern in Git is to only synchronize
+a single branch — <tt>git pull upstream feature/branch</tt> — instead
+of all refs, Fossil does not give you a choice; it
+syncs the entire DAG or nothing. Git commands,
+GitHub, and GitLab tend to show only a single branch at
+a time, whereas Fossil usually shows all parallel branches at
+once. Git has commands like "rebase" that help keep all relevant
+changes on a single branch, whereas Fossil encourages a style of
+many concurrent branches constantly springing into existence,
+undergoing active development in parallel for a few days or weeks, then
+merging back into the main line and disappearing.
+
+This difference in emphasis arises from the different purposes of
+the two systems. Git's focus on individual branches
+is exactly what you want for a highly-distributed bazaar-style project
+such as Linux. Linus Torvalds does not want to see every check-in
+by every contributor to Linux: such extreme visibility does not scale
+well. Contrast Fossil, which was written for the cathedral-style SQLite project
+and its handful of active committers. Seeing all
+changes on all branches all at once helps keep the whole team
+up-to-date with what everybody else is doing, resulting in a more
+tightly focused and cohesive implementation.
+
+
+<h3 id="checkouts">2.6 One vs. Many Check-outs per Repository</h3>
+
+Because Git commingles the repository data with the initial checkout of
+that repository, the default mode of operation in Git is to stick to that
+single work/repo tree, even when that's a shortsighted way of working.
+
+Fossil doesn't work that way. A Fossil repository is an SQLite database
+file which is normally stored outside the working checkout directory. You can
+[/help/open | open] a Fossil repository any number of times into
+any number of working directories. A common usage pattern is to have one
+working directory per active working branch, so that switching branches
+is done with a <tt>cd</tt> command rather than by checking out the
+branches successively in a single working directory.
+
+Fossil does allow you to switch branches within a working checkout
+directory, and this is also often done. It is simply that there is no
+inherent penalty to either choice in Fossil as there is in Git. The
+standard advice is to use a switch-in-place workflow in Fossil when
+the disturbance from switching branches is small, and to use multiple
+checkouts when you have long-lived working branches that are different
+enough that switching in place is disruptive.
+
+While you can [./gitusers.md#worktree | use Git in the Fossil style] via
+its worktree feature, tutorials continue to teach the style of having
+one working directory only. Git can even fight you on this, as when
+working with a forked repository; it is best to have independent clones
+of the upstream and your fork, to allow separate "remote" lists and
+such. This can result in two working directories but each having a
+captive repo clone each, which isn't in the spirit of <tt>git
+worktree</tt> at all. Yet, it beats the alternative, which then
+highlights a gap in the model of diverging and re-converging forks.
+Ideally, Git would let you create one of these forks as a worktree while
+maintaining a strong separation between your fork and the upstream repo,
+but it ends up being too much hassle to bother with.
+
+There are
+[https://duckduckgo.com/?q=git+worktree+problem | several known
+problems] with the single worktree style, ones which don't happen in
+Fossil because of the clear [./ckout-workflows.md | separation] between
+a Fossil repository and each working directory.
+
+This distinction matters because switching branches inside a single working directory loses local context
+on each switch.
+
+For instance, in any software project where the runnable program must be
+built from source files, you invalidate build objects on each switch,
+artificially increasing the time required to switch versions. Most obviously, this
+affects software written in statically-compiled programming languages
+such as C, Java, and Haskell, but it can even affect programs written in
+dynamic languages like JavaScript. A typical
+[https://en.wikipedia.org/wiki/Single-page_application | SPA] build
+process involves several passes: [http://browserify.org/ | Browserify] to convert
+[https://nodejs.org/ | Node] packages so they'll run in a web browser,
+[https://sass-lang.com | SASS] to CSS translation,
+transpilation of [https://www.typescriptlang.org | Typescript] to JavaScript,
+[https://github.com/mishoo/UglifyJS | uglification], etc.
+Once all that processing work is done for a given input
+file in a given working directory, why re-do that work just to switch
+versions? If most of the files that differ between versions don't change
+very often, you can save substantial time by switching branches with
+<tt>cd</tt> rather than swapping versions in-place within a working
+checkout directory.
+
+For another example, you might have an active long-running test grinding
+away in a working directory, then get a call from a customer requiring
+that you switch to a stable branch to answer questions in terms of the
+version that customer is running. You don't want to stop the test in
+order to switch your lone working directory to the stable branch.
+
+Disk space is cheap. Having several working directories — each with its
+own local state — makes switching versions cheap and fast.
+
+Plus,
+<tt>cd</tt> is faster to type than <tt>git checkout</tt> or <tt>fossil
+update</tt>.
+
+<h3 id="history">2.7 What you should have done vs. What you actually did</h3>
+
+Git puts a lot of emphasis on maintaining
+a "clean" check-in history. Extraneous and experimental branches by
+individual developers often never make it into the main repository.
+Branches may be rebased before being pushed to make
+it appear as if development had been linear, or "squashed" to make it
+appear that multiple commits were made as a single commit.
+There are [https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History |
+other history rewriting mechanisms in Git] as well. Git strives to record what
+the development of a project should have looked like had there been no
+mistakes.
+
+Fossil, in contrast, puts more emphasis on recording exactly what happened,
+including all of the messy errors, dead-ends, experimental branches, and
+so forth. One might argue that this
+makes the history of a Fossil project "messy," but another point of view
+is that this makes the history "accurate." In actual practice, the
+superior reporting tools available in Fossil mean that this incidental mess
+is not a factor.
+
+Like Git, Fossil has an [/help/amend|amend command] for modifying
+prior commits, but unlike in Git, this works not by replacing data in
+the repository, but by adding a correction record to the repository that
+affects how later Fossil operations present the corrected data. The old
+information is still there in the repository, it is just overridden from
+the amendment point forward.
+
+Fossil lacks almost every other history rewriting mechanism listed on
+the Git documentation page linked above. [./rebaseharm.md | There is no
+rebase] in Fossil, on purpose, thus no way to reorder or copy commits
+around in the commit hash tree. There is no commit squashing, dropping,
+or interactive patch-based cherry-picking of commit elements in Fossil.
+There is nothing like Git's <tt>filter-branch</tt> in Fossil.
+
+The lone exception is deleting commits. Fossil has two methods for doing
+that, both of which have stringent limitations, on purpose.
+
+The first is [/doc/trunk/www/shunning.wiki | shunning]. See that
+document for details, but briefly, you only get mandatory compliance
+for shun requests within a single repository. Shun requests do not
+propagate automatically between repository clones. A Fossil repository
+administrator can <i>cooperatively</i> pull another repo's shun requests
+across a sync boundary, so that two admins can get together and agree to
+shun certain committed artifacts, but a person cannot force their local
+shun requests into another repo without having admin-level control over
+the receiving repo as well. Fossil's shun feature isn't for fixing up
+everyday bad commits, it's for dealing with extreme situations: public
+commits of secret material, ticket/wiki/forum spam, law enforcement
+takedown demands, etc.
+
+There is also the experimental [/help/purge | <tt>purge</tt>
+command], which differs from shunning in ways that aren't especially
+important in the context of this document. At a 30000 foot level, you
+can think of purging as useful only when you've turned off Fossil's
+autosync feature and want to pluck artifacts out of its hash tree before
+they get pushed. In that sense, it's approximately the same as
+<tt>git rebase -i, drop</tt>. However, given that Fossil defaults to
+having autosync enabled [#devorg | for good reason], the purge command
+isn't very useful in practice: once a commit has been pushed into
+another repo, shunning is more useful if you need to delete it from
+history.
+
+If these accommodations strike you as incoherent with respect to
+Fossil's philosophy of durable, unchanging commits, realize that if
+shunning and purging were removed from Fossil, you could still remove
+artifacts from the repository with SQL <tt>DELETE</tt> statements; the
+repository database file is, after all, directly modifiable, being
+writable by your user. Where the Fossil philosophy really takes hold is
+in making it difficult to violate the integrity of the hash tree.
+It's somewhat tangential, but the document [./blockchain.md | "Is Fossil
+a Blockchain?"] touches on this and related topics.
+
+One commentator characterized Git as recording history according to
+the victors, whereas Fossil records history as it actually happened.
+
+
+<h3 id="testing">2.8 Test Before Commit</h3>
+
+One of the things that falls out of Git's default separation of commit
+from push is that there are several Git sub-commands that jump straight
+to the commit step before a change could possibly be tested. Fossil, by
+contrast, makes the equivalent change to the local working check-out
+only, requiring a separate check-in step to commit the change. This
+design difference falls naturally out of Fossil's default-enabled
+autosync feature and its philosophy of [#history | not offering history
+rewriting features].
+
+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
+since it lacks an autosync feature, 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 or rewrite history before pushing it if the rebase causes a
+problem. If you push your rebased local repo up to the parent without
+testing first, you cannot fix it without violating
+[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 commit their change to the local repository
+immediately without giving you
+an opportunity to test the change first unless you give the
+<tt>--no-commit</tt> option. Otherwise, you're back in the same boat:
+reset the local repository or rewrite history to fix things, then maybe
+retry.
+
+Fossil cannot sensibly work that way because of its default-enabled
+autosync feature and its purposeful paucity of commands for modifying
+commits, as discussed in [#history | the prior section].
+
+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!) Thus, Fossil doesn't need rebase, squashing,
+<tt>reset --hard</tt>, or other Git commit mutating mechanisms.
+
+Because Fossil requires an explicit commit for a merge, it has the nice
+side benefit that 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.
+
+We don't look at this difference as a workaround in Fossil for autosync,
+but instead as a test-first philosophical difference:
+<tt>fossil commit</tt> is a <i>commitment</i>. When every commit is
+pushed to the parent repo by default, it encourages a working style in
+which every commit is tested first. It encourages thinking before
+acting. We believe this is an inherently good thing.
+
+Incidentally, this is a good example of Git's messy command design.
+These three commands:
+
+<pre>
+$ git merge HASH
+$ git cherry-pick HASH
+$ git revert HASH
+</pre>
+
+...are all the same command in Fossil:
+
+<pre>
+$ fossil merge HASH
+$ fossil merge --cherrypick HASH
+$ fossil merge --backout HASH
+</pre>
+
+If you think about it, they're all the same function: apply work done on
+one branch to another. All that changes between these commands is how
+much work gets applied — just one check-in or a whole branch — and the
+merge direction. This is the sort of thing we mean when we point out
+that Fossil's command interface is simpler than Git's: there are fewer
+concepts to keep track of in your mental model of Fossil's internal
+operation.
+
+Fossil's implementation of the feature is also simpler to describe. The
+brief online help for <tt>[/help/merge | fossil merge]</tt> is
+currently 50 lines long, to which you want to add the ~800 lines of
+[./branching.wiki | the branching document]. The equivalent
+documentation in Git is the aggregation of the man pages for the above
+three commands, which is approaching 1400 lines as of this writing, much of it mutually redundant.
+(e.g. Git's <tt>--edit</tt> and <tt>--no-commit</tt> options get
+described three times, each time differently.) Fossil's
+documentation is not only more concise, it gives a nice split of brief
+online help and full online documentation.
+
+
+<h3 id="hash">2.9 Hash Algorithm: SHA-3 vs SHA-2 vs SHA-1</h3>
+
+Fossil started out using 160-bit SHA-1 hashes to identify check-ins,
+just as in Git. That changed in early 2017 when news of the
+[https://shattered.io/|SHAttered attack] broke, demonstrating that SHA-1
+collisions were now practical to create. Two weeks later, the creator of
+Fossil delivered a new release allowing a clean migration to
+[https://en.wikipedia.org/wiki/SHA-3|256-bit SHA-3] with
+[./hashpolicy.wiki|full backwards compatibility] to old SHA-1 based
+repositories.
+
+In October 2019, after the last of the major binary
+package repos offering Fossil upgraded to Fossil 2.<i>x</i>,
+we switched the default hash mode so that
+the conversion to SHA-3 is fully automatic.
+This not
+only solves the SHAttered problem, it should prevent a reoccurrence of
+similar problems for the foreseeable future.
+
+Meanwhile, the Git community took until August 2018 to publish
+[https://git-scm.com/docs/hash-function-transition/ | their plan] for
+solving the same problem by moving to SHA-256, a variant of the
+[https://en.wikipedia.org/wiki/SHA-2 | older SHA-2 algorithm]. That is
+now technically implemented in the sense that <tt>git init
+--object-format=sha256</tt> exists, but note well: this is not only an
+optional setting, Git forge support is mixed, most notably
+[https://github.com/GitoxideLabs/gitoxide/issues/281 | lacking in
+GitHub], plus also BitBucket and others. This is doubtless because of
+this warning in the latest ([https://git-scm.com/docs/git-init/2.54.0 |
+as of this writing]) <tt>git init</tt> docs:
+
+<blockquote>Note: At present, there is no interoperability between
+SHA-256 repositories and SHA-1 repositories.</blockquote>
+
+Although we are now in the <i>tenth year</i> of this situation, there
+remains hope that Git will manage to make the transition without taking
+the full decade: the
+[https://www.deployhq.com/blog/git-3-0-on-the-horizon-what-git-users-need-to-know-about-the-next-major-release
+| latest plan] is that Git 3.0 will finally <i>(finally!)</i> switch to
+SHA256 by default, forcing the issue. Given the track record, we are
+taking a "show me" stance on this claim.
+
+Always remember, attacks only get better, never worse.
+Almost three years after Fossil solved this problem, the
+[https://sha-mbles.github.io/ | SHAmbles attack] was published, further
+weakening the case for continuing to use SHA-1.
+
+The practical impact of attacks like SHAttered and SHAmbles on the
+Git and Fossil Merkle trees isn't clear, but you want to have your repositories
+moved over to a stronger hash algorithm <i>before</i> someone figures out how
+to make use of the weaknesses in the old one. Fossil's solution is long
+since [https://repology.org/project/fossil/versions | universally deployed].
+
+<hr/>
+
+<h3>Asides and Digressions</h3>
+
+<i><small><ol>
+ <li><p>[./mirrorlimitations.md|Many
+ things are lost] in making a Git mirror of a Fossil repo due to
+ limitations of Git relative to Fossil. GitHub adds some of these
+ missing features to stock
+ Git, but because they're not part of Git proper,
+ [./mirrortogithub.md|exporting a Fossil repository to GitHub] will
+ still not include them; Fossil tickets do not become GitHub issues,
+ for example.
+
+ <li><p>The <tt>fossil-scm.org</tt> web site is actually hosted in
+ several parts, so that it is not strictly true that "everything" on
+ it is in the self-hosting Fossil project repo. The web forum is
+ hosted as [https://fossil-scm.org/forum/|a separate Fossil repo]
+ from the [https://fossil-scm.org/home/|main Fossil self-hosting
+ repo] for administration reasons, and the Download page content
+ isn't normally synchronized with a "<tt>fossil clone</tt>" command unless
+ you add the "-u" option. (See "[./aboutdownload.wiki|How the
+ Download Page Works]" for details.)
+ Chat history is deliberately not synced as
+ chat messages are intended to be ephemeral.
+ There may also be some purely
+ static elements of the web site served via D. Richard Hipp's own
+ lightweight web server,
+ <tt>[https://sqlite.org/althttpd/|althttpd]</tt>,
+ which is configured as a front end to Fossil running in CGI mode on
+ these sites.
+
+ <li><p>This means you can give up waiting for Fossil to be ported to
+ the PDP-11, but we remain hopeful that someone may eventually port
+ it to [https://en.wikipedia.org/wiki/Z/OS|z/OS].
+
+ <li><p>"Why is there all this Tcl in and around Fossil?" you may
+ ask. It is because D. Richard Hipp is a long-time Tcl user and
+ contributor. SQLite started out as an embedded database for Tcl
+ specifically. ([https://sqlite.org/tclsqlite.html | [Reference]])
+ When he then created Fossil to manage the development of SQLite, it
+ was natural for him to use Tcl-based tools for its scripting, build
+ system, test system, etc. It came full circle in 2011 when
+ [https://www.reddit.com/r/programming/comments/fwrx5/tcl_and_tk_move_away_from_cvs_to_fossil/
+ | the Tcl and Tk projects moved from CVS to Fossil].
+
+ <li><p>A minority of the pieces of the Git core software suite are
+ written in other languages, primarily Perl, Python, and Tcl. (e.g.
+ <tt>git-send-mail</tt>, <tt>git-p4</tt>, and <tt>gitk</tt>,
+ respectively.) Although these interpreters are quite portable, they
+ aren't installed by default everywhere, and on some platforms you
+ can't count on them at all. (Not just Windows, but also the BSDs and
+ many other non-Linux platforms.) This expands the dependency
+ footprint of Git considerably. It is why the current Git for Windows
+ distribution is 44.7&nbsp;MiB but the current <tt>fossil.exe</tt>
+ zip file for Windows is 2.24&nbsp;MiB. Fossil is much smaller
+ despite using a roughly similar amount of high-level scripting code
+ because its interpreters are compact and built into Fossil itself.
+
+ <li><p>Both Fossil and Git support
+ [https://en.wikipedia.org/wiki/Patch_(Unix)|<tt>patch(1)</tt>
+ files] — unified diff formatted output — for accepting drive-by contributions, but it's a
+ lossy contribution path for both systems. Unlike Git PRs and Fossil
+ bundles, patch files collapse multiple checkins together, they don't
+ include check-in comments, and they cannot encode changes made above
+ the individual file content layer: you lose branching decisions,
+ tag changes, file renames, and more when using patch files. The
+ [./patchcmd.md | <tt>fossil patch</tt> command]
+ also solves these problems, but it is because it works like a Fossil
+ bundle, only for uncommitted changes; it doesn't use Larry Wall's
+ <tt>patch</tt> tool to apply unified diff output to the receiving
+ Fossil checkout.</p></li>
+</ol></i></small>