Fossil SCM

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

Keyboard Shortcuts

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