summaryrefslogtreecommitdiffstats
path: root/www/whynotgit.html
blob: 02ef25e613b2f14c2a2ec7bd2b1b92f521a16590 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
<!DOCTYPE html>
<html><head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link href="sqlite.css" rel="stylesheet">
<title>Why SQLite Does Not Use Git</title>
<!-- path= -->
</head>
<body>
<div class=nosearch>
<a href="index.html">
<img class="logo" src="images/sqlite370_banner.gif" alt="SQLite" border="0">
</a>
<div><!-- IE hack to prevent disappearing logo --></div>
<div class="tagline desktoponly">
Small. Fast. Reliable.<br>Choose any three.
</div>
<div class="menu mainmenu">
<ul>
<li><a href="index.html">Home</a>
<li class='mobileonly'><a href="javascript:void(0)" onclick='toggle_div("submenu")'>Menu</a>
<li class='wideonly'><a href='about.html'>About</a>
<li class='desktoponly'><a href="docs.html">Documentation</a>
<li class='desktoponly'><a href="download.html">Download</a>
<li class='wideonly'><a href='copyright.html'>License</a>
<li class='desktoponly'><a href="support.html">Support</a>
<li class='desktoponly'><a href="prosupport.html">Purchase</a>
<li class='search' id='search_menubutton'>
<a href="javascript:void(0)" onclick='toggle_search()'>Search</a>
</ul>
</div>
<div class="menu submenu" id="submenu">
<ul>
<li><a href='about.html'>About</a>
<li><a href='docs.html'>Documentation</a>
<li><a href='download.html'>Download</a>
<li><a href='support.html'>Support</a>
<li><a href='prosupport.html'>Purchase</a>
</ul>
</div>
<div class="searchmenu" id="searchmenu">
<form method="GET" action="search">
<select name="s" id="searchtype">
<option value="d">Search Documentation</option>
<option value="c">Search Changelog</option>
</select>
<input type="text" name="q" id="searchbox" value="">
<input type="submit" value="Go">
</form>
</div>
</div>
<script>
function toggle_div(nm) {
var w = document.getElementById(nm);
if( w.style.display=="block" ){
w.style.display = "none";
}else{
w.style.display = "block";
}
}
function toggle_search() {
var w = document.getElementById("searchmenu");
if( w.style.display=="block" ){
w.style.display = "none";
} else {
w.style.display = "block";
setTimeout(function(){
document.getElementById("searchbox").focus()
}, 30);
}
}
function div_off(nm){document.getElementById(nm).style.display="none";}
window.onbeforeunload = function(e){div_off("submenu");}
/* Disable the Search feature if we are not operating from CGI, since */
/* Search is accomplished using CGI and will not work without it. */
if( !location.origin || !location.origin.match || !location.origin.match(/http/) ){
document.getElementById("search_menubutton").style.display = "none";
}
/* Used by the Hide/Show button beside syntax diagrams, to toggle the */
function hideorshow(btn,obj){
var x = document.getElementById(obj);
var b = document.getElementById(btn);
if( x.style.display!='none' ){
x.style.display = 'none';
b.innerHTML='show';
}else{
x.style.display = '';
b.innerHTML='hide';
}
return false;
}
var antiRobot = 0;
function antiRobotGo(){
if( antiRobot!=3 ) return;
antiRobot = 7;
var j = document.getElementById("mtimelink");
if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href");
}
function antiRobotDefense(){
document.body.onmousedown=function(){
antiRobot |= 2;
antiRobotGo();
document.body.onmousedown=null;
}
document.body.onmousemove=function(){
antiRobot |= 2;
antiRobotGo();
document.body.onmousemove=null;
}
setTimeout(function(){
antiRobot |= 1;
antiRobotGo();
}, 100)
antiRobotGo();
}
antiRobotDefense();
</script>
<div class=fancy>
<div class=nosearch>
<div class="fancy_title">
Why SQLite Does Not Use Git
</div>
<div class="fancy_toc">
<a onclick="toggle_toc()">
<span class="fancy_toc_mark" id="toc_mk">&#x25ba;</span>
Table Of Contents
</a>
<div id="toc_sub"><div class="fancy-toc1"><a href="#introduction">1. Introduction</a></div>
<div class="fancy-toc2"><a href="#edits">1.1. Edits</a></div>
<div class="fancy-toc1"><a href="#a_few_reasons_why_sqlite_does_not_use_git">2. A Few Reasons Why SQLite Does Not Use Git</a></div>
<div class="fancy-toc2"><a href="#git_does_not_provide_good_situational_awareness">2.1. Git does not provide good situational awareness</a></div>
<div class="fancy-toc2"><a href="#git_makes_it_difficult_to_find_successors_descendants_of_a_check_in">2.2. Git makes it difficult to find successors (descendants)
of a check-in</a></div>
<div class="fancy-toc2"><a href="#the_mental_model_for_git_is_needlessly_complex">2.3. The mental model for Git is needlessly complex</a></div>
<div class="fancy-toc2"><a href="#git_does_not_track_historical_branch_names">2.4. Git does not track historical branch names</a></div>
<div class="fancy-toc2"><a href="#git_requires_more_administrative_support">2.5. Git requires more administrative support</a></div>
<div class="fancy-toc2"><a href="#git_provides_a_poor_user_experience">2.6. Git provides a poor user experience</a></div>
<div class="fancy-toc1"><a href="#a_git_user_s_guide_to_accessing_sqlite_source_code">3. A Git-User's Guide To Accessing SQLite Source Code</a></div>
<div class="fancy-toc2"><a href="#the_official_github_mirror">3.1. The Official GitHub Mirror</a></div>
<div class="fancy-toc2"><a href="#web_access">3.2. Web Access</a></div>
<div class="fancy-toc2"><a href="#fossil_access">3.3. Fossil Access</a></div>
<div class="fancy-toc2"><a href="#verifying_source_code_integrity">3.4. Verifying Source Code Integrity</a></div>
<div class="fancy-toc1"><a href="#see_also">4. See Also</a></div>
</div>
</div>
<script>
function toggle_toc(){
var sub = document.getElementById("toc_sub")
var mk = document.getElementById("toc_mk")
if( sub.style.display!="block" ){
sub.style.display = "block";
mk.innerHTML = "&#x25bc;";
} else {
sub.style.display = "none";
mk.innerHTML = "&#x25ba;";
}
}
</script>
</div>




<h1 id="introduction"><span>1. </span>Introduction</h1>

<p>
SQLite does not use the
<a href="https://git-scm.org">Git</a> version control system.
SQLite uses
<a href="https://fossil-scm.org/">Fossil</a> instead, which is a
version control system that was specifically designed
and written to support SQLite.

</p><p>
People often wonder why SQLite does not use the
<a href="https://git-scm.org">Git</a> version control system like everybody
else.
This article attempts to answer that question.  Also,
in <a href="#getthecode">section 3</a>,
this article provides hints to Git users
about how they can easily access the SQLite source code.

</p><p>
This article is <u>not</u> a comparison between Fossil
and Git.  See
<a href="https://fossil-scm.org/fossil/doc/trunk/www/fossil-v-git.wiki">https://fossil-scm.org/fossil/doc/trunk/www/fossil-v-git.wiki</a>
for one comparison of the two systems.  Other third-party
comparisons are available as well - use a search engine to find them.

</p><p>
This article is <u>not</u> advocating that you switch your projects
away from Git.  You can use whatever version control system you want.
If you are perfectly happy with Git, then by all means keep using
Git.  But, if Git is not working well for you or you are wondering
if it can be improved or if there is something better,
then maybe try to understand the perspectives presented below.
Use the insights thus obtained to find or write a different and
better version control system, or to just make
improvements to Git itself.

</p><h2 id="edits"><span>1.1. </span>Edits</h2>

<p>
This article has been revised multiple times in an attempt
to improve clarity, address concerns and misgivings,
and to fix errors.
The complete edit history for this document can be seen at
<a href="https://sqlite.org/docsrc/finfo/pages/whynotgit.in">https://sqlite.org/docsrc/finfo/pages/whynotgit.in</a>.
(Usage hint: Click on any two nodes of the graph for a diff.
BTW, are there any Git web interfaces that offers a similar
capability?)

</p><h1 id="a_few_reasons_why_sqlite_does_not_use_git"><span>2. </span>A Few Reasons Why SQLite Does Not Use Git</h1>

<h2 id="git_does_not_provide_good_situational_awareness"><span>2.1. </span>Git does not provide good situational awareness</h2>

<p>
When I want to see what has been happening on SQLite, I visit the
<a href="https://sqlite.org/src/timeline">timeline</a> and in a single
screen I see a summary of the latest changes, on all branches.
In a few clicks, I can drill down as much detail as I
want.  I can even do this from a phone.

</p><p>
GitHub and GitLab offer nothing comparable.  The closest I have
found is the <a href="https://github.com/sqlite/sqlite/network">network</a>,
which is slow to render (unless it is already cached), does not
offer nearly as much details, and scarcely works at all on mobile.
The <a href="https://github.com/sqlite/sqlite/commits/master">commits</a> view
of GitHub provides more detail, renders quickly,
and works on mobile, but only shows a single branch at a time,
so I cannot easily know if I've seen all of the recent changes.
And even if GitHub/GitLab did offer better interfaces, both are
third-party services.  They are not a core part of Git.  Hence,
using them introduces yet another dependency into the project.

</p><p>
I am told that Git users commonly install third-party graphical
viewers for Git, many of which do a better job of showing recent
activity on the project.  That is great, but these are still
more third-party applications that must be installed and
managed separately.  Many are platform-specific.  (One of the
better ones, <a href="https://gitup.co/">GitUp</a>, only works on Mac, for
example.)  All require that you first sync your local repository
then bring up their graphical interface on your desktop.  And
even with all that, I still cannot see what I typically want to
see without multiple clicks.  Checking on project status from
a phone while away from the office is not an option.

</p><h2 id="git_makes_it_difficult_to_find_successors_descendants_of_a_check_in"><span>2.2. </span>Git makes it difficult to find successors (descendants)
of a check-in</h2>

<p>
Git lets you look backwards in time, but not forwards.
Given some historical check-in, you can see what came before,
but it is challenging see what came next.

</p><p>
In contrast, Fossil offers helpful displays such as
<a href="https://sqlite.org/src/timeline?df=major-release">https://sqlite.org/src/timeline?df=major-release</a>
to show all check-ins that are derived from the most
recent major release.

</p><p>
</p><ul>
<li>
<a href="https://sqlite.org/src/timeline?df=major-release">
All SQLite check-ins derived from the most recent major release</a>
</li></ul>


<p>It is not impossible to find the descendants of a check-in
in Git.  It is merely difficult.  For example,
there is a
<a href="https://stackoverflow.com/questions/27960605/find-all-the-direct-descendants-of-a-given-commit#27962018">stackoverflow page</a>
showing the command sequence for finding the descendants of a check-in
in unix:

</p><div class="codeblock"><pre>git rev-list --all --parents | grep ".\{40\}.*<parent_sha1>.*" | awk '{print $1}'
</parent_sha1>
</pre></div>

<p>
But this is not the same thing.  The command above gives
a list of descendants without showing the branching structure, which
is important for understanding what happened.  And the command only works
if you have a local clone of the repository; finding the descendants of
a check-in is not something you can do with web interfaces such
as GitHub or GitLab.

</p><p>
This is not really about just finding the descendants of a check-in
from time to time.  The fact that descendants are readily available in
Fossil means that the information pervades the web pages provided by
Fossil.  One example: Every Fossil check-in information page
(<a href="https://www.sqlite.org/src/info/ec7addc87f97bcff">example</a>) shows
a small "Context" graph of the immediate predecessor and successors
to that check-in.  This helps the user maintain better situational
awareness, and it provides useful capabilities, such as the ability
to click forward to the next check-in within a sequence.  Another example:
Fossil easily shows the context around a specific check-in
(<a href="https://www.sqlite.org/src/timeline?c=2018-03-16&n=10">example</a>)
which again helps to promote situational awareness and a deeper
understanding of what is happening in the code.  There is a
<a href="https://fossil-scm.org/fossil/doc/trunk/www/webpage-ex.md">whole page of additional examples</a>
in the <a href="https://fossil-scm.org/fossil">Fossil documentation</a>.

</p><p>
All of the above is theoretically possible with Git, given the right extensions
and tools and using the right commands.  But it is not easy to do,
and so it rarely gets done.  Consequently, developers have less awareness
of what is happening in the code.

</p><h2 id="the_mental_model_for_git_is_needlessly_complex"><span>2.3. </span>The mental model for Git is needlessly complex</h2>

<p>
The complexity of Git
distracts attention from the software under development.  A user of Git
needs to keep all of the following in mind:
</p><ol type="a">
<li> The working directory
</li><li> The "index" or staging area
</li><li> The local head
</li><li> The local copy of the remote head
</li><li> The actual remote head
</li></ol>
<p>
Git has commands (and/or options on commands) for moving and
comparing content between all of these locations.

</p><p>In contrast,
Fossil users only need to think about their working directory and
the check-in they are working on.  That is 60% less distraction.
Every developer has a finite number of brain-cycles.  Fossil
requires fewer brain-cycles to operate, thus freeing up
intellectual resources to focus on the software under development.

</p><p>One user of both Git and Fossil
<a href="https://news.ycombinator.com/item?id=16806955">writes in HN</a>:

</p><blockquote><i>
Fossil gives me peace of mind that I have everything ... synced to
the server with a single command....
I never get this peace of mind with git.
</i></blockquote>

<h2 id="git_does_not_track_historical_branch_names"><span>2.4. </span>Git does not track historical branch names</h2>

<p>
Git keeps the complete DAG of the check-in sequence.  But branch
tags are local information that is not synced and not retained
once a branch closes.
This makes review of historical
branches tedious.

</p><p>
As an example, suppose a customer asks you:
"What ever became of that 'prefer-coroutine-sort-subquery' branch
from two years ago?"
You might try to answer by consulting the history in
your version control system, thusly:

</p><ul>
<li><b>GitHub:</b> <a href="https://github.com/sqlite/sqlite/commits/prefer-coroutine-sort-subquery">https://github.com/sqlite/sqlite/commits/prefer-coroutine-sort-subquery</a>
</li><li><b>Fossil:</b> <a href="https://sqlite.org/src/timeline?r=prefer-coroutine-sort-subquery">https://sqlite.org/src/timeline?r=prefer-coroutine-sort-subquery</a>
</li></ul>

<p>
The Fossil view clearly shows that the branch was eventually merged back into
trunk.  It shows where the branch started, and it shows two occasions where changes
on trunk were merged into the branch.  GitHub shows none of this.  In fact, the
GitHub display is mostly useless in trying to figure out what happened.

</p><p>
Many readers have recommended various third-party GUIs for Git that
might do a better job of showing historical development activity.  Maybe
some of them do work better than native Git and/or GitHub, though they
will all be hampered by the fact that Git does not preserve historical
branch names across syncs.  And even if those other tools are better,
the fact that it is necessary to go to a third-party tool to get the information
desired does not speak well of the core system.

</p><h2 id="git_requires_more_administrative_support"><span>2.5. </span>Git requires more administrative support</h2>

<p>
Git is complex software.
One needs an installer of some kind to put Git on a developer
workstation, or to upgrade to a newer version of Git.
Standing up a Git server is non-trivial, and so most developers
use a third-party service such as GitHub or GitLab,
and thus introduce additional dependencies.

</p><p>
In contrast, Fossil is a single standalone binary which is
installed by putting it on $PATH.  That one binary contains all
the functionality of core Git and also GitHub and/or GitLab.  It
manages a community server with wiki, bug tracking, and forums,
provides packaged downloads for consumers, login managements,
and so forth, with no extra software required.  Standing up a
community server for Fossil takes minutes.  And Fossil is efficient.
A Fossil server will run fine on a $5/month VPS or a Raspberry Pi,
whereas GitLab and similar require beefier hardware.

</p><p>
Less administration means that programmers spend more time working
on the software (SQLite in this case) and less time fussing with
the version control system.

</p><h2 id="git_provides_a_poor_user_experience"><span>2.6. </span>Git provides a poor user experience</h2>

<p>The following <a href="https://xkcd.com/1597/">https://xkcd.com/1597/</a> cartoon is an
exaggeration, yet hits close to home:

</p><p>
<img src="https://www.fossil-scm.org/fossil/doc/trunk/www/xkcd-git.gif">

</p><p>Let's be real.  Few people dispute that Git provides
a suboptimal user experience.  A lot of
the underlying implementation shows through into the user
interface.  The interface is so bad that there is even a
parody site that generates
<a href="https://git-man-page-generator.lokaltog.net/">fake git man pages</a>.

</p><p>Designing software is hard.  It takes a lot of focus.
A good version control system should provide the developer with
assistance, not frustration.  Git has gotten better in this
regard over the past decade, but it still has a long way to go.

<a name="getthecode"></a>
</p><h1 id="a_git_user_s_guide_to_accessing_sqlite_source_code"><span>3. </span>A Git-User's Guide To Accessing SQLite Source Code</h1>

<p>
If you are a devoted Git user, you can still easily access SQLite.
This section gives some hints on how to do so.

</p><h2 id="the_official_github_mirror"><span>3.1. </span>The Official GitHub Mirror</h2>

<p>
As of 2019-03-20, there is now an
<a href="https://github.com/sqlite/sqlite">official Git mirror</a> of the
SQLite sources on GitHub.

</p><p>The mirror is an incremental export of the
<a href="https://sqlite.org/src/timeline">canonical Fossil repository</a> for
SQLite.  A cron-job updates the GitHub repository once an hour.
This is a one-way, read-only code mirror.  No pull requests or
changes are accepted via GitHub.  The GitHub repository merely copies
the content from the Fossil repository.  All changes are input via
Fossil.

</p><p>
The hashes that identify check-ins and files on the Git mirror are
different from the hashes in Fossil.  There are many reasons for
this, chief among them that Fossil uses a SHA3-256 hash whereas
Git uses a SHA1 hash.  During export, the original Fossil hash for
each check-in is added as a footer to check-in comments.  To avoid
confusion, always use the original Fossil hash, not the Git hash,
when referring to SQLite check-ins.

</p><h2 id="web_access"><span>3.2. </span>Web Access</h2>

<p>
The <a href="https://sqlite.org/src/timeline">SQLite Fossil Repository</a> contains links
for downloading  a Tarball, ZIP Archive, or <a href="sqlar.html">SQLite Archive</a> for any
historical version of SQLite.  The URLs for these downloads are
simple and can be incorporated easily into automated tools.  The format is:

</p><blockquote>
<tt>https://sqlite.org/src/tarball/</tt><i>VERSION</i><tt>/sqlite.tar.gz</tt>
</blockquote>

<p>
Simply replace <i>VERSION</i> with some description of the version to be
downloaded.  The <i>VERSION</i> can be a prefix of the cryptographic hash
name of a specific check-in, or the name of a branch (in which case the
most recent version of the branch is fetched) or a tag for a specific
check-in like "version-3.23.1":

</p><blockquote>
<tt>https://sqlite.org/src/tarball/version-3.23.1/sqlite.tar.gz</tt>
</blockquote>


<p>To get the latest release, use "release"
for <i>VERSION</i>, like this:

</p><blockquote>
<tt>https://sqlite.org/src/tarball/release/sqlite.tar.gz</tt>
</blockquote>

<p>
To get the latest trunk check-in, us "trunk" for <i>VERSION</i>:

</p><blockquote>
<tt>https://sqlite.org/src/tarball/trunk/sqlite.tar.gz</tt>
</blockquote>

<p>
And so forth.
For ZIP archives and SQLite Archives, simply change the "/tarball/" element
into either "/zip/" or "/sqlar/", and maybe also change the name of the
download file to have a ".zip" or ".sqlar" suffix.

</p><h2 id="fossil_access"><span>3.3. </span>Fossil Access</h2>

<p>
Fossil is easy to install and use.  Here are the steps for unix.
(Windows is similar.)

</p><ol>
<li>
Download the self-contained Fossil executable from
<a href="https://fossil-scm.org/fossil/uv/download.html">https://fossil-scm.org/fossil/uv/download.html</a> and put the executable
somewhere on your $PATH.
</li><li><tt>mkdir ~/fossils</tt>
</li><li><tt>fossil clone https://sqlite.org/src ~/fossils/sqlite.fossil</tt>
</li><li><tt>mkdir ~/sqlite; cd ~/sqlite</tt>
</li><li><tt>fossil open ~/fossils/sqlite.fossil</tt>
</li></ol>

<p>
At this point you are ready to type "<tt>./configure; make</tt>"
(or on Windows with MSVC, "<tt>nmake /f Makefile.msc</tt>").

</p><p>
To change your checkout to a different version of Fossil use
the "update" command:

</p><blockquote>
<tt>fossil update </tt><i>VERSION</i>
</blockquote>

<p>
Use "trunk" for <i>VERSION</i> to get the latest trunk version of SQLite.
Or use a prefix of a cryptographic hash name, or the name of some branch
or tag.  See
<a href="https://fossil-scm.org/fossil/doc/trunk/www/checkin_names.wiki">https://fossil-scm.org/fossil/doc/trunk/www/checkin_names.wiki</a> for more
suggestions on what names can be used for <i>VERSION</i>.

</p><p>
Use the "<tt>fossil ui</tt>" command from within the ~/sqlite checkout to
bring up a local copy of the website.

</p><p>
Additional documentation on Fossil can be found at
<a href="https://fossil-scm.org/fossil/doc/trunk/www/permutedindex.html">https://fossil-scm.org/fossil/doc/trunk/www/permutedindex.html</a>

</p><p>
Do not be afraid to explore and experiment.
Without a log-in you won't be able to
push back any changes you make, so you cannot damage the project.

</p><h2 id="verifying_source_code_integrity"><span>3.4. </span>Verifying Source Code Integrity</h2>

<p>
If you need to verify that the SQLite source code that you have is
authentic and has not been modified in any way (perhaps by an adversary)
that can be done using a few simple command-line tools.  At the root
of the SQLite source tree is a file named "manifest".  The manifest
file contains the name of every other file in the source tree together
with either a SHA1 or SHA3-256 hash for that file.  (SHA1 is used for
older files and SHA3-256 for newer files.)  You can write a
script to extract these hashes and verify them against the source code
files.  The hash name for the check-in is just the SHA3-256 hash of the
"manifest" file itself, possibly with the last line omitted if the
last line begins with "# Remove this line..."

</p><h1 id="see_also"><span>4. </span>See Also</h1>

<p>Other pages that talk about Fossil and Git include:
</p><ul>
<li><p><a href="https://fossil-scm.org/fossil/doc/trunk/www/fossil-v-git.wiki">Fossil vs. Git</a>
</p></li><li><p><a href="https://www.fossil-scm.org/fossil/doc/trunk/www/quotes.wiki">What others say about Fossil and Git</a>
</p></li></ul>
<p align="center"><small><i>This page last modified on  <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink"  data-href="https://sqlite.org/docsrc/finfo/pages/whynotgit.in?m=fbbfef78bd">2023-02-27 02:07:35</a> UTC </small></i></p>