Fossil SCM

Merge trunk enhancements and fixes into the forum-editor-2026 branch.

drh 2026-06-10 09:46 UTC forum-editor-2026 merge
Commit 5e71becc09ec6504fa1e05727c24ff07ed93027fbb6351de6c7af7c134ddb423
+26 -14
--- src/delta.c
+++ src/delta.c
@@ -186,20 +186,29 @@
186186
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
187187
-1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
188188
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, 36,
189189
-1, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
190190
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, -1, -1, -1, 63, -1,
191
+
192
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
193
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
194
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
195
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
196
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
197
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
198
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
199
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
191200
};
192201
unsigned int v = 0;
193202
int c;
194203
unsigned char *z = (unsigned char*)*pz;
195
- unsigned char *zStart = z;
196
- while( (c = zValue[0x7f&*(z++)])>=0 ){
197
- v = (v<<6) + c;
204
+ unsigned char *zEnd = z + (*pLen);
205
+ while( z<zEnd && (c = zValue[*z])>=0 ){
206
+ v = (v<<6) + c;
207
+ z++;
198208
}
199
- z--;
200
- *pLen -= z - zStart;
209
+ *pLen -= (int)(z - (unsigned char*)*pz);
201210
*pz = (char*)z;
202211
return v;
203212
}
204213
205214
/*
@@ -537,11 +546,11 @@
537546
** needed.
538547
*/
539548
int delta_output_size(const char *zDelta, int lenDelta){
540549
int size;
541550
size = getInt(&zDelta, &lenDelta);
542
- if( *zDelta!='\n' ){
551
+ if( lenDelta<=0 || *zDelta!='\n' ){
543552
/* ERROR: size integer not terminated by "\n" */
544553
return -1;
545554
}
546555
return size;
547556
}
@@ -574,28 +583,30 @@
574583
int lenDelta, /* Length of the delta */
575584
char *zOut /* Write the output into this preallocated buffer */
576585
){
577586
sqlite3_uint64 limit;
578587
sqlite3_uint64 total = 0;
588
+
579589
#ifdef FOSSIL_ENABLE_DELTA_CKSUM_TEST
580590
char *zOrigOut = zOut;
581591
#endif
582592
583593
limit = getInt(&zDelta, &lenDelta);
584
- if( *zDelta!='\n' ){
594
+ if( lenDelta<=0 || *zDelta!='\n' ){
585595
/* ERROR: size integer not terminated by "\n" */
586596
return -1;
587597
}
588
- zDelta++; lenDelta--;
589
- while( *zDelta && lenDelta>0 ){
598
+ zDelta++; lenDelta--; /* Skip the \n */
599
+ while( lenDelta>0 && zDelta[0] ){
590600
unsigned int cnt, ofst;
591601
cnt = getInt(&zDelta, &lenDelta);
602
+ if( lenDelta<=0 ) return -1;
592603
switch( zDelta[0] ){
593604
case '@': {
594605
zDelta++; lenDelta--;
595606
ofst = getInt(&zDelta, &lenDelta);
596
- if( lenDelta>0 && zDelta[0]!=',' ){
607
+ if( lenDelta<=0 || zDelta[0]!=',' ){
597608
/* ERROR: copy command not terminated by ',' */
598609
return -1;
599610
}
600611
zDelta++; lenDelta--;
601612
DEBUG1( printf("COPY %d from %d\n", cnt, ofst); )
@@ -618,11 +629,11 @@
618629
if( total>limit ){
619630
/* ERROR: insert command gives an output larger than predicted */
620631
return -1;
621632
}
622633
DEBUG1( printf("INSERT %d\n", cnt); )
623
- if( (int)cnt>lenDelta ){
634
+ if( (i64)cnt>(i64)lenDelta ){
624635
/* ERROR: insert count exceeds size of delta */
625636
return -1;
626637
}
627638
memcpy(zOut, zDelta, cnt);
628639
zOut += cnt;
@@ -668,23 +679,24 @@
668679
){
669680
unsigned int nInsert = 0;
670681
unsigned int nCopy = 0;
671682
672683
(void)getInt(&zDelta, &lenDelta);
673
- if( *zDelta!='\n' ){
684
+ if( lenDelta<=0 || *zDelta!='\n' ){
674685
/* ERROR: size integer not terminated by "\n" */
675686
return -1;
676687
}
677688
zDelta++; lenDelta--;
678689
while( *zDelta && lenDelta>0 ){
679690
unsigned int cnt;
680691
cnt = getInt(&zDelta, &lenDelta);
692
+ if( lenDelta<=0 ) break;
681693
switch( zDelta[0] ){
682694
case '@': {
683695
zDelta++; lenDelta--;
684696
(void)getInt(&zDelta, &lenDelta);
685
- if( lenDelta>0 && zDelta[0]!=',' ){
697
+ if( lenDelta<=0 || zDelta[0]!=',' ){
686698
/* ERROR: copy command not terminated by ',' */
687699
return -1;
688700
}
689701
zDelta++; lenDelta--;
690702
nCopy += cnt;
@@ -691,11 +703,11 @@
691703
break;
692704
}
693705
case ':': {
694706
zDelta++; lenDelta--;
695707
nInsert += cnt;
696
- if( (int)cnt>lenDelta ){
708
+ if( (i64)cnt>(i64)lenDelta ){
697709
/* ERROR: insert count exceeds size of delta */
698710
return -1;
699711
}
700712
zDelta += cnt;
701713
lenDelta -= cnt;
702714
--- src/delta.c
+++ src/delta.c
@@ -186,20 +186,29 @@
186 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
187 -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
188 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, 36,
189 -1, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
190 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, -1, -1, -1, 63, -1,
 
 
 
 
 
 
 
 
 
191 };
192 unsigned int v = 0;
193 int c;
194 unsigned char *z = (unsigned char*)*pz;
195 unsigned char *zStart = z;
196 while( (c = zValue[0x7f&*(z++)])>=0 ){
197 v = (v<<6) + c;
 
198 }
199 z--;
200 *pLen -= z - zStart;
201 *pz = (char*)z;
202 return v;
203 }
204
205 /*
@@ -537,11 +546,11 @@
537 ** needed.
538 */
539 int delta_output_size(const char *zDelta, int lenDelta){
540 int size;
541 size = getInt(&zDelta, &lenDelta);
542 if( *zDelta!='\n' ){
543 /* ERROR: size integer not terminated by "\n" */
544 return -1;
545 }
546 return size;
547 }
@@ -574,28 +583,30 @@
574 int lenDelta, /* Length of the delta */
575 char *zOut /* Write the output into this preallocated buffer */
576 ){
577 sqlite3_uint64 limit;
578 sqlite3_uint64 total = 0;
 
579 #ifdef FOSSIL_ENABLE_DELTA_CKSUM_TEST
580 char *zOrigOut = zOut;
581 #endif
582
583 limit = getInt(&zDelta, &lenDelta);
584 if( *zDelta!='\n' ){
585 /* ERROR: size integer not terminated by "\n" */
586 return -1;
587 }
588 zDelta++; lenDelta--;
589 while( *zDelta && lenDelta>0 ){
590 unsigned int cnt, ofst;
591 cnt = getInt(&zDelta, &lenDelta);
 
592 switch( zDelta[0] ){
593 case '@': {
594 zDelta++; lenDelta--;
595 ofst = getInt(&zDelta, &lenDelta);
596 if( lenDelta>0 && zDelta[0]!=',' ){
597 /* ERROR: copy command not terminated by ',' */
598 return -1;
599 }
600 zDelta++; lenDelta--;
601 DEBUG1( printf("COPY %d from %d\n", cnt, ofst); )
@@ -618,11 +629,11 @@
618 if( total>limit ){
619 /* ERROR: insert command gives an output larger than predicted */
620 return -1;
621 }
622 DEBUG1( printf("INSERT %d\n", cnt); )
623 if( (int)cnt>lenDelta ){
624 /* ERROR: insert count exceeds size of delta */
625 return -1;
626 }
627 memcpy(zOut, zDelta, cnt);
628 zOut += cnt;
@@ -668,23 +679,24 @@
668 ){
669 unsigned int nInsert = 0;
670 unsigned int nCopy = 0;
671
672 (void)getInt(&zDelta, &lenDelta);
673 if( *zDelta!='\n' ){
674 /* ERROR: size integer not terminated by "\n" */
675 return -1;
676 }
677 zDelta++; lenDelta--;
678 while( *zDelta && lenDelta>0 ){
679 unsigned int cnt;
680 cnt = getInt(&zDelta, &lenDelta);
 
681 switch( zDelta[0] ){
682 case '@': {
683 zDelta++; lenDelta--;
684 (void)getInt(&zDelta, &lenDelta);
685 if( lenDelta>0 && zDelta[0]!=',' ){
686 /* ERROR: copy command not terminated by ',' */
687 return -1;
688 }
689 zDelta++; lenDelta--;
690 nCopy += cnt;
@@ -691,11 +703,11 @@
691 break;
692 }
693 case ':': {
694 zDelta++; lenDelta--;
695 nInsert += cnt;
696 if( (int)cnt>lenDelta ){
697 /* ERROR: insert count exceeds size of delta */
698 return -1;
699 }
700 zDelta += cnt;
701 lenDelta -= cnt;
702
--- src/delta.c
+++ src/delta.c
@@ -186,20 +186,29 @@
186 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
187 -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
188 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, 36,
189 -1, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
190 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, -1, -1, -1, 63, -1,
191
192 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
193 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
194 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
195 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
196 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
197 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
198 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
199 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
200 };
201 unsigned int v = 0;
202 int c;
203 unsigned char *z = (unsigned char*)*pz;
204 unsigned char *zEnd = z + (*pLen);
205 while( z<zEnd && (c = zValue[*z])>=0 ){
206 v = (v<<6) + c;
207 z++;
208 }
209 *pLen -= (int)(z - (unsigned char*)*pz);
 
210 *pz = (char*)z;
211 return v;
212 }
213
214 /*
@@ -537,11 +546,11 @@
546 ** needed.
547 */
548 int delta_output_size(const char *zDelta, int lenDelta){
549 int size;
550 size = getInt(&zDelta, &lenDelta);
551 if( lenDelta<=0 || *zDelta!='\n' ){
552 /* ERROR: size integer not terminated by "\n" */
553 return -1;
554 }
555 return size;
556 }
@@ -574,28 +583,30 @@
583 int lenDelta, /* Length of the delta */
584 char *zOut /* Write the output into this preallocated buffer */
585 ){
586 sqlite3_uint64 limit;
587 sqlite3_uint64 total = 0;
588
589 #ifdef FOSSIL_ENABLE_DELTA_CKSUM_TEST
590 char *zOrigOut = zOut;
591 #endif
592
593 limit = getInt(&zDelta, &lenDelta);
594 if( lenDelta<=0 || *zDelta!='\n' ){
595 /* ERROR: size integer not terminated by "\n" */
596 return -1;
597 }
598 zDelta++; lenDelta--; /* Skip the \n */
599 while( lenDelta>0 && zDelta[0] ){
600 unsigned int cnt, ofst;
601 cnt = getInt(&zDelta, &lenDelta);
602 if( lenDelta<=0 ) return -1;
603 switch( zDelta[0] ){
604 case '@': {
605 zDelta++; lenDelta--;
606 ofst = getInt(&zDelta, &lenDelta);
607 if( lenDelta<=0 || zDelta[0]!=',' ){
608 /* ERROR: copy command not terminated by ',' */
609 return -1;
610 }
611 zDelta++; lenDelta--;
612 DEBUG1( printf("COPY %d from %d\n", cnt, ofst); )
@@ -618,11 +629,11 @@
629 if( total>limit ){
630 /* ERROR: insert command gives an output larger than predicted */
631 return -1;
632 }
633 DEBUG1( printf("INSERT %d\n", cnt); )
634 if( (i64)cnt>(i64)lenDelta ){
635 /* ERROR: insert count exceeds size of delta */
636 return -1;
637 }
638 memcpy(zOut, zDelta, cnt);
639 zOut += cnt;
@@ -668,23 +679,24 @@
679 ){
680 unsigned int nInsert = 0;
681 unsigned int nCopy = 0;
682
683 (void)getInt(&zDelta, &lenDelta);
684 if( lenDelta<=0 || *zDelta!='\n' ){
685 /* ERROR: size integer not terminated by "\n" */
686 return -1;
687 }
688 zDelta++; lenDelta--;
689 while( *zDelta && lenDelta>0 ){
690 unsigned int cnt;
691 cnt = getInt(&zDelta, &lenDelta);
692 if( lenDelta<=0 ) break;
693 switch( zDelta[0] ){
694 case '@': {
695 zDelta++; lenDelta--;
696 (void)getInt(&zDelta, &lenDelta);
697 if( lenDelta<=0 || zDelta[0]!=',' ){
698 /* ERROR: copy command not terminated by ',' */
699 return -1;
700 }
701 zDelta++; lenDelta--;
702 nCopy += cnt;
@@ -691,11 +703,11 @@
703 break;
704 }
705 case ':': {
706 zDelta++; lenDelta--;
707 nInsert += cnt;
708 if( (i64)cnt>(i64)lenDelta ){
709 /* ERROR: insert count exceeds size of delta */
710 return -1;
711 }
712 zDelta += cnt;
713 lenDelta -= cnt;
714
+142 -119
--- www/fossil-v-git.wiki
+++ www/fossil-v-git.wiki
@@ -20,12 +20,12 @@
2020
In this document, we set all of that similarity and interoperability
2121
aside and focus on the important differences between the two, especially
2222
those that impact the user experience.
2323
2424
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
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
2727
time using Fossil, not Git. Ask around for second opinions from
2828
people who have used <em>both</em> Fossil and Git.
2929
3030
If you want a more practical, less philosophical guide to moving from
3131
Git to Fossil, see our [./gitusers.md | Git to Fossil Translation Guide].
@@ -178,36 +178,40 @@
178178
This policy is particularly useful when running Fossil inside a
179179
restrictive container, anything from [./chroot.md | classic chroot
180180
jails] to modern [https://en.wikipedia.org/wiki/OS-level_virtualization
181181
| OS-level virtualization mechanisms] such as
182182
[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
183
+Our [./containers.md | stock container image] is under 11&nbsp;MB when
184
+uncompressed and running because it contains nothing but a single
185185
statically-linked binary.
186186
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
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
189190
platform libraries with stable ABIs such as glibc, zlib, and openssl.
190191
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.
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>.
195197
196198
Fossil is easy to build from sources. Just run
197199
"<tt>./configure && make</tt>" on POSIX systems and
198200
"<tt>nmake /f Makefile.msc</tt>" on Windows.
199201
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...
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.
209213
210214
Some say that Git more closely adheres to the Unix philosophy,
211215
summarized as "many small tools, loosely joined," but we have many
212216
examples of other successful Unix software that violates that principle
213217
to good effect, from Apache to Python to ZFS. We can infer from that
@@ -216,26 +220,47 @@
216220
matters is effectiveness and efficiency. We believe Fossil achieves
217221
this.
218222
219223
The above size comparisons aren't apples-to-apples anyway. We've
220224
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.
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.
237262
238263
The Fossil project itself is [./selfhost.wiki|hosted on a small and
239264
inexpensive VPS]. A bare-bones $5/month VPS or a
240265
spare Raspberry Pi is sufficient to run a full-up project
241266
site, complete with tickets, wiki, chat, and forum, in addition to
@@ -255,33 +280,34 @@
255280
<tt>.git</tt> folder or compressed into bespoke key/value
256281
[https://git-scm.com/book/en/v2/Git-Internals-Packfiles|pack-files],
257282
whereas Fossil stores its objects in a [https://www.sqlite.org/|SQLite]
258283
database file which provides ACID transactions and a high-level query
259284
language.
260
-This difference is more than an implementation detail. It has important
285
+
286
+This difference is more than an implementation detail; it has important
261287
practical consequences.
262288
263
-One notable consequence is that it is difficult to find the descendants
289
+One notable example is that it is difficult to find the descendants
264290
of check-ins in Git.
265291
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".
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."
276302
277303
Leaf check-ins in Git that lack a "ref" become "detached," making them
278304
difficult to locate and subject to garbage collection. This
279305
[https://stackoverflow.com/q/3965676 | detached head
280306
state] problem has caused grief for
281
-[https://www.google.com/search?q=git+detached+head+state | many
282
-Git users]. With
307
+[https://www.google.com/search?q=git+detached+head+state |
308
+untold millions of Git users]. With
283309
Fossil, detached heads are simply impossible because we can always find
284310
our way back into the Merkle tree using one or more of the relations
285311
in the SQL database.
286312
287313
The SQL query capabilities of Fossil make it easier to track the
@@ -288,34 +314,27 @@
288314
changes for one particular file within a project. For example,
289315
you can easily find
290316
[/finfo/www/fossil-v-git.wiki|the complete edit history of this one document],
291317
or even
292318
[/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
319
+Both come down to simple SQL queries in Fossil, with procedural code
294320
only being used to format the result for display.
295321
The same result could be obtained from Git, but because the data is
296322
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.
323
+walk the data and compute the result.
299324
300325
The ease of querying Fossil data using SQL means that status or
301326
history information about the project under management is easier
302
-to obtain. Being easier means that it is more likely to happen.
327
+to obtain, hence more likely to happen, giving its developers better
328
+situational awareness.
303329
Fossil reports tend to be more detailed and useful.
304330
Compare [/timeline?c=6df7a853ec16865b|this Fossil timeline]
305331
to
306332
[https://github.com/drhsqlite/fossil-mirror/commits/master?after=f720c106d297ca1f61bccb30c5c191b88a626d01+34 |
307
-its closest equivalent in GitHub]. Judge for yourself: which of those
333
+its closest equivalent in the GitHub mirror]. Judge for yourself: which of those
308334
reports is more useful to a developer trying to understand what happened?
309335
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
-
317336
<h3 id="portable">2.4 Portable</h3>
318337
319338
Fossil is largely written in ISO C, almost purely conforming to the
320339
original 1989 standard. We make very little use of
321340
[https://en.wikipedia.org/wiki/C99|C99], and we do not knowingly make
@@ -326,11 +345,11 @@
326345
facilities Fossil needs to do its thing. (Network sockets, file locking,
327346
etc.) There are certainly well-known platforms Fossil hasn't been ported
328347
to yet, but that's most likely due to lack of interest rather than
329348
inherent difficulties in doing the port. We believe the most stringent
330349
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
350
+several megs of flat-addressed memory.³ Fossil isn't quite as
332351
[https://www.sqlite.org/custombuild.html|portable as SQLite], but it's
333352
close.
334353
335354
Over half of the C code in Fossil is actually an embedded copy of the
336355
current version of SQLite. Much of what is Fossil-specific after you set
@@ -344,20 +363,20 @@
344363
necessary]. The server-side
345364
UI scripting uses a custom minimal
346365
[https://en.wikipedia.org/wiki/Tcl|Tcl] dialect called
347366
[./th1.md|TH1], which is
348367
embedded into Fossil itself. Fossil's build system and test suite are
349
-largely based on Tcl.⁵ All of this is quite portable.
368
+largely based on Tcl.⁴ All of this is quite portable.
350369
351370
About half of Git's code is POSIX C, and about a third is POSIX shell
352371
code. This is largely why the so-called "Git for Windows" distributions
353372
(both [https://git-scm.com/download/win|first-party] and
354373
[https://gitforwindows.org/|third-party]) are actually an
355374
[https://www.msys2.org/wiki/Home/|MSYS POSIX portability environment] bundled
356375
with all of the Git stuff, because it would be too painful to port Git
357376
natively to Windows. Git is a foreign citizen on Windows, speaking to it
358
-only through a translator.⁶
377
+only through a translator.⁵
359378
360379
While Fossil does lean toward POSIX norms when given a choice — LF-only
361380
line endings are treated as first-class citizens over CR+LF, for example
362381
— the Windows build of Fossil is truly native.
363382
@@ -444,11 +463,11 @@
444463
[https://www.git-scm.com/docs/git-request-pull|pull requests] offer
445464
a low-friction path to accepting
446465
[https://www.jonobacon.com/2012/07/25/building-strong-community-structural-integrity/|drive-by
447466
contributions]. Fossil's closest equivalents are its unique
448467
[/help/bundle|bundle] and [/help/patch|patch] features, which require higher engagement
449
- than firing off a PR.⁷ This difference comes directly from the
468
+ than firing off a PR.⁶ This difference comes directly from the
450469
initial designed purpose for each tool: the SQLite project doesn't
451470
accept outside contributions from previously-unknown developers, but
452471
the Linux kernel does.
453472
454473
* <b>No rebasing:</b> When your local repo clone syncs changes
@@ -500,16 +519,16 @@
500519
that everyone — especially the project leader — can maintain a better
501520
mental picture of what is happening, leading to better situational
502521
awareness.
503522
504523
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
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
507526
software projects], most of which were created by forking a
508527
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
528
+[https://www.griddynamics.com/blog/number-software-developers-world |
529
+~11× the number of developers in the world], it beggars belief that
511530
most of these forks are still under active development. The vast bulk
512531
of these must be abandoned one-off efforts. This is part of the nature
513532
of bazaar style development.
514533
515534
You can think about this difference in terms of
@@ -533,18 +552,18 @@
533552
<h4 id="scale">2.5.2 Scale</h4>
534553
535554
The Linux kernel has a far bigger developer community than that of
536555
SQLite: there are thousands and thousands of contributors to Linux, most
537556
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
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
541560
kernel and its development process were already uncommonly large back in
542561
2005 when Git was designed, specifically to support the consequences of
543562
having such a large set of developers working on such a large code base.
544563
545
-95% of the code in SQLite comes from just four programmers, and 64% of
564
+95% of the code in SQLite comes from just six programmers, and 62% of
546565
it is from the lead developer alone. The SQLite developers know each
547566
other well and interact daily. Fossil was designed for this development
548567
model.
549568
550569
When choosing your DVCS, we think you should ask yourself whether the
@@ -564,35 +583,33 @@
564583
565584
Both Fossil and Git store history as a directed acyclic graph (DAG)
566585
of changes, but Git tends to focus more on individual branches of
567586
the DAG, whereas Fossil puts more emphasis on the entire DAG.
568587
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,
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,
572592
GitHub, and GitLab tend to show only a single branch at
573593
a time, whereas Fossil usually shows all parallel branches at
574594
once. Git has commands like "rebase" that help keep all relevant
575595
changes on a single branch, whereas Fossil encourages a style of
576596
many concurrent branches constantly springing into existence,
577597
undergoing active development in parallel for a few days or weeks, then
578598
merging back into the main line and disappearing.
579599
580600
This difference in emphasis arises from the different purposes of
581
-the two systems. Git focuses on individual branches, because that
601
+the two systems. Git's focus on individual branches
582602
is exactly what you want for a highly-distributed bazaar-style project
583603
such as Linux. Linus Torvalds does not want to see every check-in
584604
by every contributor to Linux: such extreme visibility does not scale
585605
well. Contrast Fossil, which was written for the cathedral-style SQLite project
586606
and its handful of active committers. Seeing all
587607
changes on all branches all at once helps keep the whole team
588608
up-to-date with what everybody else is doing, resulting in a more
589609
tightly focused and cohesive implementation.
590610
591
-Parts of this section are [https://fossil-scm.org/forum/forumpost/5961e969fa|disputed]
592
-by [https://github.com/olorin37|Jakub A. G.].
593
-
594611
595612
<h3 id="checkouts">2.6 One vs. Many Check-outs per Repository</h3>
596613
597614
Because Git commingles the repository data with the initial checkout of
598615
that repository, the default mode of operation in Git is to stick to that
@@ -612,20 +629,28 @@
612629
standard advice is to use a switch-in-place workflow in Fossil when
613630
the disturbance from switching branches is small, and to use multiple
614631
checkouts when you have long-lived working branches that are different
615632
enough that switching in place is disruptive.
616633
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
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
623648
[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.
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.
627652
628653
This distinction matters because switching branches inside a single working directory loses local context
629654
on each switch.
630655
631656
For instance, in any software project where the runnable program must be
@@ -658,13 +683,10 @@
658683
659684
Plus,
660685
<tt>cd</tt> is faster to type than <tt>git checkout</tt> or <tt>fossil
661686
update</tt>.
662687
663
-Parts of this section are [https://fossil-scm.org/forum/forumpost/5961e969fa|disputed]
664
-by [https://github.com/olorin37|Jakub A. G.].
665
-
666688
<h3 id="history">2.7 What you should have done vs. What you actually did</h3>
667689
668690
Git puts a lot of emphasis on maintaining
669691
a "clean" check-in history. Extraneous and experimental branches by
670692
individual developers often never make it into the main repository.
@@ -822,14 +844,14 @@
822844
concepts to keep track of in your mental model of Fossil's internal
823845
operation.
824846
825847
Fossil's implementation of the feature is also simpler to describe. The
826848
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
849
+currently 50 lines long, to which you want to add the ~800 lines of
828850
[./branching.wiki | the branching document]. The equivalent
829851
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.
852
+three commands, which is approaching 1400 lines as of this writing, much of it mutually redundant.
831853
(e.g. Git's <tt>--edit</tt> and <tt>--no-commit</tt> options get
832854
described three times, each time differently.) Fossil's
833855
documentation is not only more concise, it gives a nice split of brief
834856
online help and full online documentation.
835857
@@ -852,35 +874,42 @@
852874
This not
853875
only solves the SHAttered problem, it should prevent a reoccurrence of
854876
similar problems for the foreseeable future.
855877
856878
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
-
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.
873902
Almost three years after Fossil solved this problem, the
874903
[https://sha-mbles.github.io/ | SHAmbles attack] was published, further
875904
weakening the case for continuing to use SHA-1.
876905
877906
The practical impact of attacks like SHAttered and SHAmbles on the
878907
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.
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].
882911
883912
<hr/>
884913
885914
<h3>Asides and Digressions</h3>
886915
@@ -910,16 +939,10 @@
910939
lightweight web server,
911940
<tt>[https://sqlite.org/althttpd/|althttpd]</tt>,
912941
which is configured as a front end to Fossil running in CGI mode on
913942
these sites.
914943
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
-
921944
<li><p>This means you can give up waiting for Fossil to be ported to
922945
the PDP-11, but we remain hopeful that someone may eventually port
923946
it to [https://en.wikipedia.org/wiki/Z/OS|z/OS].
924947
925948
<li><p>"Why is there all this Tcl in and around Fossil?" you may
926949
--- www/fossil-v-git.wiki
+++ www/fossil-v-git.wiki
@@ -20,12 +20,12 @@
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].
@@ -178,36 +178,40 @@
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
@@ -216,26 +220,47 @@
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
@@ -255,33 +280,34 @@
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,34 +314,27 @@
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
@@ -326,11 +345,11 @@
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
@@ -344,20 +363,20 @@
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
@@ -444,11 +463,11 @@
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
@@ -500,16 +519,16 @@
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
@@ -533,18 +552,18 @@
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
@@ -564,35 +583,33 @@
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
@@ -612,20 +629,28 @@
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
@@ -658,13 +683,10 @@
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.
@@ -822,14 +844,14 @@
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
@@ -852,35 +874,42 @@
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
@@ -910,16 +939,10 @@
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
--- www/fossil-v-git.wiki
+++ www/fossil-v-git.wiki
@@ -20,12 +20,12 @@
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].
@@ -178,36 +178,40 @@
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
@@ -216,26 +220,47 @@
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
@@ -255,33 +280,34 @@
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
@@ -288,34 +314,27 @@
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
@@ -326,11 +345,11 @@
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
@@ -344,20 +363,20 @@
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
@@ -444,11 +463,11 @@
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
@@ -500,16 +519,16 @@
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
@@ -533,18 +552,18 @@
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
@@ -564,35 +583,33 @@
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
@@ -612,20 +629,28 @@
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
@@ -658,13 +683,10 @@
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.
@@ -822,14 +844,14 @@
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
@@ -852,35 +874,42 @@
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
@@ -910,16 +939,10 @@
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
--- www/javascript.md
+++ www/javascript.md
@@ -66,11 +66,11 @@
6666
Most JavaScript-based Fossil pages use less code than that.
6767
6868
Atop that, Fossil sends HTTP headers to the browser that allow it
6969
to perform aggressive caching so that typical page loads will skip
7070
re-loading this content on subsequent loads. These features are
71
- currently optional: you must either set the new
71
+ currently optional: you must either set the
7272
[`fossil server --jsmode bundle` option][fsrv] or the corresponding
7373
`jsmode` control line
7474
in your [`fossil cgi`][fcgi] script when setting up your
7575
[Fossil server][fshome]. That done, Fossil’s JavaScript files will
7676
load almost instantly from the browser’s cache after the initial
@@ -100,11 +100,11 @@
100100
Ajax partial page updates are faster than
101101
the no-JS alternative, a full HTTP POST round-trip to submit new
102102
data to the remote server, retrieve an entire new HTML document,
103103
and re-render the whole thing client-side.
104104
105
-3. <a id="3pjs"></a>“**Third-party JavaScript cannot be trusted.**”
105
+3. “<a id="3pjs"></a>**Third-party JavaScript cannot be trusted.**”
106106
107107
Fossil does not use any third-party JavaScript libraries, not even
108108
very common ones like jQuery. Every bit of JavaScript served by the
109109
stock version of Fossil was written specifically for the Fossil
110110
project and is stored [in its code repository][fsrc].
@@ -113,11 +113,11 @@
113113
Fossil and mechanisms like [skin editing][cskin] don’t suffice for your
114114
purposes, you can hack on the JavaScript in your local instance
115115
directly, just as you can hack on its C, SQL, and Tcl code. Fossil
116116
is free and open source software, under [a single license][2cbsd].
117117
118
-4. <a id="snoop"></a>“**JavaScript and cookies are used to snoop on web users.**”
118
+4. “<a id="snoop"></a>**JavaScript and cookies are used to snoop on web users.**”
119119
120120
There is no tracking or other snooping technology in Fossil other than
121121
that necessary for basic security, such as IP address logging on
122122
check-ins. (This is in part why we have no [comprehensive user
123123
statistics](#stats)!)
@@ -184,11 +184,11 @@
184184
The no-JS case is a [minority position](#stats), so those that want
185185
Fossil to have no-JS alternatives and graceful fallbacks will need
186186
to get involved with the development if they want this state of
187187
affairs to continue.
188188
189
-8. <a id="stats"></a>“**A large number of users run without JavaScript enabled.**”
189
+8. “<a id="stats"></a>**A large number of users run without JavaScript enabled.**”
190190
191191
That’s not what web audience measurements say:
192192
193193
* [What percentage of browsers with javascript disabled?][s1]
194194
* [How many people are missing out on JavaScript enhancement?][s2]
@@ -207,11 +207,11 @@
207207
run [powerful conditional blocking plugins](#block) in their
208208
browsers, rather than block JavaScript entirely. We suspect that
209209
between these two forces, the number of no-JS purists among Fossil’s
210210
user base is still a tiny minority.
211211
212
-9. <a id="block"></a>“**I block JavaScript entirely in my browser. That breaks Fossil.**”
212
+9. “<a id="block"></a>**I block JavaScript entirely in my browser. That breaks Fossil.**”
213213
214214
First, see our philosophy statements above. Briefly, we intend that
215215
there always be some other way to get any given result without using
216216
JavaScript, developer interest willing.
217217
@@ -237,11 +237,11 @@
237237
a few of these part-timers are responsible for the bulk of the code
238238
in Fossil. If you want Fossil to support such niche use cases, then
239239
you will have to [get involved with its development][cg]: it’s
240240
*your* uncommon itch.
241241
242
-11. <a id="compat"></a>“**Fossil’s JavaScript code isn’t compatible with my browser.**”
242
+11. “<a id="compat"></a>**Fossil’s JavaScript code isn’t compatible with my browser.**”
243243
244244
The Fossil project’s developers aim to remain compatible with
245245
the largest portions of the client-side browser base. We use only
246246
standards-defined JavaScript features which are known to work in the
247247
overwhelmingly vast majority of browsers going back approximately 5
248248
--- www/javascript.md
+++ www/javascript.md
@@ -66,11 +66,11 @@
66 Most JavaScript-based Fossil pages use less code than that.
67
68 Atop that, Fossil sends HTTP headers to the browser that allow it
69 to perform aggressive caching so that typical page loads will skip
70 re-loading this content on subsequent loads. These features are
71 currently optional: you must either set the new
72 [`fossil server --jsmode bundle` option][fsrv] or the corresponding
73 `jsmode` control line
74 in your [`fossil cgi`][fcgi] script when setting up your
75 [Fossil server][fshome]. That done, Fossil’s JavaScript files will
76 load almost instantly from the browser’s cache after the initial
@@ -100,11 +100,11 @@
100 Ajax partial page updates are faster than
101 the no-JS alternative, a full HTTP POST round-trip to submit new
102 data to the remote server, retrieve an entire new HTML document,
103 and re-render the whole thing client-side.
104
105 3. <a id="3pjs"></a>“**Third-party JavaScript cannot be trusted.**”
106
107 Fossil does not use any third-party JavaScript libraries, not even
108 very common ones like jQuery. Every bit of JavaScript served by the
109 stock version of Fossil was written specifically for the Fossil
110 project and is stored [in its code repository][fsrc].
@@ -113,11 +113,11 @@
113 Fossil and mechanisms like [skin editing][cskin] don’t suffice for your
114 purposes, you can hack on the JavaScript in your local instance
115 directly, just as you can hack on its C, SQL, and Tcl code. Fossil
116 is free and open source software, under [a single license][2cbsd].
117
118 4. <a id="snoop"></a>“**JavaScript and cookies are used to snoop on web users.**”
119
120 There is no tracking or other snooping technology in Fossil other than
121 that necessary for basic security, such as IP address logging on
122 check-ins. (This is in part why we have no [comprehensive user
123 statistics](#stats)!)
@@ -184,11 +184,11 @@
184 The no-JS case is a [minority position](#stats), so those that want
185 Fossil to have no-JS alternatives and graceful fallbacks will need
186 to get involved with the development if they want this state of
187 affairs to continue.
188
189 8. <a id="stats"></a>“**A large number of users run without JavaScript enabled.**”
190
191 That’s not what web audience measurements say:
192
193 * [What percentage of browsers with javascript disabled?][s1]
194 * [How many people are missing out on JavaScript enhancement?][s2]
@@ -207,11 +207,11 @@
207 run [powerful conditional blocking plugins](#block) in their
208 browsers, rather than block JavaScript entirely. We suspect that
209 between these two forces, the number of no-JS purists among Fossil’s
210 user base is still a tiny minority.
211
212 9. <a id="block"></a>“**I block JavaScript entirely in my browser. That breaks Fossil.**”
213
214 First, see our philosophy statements above. Briefly, we intend that
215 there always be some other way to get any given result without using
216 JavaScript, developer interest willing.
217
@@ -237,11 +237,11 @@
237 a few of these part-timers are responsible for the bulk of the code
238 in Fossil. If you want Fossil to support such niche use cases, then
239 you will have to [get involved with its development][cg]: it’s
240 *your* uncommon itch.
241
242 11. <a id="compat"></a>“**Fossil’s JavaScript code isn’t compatible with my browser.**”
243
244 The Fossil project’s developers aim to remain compatible with
245 the largest portions of the client-side browser base. We use only
246 standards-defined JavaScript features which are known to work in the
247 overwhelmingly vast majority of browsers going back approximately 5
248
--- www/javascript.md
+++ www/javascript.md
@@ -66,11 +66,11 @@
66 Most JavaScript-based Fossil pages use less code than that.
67
68 Atop that, Fossil sends HTTP headers to the browser that allow it
69 to perform aggressive caching so that typical page loads will skip
70 re-loading this content on subsequent loads. These features are
71 currently optional: you must either set the
72 [`fossil server --jsmode bundle` option][fsrv] or the corresponding
73 `jsmode` control line
74 in your [`fossil cgi`][fcgi] script when setting up your
75 [Fossil server][fshome]. That done, Fossil’s JavaScript files will
76 load almost instantly from the browser’s cache after the initial
@@ -100,11 +100,11 @@
100 Ajax partial page updates are faster than
101 the no-JS alternative, a full HTTP POST round-trip to submit new
102 data to the remote server, retrieve an entire new HTML document,
103 and re-render the whole thing client-side.
104
105 3. “<a id="3pjs"></a>**Third-party JavaScript cannot be trusted.**”
106
107 Fossil does not use any third-party JavaScript libraries, not even
108 very common ones like jQuery. Every bit of JavaScript served by the
109 stock version of Fossil was written specifically for the Fossil
110 project and is stored [in its code repository][fsrc].
@@ -113,11 +113,11 @@
113 Fossil and mechanisms like [skin editing][cskin] don’t suffice for your
114 purposes, you can hack on the JavaScript in your local instance
115 directly, just as you can hack on its C, SQL, and Tcl code. Fossil
116 is free and open source software, under [a single license][2cbsd].
117
118 4. “<a id="snoop"></a>**JavaScript and cookies are used to snoop on web users.**”
119
120 There is no tracking or other snooping technology in Fossil other than
121 that necessary for basic security, such as IP address logging on
122 check-ins. (This is in part why we have no [comprehensive user
123 statistics](#stats)!)
@@ -184,11 +184,11 @@
184 The no-JS case is a [minority position](#stats), so those that want
185 Fossil to have no-JS alternatives and graceful fallbacks will need
186 to get involved with the development if they want this state of
187 affairs to continue.
188
189 8. “<a id="stats"></a>**A large number of users run without JavaScript enabled.**”
190
191 That’s not what web audience measurements say:
192
193 * [What percentage of browsers with javascript disabled?][s1]
194 * [How many people are missing out on JavaScript enhancement?][s2]
@@ -207,11 +207,11 @@
207 run [powerful conditional blocking plugins](#block) in their
208 browsers, rather than block JavaScript entirely. We suspect that
209 between these two forces, the number of no-JS purists among Fossil’s
210 user base is still a tiny minority.
211
212 9. “<a id="block"></a>**I block JavaScript entirely in my browser. That breaks Fossil.**”
213
214 First, see our philosophy statements above. Briefly, we intend that
215 there always be some other way to get any given result without using
216 JavaScript, developer interest willing.
217
@@ -237,11 +237,11 @@
237 a few of these part-timers are responsible for the bulk of the code
238 in Fossil. If you want Fossil to support such niche use cases, then
239 you will have to [get involved with its development][cg]: it’s
240 *your* uncommon itch.
241
242 11. “<a id="compat"></a>**Fossil’s JavaScript code isn’t compatible with my browser.**”
243
244 The Fossil project’s developers aim to remain compatible with
245 the largest portions of the client-side browser base. We use only
246 standards-defined JavaScript features which are known to work in the
247 overwhelmingly vast majority of browsers going back approximately 5
248

Keyboard Shortcuts

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