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

Keyboard Shortcuts

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