|
4f5533b…
|
drh
|
1 |
# 101 Reasons Why Fossil Is Better Than Git |
|
4f5533b…
|
drh
|
2 |
|
|
4f5533b…
|
drh
|
3 |
1. **Fossil comes as a single self-contained executable file**.<p> |
|
c629e71…
|
brickviking
|
4 |
Install Fossil by copying "fossil" (or "fossil.exe") to some place |
|
4f5533b…
|
drh
|
5 |
on your $PATH (or %PATH%). Upgrade (or downgrade) by overwriting |
|
4f5533b…
|
drh
|
6 |
that one file. Uninstall by deleting that one file.<p> |
|
d494477…
|
danield
|
7 |
A Git installation requires hundreds of files. You want to use a |
|
4f5533b…
|
drh
|
8 |
package manager to install, upgrade, or uninstall Git. If you |
|
4f5533b…
|
drh
|
9 |
tinker with individual files of a Git installation, you run a high |
|
4f5533b…
|
drh
|
10 |
risk of messing things up. |
|
4f5533b…
|
drh
|
11 |
|
|
4f5533b…
|
drh
|
12 |
1. **Fossil comes with a built-in full-featured web interface**.<p> |
|
4f5533b…
|
drh
|
13 |
The Fossil web interface meets or exceeds the capabilities |
|
4f5533b…
|
drh
|
14 |
of GitHub, GitLab, Gitea, Forgejo, and similar. |
|
4f5533b…
|
drh
|
15 |
Some people think of Fossil as "GitHub-in-a-box". |
|
4f5533b…
|
drh
|
16 |
Git has "gitweb", but that CGI program |
|
4f5533b…
|
drh
|
17 |
is so limited and difficult to set up and use that few people |
|
4f5533b…
|
drh
|
18 |
even know it exists, so I do not count it |
|
4f5533b…
|
drh
|
19 |
for the purposes of this point. |
|
4f5533b…
|
drh
|
20 |
|
|
4f5533b…
|
drh
|
21 |
1. **You can run the Fossil web interface locally |
|
4f5533b…
|
drh
|
22 |
using the "fossil ui" command.**<p> |
|
4f5533b…
|
drh
|
23 |
Just type the command "fossil ui" from any Fossil checkout, |
|
4f5533b…
|
drh
|
24 |
or add an argument that is the name of a Fossil repository file |
|
4f5533b…
|
drh
|
25 |
or a directory that is the root of an open checkout |
|
4f5533b…
|
drh
|
26 |
and Fossil automatically brings up a new window with the |
|
4f5533b…
|
drh
|
27 |
Fossil web interface in your preferred web browser. |
|
4f5533b…
|
drh
|
28 |
This works seamlessly on all platforms. There is nothing |
|
4f5533b…
|
drh
|
29 |
extra to install. There is no configuration or setup. |
|
4f5533b…
|
drh
|
30 |
It just works. |
|
4f5533b…
|
drh
|
31 |
|
|
4f5533b…
|
drh
|
32 |
1. **The Fossil web interface shows a graphical timeline of changes.**<p> |
|
4f5533b…
|
drh
|
33 |
See, for example <https://sqlite.org/src/timeline> or |
|
4f5533b…
|
drh
|
34 |
<https://fossil-scm.org/home/timeline>. Similar timeline features |
|
4f5533b…
|
drh
|
35 |
for Git are available from the command-line for a local clone |
|
4f5533b…
|
drh
|
36 |
(for example using "gitk" or other third-party programs), but |
|
4f5533b…
|
drh
|
37 |
nothing with anything close to the capabilities of the Fossil |
|
4f5533b…
|
drh
|
38 |
timeline is available via a web interface, as far as I know.<p> |
|
4f5533b…
|
drh
|
39 |
Using the web interface, one can easily check on the status |
|
4f5533b…
|
drh
|
40 |
of a project when away from the office and without access to a clone |
|
4f5533b…
|
drh
|
41 |
of the repository. |
|
4f5533b…
|
drh
|
42 |
|
|
d494477…
|
danield
|
43 |
1. **The Fossil web interface view of a single check-in shows a |
|
d494477…
|
danield
|
44 |
context graph of all other directly connected check-ins.**<p> |
|
d494477…
|
danield
|
45 |
See the page for [check-in 59985724d71229bf](/info/59985724d71229bf) |
|
d494477…
|
danield
|
46 |
for example. The context graph shows four other check-ins: |
|
4f5533b…
|
drh
|
47 |
two direct descendants, one merge descendant, and one ancestor. |
|
4f5533b…
|
drh
|
48 |
This context graph is useful in understanding how a particular |
|
d494477…
|
danield
|
49 |
check-in fits into the history of the project. The context graph |
|
4f5533b…
|
drh
|
50 |
can also be used to step forwards or backwards in time, by |
|
d494477…
|
danield
|
51 |
clicking on the "check-in:" hash links for nearby check-ins. |
|
4f5533b…
|
drh
|
52 |
|
|
4f5533b…
|
drh
|
53 |
1. **The graphical timeline dynamically adjusts its layout as you resize |
|
4f5533b…
|
drh
|
54 |
your browser window.**<p> |
|
4f5533b…
|
drh
|
55 |
The server sends down an HTML page that contains (among other things) |
|
4f5533b…
|
drh
|
56 |
a JSON object that gives the basic structure of the |
|
4f5533b…
|
drh
|
57 |
timeline graph, then Javascript renders the graph. The JS code is |
|
4f5533b…
|
drh
|
58 |
small, does not use any third-party frameworks, and is (by default) |
|
4f5533b…
|
drh
|
59 |
appended to the HTML page. Except for a separate CSS file, the HTML |
|
4f5533b…
|
drh
|
60 |
is completely stand-alone. The local |
|
4f5533b…
|
drh
|
61 |
web browser isn't required to go gather lots of separate resources. |
|
4f5533b…
|
drh
|
62 |
|
|
4f5533b…
|
drh
|
63 |
1. **The graphical timeline works on a phone.**<p> |
|
4f5533b…
|
drh
|
64 |
The graph layout automatically compresses on a small display, and |
|
d494477…
|
danield
|
65 |
can seem a little cramped for a complex project. The timeline |
|
4f5533b…
|
drh
|
66 |
does look better on a desktop. Even so, the timeline display is |
|
4f5533b…
|
drh
|
67 |
functional on a phone and it is very convenient |
|
4f5533b…
|
drh
|
68 |
to be able to see what is happening on a project |
|
4f5533b…
|
drh
|
69 |
while away from the office and without access to a laptop. |
|
4f5533b…
|
drh
|
70 |
|
|
4f5533b…
|
drh
|
71 |
1. **The graphical timeline is bandwidth efficient.**<p> |
|
4f5533b…
|
drh
|
72 |
To display a timeline of recent activity on Fossil uses less |
|
4f5533b…
|
drh
|
73 |
than 5% of the bandwidth as GitHub. In a typical example, |
|
4f5533b…
|
drh
|
74 |
GitHub requires about 3.5MB of transfer to retrieve 56 different |
|
4f5533b…
|
drh
|
75 |
resources compared to 150KB for just one HTML file and one CSS file |
|
4f5533b…
|
drh
|
76 |
with Fossil. And for all that 3.5MB, GitHub only gives you a list |
|
4f5533b…
|
drh
|
77 |
of recent check-ins without any indication of the branching |
|
4f5533b…
|
drh
|
78 |
structure, whereas Fossil gives you an easy-to-read color-coded |
|
4f5533b…
|
drh
|
79 |
graph. |
|
4f5533b…
|
drh
|
80 |
|
|
4f5533b…
|
drh
|
81 |
1. **The Fossil web interface makes it easy to see a diff between |
|
d494477…
|
danield
|
82 |
any two check-ins with just a couple of clicks.**<p> |
|
4f5533b…
|
drh
|
83 |
On the timeline display, click on one node of the graph to |
|
4f5533b…
|
drh
|
84 |
select it (a red dot will appear in the center of the node) and |
|
4f5533b…
|
drh
|
85 |
then click on any other graph node, and Fossil will compute and |
|
4f5533b…
|
drh
|
86 |
display a diff between those two check-ins. (Usage hint: |
|
4f5533b…
|
drh
|
87 |
click the selected node a second time to deselect it.) |
|
4f5533b…
|
drh
|
88 |
|
|
4f5533b…
|
drh
|
89 |
1. **The Fossil web-based diff page shows the context of the two |
|
d494477…
|
danield
|
90 |
check-ins being diffed.**<p> |
|
4f5533b…
|
drh
|
91 |
At the top of the web-based diff is a graph that shows |
|
d494477…
|
danield
|
92 |
specifically the two check-ins being diffed and the context |
|
4f5533b…
|
drh
|
93 |
around them. |
|
4f5533b…
|
drh
|
94 |
[Example](/vdiff?from=052390edaf04a5f5&to=9b686daeeda7b4ca). |
|
4f5533b…
|
drh
|
95 |
This helps to reduce any confusion about what you are looking at. |
|
4f5533b…
|
drh
|
96 |
|
|
4f5533b…
|
drh
|
97 |
1. **In Fossil, a repository is distinct from a working checkout.**<p> |
|
4f5533b…
|
drh
|
98 |
A Fossil repository can be colocated with the working checkout, as |
|
4f5533b…
|
drh
|
99 |
they are required to be in Git. But most people keep the repository |
|
4f5533b…
|
drh
|
100 |
separate. One common pattern is to put all Fossil repositories in |
|
4f5533b…
|
drh
|
101 |
a single directory named $HOME/Fossils or $HOME/Museum and then open |
|
d494477…
|
danield
|
102 |
working checkouts against each repository wherever they are needed. |
|
4f5533b…
|
drh
|
103 |
|
|
4f5533b…
|
drh
|
104 |
1. **A single Fossil repository can support multiple working checkouts.** |
|
4f5533b…
|
drh
|
105 |
<p> |
|
4f5533b…
|
drh
|
106 |
Git has worktrees, but all worktrees checkouts must be on separate |
|
4f5533b…
|
drh
|
107 |
branches. Fossil allows multiple working checkouts on the same branch |
|
d494477…
|
danield
|
108 |
or even on the same check-in. One common pattern is to have one |
|
d494477…
|
danield
|
109 |
checkout that is being edited, and another that is a pristine, unedited |
|
d494477…
|
danield
|
110 |
version of the same check-in. This allows both to be compiled |
|
d494477…
|
danield
|
111 |
simultaneously for performance comparison, or to step through both |
|
4f5533b…
|
drh
|
112 |
binaries in two separate "gdb" sessions to hunt down a bug. |
|
4f5533b…
|
drh
|
113 |
|
|
4f5533b…
|
drh
|
114 |
1. **A Fossil repository is a single disk file, not a directory |
|
4f5533b…
|
drh
|
115 |
hierarchy.**<p> |
|
4f5533b…
|
drh
|
116 |
You can "mv" a Fossil repository to a new place. You can "scp" |
|
4f5533b…
|
drh
|
117 |
a Fossil repository to another machine. It is just a file, |
|
4f5533b…
|
drh
|
118 |
specifically an SQLite database file. You can name a Fossil |
|
4f5533b…
|
drh
|
119 |
repository anything you like. The usual convention is to give the |
|
4f5533b…
|
drh
|
120 |
repository file a ".fossil" suffix, but that is not required. |
|
4f5533b…
|
drh
|
121 |
|
|
4f5533b…
|
drh
|
122 |
1. **Fossil does not have a staging area**.</p> |
|
4f5533b…
|
drh
|
123 |
A staging area does not add new capabilities, it only adds |
|
4f5533b…
|
drh
|
124 |
complication. (Partial commits |
|
4f5533b…
|
drh
|
125 |
are accomplished in Fossil simply by listing the subset of files to |
|
4f5533b…
|
drh
|
126 |
be committed on the "fossil commit" command line.) |
|
4f5533b…
|
drh
|
127 |
The staging area complicates the mental model |
|
4f5533b…
|
drh
|
128 |
of the project that Git users need to keep up with, forcing the |
|
4f5533b…
|
drh
|
129 |
developer to spend more effort thinking about the version control |
|
4f5533b…
|
drh
|
130 |
system and hence less time thinking about the project they are |
|
4f5533b…
|
drh
|
131 |
working on. |
|
4f5533b…
|
drh
|
132 |
|
|
4f5533b…
|
drh
|
133 |
1. **Fossil remembers where all your repositories and working |
|
4f5533b…
|
drh
|
134 |
checkouts are located.**<p> |
|
4f5533b…
|
drh
|
135 |
This and other information (such as all your global settings) |
|
4f5533b…
|
drh
|
136 |
is stored in a per-user database file |
|
4f5533b…
|
drh
|
137 |
at $HOME/.config/fossil.db on unix or in %LOCALAPPDATA%/_fossil on |
|
4f5533b…
|
drh
|
138 |
Windows. Fossil creates and manages that file automatically. |
|
d494477…
|
danield
|
139 |
The user never has to know the file even exists. If you |
|
4f5533b…
|
drh
|
140 |
move or rename repositories or checkouts, the database will get |
|
4f5533b…
|
drh
|
141 |
temporarily out of sync with reality, but Fossil will automatically |
|
4f5533b…
|
drh
|
142 |
fix the database the next time you do anything with the file or |
|
4f5533b…
|
drh
|
143 |
checkout that was moved or renamed.<p> |
|
4f5533b…
|
drh
|
144 |
You can get a list of repositories using the |
|
4f5533b…
|
drh
|
145 |
"<tt>fossil all ls</tt>" command, or a list of open |
|
4f5533b…
|
drh
|
146 |
checkouts using "<tt>fossil all ls --ckout</tt>". |
|
4f5533b…
|
drh
|
147 |
|
|
d494477…
|
danield
|
148 |
1. **Fossil lets you bring up a web-based UI that shows all of |
|
4f5533b…
|
drh
|
149 |
your repositories at once.**<p> |
|
4f5533b…
|
drh
|
150 |
Run the command "<tt>fossil ui /</tt>" and your |
|
4f5533b…
|
drh
|
151 |
default web browser will pop up a new tab that lists all of your |
|
4f5533b…
|
drh
|
152 |
repositories together with the |
|
4f5533b…
|
drh
|
153 |
associated project name and how recently that repository was modified. |
|
4f5533b…
|
drh
|
154 |
Click on links to bring up repository-specific web-pages. Or click |
|
4f5533b…
|
drh
|
155 |
on column headers to sort by that column.<p> |
|
4f5533b…
|
drh
|
156 |
If you are like me and have hundreds of repositories on your desktop |
|
4f5533b…
|
drh
|
157 |
system, this feature makes it easier to keep track of them all, or |
|
4f5533b…
|
drh
|
158 |
just to remember what you called each one. |
|
4f5533b…
|
drh
|
159 |
Are you on an infrequently used travel laptop and forgot where you |
|
4f5533b…
|
drh
|
160 |
put a particular repository, this feature helps you find it. |
|
4f5533b…
|
drh
|
161 |
|
|
4f5533b…
|
drh
|
162 |
1. **Fossil lets you quickly find uncommitted changes across all of |
|
4f5533b…
|
drh
|
163 |
your open checkouts.**<p> |
|
4f5533b…
|
drh
|
164 |
Simply run "<tt>fossil all changes</tt>" to get a quick |
|
4f5533b…
|
drh
|
165 |
summary of every checkout on your local machine that needs a commit. |
|
4f5533b…
|
drh
|
166 |
|
|
4f5533b…
|
drh
|
167 |
1. **Fossil lets you sync all of the changes in all of your local |
|
4f5533b…
|
drh
|
168 |
repositories to their remotes, with a single command.**<p> |
|
4f5533b…
|
drh
|
169 |
Run "<tt>fossil all sync</tt>" and all your local |
|
4f5533b…
|
drh
|
170 |
repositories will sync up. This is useful, for example when |
|
4f5533b…
|
drh
|
171 |
taking a laptop off-network. Before disconnecting, you sync |
|
4f5533b…
|
drh
|
172 |
all of your repositories. Fossil itself keeps track of all |
|
4f5533b…
|
drh
|
173 |
of your repositories, so you cannot accidentally forget one or two. |
|
4f5533b…
|
drh
|
174 |
While off-network, you might commit changes to one or |
|
4f5533b…
|
drh
|
175 |
more of those repositories. Once you reconnect, you simply |
|
4f5533b…
|
drh
|
176 |
run "<tt>fossil all sync</tt>" again to push out your edits |
|
4f5533b…
|
drh
|
177 |
back to the community. |
|
4f5533b…
|
drh
|
178 |
|
|
d494477…
|
danield
|
179 |
1. **Fossil allows multiple check-ins to have the same tag.**<p> |
|
4f5533b…
|
drh
|
180 |
For example, on the SQLite project, every release is tagged with |
|
4f5533b…
|
drh
|
181 |
"release". |
|
4f5533b…
|
drh
|
182 |
|
|
d494477…
|
danield
|
183 |
1. **The Fossil timeline can show all check-ins with a specific tag.**<p> |
|
4f5533b…
|
drh
|
184 |
For example, to see all SQLite releases visit |
|
4f5533b…
|
drh
|
185 |
<https://sqlite.org/src/timeline?t=release> or to see all |
|
4f5533b…
|
drh
|
186 |
Fossil releases go to |
|
4f5533b…
|
drh
|
187 |
<https://fossil-scm.org/home/timeline?t=release>. |
|
4f5533b…
|
drh
|
188 |
|
|
4f5533b…
|
drh
|
189 |
1. **Fossil has a built-in wiki**.<p> |
|
4f5533b…
|
drh
|
190 |
Wiki pages are stored in the same repository file as your code, so that |
|
4f5533b…
|
drh
|
191 |
they push, pull, sync, and clone together with your code. |
|
696ae59…
|
drh
|
192 |
<p> |
|
696ae59…
|
drh
|
193 |
Git does not itself have a wiki. The various Git forges usually add |
|
696ae59…
|
drh
|
194 |
wikis, and store the wiki content in Git, though in a separate |
|
696ae59…
|
drh
|
195 |
Git repository. There is no option to store the wiki and source code |
|
696ae59…
|
drh
|
196 |
together such that they clone and sync as one, in the Git ecosystem. |
|
4f5533b…
|
drh
|
197 |
|
|
d494477…
|
danield
|
198 |
1. **Fossil can associate a wiki page with a particular check-in.**<p> |
|
d494477…
|
danield
|
199 |
Rather than including an oversized check-in comment on an |
|
d494477…
|
danield
|
200 |
important check-in (such as the merge of a big new feature), Fossil |
|
d494477…
|
danield
|
201 |
allows you to assign a wiki page to that check-in. That wiki page |
|
d494477…
|
danield
|
202 |
is shown as part of the check-in information in the web interface. |
|
4f5533b…
|
drh
|
203 |
See, for example, the "About" section of |
|
d494477…
|
danield
|
204 |
[SQLite check-in 2019-11-21T18:28:44.463Z](https://sqlite.org/src/info/2019-11-21T18:28:44.463Z). |
|
d494477…
|
danield
|
205 |
The wiki page associated with a check-in can be created and revised |
|
d494477…
|
danield
|
206 |
after the check-in is committed and pushed. This feature can be used |
|
4f5533b…
|
drh
|
207 |
to add notes or bug reports that occur long after the |
|
d494477…
|
danield
|
208 |
check-in itself has been inserted into the DAG. |
|
4f5533b…
|
drh
|
209 |
|
|
4f5533b…
|
drh
|
210 |
1. **Fossil can associate a wiki page with a particular branch.**<p> |
|
4f5533b…
|
drh
|
211 |
You can create a wiki page for a branch that documents the purpose |
|
4f5533b…
|
drh
|
212 |
of that branch. The wiki page can be displayed separately (like any |
|
4f5533b…
|
drh
|
213 |
other wiki page) but is also displayed automatically at the top of |
|
4f5533b…
|
drh
|
214 |
every timeline for that branch. See, for example, |
|
4f5533b…
|
drh
|
215 |
<https://sqlite.org/src/timeline?r=autosetup>. |
|
4f5533b…
|
drh
|
216 |
|
|
4f5533b…
|
drh
|
217 |
1. **Fossil keeps track of historical branch names.**<p> |
|
d494477…
|
danield
|
218 |
Git does not track branches. Git only names each leaf |
|
4f5533b…
|
drh
|
219 |
of the DAG and infers branches based on the names of leaves. |
|
4f5533b…
|
drh
|
220 |
Fossil actually remembers the name of branches. |
|
4f5533b…
|
drh
|
221 |
For example, suppose a customer asks |
|
4f5533b…
|
drh
|
222 |
"Whatever became of that setlk-snapshot-fix branch you |
|
4f5533b…
|
drh
|
223 |
started last year?" That branch still exists and you can |
|
4f5533b…
|
drh
|
224 |
[see it on GitHub](https://github.com/sqlite/sqlite/commits/setlk-snapshot-fix) |
|
4f5533b…
|
drh
|
225 |
and [in Fossil](https://sqlite.org/src/timeline?r=setlk-snapshot-fix). |
|
4f5533b…
|
drh
|
226 |
Notice, though, that GitHub does not show how the branch was resolved. |
|
4f5533b…
|
drh
|
227 |
(Aside: Also notice how much faster Fossil renders!) |
|
4f5533b…
|
drh
|
228 |
Fossil clearly shows that the branch ended up being merged into trunk. |
|
4f5533b…
|
drh
|
229 |
GitHub just shows us all ancestors of the leaf node labeled |
|
4f5533b…
|
drh
|
230 |
"setlk-snapshot-fix", including ancestors that were in other branches |
|
4f5533b…
|
drh
|
231 |
that got merged in, and ancestors that predate the founding of the |
|
4f5533b…
|
drh
|
232 |
setlk-snapshot-fix branch. |
|
4f5533b…
|
drh
|
233 |
<p> |
|
d494477…
|
danield
|
234 |
GitHub is unable to show you the check-ins of branch setlk-snapshot-fix |
|
4f5533b…
|
drh
|
235 |
only. There are other third-party tools that will show you that, I am |
|
4f5533b…
|
drh
|
236 |
told, but they all require a local clone of the repository. Apparently |
|
4f5533b…
|
drh
|
237 |
there is no way to see this information in a web browser using Git, |
|
4f5533b…
|
drh
|
238 |
with or without third-party tools. |
|
4f5533b…
|
drh
|
239 |
|
|
4f5533b…
|
drh
|
240 |
1. **Fossil has a built-in bug tracking system.**.<p> |
|
4f5533b…
|
drh
|
241 |
Tickets are stored in the repository together with source code and |
|
4f5533b…
|
drh
|
242 |
push/pull/sync the same as the code. The ticket system is configurable |
|
4f5533b…
|
drh
|
243 |
and distributed. Repository administrators can determine what |
|
4f5533b…
|
drh
|
244 |
fields appear in tickets and what users are allowed to create, |
|
4f5533b…
|
drh
|
245 |
edit, or moderate tickets. |
|
4f5533b…
|
drh
|
246 |
|
|
4f5533b…
|
drh
|
247 |
1. **Fossil allows multiple branches with the same name.**<p> |
|
4f5533b…
|
drh
|
248 |
As an example, the SQLite project has multiple branches |
|
4f5533b…
|
drh
|
249 |
named "experimental" |
|
4f5533b…
|
drh
|
250 |
<https://sqlite.org/src/timeline?r=experimental> and many |
|
4f5533b…
|
drh
|
251 |
others named "mistake" |
|
4f5533b…
|
drh
|
252 |
<https://sqlite.org/src/timeline?r=mistake>. |
|
4f5533b…
|
drh
|
253 |
Another example: |
|
4f5533b…
|
drh
|
254 |
[the empty-table-optimizations branch(es)](https://sqlite.org/src/timeline?r=empty-table-optimizations) |
|
4f5533b…
|
drh
|
255 |
which was initially merged to trunk and closed |
|
4f5533b…
|
drh
|
256 |
on 2025-07-02, but then reopened and continued with more enhancements |
|
4f5533b…
|
drh
|
257 |
until it was merged again on 2025-07-08. |
|
4f5533b…
|
drh
|
258 |
|
|
4f5533b…
|
drh
|
259 |
1. **Fossil allows both legacy SHA1 hashes and newer SHA3-256 hashes |
|
4f5533b…
|
drh
|
260 |
in the same repository.**<p> |
|
4f5533b…
|
drh
|
261 |
Both Fossil and Git started out using only SHA1 hashes. But when the |
|
4f5533b…
|
drh
|
262 |
[SHAttered attack](https://www.marc-stevens.nl/research/shattered.io/) |
|
4f5533b…
|
drh
|
263 |
against SHA1 was published on 2017-02-23, the need to migrate to a |
|
4f5533b…
|
drh
|
264 |
stronger hash algorithm was recognized. Fossil added the ability |
|
4f5533b…
|
drh
|
265 |
to use SHA3-256 as an alternative on 2017-03-01 (six days after the |
|
4f5533b…
|
drh
|
266 |
SHAttered attack was first published). |
|
d494477…
|
danield
|
267 |
SHA3-256 is now the default for all new repositories and check-ins |
|
d494477…
|
danield
|
268 |
in Fossil, though older check-ins that occurred |
|
d494477…
|
danield
|
269 |
prior to SHAttered can still use their original SHA1 hash. Hence, |
|
4f5533b…
|
drh
|
270 |
no repositories had to be rebuilt and no hyperlinks were broken.<p> |
|
4f5533b…
|
drh
|
271 |
In contrast, after nine years, a Git repository can still only |
|
d494477…
|
danield
|
272 |
support one hash algorithm at a time. |
|
4f5533b…
|
drh
|
273 |
Newer Git repositories are able to use SHA2, though the default |
|
4f5533b…
|
drh
|
274 |
is still SHA1. |
|
4f5533b…
|
drh
|
275 |
|
|
d494477…
|
danield
|
276 |
1. **Fossil allows check-ins to be identified by timestamp**<p> |
|
d494477…
|
danield
|
277 |
The canonical name for a check-in is its hash. Both Git and Fossil |
|
d494477…
|
danield
|
278 |
allow a check-in to be identified by any unique prefix of its hash. |
|
d494477…
|
danield
|
279 |
But only Fossil allows a check-in to also be identified by its |
|
4f5533b…
|
drh
|
280 |
timestamp. The names "2026-02-02T16:03:24.852Z" and "fdebbedbd9a99165" |
|
84ced25…
|
drh
|
281 |
both refer to |
|
84ced25…
|
drh
|
282 |
[the same check-in](https://sqlite.org/src/info/fdebbedbd9a99165), |
|
4f5533b…
|
drh
|
283 |
but the first one has the advantage of giving some time |
|
4f5533b…
|
drh
|
284 |
context rather than just being a seemingly random sequence of hexadecimal |
|
d494477…
|
danield
|
285 |
digits. It is possible that two or more check-ins can have the same |
|
4f5533b…
|
drh
|
286 |
timestamp, in which case the timestamp would be ambiguous. And a |
|
d494477…
|
danield
|
287 |
check-in timestamp can be changed after it is committed, by using |
|
4f5533b…
|
drh
|
288 |
a special tag. So timestamp identifiers do not have the uniqueness |
|
4f5533b…
|
drh
|
289 |
and stability guarantees as hash identifiers, but they are available |
|
4f5533b…
|
drh
|
290 |
as an option and are often useful. |
|
4f5533b…
|
drh
|
291 |
|
|
4f5533b…
|
drh
|
292 |
1. **Fossil has a built-in forum.**<p> |
|
4f5533b…
|
drh
|
293 |
The forum content is replicated via push, pull, sync, and clone just like |
|
d494477…
|
danield
|
294 |
source code. Forum posts can be enabled per user or for all users or |
|
d494477…
|
danield
|
295 |
for all users and anonymous passers-by. Some users can be appointed |
|
4f5533b…
|
drh
|
296 |
as moderators and posts from untrusted users can be held for |
|
4f5533b…
|
drh
|
297 |
moderation. |
|
4f5533b…
|
drh
|
298 |
<p> |
|
4f5533b…
|
drh
|
299 |
The [Fossil Forum](https://fossil-scm.org/forum), the |
|
4f5533b…
|
drh
|
300 |
[SQLite User Forum](https://sqlite.org/forum), and the |
|
4f5533b…
|
drh
|
301 |
[SQLite Bugs Forum](https://sqlite.org/bugs) are all forums |
|
4f5533b…
|
drh
|
302 |
set up for specific purposes and deliberately kept separate |
|
4f5533b…
|
drh
|
303 |
from source code. But other projects such as |
|
4f5533b…
|
drh
|
304 |
[Pikchr](https://pikchr.org/) comingle their forum and the source code |
|
4f5533b…
|
drh
|
305 |
in the same repository. Thus when you clone the |
|
4f5533b…
|
drh
|
306 |
Pikchr source repository, you also get all the Forum history. |
|
4f5533b…
|
drh
|
307 |
|
|
4f5533b…
|
drh
|
308 |
1. **Fossil makes it easy to set up a project website using CGI.**<p> |
|
4f5533b…
|
drh
|
309 |
If you have an internet-facing machine running a CGI-capable web |
|
4f5533b…
|
drh
|
310 |
server, you can stand up a complete self-hosting project |
|
4f5533b…
|
drh
|
311 |
website with a two-line CGI script. The canonical |
|
4f5533b…
|
drh
|
312 |
[Fossil website](https://fossil-scm.org/home) is really just such |
|
4f5533b…
|
drh
|
313 |
a CGI script. When you clone the Fossil source code, you don't |
|
4f5533b…
|
drh
|
314 |
just get the code, you get the entire website. |
|
4f5533b…
|
drh
|
315 |
<p> |
|
4f5533b…
|
drh
|
316 |
The CGI script used to run the Fossil website looks |
|
4f5533b…
|
drh
|
317 |
approximately like this: |
|
4f5533b…
|
drh
|
318 |
<pre> |
|
4f5533b…
|
drh
|
319 |
#!/usr/bin/fossil |
|
4f5533b…
|
drh
|
320 |
repository: /Fossils/fossil.fossil</pre> |
|
4f5533b…
|
drh
|
321 |
You can, of course, also create a self-hosting website using |
|
4f5533b…
|
drh
|
322 |
GitLab or Forgejo or similar, but the setup and maintenance is |
|
4f5533b…
|
drh
|
323 |
somewhat more involved. You'll also probably need a bigger machine |
|
4f5533b…
|
drh
|
324 |
if you are using GitLab, whereas a Fossil website |
|
4f5533b…
|
drh
|
325 |
works fine on a 2GiB Raspberry PI or a $6/month VPS. |
|
4f5533b…
|
drh
|
326 |
I am told that Gitea and Forgejo also work well on a small machine. |
|
4f5533b…
|
drh
|
327 |
No direct size and performance comparisons between Gitea/Forgejo and |
|
4f5533b…
|
drh
|
328 |
Fossil have been made, as of this writing. |
|
4f5533b…
|
drh
|
329 |
|
|
4f5533b…
|
drh
|
330 |
1. **Fossil makes it easy to set up a project website using SCGI.**<p> |
|
4f5533b…
|
drh
|
331 |
CGI is easier, but some web servers (ex: Nginx) do not support CGI. |
|
4f5533b…
|
drh
|
332 |
If you are using such a web server, you can also run a Fossil |
|
4f5533b…
|
drh
|
333 |
server using SCGI. See the |
|
4f5533b…
|
drh
|
334 |
[on-line Fossil SCGI documentation](/doc/trunk/www/scgi.wiki) |
|
4f5533b…
|
drh
|
335 |
for details. |
|
4f5533b…
|
drh
|
336 |
|
|
4f5533b…
|
drh
|
337 |
1. **Fossil makes it easy to set up a project website behind a |
|
4f5533b…
|
drh
|
338 |
reverse proxy.**<p> |
|
4f5533b…
|
drh
|
339 |
Simply run a [Fossil HTTP server](/doc/trunk/www/server/any/none.md) |
|
4f5533b…
|
drh
|
340 |
and have your reverse proxy redirect requests to this new Fossil |
|
4f5533b…
|
drh
|
341 |
server. You can also set up the Fossil server to work over named |
|
4f5533b…
|
drh
|
342 |
pipes rather than a loopback, if your reverse proxy supports that. |
|
4f5533b…
|
drh
|
343 |
|
|
4f5533b…
|
drh
|
344 |
1. **Fossil makes it easy to set up a project website without |
|
4f5533b…
|
drh
|
345 |
using any web server at all.**<p> |
|
4f5533b…
|
drh
|
346 |
The [fossil server command](/help/server) includes a --cert |
|
4f5533b…
|
drh
|
347 |
option with which you can specify a TLS cert for encrypted |
|
4f5533b…
|
drh
|
348 |
communication, and with the option, Fossil will accept ordinary |
|
4f5533b…
|
drh
|
349 |
HTTPS requests from the open internet. There is no need to |
|
4f5533b…
|
drh
|
350 |
install and configure a separate web server. Hence, the only |
|
4f5533b…
|
drh
|
351 |
software you need to stand up a project website using Fossil is |
|
4f5533b…
|
drh
|
352 |
the stand-alone "fossil" binary. |
|
4f5533b…
|
drh
|
353 |
|
|
4f5533b…
|
drh
|
354 |
1. **A single Fossil server is able to host multiple projects.**<p> |
|
4f5533b…
|
drh
|
355 |
By default, each Fossil server provides content for a single |
|
4f5533b…
|
drh
|
356 |
repository. But you can launch a Fossil server that hosts |
|
4f5533b…
|
drh
|
357 |
multiple repositories by putting all those repositories in a |
|
4f5533b…
|
drh
|
358 |
directory and giving the directory name as the object to serve |
|
4f5533b…
|
drh
|
359 |
instead of the repository name. For this mode of operation, |
|
4f5533b…
|
drh
|
360 |
the repositories must be named with the "<tt>.fossil</tt>" file |
|
4f5533b…
|
drh
|
361 |
suffix. Individual projects have URLs that begin with the |
|
4f5533b…
|
drh
|
362 |
repository base name, omitting the "<tt>.fossil</tt>" suffix. |
|
4f5533b…
|
drh
|
363 |
|
|
4f5533b…
|
drh
|
364 |
1. **Fossil automatically pushes after each commit, by default**.<p> |
|
4f5533b…
|
drh
|
365 |
The [autosync setting](/help/autosync), which defaults to "on", causes |
|
4f5533b…
|
drh
|
366 |
every commit to automatically push to the default remote. This helps |
|
4f5533b…
|
drh
|
367 |
to keep the remote up-to-date and helps all the developers working on |
|
4f5533b…
|
drh
|
368 |
the project keep up with what other developers are doing. |
|
4f5533b…
|
drh
|
369 |
<p> |
|
4f5533b…
|
drh
|
370 |
Long-time Git users might cringe at autosync, thinking that this |
|
4f5533b…
|
drh
|
371 |
could cause problems if another developer commits ahead of you. |
|
4f5533b…
|
drh
|
372 |
True enough, that would cause headaches for Git, but it does not |
|
4f5533b…
|
drh
|
373 |
create problems for Fossil. |
|
d494477…
|
danield
|
374 |
The worst that could happen is that the branch will fork. Fossil |
|
4f5533b…
|
drh
|
375 |
will usually detect an impending fork and warn you. |
|
4f5533b…
|
drh
|
376 |
But even if you don't get the warning (due to a race) or even if you |
|
4f5533b…
|
drh
|
377 |
override the warning and force the commit anyhow, a fork on a branch |
|
4f5533b…
|
drh
|
378 |
in Fossil is harmless. It shows cleanly in the timeline and |
|
4f5533b…
|
drh
|
379 |
is easily resolved. So while autosync might cause issues with Git, |
|
4f5533b…
|
drh
|
380 |
it is harmless when using Fossil. Since forks are harmless, |
|
4f5533b…
|
drh
|
381 |
the benefits of autosync far outweigh the risks. |
|
4f5533b…
|
drh
|
382 |
|
|
4f5533b…
|
drh
|
383 |
1. **Fossil supports embedded Pikchr in Wiki and in the Forum.**</p> |
|
4f5533b…
|
drh
|
384 |
[Pikchr](https://pikchr.org/) is a |
|
4f5533b…
|
drh
|
385 |
[PIC-like](https://en.wikipedia.org/wiki/Pic_language) markup language |
|
c629e71…
|
brickviking
|
386 |
for diagrams. Pikchr is designed for use with Markdown, but also works |
|
4f5533b…
|
drh
|
387 |
with other markup languages. |
|
4f5533b…
|
drh
|
388 |
The diagrams that appear in the Fossil documentation are |
|
4f5533b…
|
drh
|
389 |
all drawn using Pikchr. |
|
4f5533b…
|
drh
|
390 |
|
|
4f5533b…
|
drh
|
391 |
1. **Fossil has a Pikchr sandbox for experimenting with Pikchr scripts.** |
|
4f5533b…
|
drh
|
392 |
<p> |
|
4f5533b…
|
drh
|
393 |
The [pikchrshow page](/pikchrshow) allows users to experiment with and |
|
4f5533b…
|
drh
|
394 |
refine their Pikchr diagrams prior to copy/pasting them into their |
|
4f5533b…
|
drh
|
395 |
documents. |
|
4f5533b…
|
drh
|
396 |
|
|
4f5533b…
|
drh
|
397 |
1. **The Fossil web interface supports "embedded documentation"**</p> |
|
4f5533b…
|
drh
|
398 |
See the [Project Documentation](/doc/trunk/www/embeddeddoc.wiki) page |
|
4f5533b…
|
drh
|
399 |
for details. Markdown, Wiki, plain-text, and HTML files in the |
|
4f5533b…
|
drh
|
400 |
source tree can be rendered and used as documentation pages. This |
|
4f5533b…
|
drh
|
401 |
is how all of the documentation files for Fossil itself are created. |
|
4f5533b…
|
drh
|
402 |
|
|
4f5533b…
|
drh
|
403 |
1. **Fossil can easily host an entire project website, using only the |
|
4f5533b…
|
drh
|
404 |
repository as the backing store.**<p> |
|
4f5533b…
|
drh
|
405 |
The embedded documentation and wiki features allow you to write |
|
c629e71…
|
brickviking
|
406 |
web pages. The unversioned file feature gives you space to put |
|
4f5533b…
|
drh
|
407 |
precompiled binaries or other transient and/or derived resources |
|
4f5533b…
|
drh
|
408 |
without contaminating the source tree. The Forum and Ticket features |
|
4f5533b…
|
drh
|
409 |
provide for community discussion and bug tracking. Fossil provides |
|
4f5533b…
|
drh
|
410 |
everything you need to host a complete software project website. |
|
4f5533b…
|
drh
|
411 |
Indeed, the |
|
4f5533b…
|
drh
|
412 |
[canonical Fossil website](https://fossil-scm.org/home) is just |
|
4f5533b…
|
drh
|
413 |
an instance of Fossil running on the self-hosting Fossil repository. |
|
4f5533b…
|
drh
|
414 |
If you clone the Fossil self-hosting repository, you don't get just |
|
84ced25…
|
drh
|
415 |
code - you get the entire website. (Exception: |
|
4f5533b…
|
drh
|
416 |
[Fossil Forum](https://sqlite.org/forum) is hosted separately using |
|
4f5533b…
|
drh
|
417 |
a separate Fossil repository, so you'd actually need to clone that |
|
4f5533b…
|
drh
|
418 |
one too, in order to get the whole website.) |
|
4f5533b…
|
drh
|
419 |
|
|
4f5533b…
|
drh
|
420 |
1. **Using Fossil, backing up your project website is just a sync.**<p> |
|
4f5533b…
|
drh
|
421 |
If you host your entire project website in a Fossil repository, |
|
4f5533b…
|
drh
|
422 |
as Fossil itself does, then backing up that website is as simple |
|
4f5533b…
|
drh
|
423 |
as creating a clone and keeping the clone synced. |
|
4f5533b…
|
drh
|
424 |
|
|
4f5533b…
|
drh
|
425 |
1. **Fossil will render uncommitted changes to embedded documentation.** |
|
4f5533b…
|
drh
|
426 |
<p> |
|
4f5533b…
|
drh
|
427 |
Using the "<tt>fossil ui</tt>" and the |
|
4f5533b…
|
drh
|
428 |
[/doc/VERSION/FILE](/help/www/doc) webpage, if the VERSION is the |
|
4f5533b…
|
drh
|
429 |
special keyword "ckout", then the content is taken from the local |
|
4f5533b…
|
drh
|
430 |
checkout rather than from the repository. This allows you to edit |
|
4f5533b…
|
drh
|
431 |
embedded documentation files and then press Reload on your browser |
|
4f5533b…
|
drh
|
432 |
to see how they will look and work on the |
|
4f5533b…
|
drh
|
433 |
actual website without having to commit. |
|
4f5533b…
|
drh
|
434 |
|
|
4f5533b…
|
drh
|
435 |
1. **Fossil has a wiki sandbox for experimenting with markup.**</p> |
|
4f5533b…
|
drh
|
436 |
The [wiki sandbox](/wikiedit?name=Sandbox) allows users to experiment |
|
4f5533b…
|
drh
|
437 |
with Markdown or other text markup languages supported by Fossil, |
|
4f5533b…
|
drh
|
438 |
without making permanent changes to the repository. |
|
4f5533b…
|
drh
|
439 |
|
|
4f5533b…
|
drh
|
440 |
1. **Fossil supports interwiki hyperlinks.**<p> |
|
4f5533b…
|
drh
|
441 |
Core Git does not have any kind of markup language. Check-in comments |
|
4f5533b…
|
drh
|
442 |
in Git are always displayed verbatim. But wrappers such as GitHub, |
|
4f5533b…
|
drh
|
443 |
GitLab, Gitea, Forgejo, and similar generally support some variant |
|
4f5533b…
|
drh
|
444 |
of Markdown. However, none of these system support links (apart from |
|
4f5533b…
|
drh
|
445 |
full URLs) to other wiki systems. Fossil does support interwiki links |
|
d494477…
|
danield
|
446 |
using the syntax "<tt>remote:path</tt>". So, for example, a check-in |
|
4f5533b…
|
drh
|
447 |
in the SQLite source repository (<https://sqlite.org/src>) that wants |
|
4f5533b…
|
drh
|
448 |
to reference a bug report (perhaps because it fixes the bug) can |
|
4f5533b…
|
drh
|
449 |
include a link of the form "<tt>bugs:/info/</tt><i>HASH</i>" to |
|
4f5533b…
|
drh
|
450 |
reference that bug. The source repository knows that "bugs:" refers |
|
4f5533b…
|
drh
|
451 |
to the [SQLite Bug Forum](https://sqlite.org/bugs) and completes the |
|
4f5533b…
|
drh
|
452 |
link accordingly. |
|
4f5533b…
|
drh
|
453 |
<p> |
|
c629e71…
|
brickviking
|
454 |
Interwiki links are important because (1) they help keep hyperlinks |
|
4f5533b…
|
drh
|
455 |
shorter, and (2) if the target wiki |
|
4f5533b…
|
drh
|
456 |
ever moves to a new domain, all the links automatically adjust |
|
4f5533b…
|
drh
|
457 |
by changing a single server setting, and (3) clones can have |
|
4f5533b…
|
drh
|
458 |
different mappings for interwiki links, so that (for example) |
|
4f5533b…
|
drh
|
459 |
a "bugs:" link in a clone of the source repository can map to |
|
4f5533b…
|
drh
|
460 |
a clone of the Bugs Forum repository rather than the canonical |
|
4f5533b…
|
drh
|
461 |
Bugs Forum. |
|
4f5533b…
|
drh
|
462 |
|
|
4f5533b…
|
drh
|
463 |
1. **Fossil has a built-in chat server.**<p> |
|
4f5533b…
|
drh
|
464 |
Users with appropriate permissions (usually just registered |
|
4f5533b…
|
drh
|
465 |
developers, not anonymous passers-by) can bring up a web-based chat |
|
c629e71…
|
brickviking
|
466 |
window on any Fossil web-server instance. This feature allows |
|
4f5533b…
|
drh
|
467 |
geographically distributed developers to collaborate interactively, |
|
4f5533b…
|
drh
|
468 |
without having to involve a third-party chat provider such as Slack. |
|
4f5533b…
|
drh
|
469 |
Nothing needs to be configured in order to activate Chat, other |
|
c629e71…
|
brickviking
|
470 |
than enabling the Chat privilege on the permission bits of the |
|
4f5533b…
|
drh
|
471 |
users whom you want to have access to Chat. |
|
4f5533b…
|
drh
|
472 |
|
|
4f5533b…
|
drh
|
473 |
1. **Fossil chat can be configured to send automatic notifications |
|
4f5533b…
|
drh
|
474 |
when changes occur in the repository.**<p> |
|
4f5533b…
|
drh
|
475 |
This helps developers keep up with what is happening in the repository. |
|
4f5533b…
|
drh
|
476 |
The chat window beeps (or not, configurable individually by each user) |
|
4f5533b…
|
drh
|
477 |
when new messages arrive, as an alert. |
|
4f5533b…
|
drh
|
478 |
|
|
4f5533b…
|
drh
|
479 |
1. **The Fossil Chat system has hooks that allow external subsystems |
|
4f5533b…
|
drh
|
480 |
to inject chat messages.**<p> |
|
4f5533b…
|
drh
|
481 |
The SQLite developers use this to get notifications of testing |
|
4f5533b…
|
drh
|
482 |
failures from our fuzz testing infrastructure. It could also |
|
4f5533b…
|
drh
|
483 |
be leveraged to get chat notifications of CI/CD problems. |
|
4f5533b…
|
drh
|
484 |
|
|
4f5533b…
|
drh
|
485 |
1. **Fossil chat is able to send attachments.**<p> |
|
4f5533b…
|
drh
|
486 |
When the SQLite developers are working collaboratively on a problem |
|
4f5533b…
|
drh
|
487 |
(while working, literally, on three different continents) we easily |
|
4f5533b…
|
drh
|
488 |
send patches or diffs to one another over Chat. |
|
4f5533b…
|
drh
|
489 |
|
|
d494477…
|
danield
|
490 |
1. **Fossil supports hyperlinks in check-in comments.**<p> |
|
4f5533b…
|
drh
|
491 |
Check-in comments need not be just verbatim text (though they can |
|
d494477…
|
danield
|
492 |
be, depending on repository settings). By default, check-in |
|
4f5533b…
|
drh
|
493 |
comments can contain hyperlinks, including hyperlinks to |
|
d494477…
|
danield
|
494 |
wiki pages, prior check-ins, forum posts, and interwiki hyperlinks. |
|
4f5533b…
|
drh
|
495 |
|
|
4f5533b…
|
drh
|
496 |
1. **Fossil supports hyperlink back references**<p> |
|
fa7f715…
|
brickviking
|
497 |
If the check-in comment for a newer commit contains a hyperlink |
|
d494477…
|
danield
|
498 |
back to an older commit, then when the web interface shows the |
|
d494477…
|
danield
|
499 |
details of the older commit, it also provides a forward |
|
4f5533b…
|
drh
|
500 |
reference to the newer commit. |
|
4f5533b…
|
drh
|
501 |
|
|
4f5533b…
|
drh
|
502 |
1. **Fossil supports a graphical timeline display of a bisect.**<p> |
|
4f5533b…
|
drh
|
503 |
[For example](https://sqlite.org/src/timeline?bid=y2f0bde4bc8-ndfc790f998-ye2634e500c-yff205f2993-y6bb717acf7-nb48d951916-y8364d89c3b-n98a53fb276-y9d68971c58-y498ee8d514-n043ff54fb7-ye33da6d5dc). |
|
4f5533b…
|
drh
|
504 |
This is not strictly necessary to make effective use of bisect, but |
|
4f5533b…
|
drh
|
505 |
the graphical display does seem to help with situational awareness. |
|
4f5533b…
|
drh
|
506 |
|
|
4f5533b…
|
drh
|
507 |
1. **Fossil can show you the first release in which a particular |
|
d494477…
|
danield
|
508 |
check-in appears, with a single mouse click.**<p> |
|
4f5533b…
|
drh
|
509 |
You have to configure the repository by giving it the name of the |
|
4f5533b…
|
drh
|
510 |
tag that you use to mark releases, using the |
|
4f5533b…
|
drh
|
511 |
[path-to-tag setting](/help/path-to-tag). Suppose you use the tag |
|
4f5533b…
|
drh
|
512 |
name "release". Once you do that, then |
|
fa7f715…
|
brickviking
|
513 |
when you are looking at the "info" page for a check-in, a link |
|
4f5533b…
|
drh
|
514 |
named "path-to-release" appears in the overview section, and if |
|
4f5533b…
|
drh
|
515 |
you click on that link, it brings up a new graph showing the |
|
d494477…
|
danield
|
516 |
shortest path from that check-in to the next descendant check-in |
|
4f5533b…
|
drh
|
517 |
tagged with "release". |
|
4f5533b…
|
drh
|
518 |
<p> |
|
4f5533b…
|
drh
|
519 |
Example: On the info page at |
|
4f5533b…
|
drh
|
520 |
<https://sqlite.org/src/info/b1d7123bc619e3cb>, in the Overview |
|
4f5533b…
|
drh
|
521 |
section at the top, to the right of the "Timelines:" label, you |
|
4f5533b…
|
drh
|
522 |
will see the "path-to-release" link. Click that link to take you |
|
d494477…
|
danield
|
523 |
to a page showing an abbreviated path from the original check-in |
|
d494477…
|
danield
|
524 |
to the first "release" check-in that contains the change. To |
|
fa7f715…
|
brickviking
|
525 |
see the full path, uncheck the "Brief" checkbox near the top of the page. |
|
4f5533b…
|
drh
|
526 |
<p> |
|
4f5533b…
|
drh
|
527 |
This feature is useful for when you bisect to find a bug, or a bug |
|
4f5533b…
|
drh
|
528 |
fix, and you want to know the first release in which that bug or bug fix |
|
4f5533b…
|
drh
|
529 |
appeared. |
|
4f5533b…
|
drh
|
530 |
|
|
d494477…
|
danield
|
531 |
1. **Fossil allows you to revise a check-in comment without |
|
4f5533b…
|
drh
|
532 |
rewriting history.**<p> |
|
d494477…
|
danield
|
533 |
If you find a typo or other error in an historical check-in comment, |
|
4f5533b…
|
drh
|
534 |
you can fix the problem in Fossil without having to rewrite all |
|
4f5533b…
|
drh
|
535 |
subsequent history. The Fossil file format allows you to set |
|
d494477…
|
danield
|
536 |
a special tag on the check-in that provides revised comment text. |
|
4f5533b…
|
drh
|
537 |
The new tag causes both the command-line display |
|
d494477…
|
danield
|
538 |
and the web interface to show the revised check-in comment rather |
|
d494477…
|
danield
|
539 |
that the original. Note that the original check-in comment is |
|
4f5533b…
|
drh
|
540 |
preserved, so there is still an immutable audit trail. But for |
|
4f5533b…
|
drh
|
541 |
common use cases, only the newer revised comment is shown. |
|
4f5533b…
|
drh
|
542 |
<p> |
|
d494477…
|
danield
|
543 |
If you are using the web interface and if you have check-in privilege |
|
d494477…
|
danield
|
544 |
on the repository, then on the /info page for the check-in, under |
|
4f5533b…
|
drh
|
545 |
the "Overview" section, to the right of "Other Links:", there is |
|
4f5533b…
|
drh
|
546 |
an "edit" link that will take you to a page that lets you change |
|
d494477…
|
danield
|
547 |
the check-in comment from the web interface. This is the easiest |
|
d494477…
|
danield
|
548 |
way to edit a check-in comment. |
|
4f5533b…
|
drh
|
549 |
<p> |
|
d494477…
|
danield
|
550 |
See [Fossil check-in b63d654041](/info/b63d65404) for an |
|
4f5533b…
|
drh
|
551 |
example. The original comment is shown in the "Overview" |
|
d494477…
|
danield
|
552 |
section of the check-in details, but the revised comment is shown |
|
4f5533b…
|
drh
|
553 |
in the timeline. |
|
4f5533b…
|
drh
|
554 |
|
|
d494477…
|
danield
|
555 |
1. **Fossil allows you to revise a check-in timestamp without |
|
4f5533b…
|
drh
|
556 |
rewriting history.**<p> |
|
d494477…
|
danield
|
557 |
When generating a new check-in, Fossil uses the current time on the |
|
4f5533b…
|
drh
|
558 |
system where the commit is occurring. But if the system clock on |
|
d494477…
|
danield
|
559 |
that system is incorrect, that can lead to a check-in with an |
|
d494477…
|
danield
|
560 |
inaccurate timestamp. It can be the case that prior check-ins |
|
d494477…
|
danield
|
561 |
have later timestamps or that subsequent check-ins can have |
|
4f5533b…
|
drh
|
562 |
earlier timestamps, resulting in goofy-looking "time-warps" in the |
|
4f5533b…
|
drh
|
563 |
timeline. This can be fixed by add a timestamp correction tag |
|
d494477…
|
danield
|
564 |
to the faulty check-in to fix the timestamp. |
|
4f5533b…
|
drh
|
565 |
<p> |
|
d494477…
|
danield
|
566 |
If you are using the web interface and if you have check-in privilege |
|
d494477…
|
danield
|
567 |
on the repository, then on the /info page for the check-in, under |
|
4f5533b…
|
drh
|
568 |
the "Overview" section, to the right of "Other Links:", there is |
|
4f5533b…
|
drh
|
569 |
an "edit" link that will take you to a page that lets you change |
|
d494477…
|
danield
|
570 |
the timestamp for a check-in from the web interface. This is the |
|
4f5533b…
|
drh
|
571 |
easiest way to make the change. |
|
4f5533b…
|
drh
|
572 |
|
|
d494477…
|
danield
|
573 |
1. **Fossil allows you to move a check-in to a new branch without |
|
4f5533b…
|
drh
|
574 |
rewriting history.**<p> |
|
4f5533b…
|
drh
|
575 |
If you mistakenly commit to the wrong branch, you can move that |
|
d494477…
|
danield
|
576 |
check-in to a new branch by attaching a special tag. |
|
d494477…
|
danield
|
577 |
Note, however, that this will also move all subsequent check-ins |
|
4f5533b…
|
drh
|
578 |
to that same new branch. |
|
4f5533b…
|
drh
|
579 |
<p> |
|
4f5533b…
|
drh
|
580 |
In the SQLite and Fossil projects, when developers mistakenly commit |
|
4f5533b…
|
drh
|
581 |
on the wrong branch, the usual way we fix that is to move the |
|
d494477…
|
danield
|
582 |
mistaken check-in to a branch named "mistake". Sometimes we also |
|
d494477…
|
danield
|
583 |
set the "hidden" tag on that check-in as well, so that it does not |
|
4f5533b…
|
drh
|
584 |
show up on ordinary timelines (though it is still part of the |
|
4f5533b…
|
drh
|
585 |
immutable audit history and is visible with special options). |
|
d494477…
|
danield
|
586 |
Then we just cherrypick the check-in onto the correct branch. |
|
4f5533b…
|
drh
|
587 |
<p> |
|
d494477…
|
danield
|
588 |
If you are using the web interface and if you have check-in privilege |
|
d494477…
|
danield
|
589 |
on the repository, then on the /info page for the check-in, under |
|
4f5533b…
|
drh
|
590 |
the "Overview" section, to the right of "Other Links:", there is |
|
fa7f715…
|
brickviking
|
591 |
an "edit" link that will take you to a page that lets you move the |
|
fa7f715…
|
brickviking
|
592 |
check-in to a new branch from the web interface. You can also do this |
|
d494477…
|
danield
|
593 |
from the Fossil command-line, but the web interface is easier and less |
|
4f5533b…
|
drh
|
594 |
error prone. |
|
4f5533b…
|
drh
|
595 |
|
|
4f5533b…
|
drh
|
596 |
1. **Fossil supports unversioned files**.<p> |
|
4f5533b…
|
drh
|
597 |
[Unversioned Files](/doc/trunk/www/unvers.wiki) are files held |
|
4f5533b…
|
drh
|
598 |
in the repository but which are not versioned and which are not |
|
4f5533b…
|
drh
|
599 |
synced by default. Unversioned files are used by Fossil itself |
|
4f5533b…
|
drh
|
600 |
to store [Precompiled Binaries of Fossil](/uv/download.html). |
|
4f5533b…
|
drh
|
601 |
<p> |
|
d494477…
|
danield
|
602 |
Unversioned content is not synced *by default*. But unversioned |
|
4f5533b…
|
drh
|
603 |
files will sync if you add the -u option to the |
|
4f5533b…
|
drh
|
604 |
[fossil sync command](/help/sync). |
|
d494477…
|
danield
|
605 |
There is also the [fossil uv sync](/help/uv) command. |
|
4f5533b…
|
drh
|
606 |
|
|
d494477…
|
danield
|
607 |
1. **Fossil automatically selects check-in background colors according to |
|
d494477…
|
danield
|
608 |
the branch that each check-in occurs on.**<p> |
|
4f5533b…
|
drh
|
609 |
This helps to make the timeline easier to read at a glance, by |
|
d494477…
|
danield
|
610 |
clearly showing which check-ins are on which branches. Developers |
|
4f5533b…
|
drh
|
611 |
can assign specific colors to branches either when the branch is |
|
4f5533b…
|
drh
|
612 |
first created, or after the branch has been running for a while. |
|
4f5533b…
|
drh
|
613 |
But experience teaches us that it is better to just let the web |
|
4f5533b…
|
drh
|
614 |
interface pick the branch colors automatically. The color is |
|
4f5533b…
|
drh
|
615 |
derived from a hash of the branch name. |
|
4f5533b…
|
drh
|
616 |
|
|
4f5533b…
|
drh
|
617 |
1. **The Fossil web interface contains a page that allows you to |
|
4f5533b…
|
drh
|
618 |
preview what colors Fossil will choose for branch names.**<p> |
|
4f5533b…
|
drh
|
619 |
On the [/hash-color-test page](/hash-color-test), one can enter |
|
4f5533b…
|
drh
|
620 |
candidate branch names and see in advance what colors Fossil will |
|
4f5533b…
|
drh
|
621 |
pick for that branch name. This seems like cheating, but I will |
|
4f5533b…
|
drh
|
622 |
admit that I do this myself, sometimes... |
|
4f5533b…
|
drh
|
623 |
|
|
d494477…
|
danield
|
624 |
1. **The Fossil web interface timeline can be asked to pick check-in |
|
4f5533b…
|
drh
|
625 |
colors using the name of the committer, rather than the branch |
|
4f5533b…
|
drh
|
626 |
name.**<p> |
|
4f5533b…
|
drh
|
627 |
Simply add the "ubg" query parameter (mnemonic: User BackGround) and |
|
d494477…
|
danield
|
628 |
the check-in colors will be determined by the committer login name |
|
4f5533b…
|
drh
|
629 |
rather than the branch name or any preselected color name. This |
|
4f5533b…
|
drh
|
630 |
results in a timeline that gives the reader a clearer view of who is |
|
4f5533b…
|
drh
|
631 |
making changes. |
|
4f5533b…
|
drh
|
632 |
[Example](/timeline?n=200&y=ci&ubg). |
|
4f5533b…
|
drh
|
633 |
|
|
4f5533b…
|
drh
|
634 |
1. **Fossil tracks cherrypick merges.**<p> |
|
4f5533b…
|
drh
|
635 |
Cherrypicks are recorded as part of the underlying |
|
4f5533b…
|
drh
|
636 |
[Fossil file format](/doc/trunk/www/fileformat.wiki). |
|
4f5533b…
|
drh
|
637 |
Cherrypicks appear on the timeline as thin dashed lines. |
|
4f5533b…
|
drh
|
638 |
|
|
4f5533b…
|
drh
|
639 |
1. **Fossil draws arrows pointing forwards in time.**<p> |
|
4f5533b…
|
drh
|
640 |
Forward-pointing arrows are more intuitive than arrows |
|
d494477…
|
danield
|
641 |
that point backwards in time, like Git uses. Yes, I am aware |
|
4f5533b…
|
drh
|
642 |
that the underlying implementation of Git has pointers going from child |
|
4f5533b…
|
drh
|
643 |
to parent, and thus must necessarily go backwards in time. Fossil |
|
4f5533b…
|
drh
|
644 |
has the same pointers. But just because the *implementation* |
|
4f5533b…
|
drh
|
645 |
points backwards in time does not mean that the *user interface* |
|
4f5533b…
|
drh
|
646 |
needs to do the same. Fossil flips those pointers around so that |
|
4f5533b…
|
drh
|
647 |
they make more sense from the perspective of the human reader. |
|
4f5533b…
|
drh
|
648 |
|
|
4f5533b…
|
drh
|
649 |
1. **Fossil implements some unix-like shell commands to use as |
|
4f5533b…
|
drh
|
650 |
substitutes on systems that don't have them or that have inferior |
|
4f5533b…
|
drh
|
651 |
implementations.**<p> |
|
4f5533b…
|
drh
|
652 |
For example the "fossil system ls" command works like the standard |
|
4f5533b…
|
drh
|
653 |
"ls" command on unix. It doesn't support all the options that a typical |
|
4f5533b…
|
drh
|
654 |
"ls" implementation supports on Linux, but it is still way better than |
|
4f5533b…
|
drh
|
655 |
having to run "dir". Other substitute commands include |
|
4f5533b…
|
drh
|
656 |
"date", "pwd", "stty", "unzip", "which", and "zip". Probably |
|
4f5533b…
|
drh
|
657 |
more will be added as needs arise. Having ready access to these |
|
4f5533b…
|
drh
|
658 |
commands built into the standalone Fossil binary makes working on |
|
4f5533b…
|
drh
|
659 |
non-Linux platforms more comfortable for unix geeks, and saves having |
|
4f5533b…
|
drh
|
660 |
to hunt around and install system-specific alternatives. |
|
4f5533b…
|
drh
|
661 |
|
|
d494477…
|
danield
|
662 |
1. **Fossil can copy all uncommitted changes from a checkout on a |
|
4f5533b…
|
drh
|
663 |
remote system over to a checkout on the local machine.**<p> |
|
4f5533b…
|
drh
|
664 |
The command is [fossil patch pull](/help/patch). It contacts the |
|
4f5533b…
|
drh
|
665 |
remote system via SSH, updates its local checkout to the same baseline |
|
4f5533b…
|
drh
|
666 |
as is found on the remote, then pulls over a minimal set of diffs and |
|
4f5533b…
|
drh
|
667 |
applies them.<p> |
|
4f5533b…
|
drh
|
668 |
This is very useful in pre-commit testing. For example, if you have |
|
4f5533b…
|
drh
|
669 |
a big change on your desktop, and you want to test it before |
|
4f5533b…
|
drh
|
670 |
committing, on multiple platforms, you can ssh over to those other |
|
4f5533b…
|
drh
|
671 |
platforms and run "fossil patch pull ... && make test". When working |
|
4f5533b…
|
drh
|
672 |
on SQLite, I will typically do that on a remote Mac, a remote |
|
4f5533b…
|
drh
|
673 |
Win11 machine, and on a 32-core remote Linux machine that runs |
|
4f5533b…
|
drh
|
674 |
faster than my desktop. |
|
4f5533b…
|
drh
|
675 |
|
|
4f5533b…
|
drh
|
676 |
1. **Fossil can push uncommitted changes to a checkout on another |
|
4f5533b…
|
drh
|
677 |
machine.**<p> |
|
4f5533b…
|
drh
|
678 |
This is the same as the previous but in reverse. It is used, for |
|
4f5533b…
|
drh
|
679 |
example, to push proposed changes up to a secure sandbox to be |
|
4f5533b…
|
drh
|
680 |
reviewed by Claude/Codex/Copilot prior to commit. The sandbox is |
|
4f5533b…
|
drh
|
681 |
not able to pull, for security reasons, but it can accept a push. |
|
4f5533b…
|
drh
|
682 |
|
|
4f5533b…
|
drh
|
683 |
1. **Fossil lets you set up aliases for remote checkouts with which |
|
4f5533b…
|
drh
|
684 |
you commonly push or pull.**<p> |
|
4f5533b…
|
drh
|
685 |
My desktop is named "r21" and I normally do SQLite development |
|
4f5533b…
|
drh
|
686 |
work in the directory ~/sqlite/sqlite. If I have uncommitted |
|
4f5533b…
|
drh
|
687 |
changes that I want to test on Windows, I SSH over to the Win11 |
|
d494477…
|
danield
|
688 |
machine then run commands like:<pre> |
|
4f5533b…
|
drh
|
689 |
fossil patch pull r21:sqlite/sqlite -f |
|
4f5533b…
|
drh
|
690 |
make clean test</pre> |
|
4f5533b…
|
drh
|
691 |
But typing in "r21:sqlite/sqlite" can be tedious and error-prone, |
|
fa7f715…
|
brickviking
|
692 |
maybe not so much in this particular example but definitely the |
|
4f5533b…
|
drh
|
693 |
case for longer hostnames and subdirectory paths. Fortunately, |
|
4f5533b…
|
drh
|
694 |
Fossil allows us to define patch alias. On my Win11 machine, |
|
4f5533b…
|
drh
|
695 |
the alias named "@" is defined as "r21:sqlite/sqlite" and so I |
|
4f5533b…
|
drh
|
696 |
can get by with typing just:<pre> |
|
4f5533b…
|
drh
|
697 |
fossil patch pull @ -f</pre> |
|
4f5533b…
|
drh
|
698 |
(Aside: the -f option tells the command to first "revert" any |
|
4f5533b…
|
drh
|
699 |
uncommitted changes currently in the checkout prior to pulling |
|
4f5533b…
|
drh
|
700 |
over the new ones from r21:sqlite/sqlite. Without that option, the |
|
4f5533b…
|
drh
|
701 |
changes would be merged.) |
|
4f5533b…
|
drh
|
702 |
|
|
fa7f715…
|
brickviking
|
703 |
1. **Fossil allows you to view uncommitted changes on a remote machine |
|
4f5533b…
|
drh
|
704 |
in a web browser over SSH.**<p> |
|
4f5533b…
|
drh
|
705 |
Suppose you have some edits on a remote, headless machine and you |
|
4f5533b…
|
drh
|
706 |
would like to review those changes. Fossil lets you see those |
|
4f5533b…
|
drh
|
707 |
changes using a command like:<pre> |
|
4f5533b…
|
drh
|
708 |
fossil ui remote:path/to/checkout</pre> |
|
4f5533b…
|
drh
|
709 |
Substitute the name of your remote and the path to the checkout |
|
4f5533b…
|
drh
|
710 |
on the remote, of course.<p> |
|
4f5533b…
|
drh
|
711 |
The way this works is that Fossil opens an SSH connection to the |
|
4f5533b…
|
drh
|
712 |
remote machine that runs [fossil server](/help/server) on the |
|
d494477…
|
danield
|
713 |
remote and that tunnels the HTTP content back through the SSH connection |
|
4f5533b…
|
drh
|
714 |
to your desktop. At the same time, Fossil brings up your default |
|
4f5533b…
|
drh
|
715 |
web browser and points it to the local end of your SSH tunnel. |
|
4f5533b…
|
drh
|
716 |
That's a lot of network plumbing, but Fossil handles it all |
|
4f5533b…
|
drh
|
717 |
automatically, so that you the developer don't need to think about it. |
|
4f5533b…
|
drh
|
718 |
|
|
4f5533b…
|
drh
|
719 |
1. **Fossil lets you browse a repository on a remote, headless machine |
|
4f5533b…
|
drh
|
720 |
over an SSH connection.**<p> |
|
4f5533b…
|
drh
|
721 |
Just run "<tt>fossil ui remote:path/to/repository</tt>" (substituting |
|
4f5533b…
|
drh
|
722 |
in the name of the remote machine and the path to the repository you |
|
4f5533b…
|
drh
|
723 |
want to browse, of course) and Fossil will pop up a new page on your |
|
4f5533b…
|
drh
|
724 |
default web browser (on your desktop!) that is connected over an |
|
4f5533b…
|
drh
|
725 |
SSH tunnel to that remote repository. |
|
4f5533b…
|
drh
|
726 |
|
|
4f5533b…
|
drh
|
727 |
1. **Fossil lets you see all repositories on a remote, headless machine |
|
4f5533b…
|
drh
|
728 |
all at once, over SSH.**<p> |
|
4f5533b…
|
drh
|
729 |
The command is "<tt>fossil ui remote:/</tt>". Substitute the name of |
|
4f5533b…
|
drh
|
730 |
the remote machine, of course. The special pathname "/" indicates to |
|
4f5533b…
|
drh
|
731 |
Fossil that you want to view all of the repositories on that machine. |
|
4f5533b…
|
drh
|
732 |
It causes Fossil to consult the $HOME/.config/fossil.db file |
|
4f5533b…
|
drh
|
733 |
(or %LOCALAPPDATA%/_fossil on Windows) to find the locations of all |
|
4f5533b…
|
drh
|
734 |
repositories on the remote machine, then bring up a web page listing |
|
4f5533b…
|
drh
|
735 |
all those repositories. Links on that initial page let you explore |
|
4f5533b…
|
drh
|
736 |
deeper into the details of each repository. |
|
4f5533b…
|
drh
|
737 |
|
|
4f5533b…
|
drh
|
738 |
1. **The Fossil web interface supports multiple timeline formats, to |
|
4f5533b…
|
drh
|
739 |
accommodate personal tastes.**<p> |
|
d494477…
|
danield
|
740 |
The different formats are called "Views". The current repertoire |
|
4f5533b…
|
drh
|
741 |
includes "Modern", "Columnar", "Compact", "Simple", "Verbose", and |
|
4f5533b…
|
drh
|
742 |
"Classic". Users can select whichever format they want and their |
|
4f5533b…
|
drh
|
743 |
preference is remembered in a cookie. |
|
4f5533b…
|
drh
|
744 |
|
|
4f5533b…
|
drh
|
745 |
1. **A Fossil web server admin can set the default timeline format.**<p> |
|
4f5533b…
|
drh
|
746 |
Individual users have a lot of control over what their own timeline |
|
4f5533b…
|
drh
|
747 |
displays look like, but the repository administrator can set the |
|
4f5533b…
|
drh
|
748 |
default separately for each repository. |
|
4f5533b…
|
drh
|
749 |
|
|
4f5533b…
|
drh
|
750 |
1. **Fossil is open and transparent about the cookies that it uses.**<p> |
|
4f5533b…
|
drh
|
751 |
There are really only three: The login cookie if you are logged in, |
|
4f5533b…
|
drh
|
752 |
the robot cookie indicating that you have previously passed a captcha |
|
4f5533b…
|
drh
|
753 |
if you are not logged in, and the display preferences cookie. |
|
4f5533b…
|
drh
|
754 |
If you visit the |
|
4f5533b…
|
drh
|
755 |
[/cookies page](/cookies), Fossil will |
|
4f5533b…
|
drh
|
756 |
show you all the cookies it uses and it will decode them for you to |
|
d494477…
|
danield
|
757 |
show you exactly what they mean and what information they are holding, |
|
4f5533b…
|
drh
|
758 |
and Fossil will give you an opportunity to delete each cookie |
|
4f5533b…
|
drh
|
759 |
individually. |
|
4f5533b…
|
drh
|
760 |
|
|
4f5533b…
|
drh
|
761 |
1. **The Fossil web interface comes with a variety of "skins" built in.**<p> |
|
4f5533b…
|
drh
|
762 |
A skin determines the coloration and layout of Fossil web pages. |
|
4f5533b…
|
drh
|
763 |
Visit the [/skins page](/skins) to see all the available skins and |
|
4f5533b…
|
drh
|
764 |
which one is currently in use. |
|
4f5533b…
|
drh
|
765 |
|
|
4f5533b…
|
drh
|
766 |
1. **Individual users get to choose their favorite Fossil skin.**<p> |
|
4f5533b…
|
drh
|
767 |
The repository administrator sets the default skin, but if |
|
4f5533b…
|
drh
|
768 |
individual users do not like that choice, they can select a different |
|
4f5533b…
|
drh
|
769 |
skin and their choice is recorded in the display preferences cookie. |
|
4f5533b…
|
drh
|
770 |
|
|
d494477…
|
danield
|
771 |
1. **Repository administrators can create new custom skins.**<p> |
|
4f5533b…
|
drh
|
772 |
The current library of skins are mostly derived from custom skins that |
|
4f5533b…
|
drh
|
773 |
users of Fossil have created over the years and generously donated |
|
4f5533b…
|
drh
|
774 |
to the project. If none of the default skins work for you, you can |
|
4f5533b…
|
drh
|
775 |
create your own, perhaps using one of the existing skins as a template. |
|
4f5533b…
|
drh
|
776 |
|
|
696ae59…
|
drh
|
777 |
1. **Most Fossil web-interface skins include a detailed hamburger |
|
696ae59…
|
drh
|
778 |
(☰) menu.**<p> |
|
4f5533b…
|
drh
|
779 |
Clicking on the hamburger menu brings up a dropdown "site-map" |
|
4f5533b…
|
drh
|
780 |
page that lets you quickly navigate to the information you want. |
|
4f5533b…
|
drh
|
781 |
(Note: The presence and operation of the hamburger menu is a |
|
4f5533b…
|
drh
|
782 |
skin-specific feature and might not be available on every skin, but |
|
696ae59…
|
drh
|
783 |
it is used on the more popular skins.) Git itself has nothing like |
|
696ae59…
|
drh
|
784 |
this. The various Git forges sometimes have a limited hamburger |
|
696ae59…
|
drh
|
785 |
menu, that it is not nearly as complete. I find it difficult to |
|
696ae59…
|
drh
|
786 |
locate the screens I want without consulting an AI. |
|
4f5533b…
|
drh
|
787 |
|
|
4f5533b…
|
drh
|
788 |
1. **The Fossil web interface /sitemap page is responsive to |
|
4f5533b…
|
drh
|
789 |
individual user permissions and capabilities.**<p> |
|
4f5533b…
|
drh
|
790 |
Each user on the Fossil web interface, including the special |
|
4f5533b…
|
drh
|
791 |
user "nobody" used if no login is attempted, has |
|
4f5533b…
|
drh
|
792 |
"capabilities" assigned by the repository administrator. |
|
4f5533b…
|
drh
|
793 |
Depending on capabilities, some pages will display differently or |
|
4f5533b…
|
drh
|
794 |
will not display at all. Pages that a user does not have access |
|
4f5533b…
|
drh
|
795 |
to are automatically omitted from the [/sitemap page](/sitemap). |
|
4f5533b…
|
drh
|
796 |
|
|
4f5533b…
|
drh
|
797 |
1. **The Fossil web interface allows "anonymous" users.**<p> |
|
4f5533b…
|
drh
|
798 |
The "anonymous" user is a human (we think, because he has solved |
|
4f5533b…
|
drh
|
799 |
a captcha) but we do not know who. Users who do not want to |
|
4f5533b…
|
drh
|
800 |
identify themselves but who also don't want to be mistaken for |
|
4f5533b…
|
drh
|
801 |
a spider or robot can log in as anonymous. |
|
4f5533b…
|
drh
|
802 |
<p> |
|
4f5533b…
|
drh
|
803 |
The repository administrator has complete control over the capabilities |
|
4f5533b…
|
drh
|
804 |
of anonymous. Anonymous can be completely banned, or maybe given |
|
4f5533b…
|
drh
|
805 |
read-only capabilities, or given complete access, with lots of shade |
|
4f5533b…
|
drh
|
806 |
in between, according to the needs of the project. |
|
4f5533b…
|
drh
|
807 |
<p> |
|
4f5533b…
|
drh
|
808 |
The "anonymous" user is distinct from user "nobody" in that we |
|
4f5533b…
|
drh
|
809 |
believe anonymous is a real human, whereas user nobody is presumed |
|
4f5533b…
|
drh
|
810 |
to be a robot. The repository administrator also has complete control |
|
4f5533b…
|
drh
|
811 |
over the capabilities for user "nobody". |
|
4f5533b…
|
drh
|
812 |
|
|
4f5533b…
|
drh
|
813 |
1. **The Fossil web interface has lots of built-in defenses against |
|
4f5533b…
|
drh
|
814 |
abuse by spiders and robots.**<p> |
|
4f5533b…
|
drh
|
815 |
Sadly, the internet is rapidly devolving such that most HTTP requests |
|
4f5533b…
|
drh
|
816 |
now come from AI spiders trying to find training content, and/or robots |
|
4f5533b…
|
drh
|
817 |
looking for website vulnerabilities. The flood of requests can |
|
4f5533b…
|
drh
|
818 |
rapidly bog down an undefended server. Fossil includes a range of |
|
4f5533b…
|
drh
|
819 |
defenses against aggressive bots that help keep the server load and |
|
4f5533b…
|
drh
|
820 |
ISP costs down while still providing fast and detailed responses |
|
4f5533b…
|
drh
|
821 |
to real humans. This is an on-going battle. But Fossil is, at least, |
|
4f5533b…
|
drh
|
822 |
in the fight. Everything is easily configurable, via the web interface, |
|
4f5533b…
|
drh
|
823 |
by repository administrators. |
|
4f5533b…
|
drh
|
824 |
|
|
4f5533b…
|
drh
|
825 |
1. **The Fossil web interface includes a "security audit" page accessible |
|
d494477…
|
danield
|
826 |
to repository administrators.**<p> |
|
4f5533b…
|
drh
|
827 |
The security-audit pages give a succinct summary of how a repository |
|
4f5533b…
|
drh
|
828 |
web interface is configured, with an eye toward operational security. |
|
4f5533b…
|
drh
|
829 |
As with any full-featured web application, the Fossil web interface |
|
d494477…
|
danield
|
830 |
has a large number of settings. A common worry among system |
|
4f5533b…
|
drh
|
831 |
administrators is overlooking or omitting or misconfiguring some |
|
4f5533b…
|
drh
|
832 |
security-sensitive setting. The security-audit page is designed to |
|
4f5533b…
|
drh
|
833 |
reduce that worry. |
|
4f5533b…
|
drh
|
834 |
<p> |
|
4f5533b…
|
drh
|
835 |
The security-audit page shows at a glance how a repository web interface |
|
4f5533b…
|
drh
|
836 |
is set up, and raises alerts about any settings that are questionable |
|
4f5533b…
|
drh
|
837 |
or that might facilitate mischief. The page fits on a single screen |
|
4f5533b…
|
drh
|
838 |
with minimal or no scrolling. After standing up a new Fossil server, |
|
4f5533b…
|
drh
|
839 |
a quick glance at the security-audit page (accessible only to |
|
4f5533b…
|
drh
|
840 |
administrators) gives peace of mind that all is well and that nothing |
|
4f5533b…
|
drh
|
841 |
was overlooked. |
|
4f5533b…
|
drh
|
842 |
|
|
4f5533b…
|
drh
|
843 |
1. **The Fossil web interface menu bar can be customized.**<p> |
|
4f5533b…
|
drh
|
844 |
Repository administrators can customize the menu bar on the web |
|
4f5533b…
|
drh
|
845 |
interface. Individual items can be added or omitted from the |
|
4f5533b…
|
drh
|
846 |
menu bar based on user capabilities and/or whether or not the |
|
d494477…
|
danield
|
847 |
client is a phone or other narrow-screen mobile device, a standard |
|
4f5533b…
|
drh
|
848 |
desktop browser, or a wide-screen desktop browser. |
|
4f5533b…
|
drh
|
849 |
|
|
4f5533b…
|
drh
|
850 |
1. **The Fossil web interface sitemap can be customized.**<p> |
|
4f5533b…
|
drh
|
851 |
Repository administrators can add new entries to the |
|
4f5533b…
|
drh
|
852 |
[/sitemap](/sitemap) that are shown or omitted |
|
4f5533b…
|
drh
|
853 |
based on user capabilities. |
|
4f5533b…
|
drh
|
854 |
|
|
4f5533b…
|
drh
|
855 |
1. **The Fossil web interface can be augmented with auxiliary content |
|
4f5533b…
|
drh
|
856 |
and/or CGIs that exist outside of the repository.**<p> |
|
4f5533b…
|
drh
|
857 |
The auxiliary content or CGI result uses the same theme and skin as |
|
4f5533b…
|
drh
|
858 |
the default website, and blends right in. An example of this is |
|
4f5533b…
|
drh
|
859 |
the |
|
4f5533b…
|
drh
|
860 |
[SQLite Release Checklist](https://sqlite.org/src/ext/checklist/top/index). |
|
4f5533b…
|
drh
|
861 |
The SQLite Release Checklist is a CGI that is completely separate from |
|
4f5533b…
|
drh
|
862 |
Fossil, but appears to be integrated in the Fossil web interface. |
|
4f5533b…
|
drh
|
863 |
It uses the same skin and interface settings. But the content is |
|
4f5533b…
|
drh
|
864 |
created by a separate CGI program. Fossil passes down additional |
|
4f5533b…
|
drh
|
865 |
CGI variables to tell the CGI what the Fossil user name is and what |
|
4f5533b…
|
drh
|
866 |
capabilities that user has, among other things. In the case of the |
|
4f5533b…
|
drh
|
867 |
SQLite Release Checklist, those additional settings mean only project |
|
4f5533b…
|
drh
|
868 |
committers can make changes to the checklist (such as marking items |
|
4f5533b…
|
drh
|
869 |
as "done") and that the checklist is read-only for the general public. |
|
4f5533b…
|
drh
|
870 |
<p> |
|
4f5533b…
|
drh
|
871 |
Additional information about this advanced feature of Fossil |
|
4f5533b…
|
drh
|
872 |
can be seen at <https://fossil-scm.org/home/doc/trunk/www/serverext.wiki>. |
|
4f5533b…
|
drh
|
873 |
|
|
4f5533b…
|
drh
|
874 |
1. **Fossil makes convenience commands available to run its |
|
4f5533b…
|
drh
|
875 |
cryptographic hash algorithms (SHA1 and SHA3-256)**<p> |
|
4f5533b…
|
drh
|
876 |
The "<tt>fossil sha1sum FILE ...</tt>" and |
|
4f5533b…
|
drh
|
877 |
"<tt>fossil sha3sum FILE ...</tt>" commands will |
|
4f5533b…
|
drh
|
878 |
compute SHA1 and SHA3-256 hashes on files. These commands are not |
|
4f5533b…
|
drh
|
879 |
necessary to use Fossil, but they are still useful, and they are |
|
4f5533b…
|
drh
|
880 |
not commonly installed on non-Linux platforms. Fossil ensures that |
|
d494477…
|
danield
|
881 |
those hash functions are available wherever Fossil is available. |
|
4f5533b…
|
drh
|
882 |
|
|
4f5533b…
|
drh
|
883 |
1. **Fossil exposes its 3-way-diff algorithm for external use.**<p> |
|
4f5533b…
|
drh
|
884 |
The "<tt>fossil 3-way-merge ...</tt>" command works |
|
4f5533b…
|
drh
|
885 |
like the classic unix "diff3" command in that it does a merge |
|
4f5533b…
|
drh
|
886 |
of two variants of a file given a common ancestor. This is the |
|
4f5533b…
|
drh
|
887 |
exact same algorithm that Fossil uses to compute merges internally, |
|
4f5533b…
|
drh
|
888 |
simply exposed for external use. |
|
4f5533b…
|
drh
|
889 |
|
|
4f5533b…
|
drh
|
890 |
1. **On a merge conflict, Fossil shows the conflicting inputs just |
|
4f5533b…
|
drh
|
891 |
like other merge algorithms, but it also shows a suggested conflict |
|
4f5533b…
|
drh
|
892 |
resolution.**<p> |
|
4f5533b…
|
drh
|
893 |
The suggested conflict resolution is not always correct, but it is |
|
4f5533b…
|
drh
|
894 |
sometimes, and its presence often makes resolving merge conflicts |
|
4f5533b…
|
drh
|
895 |
simpler. |
|
4f5533b…
|
drh
|
896 |
|
|
4f5533b…
|
drh
|
897 |
1. **Fossil supports single sign-in when serving multiple repositories |
|
4f5533b…
|
drh
|
898 |
from the same host computer.**<p> |
|
4f5533b…
|
drh
|
899 |
If you have a server that is hosting Fossil web interfaces for |
|
4f5533b…
|
drh
|
900 |
multiple repositories, those repositories can be interconnected |
|
4f5533b…
|
drh
|
901 |
into a common "login group" such that when a user logs into one |
|
4f5533b…
|
drh
|
902 |
repository web interface, he is also automatically logged into |
|
4f5533b…
|
drh
|
903 |
all other repositories in that login graph that hold the same |
|
4f5533b…
|
drh
|
904 |
username. Furthermore, if the user |
|
4f5533b…
|
drh
|
905 |
changes his password on one repository, it is automatically changed |
|
4f5533b…
|
drh
|
906 |
on all the others within that login group. |
|
4f5533b…
|
drh
|
907 |
|
|
4f5533b…
|
drh
|
908 |
1. **Experts can browse low-level details of a Fossil repository |
|
4f5533b…
|
drh
|
909 |
using SQL.**<p> |
|
4f5533b…
|
drh
|
910 |
A Fossil repository is just an SQLite database file. Low-level content |
|
4f5533b…
|
drh
|
911 |
of that database file can be viewed and even changed using ordinary |
|
4f5533b…
|
drh
|
912 |
SQL and the "<tt>fossil sql</tt>" command. The "fossil sql" |
|
4f5533b…
|
drh
|
913 |
command brings up a standard SQLite command-line shell, already |
|
4f5533b…
|
drh
|
914 |
connected to the repository database, and extended to include extra |
|
4f5533b…
|
drh
|
915 |
functions (including table-valued functions) to help interpret the |
|
4f5533b…
|
drh
|
916 |
low-level content of the repository. This feature is not needed nor |
|
4f5533b…
|
drh
|
917 |
recommended for the average user. However, if you want to learn more |
|
4f5533b…
|
drh
|
918 |
about the inner workings of Fossil, or if you want to generate some |
|
4f5533b…
|
drh
|
919 |
custom reports about a repository, or if you are extending or |
|
4f5533b…
|
drh
|
920 |
troubleshooting Fossil, the SQL interface is a great tool. |
|
4f5533b…
|
drh
|
921 |
|
|
4f5533b…
|
drh
|
922 |
1. **The underlying artifacts of a Fossil repository are well-documented, |
|
4f5533b…
|
drh
|
923 |
human-readable, and human-understandable.**<p> |
|
4f5533b…
|
drh
|
924 |
A Fossil repository is an SQLite database file, but not every SQLite |
|
4f5533b…
|
drh
|
925 |
database file is a Fossil repository. Fossil repositories store |
|
4f5533b…
|
drh
|
926 |
"artifacts" in a very particular format. See |
|
4f5533b…
|
drh
|
927 |
<https://fossil-scm.org/home/doc/trunk/www/fileformat.wiki> for |
|
4f5533b…
|
drh
|
928 |
the details of that format. |
|
4f5533b…
|
drh
|
929 |
<p> |
|
4f5533b…
|
drh
|
930 |
This underlying format is text-only. It is designed to be easily |
|
4f5533b…
|
drh
|
931 |
parsed and interpreted by programs written in any language. It is |
|
4f5533b…
|
drh
|
932 |
designed to be easily understood by humans, even humans not yet born. |
|
4f5533b…
|
drh
|
933 |
Many of the low-level artifact formats for Git, in contrast, are |
|
4f5533b…
|
drh
|
934 |
binary and are only thinly documented. The only sure way to understand |
|
4f5533b…
|
drh
|
935 |
the low-level Git format is, in my experience, to read the Git source |
|
4f5533b…
|
drh
|
936 |
code. |
|
4f5533b…
|
drh
|
937 |
|
|
4f5533b…
|
drh
|
938 |
1. **The Fossil web interface has a "This Day In History" page.**<p> |
|
4f5533b…
|
drh
|
939 |
See that page for [Fossil](/thisdayinhistory) or |
|
4f5533b…
|
drh
|
940 |
[SQLite](https://sqlite.org/src/thisdayinhistory). |
|
4f5533b…
|
drh
|
941 |
The page shows multiple timeline snippets from various |
|
4f5533b…
|
drh
|
942 |
days in the past: 1, 2, 5, 10, 15, 20 years ago. |
|
4f5533b…
|
drh
|
943 |
<p> |
|
4f5533b…
|
drh
|
944 |
This is something of a vanity page. It is difficult to describe a |
|
4f5533b…
|
drh
|
945 |
real business need for this information. But the page does jog old |
|
4f5533b…
|
drh
|
946 |
memories and helps developers keep perspective on how a project has |
|
4f5533b…
|
drh
|
947 |
changed through the years. |
|
4f5533b…
|
drh
|
948 |
<p> |
|
d494477…
|
danield
|
949 |
The existence of this page illustrates how the |
|
d494477…
|
danield
|
950 |
robust and modular design of the Fossil implementation |
|
d494477…
|
danield
|
951 |
facilitates custom modifications that involve very little new code. |
|
4f5533b…
|
drh
|
952 |
|
|
4f5533b…
|
drh
|
953 |
1. **Fossil allows you to update your current checkout even if it |
|
4f5533b…
|
drh
|
954 |
contains uncommitted changes.**<p> |
|
4f5533b…
|
drh
|
955 |
This is a very common idiom in Fossil: You are working on changes |
|
4f5533b…
|
drh
|
956 |
and somebody commits ahead of you. You run |
|
4f5533b…
|
drh
|
957 |
"<tt>fossil up</tt>" ("up" is short for "update") and the new |
|
d494477…
|
danield
|
958 |
external changes are merged into your own uncommitted changes. You |
|
4f5533b…
|
drh
|
959 |
continue working. |
|
4f5533b…
|
drh
|
960 |
<p> |
|
4f5533b…
|
drh
|
961 |
Doing this in Git appears to require multiple commands (or maybe |
|
4f5533b…
|
drh
|
962 |
just one command with multiple verbose options) to interact with |
|
4f5533b…
|
drh
|
963 |
the stash and to rebase your changes. |
|
4f5533b…
|
drh
|
964 |
|
|
4f5533b…
|
drh
|
965 |
1. **Fossil lets you undo an update.**<p> |
|
4f5533b…
|
drh
|
966 |
If you run "<tt>fossil up</tt>" on a checkout that contains |
|
4f5533b…
|
drh
|
967 |
uncommitted changes, and the update does not go well (for example, |
|
4f5533b…
|
drh
|
968 |
if there are a lot of merge conflicts) you can back out the update |
|
4f5533b…
|
drh
|
969 |
by running "<tt>fossil undo</tt>". |
|
4f5533b…
|
drh
|
970 |
<p> |
|
4f5533b…
|
drh
|
971 |
The need for this does not arise often, because |
|
4f5533b…
|
drh
|
972 |
"<tt>fossil up</tt>" normally just works. But the ability to |
|
4f5533b…
|
drh
|
973 |
undo is a nice safety-net for the rare cases when the update goes awry. |
|
4f5533b…
|
drh
|
974 |
|
|
4f5533b…
|
drh
|
975 |
1. **Fossil warns you if you try to commit and somebody else has |
|
4f5533b…
|
drh
|
976 |
committed ahead of you.**<p> |
|
4f5533b…
|
drh
|
977 |
You can then run "<tt>fossil up</tt>" and then retest and retry. |
|
4f5533b…
|
drh
|
978 |
Or you can override the warning and force Fossil to commit anyhow, |
|
4f5533b…
|
drh
|
979 |
thus forking the branch. Either way, |
|
4f5533b…
|
drh
|
980 |
you enter the commit with more knowledge about what is happening, |
|
4f5533b…
|
drh
|
981 |
and thus improved situational awareness. |
|
4f5533b…
|
drh
|
982 |
|
|
4f5533b…
|
drh
|
983 |
1. **Every Fossil project has a unique identifier**.<p> |
|
4f5533b…
|
drh
|
984 |
When a new repository is created, the unique identifier is created |
|
4f5533b…
|
drh
|
985 |
and stored in the repository. That identifier is called the |
|
4f5533b…
|
drh
|
986 |
"project code". The identifier is copied with every |
|
4f5533b…
|
drh
|
987 |
clone. (Uniqueness is probabilistic. The identifier simply contains |
|
4f5533b…
|
drh
|
988 |
enough of high-quality randomness to make it unlikely that there |
|
4f5533b…
|
drh
|
989 |
will ever be a collision.) |
|
4f5533b…
|
drh
|
990 |
<p> |
|
4f5533b…
|
drh
|
991 |
It is not possible in Fossil to push to or pull from a repository |
|
4f5533b…
|
drh
|
992 |
with the wrong project code. Thus you cannot contaminate one |
|
4f5533b…
|
drh
|
993 |
project with code from another simply by specifying the wrong |
|
4f5533b…
|
drh
|
994 |
remote and adding the --force flag, as is apparently possible in Git. |
|
4f5533b…
|
drh
|
995 |
|
|
4f5533b…
|
drh
|
996 |
1. **Each Fossil repository keeps an audit trail.**<p> |
|
4f5533b…
|
drh
|
997 |
For each new artifact received into a Fossil repository, by push or |
|
4f5533b…
|
drh
|
998 |
pull, or by direct commit from the command line, Fossil records a |
|
4f5533b…
|
drh
|
999 |
timestamp, username, and an IP address (where applicable) for |
|
fa7f715…
|
brickviking
|
1000 |
that artifact. If harmful or malicious content is added to |
|
4f5533b…
|
drh
|
1001 |
a repository, the repository administrator has the capability to |
|
4f5533b…
|
drh
|
1002 |
trace that content back to its source, so that appropriate |
|
4f5533b…
|
drh
|
1003 |
sanctions can be applied to the malefactor. |
|
4f5533b…
|
drh
|
1004 |
|
|
4f5533b…
|
drh
|
1005 |
1. **Fossil stores content in a power-safe ACID database.**<p> |
|
4f5533b…
|
drh
|
1006 |
The repository content cannot be corrupted by a program crash, |
|
4f5533b…
|
drh
|
1007 |
system crash, or unexpected power loss. The repository moves |
|
4f5533b…
|
drh
|
1008 |
from one consistent state to another, atomically. This helps |
|
4f5533b…
|
drh
|
1009 |
ensure that the resources stored in Fossil are kept safe, |
|
4f5533b…
|
drh
|
1010 |
even if the Fossil implementation itself contains bugs. |
|
4f5533b…
|
drh
|
1011 |
<p> |
|
4f5533b…
|
drh
|
1012 |
The underlying database engine used by Fossil is SQLite, of course. |
|
4f5533b…
|
drh
|
1013 |
<p> |
|
4f5533b…
|
drh
|
1014 |
Git also claims to be transactional. However, because Git does |
|
4f5533b…
|
drh
|
1015 |
not use a separate database engine, the transactional integrity |
|
4f5533b…
|
drh
|
1016 |
of Git depends entirely upon the correctness of the Git code |
|
4f5533b…
|
drh
|
1017 |
itself. Git is thus far more sensitive to implementation errors. |
|
4f5533b…
|
drh
|
1018 |
|
|
4f5533b…
|
drh
|
1019 |
1. **Fossil supports a built-in graphical diff tool.**<p> |
|
4f5533b…
|
drh
|
1020 |
Running "<tt>fossil gdiff</tt>" show the currently |
|
4f5533b…
|
drh
|
1021 |
uncommitted changes in a Tk-based graphical display. This |
|
4f5533b…
|
drh
|
1022 |
is built into Fossil and does not require any external tools |
|
4f5533b…
|
drh
|
1023 |
(though it does require Tcl/Tk). Git requires external tooling |
|
4f5533b…
|
drh
|
1024 |
in order to do the same. |
|
4f5533b…
|
drh
|
1025 |
|
|
4f5533b…
|
drh
|
1026 |
1. **Fossil supports showing diffs in a web browser.**<p> |
|
4f5533b…
|
drh
|
1027 |
Adding the "<tt>-b</tt>" or "<tt>-by</tt>" option to any Fossil |
|
4f5533b…
|
drh
|
1028 |
diff command causes that diff to be rendered as a new page in |
|
4f5533b…
|
drh
|
1029 |
the users default web browser. Git does not have any such |
|
4f5533b…
|
drh
|
1030 |
capability, even with the aid of external programs, as far as |
|
4f5533b…
|
drh
|
1031 |
I am aware. |
|
4f5533b…
|
drh
|
1032 |
|
|
4f5533b…
|
drh
|
1033 |
1. **The Fossil web interface provides a captcha-gated method to download |
|
d494477…
|
danield
|
1034 |
tarballs and ZIP archives for any check-in.**<p> |
|
4f5533b…
|
drh
|
1035 |
See, for example, <https://sqlite.org/src/rchvdwnld/20260704>. |
|
d494477…
|
danield
|
1036 |
That link provides access to the last check-in for the day 2026-07-04. |
|
4f5533b…
|
drh
|
1037 |
The last element of the patch can be any hash prefix, timestamp prefix, |
|
d494477…
|
danield
|
1038 |
or tag that references a check-in.<p> |
|
d494477…
|
danield
|
1039 |
Tarballs and ZIP archives are expensive to compute, not because Fossil |
|
fa7f715…
|
brickviking
|
1040 |
has trouble assembling the content, |
|
4f5533b…
|
drh
|
1041 |
but rather because the result must be run through zlib compression. |
|
4f5533b…
|
drh
|
1042 |
When computing a new archive, almost all of the CPU time is spent |
|
4f5533b…
|
drh
|
1043 |
inside of the zlib compression library. |
|
4f5533b…
|
drh
|
1044 |
For an SQLite-size tarball, the zlib compression alone can take as |
|
4f5533b…
|
drh
|
1045 |
much as 10 seconds of CPU time. If the tarball/ZIP-archive download |
|
4f5533b…
|
drh
|
1046 |
link is not protected by a captcha, multiple spiders will attempt to |
|
4f5533b…
|
drh
|
1047 |
download every possible tarball and ZIP archive, multiple times per |
|
4f5533b…
|
drh
|
1048 |
day, bringing your server to its knees. |
|
4f5533b…
|
drh
|
1049 |
|
|
d494477…
|
danield
|
1050 |
1. **Repository administrators can create a cache of recently downloaded |
|
4f5533b…
|
drh
|
1051 |
tarballs and ZIP archives**<p> |
|
4f5533b…
|
drh
|
1052 |
That way, if there are common downloads (like the most recent release) |
|
4f5533b…
|
drh
|
1053 |
the archive does not get recomputed from scratch with each download. |
|
d494477…
|
danield
|
1054 |
A download of a cached archive file is fast. |
|
4f5533b…
|
drh
|
1055 |
The size of the cache is configurable by the repository administrator. |
|
4f5533b…
|
drh
|
1056 |
|
|
4f5533b…
|
drh
|
1057 |
1. **The Fossil web interface has a "Repository Status" page that shows |
|
4f5533b…
|
drh
|
1058 |
interesting and useful facts about the repository being served.**<p> |
|
4f5533b…
|
drh
|
1059 |
See the [stat page for Fossil](/stat) for example. |
|
4f5533b…
|
drh
|
1060 |
|
|
4f5533b…
|
drh
|
1061 |
1. **The Fossil web interface easily shows all of the contributors to |
|
4f5533b…
|
drh
|
1062 |
a project, and the number of changes they have committed.**<p> |
|
4f5533b…
|
drh
|
1063 |
See <https://fossil-scm.org/home/reports> for that report about |
|
4f5533b…
|
drh
|
1064 |
Fossil itself. |
|
4f5533b…
|
drh
|
1065 |
Many other reports can be generated from the same page by selecting |
|
4f5533b…
|
drh
|
1066 |
different options from the pull-down menus at the top. |
|
d494477…
|
danield
|
1067 |
<p>The page is captcha-gated since it is a magnet for spiders. |
|
4f5533b…
|
drh
|
1068 |
|
|
4f5533b…
|
drh
|
1069 |
1. **The Fossil source code is easy to enhance with new web pages and |
|
4f5533b…
|
drh
|
1070 |
commands.**<p> |
|
d494477…
|
danield
|
1071 |
The design of the Fossil implementation makes it easy to extend with |
|
4f5533b…
|
drh
|
1072 |
new capabilities as needs arise. |
|
4f5533b…
|
drh
|
1073 |
<ul type="disk"> |
|
84ced25…
|
drh
|
1074 |
<li> The code is simple C89. |
|
84ced25…
|
drh
|
1075 |
<li> Each command or web page runs as a separate process which |
|
4f5533b…
|
drh
|
1076 |
exits when the action completes, so minor memory leaks are not |
|
4f5533b…
|
drh
|
1077 |
a concern. |
|
84ced25…
|
drh
|
1078 |
<li> Preprocessors run over the Fossil source code before the |
|
84ced25…
|
drh
|
1079 |
code reaches the C compiler to verify |
|
84ced25…
|
drh
|
1080 |
that there are no SQL injections nor XSS vulnerabilities. |
|
84ced25…
|
drh
|
1081 |
<li> New commands and webpages can be added simply by adding a new |
|
4f5533b…
|
drh
|
1082 |
procedure to do the necessary computation. The name, properties, |
|
4f5533b…
|
drh
|
1083 |
and documentation for the command or webpage are extracted from |
|
4f5533b…
|
drh
|
1084 |
specially formatted comments just prior to the procedure. |
|
4f5533b…
|
drh
|
1085 |
</ul><p> |
|
4f5533b…
|
drh
|
1086 |
The ease with which Fossil can be enhanced is part of the reason why |
|
84ced25…
|
drh
|
1087 |
it has picked up so many useful features and has become so |
|
84ced25…
|
drh
|
1088 |
powerful over its 19-year history. |
|
4f5533b…
|
drh
|
1089 |
|
|
4f5533b…
|
drh
|
1090 |
## Conclusion |
|
4f5533b…
|
drh
|
1091 |
|
|
4f5533b…
|
drh
|
1092 |
There are more reasons to prefer Fossil over Git, but |
|
d494477…
|
danield
|
1093 |
I think 101 are sufficient to prove my point. |