Fossil SCM

Merge from trunk

george 2020-12-14 20:38 wiki-history merge
Commit 959699bfb6f13990feab7f68f31d67870bfda051d0af248efd59522206d9642c
--- src/backoffice.c
+++ src/backoffice.c
@@ -461,11 +461,11 @@
461461
**
462462
** If no backoffice processes are running at all, this routine becomes
463463
** the main backoffice.
464464
**
465465
** If a primary backoffice is running, but a on-deck backoffice is
466
-** needed, this routine becomes that on-desk backoffice.
466
+** needed, this routine becomes that on-deck backoffice.
467467
*/
468468
static void backoffice_thread(void){
469469
Lease x;
470470
sqlite3_uint64 tmNow;
471471
sqlite3_uint64 idSelf;
472472
--- src/backoffice.c
+++ src/backoffice.c
@@ -461,11 +461,11 @@
461 **
462 ** If no backoffice processes are running at all, this routine becomes
463 ** the main backoffice.
464 **
465 ** If a primary backoffice is running, but a on-deck backoffice is
466 ** needed, this routine becomes that on-desk backoffice.
467 */
468 static void backoffice_thread(void){
469 Lease x;
470 sqlite3_uint64 tmNow;
471 sqlite3_uint64 idSelf;
472
--- src/backoffice.c
+++ src/backoffice.c
@@ -461,11 +461,11 @@
461 **
462 ** If no backoffice processes are running at all, this routine becomes
463 ** the main backoffice.
464 **
465 ** If a primary backoffice is running, but a on-deck backoffice is
466 ** needed, this routine becomes that on-deck backoffice.
467 */
468 static void backoffice_thread(void){
469 Lease x;
470 sqlite3_uint64 tmNow;
471 sqlite3_uint64 idSelf;
472
+5 -3
--- src/builtin.c
+++ src/builtin.c
@@ -775,13 +775,15 @@
775775
** initialize the window.fossil JS API. The first argument is the NAME
776776
** part of the first API to emit. All subsequent arguments must be
777777
** strings of the NAME part of additional fossil.NAME.js files,
778778
** followed by a NULL argument to terminate the list.
779779
**
780
-** e.g. pass it ("fetch", "dom", "tabs", 0) to load those 3 APIs (or
781
-** pass it ("fetch","tabs",0), as "dom" is a dependency of "tabs", so
782
-** it will be automatically loaded). Do not forget the trailing 0!
780
+** e.g. pass it ("fetch", "dom", "tabs", NULL) to load those 3 APIs (or
781
+** pass it ("fetch","tabs",NULL), as "dom" is a dependency of "tabs", so
782
+** it will be automatically loaded). Do not forget the trailing NULL,
783
+** and do not pass 0 instead, since that isn't always equivalent to NULL
784
+** in this context.
783785
**
784786
** If it is JS_BUNDLED then this routine queues up an emit of ALL of
785787
** the JS fossil.XYZ.js APIs which are not strictly specific to a
786788
** single page, and then calls builtin_fulfill_js_requests(). The idea
787789
** is that we can get better bundle caching and reduced HTTP requests
788790
--- src/builtin.c
+++ src/builtin.c
@@ -775,13 +775,15 @@
775 ** initialize the window.fossil JS API. The first argument is the NAME
776 ** part of the first API to emit. All subsequent arguments must be
777 ** strings of the NAME part of additional fossil.NAME.js files,
778 ** followed by a NULL argument to terminate the list.
779 **
780 ** e.g. pass it ("fetch", "dom", "tabs", 0) to load those 3 APIs (or
781 ** pass it ("fetch","tabs",0), as "dom" is a dependency of "tabs", so
782 ** it will be automatically loaded). Do not forget the trailing 0!
 
 
783 **
784 ** If it is JS_BUNDLED then this routine queues up an emit of ALL of
785 ** the JS fossil.XYZ.js APIs which are not strictly specific to a
786 ** single page, and then calls builtin_fulfill_js_requests(). The idea
787 ** is that we can get better bundle caching and reduced HTTP requests
788
--- src/builtin.c
+++ src/builtin.c
@@ -775,13 +775,15 @@
775 ** initialize the window.fossil JS API. The first argument is the NAME
776 ** part of the first API to emit. All subsequent arguments must be
777 ** strings of the NAME part of additional fossil.NAME.js files,
778 ** followed by a NULL argument to terminate the list.
779 **
780 ** e.g. pass it ("fetch", "dom", "tabs", NULL) to load those 3 APIs (or
781 ** pass it ("fetch","tabs",NULL), as "dom" is a dependency of "tabs", so
782 ** it will be automatically loaded). Do not forget the trailing NULL,
783 ** and do not pass 0 instead, since that isn't always equivalent to NULL
784 ** in this context.
785 **
786 ** If it is JS_BUNDLED then this routine queues up an emit of ALL of
787 ** the JS fossil.XYZ.js APIs which are not strictly specific to a
788 ** single page, and then calls builtin_fulfill_js_requests(). The idea
789 ** is that we can get better bundle caching and reduced HTTP requests
790
+11 -4
--- src/cgi.c
+++ src/cgi.c
@@ -1427,14 +1427,14 @@
14271427
"HTTP_ACCEPT_LANGUAGE", "HTTP_AUTHENICATION",
14281428
"HTTP_CONNECTION", "HTTP_HOST",
14291429
"HTTP_IF_NONE_MATCH", "HTTP_IF_MODIFIED_SINCE",
14301430
"HTTP_USER_AGENT", "HTTP_REFERER", "PATH_INFO", "PATH_TRANSLATED",
14311431
"QUERY_STRING", "REMOTE_ADDR", "REMOTE_PORT",
1432
- "REMOTE_USER", "REQUEST_METHOD",
1433
- "REQUEST_URI", "SCRIPT_FILENAME", "SCRIPT_NAME", "SERVER_PROTOCOL",
1434
- "HOME", "FOSSIL_HOME", "USERNAME", "USER", "FOSSIL_USER",
1435
- "SQLITE_TMPDIR", "TMPDIR",
1432
+ "REMOTE_USER", "REQUEST_METHOD", "REQUEST_SCHEME",
1433
+ "REQUEST_URI", "SCRIPT_FILENAME", "SCRIPT_NAME", "SERVER_NAME",
1434
+ "SERVER_PROTOCOL", "HOME", "FOSSIL_HOME", "USERNAME", "USER",
1435
+ "FOSSIL_USER", "SQLITE_TMPDIR", "TMPDIR",
14361436
"TEMP", "TMP", "FOSSIL_VFS",
14371437
"FOSSIL_FORCE_TICKET_MODERATION", "FOSSIL_FORCE_WIKI_MODERATION",
14381438
"FOSSIL_TCL_PATH", "TH1_DELETE_INTERP", "TH1_ENABLE_DOCS",
14391439
"TH1_ENABLE_HOOKS", "TH1_ENABLE_TCL", "REMOTE_HOST",
14401440
};
@@ -1662,10 +1662,11 @@
16621662
** and subsequent code handles the actual generation of the webpage.
16631663
*/
16641664
void cgi_handle_http_request(const char *zIpAddr){
16651665
char *z, *zToken;
16661666
int i;
1667
+ const char *zScheme = "http";
16671668
char zLine[2000]; /* A single line of input. */
16681669
g.fullHttpReply = 1;
16691670
if( fgets(zLine, sizeof(zLine),g.httpIn)==0 ){
16701671
malformed_request("missing HTTP header");
16711672
}
@@ -1725,12 +1726,17 @@
17251726
cgi_setenv("CONTENT_TYPE", zVal);
17261727
}else if( fossil_strcmp(zFieldName,"cookie:")==0 ){
17271728
cgi_setenv("HTTP_COOKIE", zVal);
17281729
}else if( fossil_strcmp(zFieldName,"https:")==0 ){
17291730
cgi_setenv("HTTPS", zVal);
1731
+ zScheme = "https";
17301732
}else if( fossil_strcmp(zFieldName,"host:")==0 ){
1733
+ char *z;
17311734
cgi_setenv("HTTP_HOST", zVal);
1735
+ z = strchr(zVal, ':');
1736
+ if( z ) z[0] = 0;
1737
+ cgi_setenv("SERVER_NAME", zVal);
17321738
}else if( fossil_strcmp(zFieldName,"if-none-match:")==0 ){
17331739
cgi_setenv("HTTP_IF_NONE_MATCH", zVal);
17341740
}else if( fossil_strcmp(zFieldName,"if-modified-since:")==0 ){
17351741
cgi_setenv("HTTP_IF_MODIFIED_SINCE", zVal);
17361742
}else if( fossil_strcmp(zFieldName,"referer:")==0 ){
@@ -1752,10 +1758,11 @@
17521758
rangeStart = x1;
17531759
rangeEnd = x2+1;
17541760
}
17551761
}
17561762
}
1763
+ cgi_setenv("REQUEST_SCHEME",zScheme);
17571764
cgi_init();
17581765
cgi_trace(0);
17591766
}
17601767
17611768
/*
17621769
--- src/cgi.c
+++ src/cgi.c
@@ -1427,14 +1427,14 @@
1427 "HTTP_ACCEPT_LANGUAGE", "HTTP_AUTHENICATION",
1428 "HTTP_CONNECTION", "HTTP_HOST",
1429 "HTTP_IF_NONE_MATCH", "HTTP_IF_MODIFIED_SINCE",
1430 "HTTP_USER_AGENT", "HTTP_REFERER", "PATH_INFO", "PATH_TRANSLATED",
1431 "QUERY_STRING", "REMOTE_ADDR", "REMOTE_PORT",
1432 "REMOTE_USER", "REQUEST_METHOD",
1433 "REQUEST_URI", "SCRIPT_FILENAME", "SCRIPT_NAME", "SERVER_PROTOCOL",
1434 "HOME", "FOSSIL_HOME", "USERNAME", "USER", "FOSSIL_USER",
1435 "SQLITE_TMPDIR", "TMPDIR",
1436 "TEMP", "TMP", "FOSSIL_VFS",
1437 "FOSSIL_FORCE_TICKET_MODERATION", "FOSSIL_FORCE_WIKI_MODERATION",
1438 "FOSSIL_TCL_PATH", "TH1_DELETE_INTERP", "TH1_ENABLE_DOCS",
1439 "TH1_ENABLE_HOOKS", "TH1_ENABLE_TCL", "REMOTE_HOST",
1440 };
@@ -1662,10 +1662,11 @@
1662 ** and subsequent code handles the actual generation of the webpage.
1663 */
1664 void cgi_handle_http_request(const char *zIpAddr){
1665 char *z, *zToken;
1666 int i;
 
1667 char zLine[2000]; /* A single line of input. */
1668 g.fullHttpReply = 1;
1669 if( fgets(zLine, sizeof(zLine),g.httpIn)==0 ){
1670 malformed_request("missing HTTP header");
1671 }
@@ -1725,12 +1726,17 @@
1725 cgi_setenv("CONTENT_TYPE", zVal);
1726 }else if( fossil_strcmp(zFieldName,"cookie:")==0 ){
1727 cgi_setenv("HTTP_COOKIE", zVal);
1728 }else if( fossil_strcmp(zFieldName,"https:")==0 ){
1729 cgi_setenv("HTTPS", zVal);
 
1730 }else if( fossil_strcmp(zFieldName,"host:")==0 ){
 
1731 cgi_setenv("HTTP_HOST", zVal);
 
 
 
1732 }else if( fossil_strcmp(zFieldName,"if-none-match:")==0 ){
1733 cgi_setenv("HTTP_IF_NONE_MATCH", zVal);
1734 }else if( fossil_strcmp(zFieldName,"if-modified-since:")==0 ){
1735 cgi_setenv("HTTP_IF_MODIFIED_SINCE", zVal);
1736 }else if( fossil_strcmp(zFieldName,"referer:")==0 ){
@@ -1752,10 +1758,11 @@
1752 rangeStart = x1;
1753 rangeEnd = x2+1;
1754 }
1755 }
1756 }
 
1757 cgi_init();
1758 cgi_trace(0);
1759 }
1760
1761 /*
1762
--- src/cgi.c
+++ src/cgi.c
@@ -1427,14 +1427,14 @@
1427 "HTTP_ACCEPT_LANGUAGE", "HTTP_AUTHENICATION",
1428 "HTTP_CONNECTION", "HTTP_HOST",
1429 "HTTP_IF_NONE_MATCH", "HTTP_IF_MODIFIED_SINCE",
1430 "HTTP_USER_AGENT", "HTTP_REFERER", "PATH_INFO", "PATH_TRANSLATED",
1431 "QUERY_STRING", "REMOTE_ADDR", "REMOTE_PORT",
1432 "REMOTE_USER", "REQUEST_METHOD", "REQUEST_SCHEME",
1433 "REQUEST_URI", "SCRIPT_FILENAME", "SCRIPT_NAME", "SERVER_NAME",
1434 "SERVER_PROTOCOL", "HOME", "FOSSIL_HOME", "USERNAME", "USER",
1435 "FOSSIL_USER", "SQLITE_TMPDIR", "TMPDIR",
1436 "TEMP", "TMP", "FOSSIL_VFS",
1437 "FOSSIL_FORCE_TICKET_MODERATION", "FOSSIL_FORCE_WIKI_MODERATION",
1438 "FOSSIL_TCL_PATH", "TH1_DELETE_INTERP", "TH1_ENABLE_DOCS",
1439 "TH1_ENABLE_HOOKS", "TH1_ENABLE_TCL", "REMOTE_HOST",
1440 };
@@ -1662,10 +1662,11 @@
1662 ** and subsequent code handles the actual generation of the webpage.
1663 */
1664 void cgi_handle_http_request(const char *zIpAddr){
1665 char *z, *zToken;
1666 int i;
1667 const char *zScheme = "http";
1668 char zLine[2000]; /* A single line of input. */
1669 g.fullHttpReply = 1;
1670 if( fgets(zLine, sizeof(zLine),g.httpIn)==0 ){
1671 malformed_request("missing HTTP header");
1672 }
@@ -1725,12 +1726,17 @@
1726 cgi_setenv("CONTENT_TYPE", zVal);
1727 }else if( fossil_strcmp(zFieldName,"cookie:")==0 ){
1728 cgi_setenv("HTTP_COOKIE", zVal);
1729 }else if( fossil_strcmp(zFieldName,"https:")==0 ){
1730 cgi_setenv("HTTPS", zVal);
1731 zScheme = "https";
1732 }else if( fossil_strcmp(zFieldName,"host:")==0 ){
1733 char *z;
1734 cgi_setenv("HTTP_HOST", zVal);
1735 z = strchr(zVal, ':');
1736 if( z ) z[0] = 0;
1737 cgi_setenv("SERVER_NAME", zVal);
1738 }else if( fossil_strcmp(zFieldName,"if-none-match:")==0 ){
1739 cgi_setenv("HTTP_IF_NONE_MATCH", zVal);
1740 }else if( fossil_strcmp(zFieldName,"if-modified-since:")==0 ){
1741 cgi_setenv("HTTP_IF_MODIFIED_SINCE", zVal);
1742 }else if( fossil_strcmp(zFieldName,"referer:")==0 ){
@@ -1752,10 +1758,11 @@
1758 rangeStart = x1;
1759 rangeEnd = x2+1;
1760 }
1761 }
1762 }
1763 cgi_setenv("REQUEST_SCHEME",zScheme);
1764 cgi_init();
1765 cgi_trace(0);
1766 }
1767
1768 /*
1769
+29 -13
--- src/clone.c
+++ src/clone.c
@@ -123,10 +123,12 @@
123123
** the -A|--admin-user parameter.
124124
**
125125
** Options:
126126
** --admin-user|-A USERNAME Make USERNAME the administrator
127127
** --httpauth|-B USER:PASS Add HTTP Basic Authorization to requests
128
+** --nested Allow opening a repository inside an opened
129
+** checkout
128130
** --nocompress Omit extra delta compression
129131
** --no-open Clone only. Do not open a check-out.
130132
** --once Don't remember the URI.
131133
** --private Also clone private branches
132134
** --save-http-password Remember the HTTP password without asking
@@ -145,12 +147,13 @@
145147
int nErr = 0;
146148
int urlFlags = URL_PROMPT_PW | URL_REMEMBER;
147149
int syncFlags = SYNC_CLONE;
148150
int noCompress = find_option("nocompress",0,0)!=0;
149151
int noOpen = find_option("no-open",0,0)!=0;
152
+ int allowNested = find_option("nested",0,0)!=0; /* Used by open */
150153
const char *zRepo = 0; /* Name of the new local repository file */
151
- const char *zWorkDir = 0; /* Open in this director, if not zero */
154
+ const char *zWorkDir = 0; /* Open in this directory, if not zero */
152155
153156
154157
/* Also clone private branches */
155158
if( find_option("private",0,0)!=0 ) syncFlags |= SYNC_PRIVATE;
156159
if( find_option("once",0,0)!=0) urlFlags &= ~URL_REMEMBER;
@@ -189,10 +192,16 @@
189192
}
190193
fossil_free(zBase);
191194
}
192195
if( -1 != file_size(zRepo, ExtFILE) ){
193196
fossil_fatal("file already exists: %s", zRepo);
197
+ }
198
+ /* Fail before clone if open will fail because inside an open checkout */
199
+ if( zWorkDir!=0 && zWorkDir[0]!=0 && !noOpen ){
200
+ if( db_open_local_v2(0, allowNested) ){
201
+ fossil_fatal("there is already an open tree at %s", g.zLocalRoot);
202
+ }
194203
}
195204
url_parse(g.argv[2], urlFlags);
196205
if( zDefaultUser==0 && g.url.user!=0 ) zDefaultUser = g.url.user;
197206
if( g.url.isFile ){
198207
file_copy(g.url.name, zRepo);
@@ -277,22 +286,29 @@
277286
fossil_print("\nproject-id: %s\n", db_get("project-code", 0));
278287
fossil_print("server-id: %s\n", db_get("server-code", 0));
279288
zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
280289
fossil_print("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword);
281290
if( zWorkDir!=0 && zWorkDir[0]!=0 && !noOpen ){
282
- char *azNew[6];
283
- fossil_print("opening the new %s repository in directory %s...\n",
284
- zRepo, zWorkDir);
285
- azNew[0] = g.argv[0];
286
- azNew[1] = "open";
287
- azNew[2] = (char*)zRepo;
288
- azNew[3] = "--workdir";
289
- azNew[4] = (char*)zWorkDir;
290
- azNew[5] = 0;
291
- g.argv = azNew;
292
- g.argc = 5;
293
- cmd_open();
291
+ char *azNew[7];
292
+ int nargs = 5;
293
+ fossil_print("opening the new %s repository in directory %s...\n",
294
+ zRepo, zWorkDir);
295
+ azNew[0] = g.argv[0];
296
+ azNew[1] = "open";
297
+ azNew[2] = (char*)zRepo;
298
+ azNew[3] = "--workdir";
299
+ azNew[4] = (char*)zWorkDir;
300
+ if( allowNested ){
301
+ azNew[5] = "--nested";
302
+ nargs++;
303
+ }else{
304
+ azNew[5] = 0;
305
+ }
306
+ azNew[6] = 0;
307
+ g.argv = azNew;
308
+ g.argc = nargs;
309
+ cmd_open();
294310
}
295311
}
296312
297313
/*
298314
** If user chooses to use HTTP Authentication over unencrypted HTTP,
299315
--- src/clone.c
+++ src/clone.c
@@ -123,10 +123,12 @@
123 ** the -A|--admin-user parameter.
124 **
125 ** Options:
126 ** --admin-user|-A USERNAME Make USERNAME the administrator
127 ** --httpauth|-B USER:PASS Add HTTP Basic Authorization to requests
 
 
128 ** --nocompress Omit extra delta compression
129 ** --no-open Clone only. Do not open a check-out.
130 ** --once Don't remember the URI.
131 ** --private Also clone private branches
132 ** --save-http-password Remember the HTTP password without asking
@@ -145,12 +147,13 @@
145 int nErr = 0;
146 int urlFlags = URL_PROMPT_PW | URL_REMEMBER;
147 int syncFlags = SYNC_CLONE;
148 int noCompress = find_option("nocompress",0,0)!=0;
149 int noOpen = find_option("no-open",0,0)!=0;
 
150 const char *zRepo = 0; /* Name of the new local repository file */
151 const char *zWorkDir = 0; /* Open in this director, if not zero */
152
153
154 /* Also clone private branches */
155 if( find_option("private",0,0)!=0 ) syncFlags |= SYNC_PRIVATE;
156 if( find_option("once",0,0)!=0) urlFlags &= ~URL_REMEMBER;
@@ -189,10 +192,16 @@
189 }
190 fossil_free(zBase);
191 }
192 if( -1 != file_size(zRepo, ExtFILE) ){
193 fossil_fatal("file already exists: %s", zRepo);
 
 
 
 
 
 
194 }
195 url_parse(g.argv[2], urlFlags);
196 if( zDefaultUser==0 && g.url.user!=0 ) zDefaultUser = g.url.user;
197 if( g.url.isFile ){
198 file_copy(g.url.name, zRepo);
@@ -277,22 +286,29 @@
277 fossil_print("\nproject-id: %s\n", db_get("project-code", 0));
278 fossil_print("server-id: %s\n", db_get("server-code", 0));
279 zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
280 fossil_print("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword);
281 if( zWorkDir!=0 && zWorkDir[0]!=0 && !noOpen ){
282 char *azNew[6];
283 fossil_print("opening the new %s repository in directory %s...\n",
284 zRepo, zWorkDir);
285 azNew[0] = g.argv[0];
286 azNew[1] = "open";
287 azNew[2] = (char*)zRepo;
288 azNew[3] = "--workdir";
289 azNew[4] = (char*)zWorkDir;
290 azNew[5] = 0;
291 g.argv = azNew;
292 g.argc = 5;
293 cmd_open();
 
 
 
 
 
 
 
294 }
295 }
296
297 /*
298 ** If user chooses to use HTTP Authentication over unencrypted HTTP,
299
--- src/clone.c
+++ src/clone.c
@@ -123,10 +123,12 @@
123 ** the -A|--admin-user parameter.
124 **
125 ** Options:
126 ** --admin-user|-A USERNAME Make USERNAME the administrator
127 ** --httpauth|-B USER:PASS Add HTTP Basic Authorization to requests
128 ** --nested Allow opening a repository inside an opened
129 ** checkout
130 ** --nocompress Omit extra delta compression
131 ** --no-open Clone only. Do not open a check-out.
132 ** --once Don't remember the URI.
133 ** --private Also clone private branches
134 ** --save-http-password Remember the HTTP password without asking
@@ -145,12 +147,13 @@
147 int nErr = 0;
148 int urlFlags = URL_PROMPT_PW | URL_REMEMBER;
149 int syncFlags = SYNC_CLONE;
150 int noCompress = find_option("nocompress",0,0)!=0;
151 int noOpen = find_option("no-open",0,0)!=0;
152 int allowNested = find_option("nested",0,0)!=0; /* Used by open */
153 const char *zRepo = 0; /* Name of the new local repository file */
154 const char *zWorkDir = 0; /* Open in this directory, if not zero */
155
156
157 /* Also clone private branches */
158 if( find_option("private",0,0)!=0 ) syncFlags |= SYNC_PRIVATE;
159 if( find_option("once",0,0)!=0) urlFlags &= ~URL_REMEMBER;
@@ -189,10 +192,16 @@
192 }
193 fossil_free(zBase);
194 }
195 if( -1 != file_size(zRepo, ExtFILE) ){
196 fossil_fatal("file already exists: %s", zRepo);
197 }
198 /* Fail before clone if open will fail because inside an open checkout */
199 if( zWorkDir!=0 && zWorkDir[0]!=0 && !noOpen ){
200 if( db_open_local_v2(0, allowNested) ){
201 fossil_fatal("there is already an open tree at %s", g.zLocalRoot);
202 }
203 }
204 url_parse(g.argv[2], urlFlags);
205 if( zDefaultUser==0 && g.url.user!=0 ) zDefaultUser = g.url.user;
206 if( g.url.isFile ){
207 file_copy(g.url.name, zRepo);
@@ -277,22 +286,29 @@
286 fossil_print("\nproject-id: %s\n", db_get("project-code", 0));
287 fossil_print("server-id: %s\n", db_get("server-code", 0));
288 zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
289 fossil_print("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword);
290 if( zWorkDir!=0 && zWorkDir[0]!=0 && !noOpen ){
291 char *azNew[7];
292 int nargs = 5;
293 fossil_print("opening the new %s repository in directory %s...\n",
294 zRepo, zWorkDir);
295 azNew[0] = g.argv[0];
296 azNew[1] = "open";
297 azNew[2] = (char*)zRepo;
298 azNew[3] = "--workdir";
299 azNew[4] = (char*)zWorkDir;
300 if( allowNested ){
301 azNew[5] = "--nested";
302 nargs++;
303 }else{
304 azNew[5] = 0;
305 }
306 azNew[6] = 0;
307 g.argv = azNew;
308 g.argc = nargs;
309 cmd_open();
310 }
311 }
312
313 /*
314 ** If user chooses to use HTTP Authentication over unencrypted HTTP,
315
--- src/extcgi.c
+++ src/extcgi.c
@@ -67,10 +67,11 @@
6767
"PATH_INFO",
6868
"QUERY_STRING",
6969
"REMOTE_ADDR",
7070
"REMOTE_USER",
7171
"REQUEST_METHOD",
72
+ "REQUEST_SCHEME",
7273
"REQUEST_URI",
7374
"SCRIPT_DIRECTORY",
7475
"SCRIPT_FILENAME",
7576
"SCRIPT_NAME",
7677
"SERVER_NAME",
@@ -326,10 +327,13 @@
326327
}else if( fossil_strnicmp(zLine,"Content-Type:",13)==0 ){
327328
int j;
328329
for(i=13; fossil_isspace(zLine[i]); i++){}
329330
for(j=i; zLine[j] && zLine[j]!=';'; j++){}
330331
zMime = mprintf("%.*s", j-i, &zLine[i]);
332
+ }else{
333
+ cgi_append_header(zLine);
334
+ cgi_append_header("\r\n");
331335
}
332336
}
333337
}
334338
blob_read_from_channel(&reply, fromChild, nContent);
335339
zFailReason = 0; /* Indicate success */
336340
--- src/extcgi.c
+++ src/extcgi.c
@@ -67,10 +67,11 @@
67 "PATH_INFO",
68 "QUERY_STRING",
69 "REMOTE_ADDR",
70 "REMOTE_USER",
71 "REQUEST_METHOD",
 
72 "REQUEST_URI",
73 "SCRIPT_DIRECTORY",
74 "SCRIPT_FILENAME",
75 "SCRIPT_NAME",
76 "SERVER_NAME",
@@ -326,10 +327,13 @@
326 }else if( fossil_strnicmp(zLine,"Content-Type:",13)==0 ){
327 int j;
328 for(i=13; fossil_isspace(zLine[i]); i++){}
329 for(j=i; zLine[j] && zLine[j]!=';'; j++){}
330 zMime = mprintf("%.*s", j-i, &zLine[i]);
 
 
 
331 }
332 }
333 }
334 blob_read_from_channel(&reply, fromChild, nContent);
335 zFailReason = 0; /* Indicate success */
336
--- src/extcgi.c
+++ src/extcgi.c
@@ -67,10 +67,11 @@
67 "PATH_INFO",
68 "QUERY_STRING",
69 "REMOTE_ADDR",
70 "REMOTE_USER",
71 "REQUEST_METHOD",
72 "REQUEST_SCHEME",
73 "REQUEST_URI",
74 "SCRIPT_DIRECTORY",
75 "SCRIPT_FILENAME",
76 "SCRIPT_NAME",
77 "SERVER_NAME",
@@ -326,10 +327,13 @@
327 }else if( fossil_strnicmp(zLine,"Content-Type:",13)==0 ){
328 int j;
329 for(i=13; fossil_isspace(zLine[i]); i++){}
330 for(j=i; zLine[j] && zLine[j]!=';'; j++){}
331 zMime = mprintf("%.*s", j-i, &zLine[i]);
332 }else{
333 cgi_append_header(zLine);
334 cgi_append_header("\r\n");
335 }
336 }
337 }
338 blob_read_from_channel(&reply, fromChild, nContent);
339 zFailReason = 0; /* Indicate success */
340
--- src/fossil.fetch.js
+++ src/fossil.fetch.js
@@ -70,18 +70,20 @@
7070
header values. When a map is passed on, all of its keys are
7171
lower-cased. When a given header is requested and that header is
7272
set multiple times, their values are (per the XHR docs)
7373
concatenated together with ", " between them.
7474
75
- - beforesend/aftersend: optional callbacks which are called without
76
- arguments immediately before the request is submitted and
77
- immediately after it is received, regardless of success or
78
- error. In the context of the callback, the options object is the
79
- "this". These can be used to, e.g., keep track of in-flight
80
- requests and update the UI accordingly, e.g. disabling/enabling DOM
81
- elements. Any exceptions triggered by beforesend/aftersend are
82
- caught and silently ignored.
75
+ - beforesend/aftersend: optional callbacks which are called
76
+ without arguments immediately before the request is submitted
77
+ and immediately after it is received, regardless of success or
78
+ error. In the context of the callback, the options object is
79
+ the "this". These can be used to, e.g., keep track of in-flight
80
+ requests and update the UI accordingly, e.g. disabling/enabling
81
+ DOM elements. Any exceptions thrown in an beforesend are passed
82
+ to the onerror() handler and cause the fetch() to prematurely
83
+ abort. Exceptions thrown in aftersend are currently silently
84
+ ignored (feature or bug?).
8385
8486
- timeout: integer in milliseconds specifying the XHR timeout
8587
duration. Default = fossil.fetch.timeout.
8688
8789
When an options object does not provide
@@ -91,12 +93,11 @@
9193
default onload/onerror implementations route the data through the
9294
dev console and (for onerror()) through fossil.error(). The default
9395
beforesend/aftersend are no-ops. Individual pages may overwrite
9496
those members to provide default implementations suitable for the
9597
page's use, e.g. keeping track of how many in-flight ajax requests
96
- are pending. Any exceptions thrown in an beforesend/aftersend
97
- handler are current ignored (feature or bug?).
98
+ are pending.
9899
99100
Note that this routine may add properties to the 2nd argument, so
100101
that instance should not be kept around for later use.
101102
102103
Returns this object, noting that the XHR request is asynchronous,
@@ -195,11 +196,15 @@
195196
opt.onload.apply(opt, args);
196197
}catch(e){
197198
opt.onerror(e);
198199
}
199200
};
200
- try{opt.beforesend()}catch(e){/*ignore*/}
201
+ try{opt.beforesend()}
202
+ catch(e){
203
+ opt.onerror(e);
204
+ return;
205
+ }
201206
x.open(opt.method||'GET', url.join(''), true);
202207
if('POST'===opt.method && 'string'===typeof opt.contentType){
203208
x.setRequestHeader('Content-Type',opt.contentType);
204209
}
205210
x.timeout = +opt.timeout || f.timeout;
206211
--- src/fossil.fetch.js
+++ src/fossil.fetch.js
@@ -70,18 +70,20 @@
70 header values. When a map is passed on, all of its keys are
71 lower-cased. When a given header is requested and that header is
72 set multiple times, their values are (per the XHR docs)
73 concatenated together with ", " between them.
74
75 - beforesend/aftersend: optional callbacks which are called without
76 arguments immediately before the request is submitted and
77 immediately after it is received, regardless of success or
78 error. In the context of the callback, the options object is the
79 "this". These can be used to, e.g., keep track of in-flight
80 requests and update the UI accordingly, e.g. disabling/enabling DOM
81 elements. Any exceptions triggered by beforesend/aftersend are
82 caught and silently ignored.
 
 
83
84 - timeout: integer in milliseconds specifying the XHR timeout
85 duration. Default = fossil.fetch.timeout.
86
87 When an options object does not provide
@@ -91,12 +93,11 @@
91 default onload/onerror implementations route the data through the
92 dev console and (for onerror()) through fossil.error(). The default
93 beforesend/aftersend are no-ops. Individual pages may overwrite
94 those members to provide default implementations suitable for the
95 page's use, e.g. keeping track of how many in-flight ajax requests
96 are pending. Any exceptions thrown in an beforesend/aftersend
97 handler are current ignored (feature or bug?).
98
99 Note that this routine may add properties to the 2nd argument, so
100 that instance should not be kept around for later use.
101
102 Returns this object, noting that the XHR request is asynchronous,
@@ -195,11 +196,15 @@
195 opt.onload.apply(opt, args);
196 }catch(e){
197 opt.onerror(e);
198 }
199 };
200 try{opt.beforesend()}catch(e){/*ignore*/}
 
 
 
 
201 x.open(opt.method||'GET', url.join(''), true);
202 if('POST'===opt.method && 'string'===typeof opt.contentType){
203 x.setRequestHeader('Content-Type',opt.contentType);
204 }
205 x.timeout = +opt.timeout || f.timeout;
206
--- src/fossil.fetch.js
+++ src/fossil.fetch.js
@@ -70,18 +70,20 @@
70 header values. When a map is passed on, all of its keys are
71 lower-cased. When a given header is requested and that header is
72 set multiple times, their values are (per the XHR docs)
73 concatenated together with ", " between them.
74
75 - beforesend/aftersend: optional callbacks which are called
76 without arguments immediately before the request is submitted
77 and immediately after it is received, regardless of success or
78 error. In the context of the callback, the options object is
79 the "this". These can be used to, e.g., keep track of in-flight
80 requests and update the UI accordingly, e.g. disabling/enabling
81 DOM elements. Any exceptions thrown in an beforesend are passed
82 to the onerror() handler and cause the fetch() to prematurely
83 abort. Exceptions thrown in aftersend are currently silently
84 ignored (feature or bug?).
85
86 - timeout: integer in milliseconds specifying the XHR timeout
87 duration. Default = fossil.fetch.timeout.
88
89 When an options object does not provide
@@ -91,12 +93,11 @@
93 default onload/onerror implementations route the data through the
94 dev console and (for onerror()) through fossil.error(). The default
95 beforesend/aftersend are no-ops. Individual pages may overwrite
96 those members to provide default implementations suitable for the
97 page's use, e.g. keeping track of how many in-flight ajax requests
98 are pending.
 
99
100 Note that this routine may add properties to the 2nd argument, so
101 that instance should not be kept around for later use.
102
103 Returns this object, noting that the XHR request is asynchronous,
@@ -195,11 +196,15 @@
196 opt.onload.apply(opt, args);
197 }catch(e){
198 opt.onerror(e);
199 }
200 };
201 try{opt.beforesend()}
202 catch(e){
203 opt.onerror(e);
204 return;
205 }
206 x.open(opt.method||'GET', url.join(''), true);
207 if('POST'===opt.method && 'string'===typeof opt.contentType){
208 x.setRequestHeader('Content-Type',opt.contentType);
209 }
210 x.timeout = +opt.timeout || f.timeout;
211
+6 -2
--- src/login.c
+++ src/login.c
@@ -1424,16 +1424,20 @@
14241424
}else
14251425
#endif /* FOSSIL_ENABLE_JSON */
14261426
{
14271427
const char *zUrl = PD("REQUEST_URI", "index");
14281428
const char *zQS = P("QUERY_STRING");
1429
+ char *zUrlNoQS;
1430
+ int i;
14291431
Blob redir;
14301432
blob_init(&redir, 0, 0);
1433
+ for(i=0; zUrl[i] && zUrl[i]!='?'; i++){}
1434
+ zUrlNoQS = fossil_strndup(zUrl, i);
14311435
if( fossil_wants_https(1) ){
1432
- blob_appendf(&redir, "%s/login?g=%T", g.zHttpsURL, zUrl);
1436
+ blob_appendf(&redir, "%s/login?g=%T", g.zHttpsURL, zUrlNoQS);
14331437
}else{
1434
- blob_appendf(&redir, "%R/login?g=%T", zUrl);
1438
+ blob_appendf(&redir, "%R/login?g=%T", zUrlNoQS);
14351439
}
14361440
if( zQS && zQS[0] ){
14371441
blob_appendf(&redir, "%%3f%T", zQS);
14381442
}
14391443
if( anonOk ) blob_append(&redir, "&anon", 5);
14401444
--- src/login.c
+++ src/login.c
@@ -1424,16 +1424,20 @@
1424 }else
1425 #endif /* FOSSIL_ENABLE_JSON */
1426 {
1427 const char *zUrl = PD("REQUEST_URI", "index");
1428 const char *zQS = P("QUERY_STRING");
 
 
1429 Blob redir;
1430 blob_init(&redir, 0, 0);
 
 
1431 if( fossil_wants_https(1) ){
1432 blob_appendf(&redir, "%s/login?g=%T", g.zHttpsURL, zUrl);
1433 }else{
1434 blob_appendf(&redir, "%R/login?g=%T", zUrl);
1435 }
1436 if( zQS && zQS[0] ){
1437 blob_appendf(&redir, "%%3f%T", zQS);
1438 }
1439 if( anonOk ) blob_append(&redir, "&anon", 5);
1440
--- src/login.c
+++ src/login.c
@@ -1424,16 +1424,20 @@
1424 }else
1425 #endif /* FOSSIL_ENABLE_JSON */
1426 {
1427 const char *zUrl = PD("REQUEST_URI", "index");
1428 const char *zQS = P("QUERY_STRING");
1429 char *zUrlNoQS;
1430 int i;
1431 Blob redir;
1432 blob_init(&redir, 0, 0);
1433 for(i=0; zUrl[i] && zUrl[i]!='?'; i++){}
1434 zUrlNoQS = fossil_strndup(zUrl, i);
1435 if( fossil_wants_https(1) ){
1436 blob_appendf(&redir, "%s/login?g=%T", g.zHttpsURL, zUrlNoQS);
1437 }else{
1438 blob_appendf(&redir, "%R/login?g=%T", zUrlNoQS);
1439 }
1440 if( zQS && zQS[0] ){
1441 blob_appendf(&redir, "%%3f%T", zQS);
1442 }
1443 if( anonOk ) blob_append(&redir, "&anon", 5);
1444
--- src/sqlcmd.c
+++ src/sqlcmd.c
@@ -119,11 +119,10 @@
119119
pIn = sqlite3_value_blob(argv[0]);
120120
if( pIn==0 ) return;
121121
nIn = sqlite3_value_bytes(argv[0]);
122122
if( nIn<4 ) return;
123123
nOut = (pIn[0]<<24) + (pIn[1]<<16) + (pIn[2]<<8) + pIn[3];
124
- if( nOut<0 ) return;
125124
pOut = sqlite3_malloc( nOut+1 );
126125
rc = uncompress(pOut, &nOut, &pIn[4], nIn-4);
127126
if( rc==Z_OK ){
128127
sqlite3_result_blob(context, pOut, nOut, sqlite3_free);
129128
}else if( rc==Z_MEM_ERROR ){
130129
--- src/sqlcmd.c
+++ src/sqlcmd.c
@@ -119,11 +119,10 @@
119 pIn = sqlite3_value_blob(argv[0]);
120 if( pIn==0 ) return;
121 nIn = sqlite3_value_bytes(argv[0]);
122 if( nIn<4 ) return;
123 nOut = (pIn[0]<<24) + (pIn[1]<<16) + (pIn[2]<<8) + pIn[3];
124 if( nOut<0 ) return;
125 pOut = sqlite3_malloc( nOut+1 );
126 rc = uncompress(pOut, &nOut, &pIn[4], nIn-4);
127 if( rc==Z_OK ){
128 sqlite3_result_blob(context, pOut, nOut, sqlite3_free);
129 }else if( rc==Z_MEM_ERROR ){
130
--- src/sqlcmd.c
+++ src/sqlcmd.c
@@ -119,11 +119,10 @@
119 pIn = sqlite3_value_blob(argv[0]);
120 if( pIn==0 ) return;
121 nIn = sqlite3_value_bytes(argv[0]);
122 if( nIn<4 ) return;
123 nOut = (pIn[0]<<24) + (pIn[1]<<16) + (pIn[2]<<8) + pIn[3];
 
124 pOut = sqlite3_malloc( nOut+1 );
125 rc = uncompress(pOut, &nOut, &pIn[4], nIn-4);
126 if( rc==Z_OK ){
127 sqlite3_result_blob(context, pOut, nOut, sqlite3_free);
128 }else if( rc==Z_MEM_ERROR ){
129
+4 -4
--- src/timeline.c
+++ src/timeline.c
@@ -604,19 +604,19 @@
604604
** comment on-the-fly
605605
*/
606606
wiki_hyperlink_override(zUuid);
607607
if( zCom[0]=='-' ){
608608
@ Deleted wiki page "%z(href("%R/whistory?name=%t",zCom+1))\
609
- @ %h(zCom+1)</a>
609
+ @ %h(zCom+1)</a>"
610610
}else if( (tmFlags & TIMELINE_REFS)!=0
611611
&& (zCom[0]=='+' || zCom[0]==':') ){
612
- @ Wiki page "%z(href("%R/wiki?name=%t",zCom+1))%h(zCom+1)</a>
612
+ @ Wiki page "%z(href("%R/wiki?name=%t",zCom+1))%h(zCom+1)</a>"
613613
}else if( zCom[0]=='+' ){
614
- @ Added wiki page "%z(href("%R/wiki?name=%t",zCom+1))%h(zCom+1)</a>
614
+ @ Added wiki page "%z(href("%R/wiki?name=%t",zCom+1))%h(zCom+1)</a>"
615615
}else if( zCom[0]==':' ){
616616
@ Changes to wiki page "%z(href("%R/wiki?name=%t",zCom+1))\
617
- @ %h(zCom+1)</a>
617
+ @ %h(zCom+1)</a>"
618618
}else{
619619
/* Legacy EVENT table entry that needs to be rebuilt */
620620
@ Changes to a wiki page &rarr; Obsolete EVENT table information.
621621
@ Run "fossil rebuild" on the repository.
622622
}
623623
--- src/timeline.c
+++ src/timeline.c
@@ -604,19 +604,19 @@
604 ** comment on-the-fly
605 */
606 wiki_hyperlink_override(zUuid);
607 if( zCom[0]=='-' ){
608 @ Deleted wiki page "%z(href("%R/whistory?name=%t",zCom+1))\
609 @ %h(zCom+1)</a>
610 }else if( (tmFlags & TIMELINE_REFS)!=0
611 && (zCom[0]=='+' || zCom[0]==':') ){
612 @ Wiki page "%z(href("%R/wiki?name=%t",zCom+1))%h(zCom+1)</a>
613 }else if( zCom[0]=='+' ){
614 @ Added wiki page "%z(href("%R/wiki?name=%t",zCom+1))%h(zCom+1)</a>
615 }else if( zCom[0]==':' ){
616 @ Changes to wiki page "%z(href("%R/wiki?name=%t",zCom+1))\
617 @ %h(zCom+1)</a>
618 }else{
619 /* Legacy EVENT table entry that needs to be rebuilt */
620 @ Changes to a wiki page &rarr; Obsolete EVENT table information.
621 @ Run "fossil rebuild" on the repository.
622 }
623
--- src/timeline.c
+++ src/timeline.c
@@ -604,19 +604,19 @@
604 ** comment on-the-fly
605 */
606 wiki_hyperlink_override(zUuid);
607 if( zCom[0]=='-' ){
608 @ Deleted wiki page "%z(href("%R/whistory?name=%t",zCom+1))\
609 @ %h(zCom+1)</a>"
610 }else if( (tmFlags & TIMELINE_REFS)!=0
611 && (zCom[0]=='+' || zCom[0]==':') ){
612 @ Wiki page "%z(href("%R/wiki?name=%t",zCom+1))%h(zCom+1)</a>"
613 }else if( zCom[0]=='+' ){
614 @ Added wiki page "%z(href("%R/wiki?name=%t",zCom+1))%h(zCom+1)</a>"
615 }else if( zCom[0]==':' ){
616 @ Changes to wiki page "%z(href("%R/wiki?name=%t",zCom+1))\
617 @ %h(zCom+1)</a>"
618 }else{
619 /* Legacy EVENT table entry that needs to be rebuilt */
620 @ Changes to a wiki page &rarr; Obsolete EVENT table information.
621 @ Run "fossil rebuild" on the repository.
622 }
623
+1 -1
--- src/tktsetup.c
+++ src/tktsetup.c
@@ -364,11 +364,11 @@
364364
@ <td colspan="3">
365365
@ Enter a detailed description of the problem.
366366
@ For code defects, be sure to provide details on exactly how
367367
@ the problem can be reproduced. Provide as much detail as
368368
@ possible. Format:
369
-@ <th1>combobox mutype {HTML {[links only]} Markdown {Plain Text} Wiki}} 1</th1>
369
+@ <th1>combobox mutype {HTML {[links only]} Markdown {Plain Text} Wiki} 1</th1>
370370
@ <br />
371371
@ <th1>set nline [linecount $comment 50 10]</th1>
372372
@ <textarea name="icomment" cols="80" rows="$nline"
373373
@ wrap="virtual" class="wikiedit">$<icomment></textarea><br />
374374
@ </tr>
375375
--- src/tktsetup.c
+++ src/tktsetup.c
@@ -364,11 +364,11 @@
364 @ <td colspan="3">
365 @ Enter a detailed description of the problem.
366 @ For code defects, be sure to provide details on exactly how
367 @ the problem can be reproduced. Provide as much detail as
368 @ possible. Format:
369 @ <th1>combobox mutype {HTML {[links only]} Markdown {Plain Text} Wiki}} 1</th1>
370 @ <br />
371 @ <th1>set nline [linecount $comment 50 10]</th1>
372 @ <textarea name="icomment" cols="80" rows="$nline"
373 @ wrap="virtual" class="wikiedit">$<icomment></textarea><br />
374 @ </tr>
375
--- src/tktsetup.c
+++ src/tktsetup.c
@@ -364,11 +364,11 @@
364 @ <td colspan="3">
365 @ Enter a detailed description of the problem.
366 @ For code defects, be sure to provide details on exactly how
367 @ the problem can be reproduced. Provide as much detail as
368 @ possible. Format:
369 @ <th1>combobox mutype {HTML {[links only]} Markdown {Plain Text} Wiki} 1</th1>
370 @ <br />
371 @ <th1>set nline [linecount $comment 50 10]</th1>
372 @ <textarea name="icomment" cols="80" rows="$nline"
373 @ wrap="virtual" class="wikiedit">$<icomment></textarea><br />
374 @ </tr>
375
+3 -2
--- www/backup.md
+++ www/backup.md
@@ -201,14 +201,15 @@
201201
of noise to anyone without the key:
202202
203203
----
204204
205205
```shell
206
+iter=52830
206207
pass="h8TixP6Mt6edJ3d6COaexiiFlvAM54auF2AjT7ZYYn"
207208
gd="$HOME/Google Drive/Fossil Backups/$bf.xz.enc"
208209
fossil sql -R ~/museum/backups/"$bf" .dump | xz -9 |
209
- openssl enc -e -aes-256-cbc -pbkdf2 -iter 52830 -pass pass:"$pass" -out "$gd"
210
+ openssl enc -e -aes-256-cbc -pbkdf2 -iter $iter -pass pass:"$pass" -out "$gd"
210211
```
211212
212213
----
213214
214215
If you’re adding this to the first script above, remove the
@@ -247,11 +248,11 @@
247248
it, but it’s worth showing it because there are some subtleties to take
248249
care of. If all variables defined in earlier scripts are available, then
249250
restoration is:
250251
251252
```
252
-openssl enc -d -aes-256-cbc -pbkdf2 -iter 52830 -pass pass:"$pass" -in "$gd" |
253
+openssl enc -d -aes-256-cbc -pbkdf2 -iter $iter -pass pass:"$pass" -in "$gd" |
253254
xz -d | fossil sql --no-repository ~/museum/restored-repo.fossil
254255
```
255256
256257
We changed the `-e` to `-d` on the `openssl` command to get decryption,
257258
and we changed the `-out` to `-in` so it reads from the encrypted backup
258259
--- www/backup.md
+++ www/backup.md
@@ -201,14 +201,15 @@
201 of noise to anyone without the key:
202
203 ----
204
205 ```shell
 
206 pass="h8TixP6Mt6edJ3d6COaexiiFlvAM54auF2AjT7ZYYn"
207 gd="$HOME/Google Drive/Fossil Backups/$bf.xz.enc"
208 fossil sql -R ~/museum/backups/"$bf" .dump | xz -9 |
209 openssl enc -e -aes-256-cbc -pbkdf2 -iter 52830 -pass pass:"$pass" -out "$gd"
210 ```
211
212 ----
213
214 If you’re adding this to the first script above, remove the
@@ -247,11 +248,11 @@
247 it, but it’s worth showing it because there are some subtleties to take
248 care of. If all variables defined in earlier scripts are available, then
249 restoration is:
250
251 ```
252 openssl enc -d -aes-256-cbc -pbkdf2 -iter 52830 -pass pass:"$pass" -in "$gd" |
253 xz -d | fossil sql --no-repository ~/museum/restored-repo.fossil
254 ```
255
256 We changed the `-e` to `-d` on the `openssl` command to get decryption,
257 and we changed the `-out` to `-in` so it reads from the encrypted backup
258
--- www/backup.md
+++ www/backup.md
@@ -201,14 +201,15 @@
201 of noise to anyone without the key:
202
203 ----
204
205 ```shell
206 iter=52830
207 pass="h8TixP6Mt6edJ3d6COaexiiFlvAM54auF2AjT7ZYYn"
208 gd="$HOME/Google Drive/Fossil Backups/$bf.xz.enc"
209 fossil sql -R ~/museum/backups/"$bf" .dump | xz -9 |
210 openssl enc -e -aes-256-cbc -pbkdf2 -iter $iter -pass pass:"$pass" -out "$gd"
211 ```
212
213 ----
214
215 If you’re adding this to the first script above, remove the
@@ -247,11 +248,11 @@
248 it, but it’s worth showing it because there are some subtleties to take
249 care of. If all variables defined in earlier scripts are available, then
250 restoration is:
251
252 ```
253 openssl enc -d -aes-256-cbc -pbkdf2 -iter $iter -pass pass:"$pass" -in "$gd" |
254 xz -d | fossil sql --no-repository ~/museum/restored-repo.fossil
255 ```
256
257 We changed the `-e` to `-d` on the `openssl` command to get decryption,
258 and we changed the `-out` to `-in` so it reads from the encrypted backup
259
--- www/changes.wiki
+++ www/changes.wiki
@@ -6,11 +6,29 @@
66
* The "[/help?cmd=clone|fossil clone]" command is enhanced so that
77
if the repository filename is omitted, an appropriate name is derived
88
from the remote URL and the newly cloned repo is opened. This makes
99
the clone command work more like Git, thus making it easier for
1010
people transitioning from Git.
11
+ * Changed the way that wiki edits are stored in the EVENT table of the
12
+ database, for more flexibility and better features.
13
+ <b>Run "fossil rebuild" to take advantage of this change</b>.
1114
* Add the "contact" sub-command to [/help?cmd=user|fossil user].
15
+ * Added commands "[/help?cmd=all|fossil all git export]" and
16
+ "[/help?cmd=all|fossil all git status]".
17
+ * Improvements to the "[/sitemap]" page. Add subpages
18
+ [/sitemap-timeline] and [/sitemap-test].
19
+ * Better text position in cylinder objects of Pikchr diagrams.
20
+ * New "details.txt" settings available to custom skins to better control
21
+ the rendering of Pikchr diagrams:
22
+ <ul>
23
+ <li> pikchr-foreground
24
+ <li> pikchr-scale
25
+ <li> pikchr-fontscale
26
+ </ul>
27
+ * Allow the use of SQL functions inside the ticket table definition
28
+ for custom ticket configurations.
29
+ * Countless improvements and enhancements to the documentation
1230
1331
<a name='v2_13'></a>
1432
<h2>Changes for Version 2.13 (2020-11-01)</h2>
1533
1634
* Added support for [./interwiki.md|interwiki links].
1735
--- www/changes.wiki
+++ www/changes.wiki
@@ -6,11 +6,29 @@
6 * The "[/help?cmd=clone|fossil clone]" command is enhanced so that
7 if the repository filename is omitted, an appropriate name is derived
8 from the remote URL and the newly cloned repo is opened. This makes
9 the clone command work more like Git, thus making it easier for
10 people transitioning from Git.
 
 
 
11 * Add the "contact" sub-command to [/help?cmd=user|fossil user].
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
13 <a name='v2_13'></a>
14 <h2>Changes for Version 2.13 (2020-11-01)</h2>
15
16 * Added support for [./interwiki.md|interwiki links].
17
--- www/changes.wiki
+++ www/changes.wiki
@@ -6,11 +6,29 @@
6 * The "[/help?cmd=clone|fossil clone]" command is enhanced so that
7 if the repository filename is omitted, an appropriate name is derived
8 from the remote URL and the newly cloned repo is opened. This makes
9 the clone command work more like Git, thus making it easier for
10 people transitioning from Git.
11 * Changed the way that wiki edits are stored in the EVENT table of the
12 database, for more flexibility and better features.
13 <b>Run "fossil rebuild" to take advantage of this change</b>.
14 * Add the "contact" sub-command to [/help?cmd=user|fossil user].
15 * Added commands "[/help?cmd=all|fossil all git export]" and
16 "[/help?cmd=all|fossil all git status]".
17 * Improvements to the "[/sitemap]" page. Add subpages
18 [/sitemap-timeline] and [/sitemap-test].
19 * Better text position in cylinder objects of Pikchr diagrams.
20 * New "details.txt" settings available to custom skins to better control
21 the rendering of Pikchr diagrams:
22 <ul>
23 <li> pikchr-foreground
24 <li> pikchr-scale
25 <li> pikchr-fontscale
26 </ul>
27 * Allow the use of SQL functions inside the ticket table definition
28 for custom ticket configurations.
29 * Countless improvements and enhancements to the documentation
30
31 <a name='v2_13'></a>
32 <h2>Changes for Version 2.13 (2020-11-01)</h2>
33
34 * Added support for [./interwiki.md|interwiki links].
35
--- www/ckout-workflows.md
+++ www/ckout-workflows.md
@@ -2,12 +2,11 @@
22
33
Because Fossil separates the concept of “check-out directory” from
44
“repository DB file,” it gives you the freedom to choose from several
55
working styles. Contrast Git, where the two concepts are normally
66
intermingled in a single working directory, which strongly encourages
7
-the “update in place” working style, leaving its `git-worktree` feature
8
-underutilized.
7
+the “update in place” working style.
98
109
1110
## <a id="mcw"></a> Multiple-Checkout Workflow
1211
1312
With Fossil, it is routine to have multiple check-outs from the same
@@ -48,13 +47,13 @@
4847
4948
Each check-out operates independently of the others.
5049
5150
This multiple-checkouts working style is especially useful when Fossil stores source code in programming languages
5251
where there is a “build” step that transforms source files into files
53
-you actually run or distribute. With Git’s typical switch-in-place workflow,
54
-you have to rebuild all outputs from the source files
55
-that differ between those versions whenever you switch versions. In the above Fossil working model,
52
+you actually run or distribute. Contrast a switch-in-place workflow,
53
+where you have to rebuild all outputs from the source files
54
+that differ between those versions whenever you switch versions. In the above model,
5655
you switch versions with a “`cd`” command instead, so that you only have
5756
to rebuild outputs from files you yourself change.
5857
5958
This style is also useful when a check-out directory may be tied up with
6059
some long-running process, as with the “test” example above, where you
@@ -72,13 +71,13 @@
7271
Nevertheless, it is possible to work in a more typical Git sort of
7372
style, switching between versions in a single check-out directory.
7473
7574
#### <a id="idiomatic"></a> The Idiomatic Fossil Way
7675
77
-With the clone done as in [the prior section](#mdw), the most idiomatic
78
-way is as follows:
76
+The most idiomatic way is as follows:
7977
78
+ fossil clone https://example.com/repo /path/to/repo.fossil
8079
mkdir work-dir
8180
cd work-dir
8281
fossil open /path/to/repo.fossil
8382
...work on trunk...
8483
@@ -87,56 +86,44 @@
8786
8887
Basically, you replace the `cd` commands in the multiple checkouts
8988
workflow above with `fossil up` commands.
9089
9190
92
-#### <a id="open"></a> The Clone-and-Open Way
91
+#### <a id="open"></a> Opening a Repository by URI
9392
94
-In Fossil 2.12, we added a feature that allows you to get closer to
95
-Git’s single-step clone-and-open behavior:
93
+In Fossil 2.12, we added a feature to simplify the single-worktree use
94
+case:
9695
9796
mkdir work-dir
9897
cd work-dir
9998
fossil open https://example.com/repo
10099
101100
Now you have “trunk” open in `work-dir`, with the repo file stored as
102101
`repo.fossil` in that same directory.
103102
104
-The use of [`fossil open`][open] here instead of [`fossil clone`][clone]
105
-is likely to surprise a Git user. When we were [discussing][caod]
106
-this, we considered following the Git command style, but we decided
107
-against it because it goes against this core Fossil design principle:
108
-given that the Fossil repo is separate from the check-out, why would you
109
-expect asking for a repo clone to also create a check-out directory for
110
-you? We view commingled repository + check-out as a design error in
111
-Git, so why would we repeat the error?
112
-
113
-To see why we see this behavior is error-prone, consider that
114
-`git clean` must have an exception to avoid nuking the `.git` directory.
115
-We had to add that complication to `fossil clean` when we added the
116
-`fossil open URI` feature: it won’t nuke the repo DB file.
117
-
118
-[clone]: /help?cmd=clone
119
-[open]: /help?cmd=open
120
-
121
-
122
-#### <a id="clone"></a> The Git Clone Way
123
-
124
-This feature didn’t placate many Git fans, though, so with Fossil 2.14 —
125
-currently unreleased — we now allow this:
103
+Users of Git may be surprised that it doesn’t create a directory for you
104
+and that you `cd` into it *before* the clone-and-open step, not after.
105
+This is because we’re overloading the “open” command, which already had
106
+the behavior of opening into the current working directory. Changing it
107
+to behave like `git clone` would therefore make the behavior surprising
108
+to Fossil users. (See [our discussions][caod] if you want the full
109
+details.)
110
+
111
+
112
+#### <a id="clone"></a> Git-Like Clone-and-Open
113
+
114
+With Fossil 2.14 — currently unreleased — we added a more Git-like
115
+alternative:
126116
127117
fossil clone https://fossil-scm.org/fossil
118
+ cd fossil
128119
129120
This results in a `fossil.fossil` repo DB file and a `fossil/` working
130121
directory.
131122
132123
Note that our `clone URI` behavior does not commingle the repo and
133
-check-out, solving our major problem with the Git design, though we
134
-still believe it to be confusing to have “clone” be part of “open,” and
135
-still more confusing to have “open” part of “clone.” We prefer keeping
136
-these operations entirely separate, either as at the [top of this
137
-section](#scw) or [as in the prior one](#mcw). Still, please yourself.
124
+check-out, solving our major problem with the Git design.
138125
139126
If you want the repo to be named something else, adjust the URL:
140127
141128
fossil clone https://fossil-scm.org/fossil/fsl
142129
@@ -149,8 +136,9 @@
149136
fossil clone https://dev.example.com/repo/my-project
150137
151138
The `/repo` addition is the key: whatever comes after is used as the
152139
repository name. [See the docs][clone] for more details.
153140
154
-[caod]: https://fossil-scm.org/forum/forumpost/3f143cec74
141
+[caod]: https://fossil-scm.org/forum/forumpost/3f143cec74
142
+[clone]: /help?cmd=clone
155143
156144
<div style="height:50em" id="this-space-intentionally-left-blank"></div>
157145
--- www/ckout-workflows.md
+++ www/ckout-workflows.md
@@ -2,12 +2,11 @@
2
3 Because Fossil separates the concept of “check-out directory” from
4 “repository DB file,” it gives you the freedom to choose from several
5 working styles. Contrast Git, where the two concepts are normally
6 intermingled in a single working directory, which strongly encourages
7 the “update in place” working style, leaving its `git-worktree` feature
8 underutilized.
9
10
11 ## <a id="mcw"></a> Multiple-Checkout Workflow
12
13 With Fossil, it is routine to have multiple check-outs from the same
@@ -48,13 +47,13 @@
48
49 Each check-out operates independently of the others.
50
51 This multiple-checkouts working style is especially useful when Fossil stores source code in programming languages
52 where there is a “build” step that transforms source files into files
53 you actually run or distribute. With Git’s typical switch-in-place workflow,
54 you have to rebuild all outputs from the source files
55 that differ between those versions whenever you switch versions. In the above Fossil working model,
56 you switch versions with a “`cd`” command instead, so that you only have
57 to rebuild outputs from files you yourself change.
58
59 This style is also useful when a check-out directory may be tied up with
60 some long-running process, as with the “test” example above, where you
@@ -72,13 +71,13 @@
72 Nevertheless, it is possible to work in a more typical Git sort of
73 style, switching between versions in a single check-out directory.
74
75 #### <a id="idiomatic"></a> The Idiomatic Fossil Way
76
77 With the clone done as in [the prior section](#mdw), the most idiomatic
78 way is as follows:
79
 
80 mkdir work-dir
81 cd work-dir
82 fossil open /path/to/repo.fossil
83 ...work on trunk...
84
@@ -87,56 +86,44 @@
87
88 Basically, you replace the `cd` commands in the multiple checkouts
89 workflow above with `fossil up` commands.
90
91
92 #### <a id="open"></a> The Clone-and-Open Way
93
94 In Fossil 2.12, we added a feature that allows you to get closer to
95 Git’s single-step clone-and-open behavior:
96
97 mkdir work-dir
98 cd work-dir
99 fossil open https://example.com/repo
100
101 Now you have “trunk” open in `work-dir`, with the repo file stored as
102 `repo.fossil` in that same directory.
103
104 The use of [`fossil open`][open] here instead of [`fossil clone`][clone]
105 is likely to surprise a Git user. When we were [discussing][caod]
106 this, we considered following the Git command style, but we decided
107 against it because it goes against this core Fossil design principle:
108 given that the Fossil repo is separate from the check-out, why would you
109 expect asking for a repo clone to also create a check-out directory for
110 you? We view commingled repository + check-out as a design error in
111 Git, so why would we repeat the error?
112
113 To see why we see this behavior is error-prone, consider that
114 `git clean` must have an exception to avoid nuking the `.git` directory.
115 We had to add that complication to `fossil clean` when we added the
116 `fossil open URI` feature: it won’t nuke the repo DB file.
117
118 [clone]: /help?cmd=clone
119 [open]: /help?cmd=open
120
121
122 #### <a id="clone"></a> The Git Clone Way
123
124 This feature didn’t placate many Git fans, though, so with Fossil 2.14 —
125 currently unreleased — we now allow this:
126
127 fossil clone https://fossil-scm.org/fossil
 
128
129 This results in a `fossil.fossil` repo DB file and a `fossil/` working
130 directory.
131
132 Note that our `clone URI` behavior does not commingle the repo and
133 check-out, solving our major problem with the Git design, though we
134 still believe it to be confusing to have “clone” be part of “open,” and
135 still more confusing to have “open” part of “clone.” We prefer keeping
136 these operations entirely separate, either as at the [top of this
137 section](#scw) or [as in the prior one](#mcw). Still, please yourself.
138
139 If you want the repo to be named something else, adjust the URL:
140
141 fossil clone https://fossil-scm.org/fossil/fsl
142
@@ -149,8 +136,9 @@
149 fossil clone https://dev.example.com/repo/my-project
150
151 The `/repo` addition is the key: whatever comes after is used as the
152 repository name. [See the docs][clone] for more details.
153
154 [caod]: https://fossil-scm.org/forum/forumpost/3f143cec74
 
155
156 <div style="height:50em" id="this-space-intentionally-left-blank"></div>
157
--- www/ckout-workflows.md
+++ www/ckout-workflows.md
@@ -2,12 +2,11 @@
2
3 Because Fossil separates the concept of “check-out directory” from
4 “repository DB file,” it gives you the freedom to choose from several
5 working styles. Contrast Git, where the two concepts are normally
6 intermingled in a single working directory, which strongly encourages
7 the “update in place” working style.
 
8
9
10 ## <a id="mcw"></a> Multiple-Checkout Workflow
11
12 With Fossil, it is routine to have multiple check-outs from the same
@@ -48,13 +47,13 @@
47
48 Each check-out operates independently of the others.
49
50 This multiple-checkouts working style is especially useful when Fossil stores source code in programming languages
51 where there is a “build” step that transforms source files into files
52 you actually run or distribute. Contrast a switch-in-place workflow,
53 where you have to rebuild all outputs from the source files
54 that differ between those versions whenever you switch versions. In the above model,
55 you switch versions with a “`cd`” command instead, so that you only have
56 to rebuild outputs from files you yourself change.
57
58 This style is also useful when a check-out directory may be tied up with
59 some long-running process, as with the “test” example above, where you
@@ -72,13 +71,13 @@
71 Nevertheless, it is possible to work in a more typical Git sort of
72 style, switching between versions in a single check-out directory.
73
74 #### <a id="idiomatic"></a> The Idiomatic Fossil Way
75
76 The most idiomatic way is as follows:
 
77
78 fossil clone https://example.com/repo /path/to/repo.fossil
79 mkdir work-dir
80 cd work-dir
81 fossil open /path/to/repo.fossil
82 ...work on trunk...
83
@@ -87,56 +86,44 @@
86
87 Basically, you replace the `cd` commands in the multiple checkouts
88 workflow above with `fossil up` commands.
89
90
91 #### <a id="open"></a> Opening a Repository by URI
92
93 In Fossil 2.12, we added a feature to simplify the single-worktree use
94 case:
95
96 mkdir work-dir
97 cd work-dir
98 fossil open https://example.com/repo
99
100 Now you have “trunk” open in `work-dir`, with the repo file stored as
101 `repo.fossil` in that same directory.
102
103 Users of Git may be surprised that it doesn’t create a directory for you
104 and that you `cd` into it *before* the clone-and-open step, not after.
105 This is because we’re overloading the “open” command, which already had
106 the behavior of opening into the current working directory. Changing it
107 to behave like `git clone` would therefore make the behavior surprising
108 to Fossil users. (See [our discussions][caod] if you want the full
109 details.)
110
111
112 #### <a id="clone"></a> Git-Like Clone-and-Open
113
114 With Fossil 2.14 — currently unreleased — we added a more Git-like
115 alternative:
 
 
 
 
 
 
 
 
 
116
117 fossil clone https://fossil-scm.org/fossil
118 cd fossil
119
120 This results in a `fossil.fossil` repo DB file and a `fossil/` working
121 directory.
122
123 Note that our `clone URI` behavior does not commingle the repo and
124 check-out, solving our major problem with the Git design.
 
 
 
 
125
126 If you want the repo to be named something else, adjust the URL:
127
128 fossil clone https://fossil-scm.org/fossil/fsl
129
@@ -149,8 +136,9 @@
136 fossil clone https://dev.example.com/repo/my-project
137
138 The `/repo` addition is the key: whatever comes after is used as the
139 repository name. [See the docs][clone] for more details.
140
141 [caod]: https://fossil-scm.org/forum/forumpost/3f143cec74
142 [clone]: /help?cmd=clone
143
144 <div style="height:50em" id="this-space-intentionally-left-blank"></div>
145
--- www/fossil-v-git.wiki
+++ www/fossil-v-git.wiki
@@ -43,22 +43,22 @@
4343
<td>VCS, tickets, wiki, docs, notes, forum, UI,
4444
[https://en.wikipedia.org/wiki/Role-based_access_control|RBAC]</td>
4545
<td><a href="#features">2.1&nbsp;&darr;</a></td>
4646
</tr>
4747
<tr>
48
- <td>Sprawling and inefficient</td>
49
- <td>Self-contained and efficient</td>
50
- <td><a href="#efficient">2.2&nbsp;&darr;</a></td>
48
+ <td>A federation of many small programs</td>
49
+ <td>One self-contained, stand-alone executable</td>
50
+ <td><a href="#selfcontained">2.2&nbsp;&darr;</a></td>
5151
</tr>
5252
<tr>
53
- <td>One-off custom pile-of-files data store</td>
54
- <td>[https://sqlite.org/famous.html|The most popular database in the world]</td>
53
+ <td>Custom key/value data store</td>
54
+ <td>[https://sqlite.org/mostdeployed.html|The most used SQL database in the world]</td>
5555
<td><a href="#durable">2.3&nbsp;&darr;</a></td>
5656
</tr>
5757
<tr>
58
- <td>Runs natively on POSIX systems only</td>
59
- <td>Native on common desktop & server platforms</td>
58
+ <td>Runs natively on POSIX systems</td>
59
+ <td>Runs natively on both POSIX and Windows</td>
6060
<td><a href="#portable">2.4&nbsp;&darr;</a></td>
6161
</tr>
6262
<tr>
6363
<td>Bazaar-style development</td>
6464
<td>Cathedral-style development</td>
@@ -93,12 +93,12 @@
9393
<td>Commit first</td>
9494
<td>Test first</td>
9595
<td><a href="#testing">2.8&nbsp;&darr;</a></td>
9696
</tr>
9797
<tr>
98
- <td>SHA-2</td>
99
- <td>SHA-3</td>
98
+ <td>SHA-1 or SHA-2</td>
99
+ <td>SHA-1 and/or SHA-3, in the same repository</td>
100100
<td><a href="#hash">2.9&nbsp;&darr;</a></td>
101101
</tr>
102102
</table></blockquote>
103103
104104
<h3 id="features">2.1 Featureful</h3>
@@ -117,16 +117,16 @@
117117
the design. One way to describe Fossil is that it is
118118
"[https://github.com/ | GitHub]-in-a-box."
119119
120120
Fossil can do operations over all local repo clones and check-out
121121
directories with a single command. For example, Fossil lets you say
122
-<tt>fossil all sync</tt> on a laptop prior to taking it off the network
122
+"<tt>fossil all sync</tt>" on a laptop prior to taking it off the network
123123
hosting those repos. You can sync up to all of the private repos on your
124124
company network plus those public Internet-hosted repos you use. Whether
125125
going out for a working lunch or on a transoceanic airplane trip, one
126126
command gets you in sync. This works with several other Fossil
127
-sub-commands, such as <tt>fossil all changes</tt> to get a list of files
127
+sub-commands, such as "<tt>fossil all changes</tt>" to get a list of files
128128
that you forgot to commit prior to the end of your working day, across
129129
all repos.
130130
131131
Whenever Fossil is told to modify the local checkout in some destructive
132132
way ([/help?cmd=rm|fossil rm], [/help?cmd=update|fossil update],
@@ -154,11 +154,11 @@
154154
history, and so forth.² That means you get a copy of this very article
155155
and all of its historical versions, plus the same for all of the other
156156
public content on this site.
157157
158158
159
-<h3 id="efficient" name="effective">2.2 Efficient</h3>
159
+<h3 id="selfcontained" name="selfcontained">2.2 Self Contained</h3>
160160
161161
Git is actually a collection of many small tools, each doing one small
162162
part of the job, which can be recombined (by experts) to perform
163163
powerful operations. Git has a lot of complexity and many dependencies,
164164
so that most people end up installing it via some kind of package
@@ -165,28 +165,30 @@
165165
manager, simply because the creation of complicated binary packages is
166166
best delegated to people skilled in their creation. Normal Git users are
167167
not expected to build Git from source and install it themselves.
168168
169169
Fossil is a single self-contained stand-alone executable which by default
170
-depends only on common platform libraries. If your platform allows static
171
-linking &mdash; not all do these days! &mdash; you can even get it down to
172
-a single executable with no external dependencies at all. Most notably,
173
-we deliver the official Windows builds of Fossil this way: the Zip file
174
-contains only <tt>fossil.exe</tt>, a self-contained Fossil executable;
175
-it is not a <tt>setup.exe</tt> style installer, it is the whole enchilada.
176
-
177
-A typical Fossil executable is about 5&nbsp;MiB, not counting system
178
-libraries it shares in common with Git such as OpenSSL and zlib, which
179
-we can factor out of the discussion.
180
-
181
-These properties allow Fossil to easily run inside a minimally configured
182
-[https://en.wikipedia.org/wiki/Chroot|chroot jail], from a Windows memory
183
-stick, off a Raspberry Pi with a tiny SD card, etc. To install Fossil,
184
-one merely puts the executable somewhere in the <tt>$PATH</tt>. Fossil is
185
-[https://fossil-scm.org/fossil/doc/trunk/www/build.wiki|straightforward
186
-to build and install], so that many Fossil users do in fact build and
187
-install "trunk" versions to get new features between formal releases.
170
+depends only on common platform libraries. You can statically link
171
+to get an executable with no external dependencies at all &mdash; a useful
172
+feature for running inside of restrictive
173
+[https://en.wikipedia.org/wiki/Chroot|chroot jail].
174
+
175
+The precompiled Fossil binaries are delivered as just a single
176
+executable. The precompiled Windows deliveries are just a ZIP archive
177
+containing only "<tt>fossil.exe</tt>". There is no "<tt>setup.exe</tt>"
178
+to run. Linux and Mac precompiled binaries are a tarball containing
179
+just the "<tt>fossil</tt>" executable. To install, just put the
180
+executable on your PATH. To uninstall, just delete the executable.
181
+To upgrade (or downgrade) simply replace the executable.
182
+
183
+A typical Fossil executable is between 5 and 7 megabytes uncompressed
184
+(as of 2020-12-12),
185
+assuming that the executable is statically linked against OpenSSL.
186
+
187
+Fossil is easy to build from sources. Just run
188
+"<tt>./configure && make</tt>" on POSIX systems and
189
+"<tt>nmake /f Makefile.msc</tt>" on Windows.
188190
189191
Contrast a basic installation of Git, which takes up about
190192
15&nbsp;MiB on Debian 10 across 230 files, not counting the contents of
191193
<tt>/usr/share/doc</tt> or <tt>/usr/share/locale</tt>. If you need to
192194
deploy to any platform where you cannot count facilities like the POSIX
@@ -216,88 +218,92 @@
216218
resource hungry] and hence more costly to run than the equivalent
217219
Fossil setup. GitLab's basic requirements are easy to accept when you're dedicating
218220
a local rack server or blade to it, since its minimum requirements are
219221
more or less a description of the smallest
220222
thing you could call a "server" these days, but when you go to host that
221
-in the cloud, you can expect to pay about 8× as much to comfortably host
223
+in the cloud, you can expect to pay about 8 times as much to comfortably host
222224
GitLab as for Fossil.³ This difference is largely due to basic
223225
technology choices: Ruby and PostgreSQL vs C and SQLite.
224226
225
-The Fossil project itself is [./selfhost.wiki|hosted on a very small
226
-VPS], and we've received many reports on the Fossil forum about people
227
-successfully hosting Fossil service on bare-bones $5/month VPS hosts,
228
-spare Raspberry Pi boards, and other small hosts.
229
-
230
-
231
-
232
-<h3 id="durable" name="database">2.3 Durable</h3>
227
+The Fossil project itself is [./selfhost.wiki|hosted on a small and
228
+inexpensive VPS]. A bare-bones $5/month VPS or a
229
+spare Raspberry Pi is sufficient to run a full-up project
230
+site, complete with tickets, wiki, and forum, in addition to
231
+being a code repository.
232
+
233
+<h3 id="durable" name="database">2.3 Query Language</h3>
233234
234235
The baseline data structures for Fossil and Git are the same, modulo
235236
formatting details. Both systems manage a
236237
[https://en.wikipedia.org/wiki/Directed_acyclic_graph | directed acyclic
237238
graph] (DAG) of [https://en.wikipedia.org/wiki/Merkle_tree | Merkle
238239
tree] structured check-in objects.
239240
Check-ins are identified by a cryptographic hash of the check-in
240
-contents, and each check-in refers to its parent via <i>its</i> hash.
241
+contents, and each check-in refers to its parent via the parent's hash.
241242
242243
The difference is that Git stores its objects as individual files in the
243
-<tt>.git</tt> folder or compressed into bespoke
244
+<tt>.git</tt> folder or compressed into bespoke key/value
244245
[https://git-scm.com/book/en/v2/Git-Internals-Packfiles|pack-files],
245246
whereas Fossil stores its objects in a [https://www.sqlite.org/|SQLite]
246
-database file using a hybrid NoSQL/relational data model of the check-in
247
-history. Git's data storage system is an ad-hoc pile-of-files key/value
248
-database, whereas Fossil uses a proven,
249
-[https://sqlite.org/testing.html|heavily-tested], general-purpose,
250
-[https://sqlite.org/transactional.html|durable] SQL database. This
251
-difference is more than an implementation detail. It has important
247
+database file which provides ACID transactions and a high-level query
248
+language.
249
+This difference is more than an implementation detail. It has important
252250
practical consequences.
253251
254
-With Git, one can easily locate the ancestors of a particular check-in
252
+One notable consequence is that it is difficult to find the descendents
253
+of check-ins in Git.
254
+One can easily locate the ancestors of a particular Git check-in
255255
by following the pointers embedded in the check-in object, but it is
256256
difficult to go the other direction and locate the descendants of a
257257
check-in. It is so difficult, in fact, that neither native Git nor
258
-GitHub provide this capability short of
259
-[http://catb.org/jargon/html/G/grovel.html|groveling] the
260
-[https://www.git-scm.com/docs/git-log|commit log]. With Git, if you
261
-are looking at some historical check-in then you cannot ask "What came
262
-next?" or "What are the children of this check-in?"
263
-
264
-Fossil, on the other hand, parses essential information about check-ins
265
-(parents, children, committers, comments, files changed, etc.) into a
266
-relational database that can easily be queried using concise SQL
267
-statements to find both ancestors and descendants of a check-in. This is
268
-the hybrid data model mentioned above: Fossil manages your check-in and
269
-other data in a NoSQL block chain structured data store, but that's backed
270
-by a set of relational lookup tables for quick indexing into that
271
-artifact store. (See "[./theory1.wiki|Thoughts On The Design Of The
272
-Fossil DVCS]" for more details.)
258
+GitHub provide this capability short of crawling the
259
+[https://www.git-scm.com/docs/git-log|commit log]. With Fossil,
260
+on the other hand, finding descendents is a simple SQL query.
261
+It is common in Fossil to ask to see
262
+[/timeline?d=release&n=all&y=ci&nd|all check-ins since the last release].
263
+Git lets you see "what came before". Fossil makes it just as
264
+easy to also see "what came after".
273265
274266
Leaf check-ins in Git that lack a "ref" become "detached," making them
275267
difficult to locate and subject to garbage collection. This
276268
[http://gitfaq.org/articles/what-is-a-detached-head.html|detached head
277
-state] problem has caused untold grief for
278
-[https://www.google.com/search?q=git+detached+head+state | a huge number
269
+state] problem has caused grief for
270
+[https://www.google.com/search?q=git+detached+head+state | many
279271
of Git users]. With
280272
Fossil, detached heads are simply impossible because we can always find
281
-our way back into the block chain using one or more of the relational
282
-indices it automatically manages for you.
273
+our way back into the Merkle tree using one or more of the relations
274
+in the SQL database.
283275
284
-This design difference shows up in several other places within each
285
-tool. It is why Fossil's [/help?cmd=timeline|timeline] is generally more
286
-detailed yet more clear than those available in Git front-ends.
287
-(Contrast [/timeline?c=6df7a853ec16865b|this Fossil timeline] with
276
+The SQL query capabilities of Fossil make it easier to track the
277
+changes for one particular file within a project. For example,
278
+you can easily find
279
+[/finfo/www/fossil-v-git.wiki|the complete edit history of this one document],
280
+or even
281
+[/finfo/www/fossil-v-git.wiki?ubg|the same history color-coded by committer],
282
+Both questions are simple SQL query in Fossil, with procedural code
283
+only being used to format the result for display.
284
+The same result could be obtained from Git, but because the data is
285
+in a key/value store, much more procedural code has to be written to
286
+walk the data and compute the result. And since that is a lot more
287
+work, the question is seldom asked.
288
+
289
+The ease of querying Fossil data using SQL means that status or
290
+history information about the project under management is easier
291
+to obtain. And being easier means that it is more likely to happen.
292
+Fossil reports tend to be more detailed and useful.
293
+Consider the [/timeline?c=6df7a853ec16865b|this Fossil timeline]
294
+compared to its
288295
[https://github.com/drhsqlite/fossil-mirror/commits/master?after=f720c106d297ca1f61bccb30c5c191b88a626d01+34|its
289
-closest equivalent in GitHub].) It's why there is no inverse of the
290
-cryptic <tt>@~</tt> notation in Git, meaning "the parent of HEAD," which
291
-Fossil simply calls "prev", but there <i>is</i> a "next"
292
-[./checkin_names.wiki|special check-in name] in Fossil. It is why Fossil
293
-has so many [./webpage-ex.md|built-in status reports] to help maintain
294
-situational awareness, aid comprehension, and avoid errors.
295
-
296
-These differences are due, in part, to Fossil's start a year later than
297
-Git: we were able to learn from its key design mistakes.
298
-
296
+closest equivalent in GitHub]. Judge for yourself: Which of those
297
+reports is more useful to a developer trying to understand what happened?
298
+
299
+The bottom line is that even though Fossil and Git are built around
300
+the same low-level data structure, the use of SQL
301
+to query this data makes the data more accessible in Fossil, resulting
302
+in more detailed information being available to the user. This
303
+improves situational awareness and makes working on the project
304
+easier.
299305
300306
<h3 id="portable">2.4 Portable</h3>
301307
302308
Fossil is largely written in ISO C, almost purely conforming to the
303309
original 1989 standard. We make very little use of
@@ -530,12 +536,12 @@
530536
not the best way to hang a picture on the living room wall.
531537
532538
533539
<h4 id="contrib">2.5.3 Accepting Contributions</h4>
534540
535
-As of this writing, Git has received about 4.5⨉ as many commits as
536
-Fossil resulting in about 2.5⨉ as many lines of source code. The line
541
+As of this writing, Git has received about 4.5 times as many commits as
542
+Fossil resulting in about 2.5times as many lines of source code. The line
537543
count excludes tests and in-tree third-party dependencies. It does not
538544
exclude the default GUI for each, since it's integral for Fossil, so we
539545
count the size of <tt>gitk</tt> in this.
540546
541547
It is obvious that Git is bigger in part because of its first-mover
@@ -906,11 +912,11 @@
906912
Almost three years after Fossil solved this problem, the
907913
[https://sha-mbles.github.io/ | SHAmbles attack] was published, further
908914
weakening the case for continuing to use SHA-1.
909915
910916
The practical impact of attacks like SHAttered and SHAmbles on the
911
-Git and Fossil blockchains isn't clear, but you want to have your repositories
917
+Git and Fossil Merkle trees isn't clear, but you want to have your repositories
912918
moved over to a stronger hash algorithm before someone figures out how
913919
to make use of the weaknesses in the old one. Fossil has had this covered
914920
for years now, so that the solution is now almost universally deployed.
915921
916922
<hr/>
917923
--- www/fossil-v-git.wiki
+++ www/fossil-v-git.wiki
@@ -43,22 +43,22 @@
43 <td>VCS, tickets, wiki, docs, notes, forum, UI,
44 [https://en.wikipedia.org/wiki/Role-based_access_control|RBAC]</td>
45 <td><a href="#features">2.1&nbsp;&darr;</a></td>
46 </tr>
47 <tr>
48 <td>Sprawling and inefficient</td>
49 <td>Self-contained and efficient</td>
50 <td><a href="#efficient">2.2&nbsp;&darr;</a></td>
51 </tr>
52 <tr>
53 <td>One-off custom pile-of-files data store</td>
54 <td>[https://sqlite.org/famous.html|The most popular database in the world]</td>
55 <td><a href="#durable">2.3&nbsp;&darr;</a></td>
56 </tr>
57 <tr>
58 <td>Runs natively on POSIX systems only</td>
59 <td>Native on common desktop & server platforms</td>
60 <td><a href="#portable">2.4&nbsp;&darr;</a></td>
61 </tr>
62 <tr>
63 <td>Bazaar-style development</td>
64 <td>Cathedral-style development</td>
@@ -93,12 +93,12 @@
93 <td>Commit first</td>
94 <td>Test first</td>
95 <td><a href="#testing">2.8&nbsp;&darr;</a></td>
96 </tr>
97 <tr>
98 <td>SHA-2</td>
99 <td>SHA-3</td>
100 <td><a href="#hash">2.9&nbsp;&darr;</a></td>
101 </tr>
102 </table></blockquote>
103
104 <h3 id="features">2.1 Featureful</h3>
@@ -117,16 +117,16 @@
117 the design. One way to describe Fossil is that it is
118 "[https://github.com/ | GitHub]-in-a-box."
119
120 Fossil can do operations over all local repo clones and check-out
121 directories with a single command. For example, Fossil lets you say
122 <tt>fossil all sync</tt> on a laptop prior to taking it off the network
123 hosting those repos. You can sync up to all of the private repos on your
124 company network plus those public Internet-hosted repos you use. Whether
125 going out for a working lunch or on a transoceanic airplane trip, one
126 command gets you in sync. This works with several other Fossil
127 sub-commands, such as <tt>fossil all changes</tt> to get a list of files
128 that you forgot to commit prior to the end of your working day, across
129 all repos.
130
131 Whenever Fossil is told to modify the local checkout in some destructive
132 way ([/help?cmd=rm|fossil rm], [/help?cmd=update|fossil update],
@@ -154,11 +154,11 @@
154 history, and so forth.² That means you get a copy of this very article
155 and all of its historical versions, plus the same for all of the other
156 public content on this site.
157
158
159 <h3 id="efficient" name="effective">2.2 Efficient</h3>
160
161 Git is actually a collection of many small tools, each doing one small
162 part of the job, which can be recombined (by experts) to perform
163 powerful operations. Git has a lot of complexity and many dependencies,
164 so that most people end up installing it via some kind of package
@@ -165,28 +165,30 @@
165 manager, simply because the creation of complicated binary packages is
166 best delegated to people skilled in their creation. Normal Git users are
167 not expected to build Git from source and install it themselves.
168
169 Fossil is a single self-contained stand-alone executable which by default
170 depends only on common platform libraries. If your platform allows static
171 linking &mdash; not all do these days! &mdash; you can even get it down to
172 a single executable with no external dependencies at all. Most notably,
173 we deliver the official Windows builds of Fossil this way: the Zip file
174 contains only <tt>fossil.exe</tt>, a self-contained Fossil executable;
175 it is not a <tt>setup.exe</tt> style installer, it is the whole enchilada.
176
177 A typical Fossil executable is about 5&nbsp;MiB, not counting system
178 libraries it shares in common with Git such as OpenSSL and zlib, which
179 we can factor out of the discussion.
180
181 These properties allow Fossil to easily run inside a minimally configured
182 [https://en.wikipedia.org/wiki/Chroot|chroot jail], from a Windows memory
183 stick, off a Raspberry Pi with a tiny SD card, etc. To install Fossil,
184 one merely puts the executable somewhere in the <tt>$PATH</tt>. Fossil is
185 [https://fossil-scm.org/fossil/doc/trunk/www/build.wiki|straightforward
186 to build and install], so that many Fossil users do in fact build and
187 install "trunk" versions to get new features between formal releases.
 
 
188
189 Contrast a basic installation of Git, which takes up about
190 15&nbsp;MiB on Debian 10 across 230 files, not counting the contents of
191 <tt>/usr/share/doc</tt> or <tt>/usr/share/locale</tt>. If you need to
192 deploy to any platform where you cannot count facilities like the POSIX
@@ -216,88 +218,92 @@
216 resource hungry] and hence more costly to run than the equivalent
217 Fossil setup. GitLab's basic requirements are easy to accept when you're dedicating
218 a local rack server or blade to it, since its minimum requirements are
219 more or less a description of the smallest
220 thing you could call a "server" these days, but when you go to host that
221 in the cloud, you can expect to pay about 8× as much to comfortably host
222 GitLab as for Fossil.³ This difference is largely due to basic
223 technology choices: Ruby and PostgreSQL vs C and SQLite.
224
225 The Fossil project itself is [./selfhost.wiki|hosted on a very small
226 VPS], and we've received many reports on the Fossil forum about people
227 successfully hosting Fossil service on bare-bones $5/month VPS hosts,
228 spare Raspberry Pi boards, and other small hosts.
229
230
231
232 <h3 id="durable" name="database">2.3 Durable</h3>
233
234 The baseline data structures for Fossil and Git are the same, modulo
235 formatting details. Both systems manage a
236 [https://en.wikipedia.org/wiki/Directed_acyclic_graph | directed acyclic
237 graph] (DAG) of [https://en.wikipedia.org/wiki/Merkle_tree | Merkle
238 tree] structured check-in objects.
239 Check-ins are identified by a cryptographic hash of the check-in
240 contents, and each check-in refers to its parent via <i>its</i> hash.
241
242 The difference is that Git stores its objects as individual files in the
243 <tt>.git</tt> folder or compressed into bespoke
244 [https://git-scm.com/book/en/v2/Git-Internals-Packfiles|pack-files],
245 whereas Fossil stores its objects in a [https://www.sqlite.org/|SQLite]
246 database file using a hybrid NoSQL/relational data model of the check-in
247 history. Git's data storage system is an ad-hoc pile-of-files key/value
248 database, whereas Fossil uses a proven,
249 [https://sqlite.org/testing.html|heavily-tested], general-purpose,
250 [https://sqlite.org/transactional.html|durable] SQL database. This
251 difference is more than an implementation detail. It has important
252 practical consequences.
253
254 With Git, one can easily locate the ancestors of a particular check-in
 
 
255 by following the pointers embedded in the check-in object, but it is
256 difficult to go the other direction and locate the descendants of a
257 check-in. It is so difficult, in fact, that neither native Git nor
258 GitHub provide this capability short of
259 [http://catb.org/jargon/html/G/grovel.html|groveling] the
260 [https://www.git-scm.com/docs/git-log|commit log]. With Git, if you
261 are looking at some historical check-in then you cannot ask "What came
262 next?" or "What are the children of this check-in?"
263
264 Fossil, on the other hand, parses essential information about check-ins
265 (parents, children, committers, comments, files changed, etc.) into a
266 relational database that can easily be queried using concise SQL
267 statements to find both ancestors and descendants of a check-in. This is
268 the hybrid data model mentioned above: Fossil manages your check-in and
269 other data in a NoSQL block chain structured data store, but that's backed
270 by a set of relational lookup tables for quick indexing into that
271 artifact store. (See "[./theory1.wiki|Thoughts On The Design Of The
272 Fossil DVCS]" for more details.)
273
274 Leaf check-ins in Git that lack a "ref" become "detached," making them
275 difficult to locate and subject to garbage collection. This
276 [http://gitfaq.org/articles/what-is-a-detached-head.html|detached head
277 state] problem has caused untold grief for
278 [https://www.google.com/search?q=git+detached+head+state | a huge number
279 of Git users]. With
280 Fossil, detached heads are simply impossible because we can always find
281 our way back into the block chain using one or more of the relational
282 indices it automatically manages for you.
283
284 This design difference shows up in several other places within each
285 tool. It is why Fossil's [/help?cmd=timeline|timeline] is generally more
286 detailed yet more clear than those available in Git front-ends.
287 (Contrast [/timeline?c=6df7a853ec16865b|this Fossil timeline] with
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
288 [https://github.com/drhsqlite/fossil-mirror/commits/master?after=f720c106d297ca1f61bccb30c5c191b88a626d01+34|its
289 closest equivalent in GitHub].) It's why there is no inverse of the
290 cryptic <tt>@~</tt> notation in Git, meaning "the parent of HEAD," which
291 Fossil simply calls "prev", but there <i>is</i> a "next"
292 [./checkin_names.wiki|special check-in name] in Fossil. It is why Fossil
293 has so many [./webpage-ex.md|built-in status reports] to help maintain
294 situational awareness, aid comprehension, and avoid errors.
295
296 These differences are due, in part, to Fossil's start a year later than
297 Git: we were able to learn from its key design mistakes.
298
299
300 <h3 id="portable">2.4 Portable</h3>
301
302 Fossil is largely written in ISO C, almost purely conforming to the
303 original 1989 standard. We make very little use of
@@ -530,12 +536,12 @@
530 not the best way to hang a picture on the living room wall.
531
532
533 <h4 id="contrib">2.5.3 Accepting Contributions</h4>
534
535 As of this writing, Git has received about 4.5⨉ as many commits as
536 Fossil resulting in about 2.5⨉ as many lines of source code. The line
537 count excludes tests and in-tree third-party dependencies. It does not
538 exclude the default GUI for each, since it's integral for Fossil, so we
539 count the size of <tt>gitk</tt> in this.
540
541 It is obvious that Git is bigger in part because of its first-mover
@@ -906,11 +912,11 @@
906 Almost three years after Fossil solved this problem, the
907 [https://sha-mbles.github.io/ | SHAmbles attack] was published, further
908 weakening the case for continuing to use SHA-1.
909
910 The practical impact of attacks like SHAttered and SHAmbles on the
911 Git and Fossil blockchains isn't clear, but you want to have your repositories
912 moved over to a stronger hash algorithm before someone figures out how
913 to make use of the weaknesses in the old one. Fossil has had this covered
914 for years now, so that the solution is now almost universally deployed.
915
916 <hr/>
917
--- www/fossil-v-git.wiki
+++ www/fossil-v-git.wiki
@@ -43,22 +43,22 @@
43 <td>VCS, tickets, wiki, docs, notes, forum, UI,
44 [https://en.wikipedia.org/wiki/Role-based_access_control|RBAC]</td>
45 <td><a href="#features">2.1&nbsp;&darr;</a></td>
46 </tr>
47 <tr>
48 <td>A federation of many small programs</td>
49 <td>One self-contained, stand-alone executable</td>
50 <td><a href="#selfcontained">2.2&nbsp;&darr;</a></td>
51 </tr>
52 <tr>
53 <td>Custom key/value data store</td>
54 <td>[https://sqlite.org/mostdeployed.html|The most used SQL database in the world]</td>
55 <td><a href="#durable">2.3&nbsp;&darr;</a></td>
56 </tr>
57 <tr>
58 <td>Runs natively on POSIX systems</td>
59 <td>Runs natively on both POSIX and Windows</td>
60 <td><a href="#portable">2.4&nbsp;&darr;</a></td>
61 </tr>
62 <tr>
63 <td>Bazaar-style development</td>
64 <td>Cathedral-style development</td>
@@ -93,12 +93,12 @@
93 <td>Commit first</td>
94 <td>Test first</td>
95 <td><a href="#testing">2.8&nbsp;&darr;</a></td>
96 </tr>
97 <tr>
98 <td>SHA-1 or SHA-2</td>
99 <td>SHA-1 and/or SHA-3, in the same repository</td>
100 <td><a href="#hash">2.9&nbsp;&darr;</a></td>
101 </tr>
102 </table></blockquote>
103
104 <h3 id="features">2.1 Featureful</h3>
@@ -117,16 +117,16 @@
117 the design. One way to describe Fossil is that it is
118 "[https://github.com/ | GitHub]-in-a-box."
119
120 Fossil can do operations over all local repo clones and check-out
121 directories with a single command. For example, Fossil lets you say
122 "<tt>fossil all sync</tt>" on a laptop prior to taking it off the network
123 hosting those repos. You can sync up to all of the private repos on your
124 company network plus those public Internet-hosted repos you use. Whether
125 going out for a working lunch or on a transoceanic airplane trip, one
126 command gets you in sync. This works with several other Fossil
127 sub-commands, such as "<tt>fossil all changes</tt>" to get a list of files
128 that you forgot to commit prior to the end of your working day, across
129 all repos.
130
131 Whenever Fossil is told to modify the local checkout in some destructive
132 way ([/help?cmd=rm|fossil rm], [/help?cmd=update|fossil update],
@@ -154,11 +154,11 @@
154 history, and so forth.² That means you get a copy of this very article
155 and all of its historical versions, plus the same for all of the other
156 public content on this site.
157
158
159 <h3 id="selfcontained" name="selfcontained">2.2 Self Contained</h3>
160
161 Git is actually a collection of many small tools, each doing one small
162 part of the job, which can be recombined (by experts) to perform
163 powerful operations. Git has a lot of complexity and many dependencies,
164 so that most people end up installing it via some kind of package
@@ -165,28 +165,30 @@
165 manager, simply because the creation of complicated binary packages is
166 best delegated to people skilled in their creation. Normal Git users are
167 not expected to build Git from source and install it themselves.
168
169 Fossil is a single self-contained stand-alone executable which by default
170 depends only on common platform libraries. You can statically link
171 to get an executable with no external dependencies at all &mdash; a useful
172 feature for running inside of restrictive
173 [https://en.wikipedia.org/wiki/Chroot|chroot jail].
174
175 The precompiled Fossil binaries are delivered as just a single
176 executable. The precompiled Windows deliveries are just a ZIP archive
177 containing only "<tt>fossil.exe</tt>". There is no "<tt>setup.exe</tt>"
178 to run. Linux and Mac precompiled binaries are a tarball containing
179 just the "<tt>fossil</tt>" executable. To install, just put the
180 executable on your PATH. To uninstall, just delete the executable.
181 To upgrade (or downgrade) simply replace the executable.
182
183 A typical Fossil executable is between 5 and 7 megabytes uncompressed
184 (as of 2020-12-12),
185 assuming that the executable is statically linked against OpenSSL.
186
187 Fossil is easy to build from sources. Just run
188 "<tt>./configure && make</tt>" on POSIX systems and
189 "<tt>nmake /f Makefile.msc</tt>" on Windows.
190
191 Contrast a basic installation of Git, which takes up about
192 15&nbsp;MiB on Debian 10 across 230 files, not counting the contents of
193 <tt>/usr/share/doc</tt> or <tt>/usr/share/locale</tt>. If you need to
194 deploy to any platform where you cannot count facilities like the POSIX
@@ -216,88 +218,92 @@
218 resource hungry] and hence more costly to run than the equivalent
219 Fossil setup. GitLab's basic requirements are easy to accept when you're dedicating
220 a local rack server or blade to it, since its minimum requirements are
221 more or less a description of the smallest
222 thing you could call a "server" these days, but when you go to host that
223 in the cloud, you can expect to pay about 8 times as much to comfortably host
224 GitLab as for Fossil.³ This difference is largely due to basic
225 technology choices: Ruby and PostgreSQL vs C and SQLite.
226
227 The Fossil project itself is [./selfhost.wiki|hosted on a small and
228 inexpensive VPS]. A bare-bones $5/month VPS or a
229 spare Raspberry Pi is sufficient to run a full-up project
230 site, complete with tickets, wiki, and forum, in addition to
231 being a code repository.
232
233 <h3 id="durable" name="database">2.3 Query Language</h3>
 
234
235 The baseline data structures for Fossil and Git are the same, modulo
236 formatting details. Both systems manage a
237 [https://en.wikipedia.org/wiki/Directed_acyclic_graph | directed acyclic
238 graph] (DAG) of [https://en.wikipedia.org/wiki/Merkle_tree | Merkle
239 tree] structured check-in objects.
240 Check-ins are identified by a cryptographic hash of the check-in
241 contents, and each check-in refers to its parent via the parent's hash.
242
243 The difference is that Git stores its objects as individual files in the
244 <tt>.git</tt> folder or compressed into bespoke key/value
245 [https://git-scm.com/book/en/v2/Git-Internals-Packfiles|pack-files],
246 whereas Fossil stores its objects in a [https://www.sqlite.org/|SQLite]
247 database file which provides ACID transactions and a high-level query
248 language.
249 This difference is more than an implementation detail. It has important
 
 
 
250 practical consequences.
251
252 One notable consequence is that it is difficult to find the descendents
253 of check-ins in Git.
254 One can easily locate the ancestors of a particular Git check-in
255 by following the pointers embedded in the check-in object, but it is
256 difficult to go the other direction and locate the descendants of a
257 check-in. It is so difficult, in fact, that neither native Git nor
258 GitHub provide this capability short of crawling the
259 [https://www.git-scm.com/docs/git-log|commit log]. With Fossil,
260 on the other hand, finding descendents is a simple SQL query.
261 It is common in Fossil to ask to see
262 [/timeline?d=release&n=all&y=ci&nd|all check-ins since the last release].
263 Git lets you see "what came before". Fossil makes it just as
264 easy to also see "what came after".
 
 
 
 
 
 
 
 
265
266 Leaf check-ins in Git that lack a "ref" become "detached," making them
267 difficult to locate and subject to garbage collection. This
268 [http://gitfaq.org/articles/what-is-a-detached-head.html|detached head
269 state] problem has caused grief for
270 [https://www.google.com/search?q=git+detached+head+state | many
271 of Git users]. With
272 Fossil, detached heads are simply impossible because we can always find
273 our way back into the Merkle tree using one or more of the relations
274 in the SQL database.
275
276 The SQL query capabilities of Fossil make it easier to track the
277 changes for one particular file within a project. For example,
278 you can easily find
279 [/finfo/www/fossil-v-git.wiki|the complete edit history of this one document],
280 or even
281 [/finfo/www/fossil-v-git.wiki?ubg|the same history color-coded by committer],
282 Both questions are simple SQL query in Fossil, with procedural code
283 only being used to format the result for display.
284 The same result could be obtained from Git, but because the data is
285 in a key/value store, much more procedural code has to be written to
286 walk the data and compute the result. And since that is a lot more
287 work, the question is seldom asked.
288
289 The ease of querying Fossil data using SQL means that status or
290 history information about the project under management is easier
291 to obtain. And being easier means that it is more likely to happen.
292 Fossil reports tend to be more detailed and useful.
293 Consider the [/timeline?c=6df7a853ec16865b|this Fossil timeline]
294 compared to its
295 [https://github.com/drhsqlite/fossil-mirror/commits/master?after=f720c106d297ca1f61bccb30c5c191b88a626d01+34|its
296 closest equivalent in GitHub]. Judge for yourself: Which of those
297 reports is more useful to a developer trying to understand what happened?
298
299 The bottom line is that even though Fossil and Git are built around
300 the same low-level data structure, the use of SQL
301 to query this data makes the data more accessible in Fossil, resulting
302 in more detailed information being available to the user. This
303 improves situational awareness and makes working on the project
304 easier.
 
305
306 <h3 id="portable">2.4 Portable</h3>
307
308 Fossil is largely written in ISO C, almost purely conforming to the
309 original 1989 standard. We make very little use of
@@ -530,12 +536,12 @@
536 not the best way to hang a picture on the living room wall.
537
538
539 <h4 id="contrib">2.5.3 Accepting Contributions</h4>
540
541 As of this writing, Git has received about 4.5 times as many commits as
542 Fossil resulting in about 2.5times as many lines of source code. The line
543 count excludes tests and in-tree third-party dependencies. It does not
544 exclude the default GUI for each, since it's integral for Fossil, so we
545 count the size of <tt>gitk</tt> in this.
546
547 It is obvious that Git is bigger in part because of its first-mover
@@ -906,11 +912,11 @@
912 Almost three years after Fossil solved this problem, the
913 [https://sha-mbles.github.io/ | SHAmbles attack] was published, further
914 weakening the case for continuing to use SHA-1.
915
916 The practical impact of attacks like SHAttered and SHAmbles on the
917 Git and Fossil Merkle trees isn't clear, but you want to have your repositories
918 moved over to a stronger hash algorithm before someone figures out how
919 to make use of the weaknesses in the old one. Fossil has had this covered
920 for years now, so that the solution is now almost universally deployed.
921
922 <hr/>
923
+61 -13
--- www/gitusers.md
+++ www/gitusers.md
@@ -467,14 +467,50 @@
467467
If you only want to commit _some_ of the changes, list the names
468468
of the files or directories you want to commit as arguments, like this:
469469
470470
fossil commit src/feature.c doc/feature.md examples/feature
471471
472
-There are currently no interactive patching features in Fossil like
473
-`git add --patch/-p` or `git commit -p`. [Contributions welcome!][ctrb]
472
+Although there are currently no
473
+<a id="csplit"></a>[commit splitting][gcspl] features in Fossil like
474
+`git add -p`, `git commit -p`, or `git rebase -i`, you can get the same
475
+effect by converting an uncommitted change set to a patch and then
476
+running it through [Patchouli].
474477
475
-[ctrb]: https://fossil-scm.org/fossil/doc/trunk/www/contribute.wiki
478
+Rather than use `fossil diff -i` to produce such a patch, a safer and
479
+more idiomatic method would be:
480
+
481
+ fossil stash save -m 'my big ball-o-hackage'
482
+ fossil stash diff > my-changes.patch
483
+
484
+That stores your changes in the stash, then lets you operate on a copy
485
+of that patch. Each time you re-run the second command, it will take the
486
+current state of the working directory into account to produce a
487
+potentially different patch, likely smaller because it leaves out patch
488
+hunks already applied.
489
+
490
+In this way, the combination of working tree and stash replaces the need
491
+for Git’s index feature.
492
+
493
+This also solves a philosophical problem with `git commit -p`: how can
494
+you test that a split commit doesn’t break anything if you do it as part
495
+of the commit action? Git’s lack of an autosync feature means you can
496
+commit locally and then rewrite history if the commit doesn’t work out,
497
+but we’d rather make changes only to the working directory, test the
498
+changes there, and only commit once we’re sure it’s right.
499
+
500
+This also explains why we don’t have anything like `git rebase -i`
501
+to split an existing commit: in Fossil, commits are *commitments,* not
502
+something you want to go back and rewrite later.
503
+
504
+If someone does [contribute][ctrb] a commit splitting feature to Fossil,
505
+we’d expect it to be an interactive form of
506
+[`fossil stash apply`][stash], rather than follow Git’s ill-considered
507
+design leads.
508
+
509
+[ctrb]: https://fossil-scm.org/fossil/doc/trunk/www/contribute.wiki
510
+[gcspl]: https://git-scm.com/docs/git-rebase#_splitting_commits
511
+[Patchouli]: https://pypi.org/project/patchouli/
476512
477513
478514
<a id="bneed"></a>
479515
## Create Branches At Point Of Need, Rather Than Ahead of Need
480516
@@ -632,10 +668,14 @@
632668
draft was written, it’s been revised multiple times to address less
633669
common objections as well. Chances are not good that you are going to
634670
come up with a new objection that we haven’t already considered and
635671
addressed there.
636672
673
+There is only one sub-feature of `git rebase` that is philosophically
674
+compatible with Fossil yet which currently has no functional equivalent.
675
+We cover [this and the workaround for it](#csplit) above.
676
+
637677
[3]: ./rebaseharm.md
638678
639679
640680
## <a id="show"></a> Showing Information About Commits
641681
@@ -687,20 +727,28 @@
687727
view][infow], though.
688728
689729
690730
#### <a name="dstat"></a> Diff Statistics
691731
692
-Fossil doesn’t have an internal equivalent to commands like
693
-`git show --stat`, but it’s easily remedied by using
694
-[the widely-available `diffstat` tool][dst]:
695
-
696
- fossil diff -i --from 2020-04-01 | diffstat
697
-
698
-We gave the `-i` flag here to force Fossil to use its internal diff
699
-implementation, bypassing [your local `diff-command` setting][dcset].
700
-If you had that set to [`colordiff`][cdiff], for example, its output
701
-would confuse `diffstat`.
732
+Fossil’s closest internal equivalent to commands like
733
+`git show --stat` is:
734
+
735
+ fossil diff -i --from 2020-04-01 --numstat
736
+
737
+The `--numstat` output is a bit cryptic, so we recommend delegating
738
+this task to [the widely-available `diffstat` tool][dst]:
739
+
740
+ fossil diff -i -N --from 2020-04-01 | diffstat
741
+
742
+We gave the `-i` flag in both cases to force Fossil to use its internal
743
+diff implementation, bypassing [your local `diff-command` setting][dcset].
744
+The `--numstat` option has no effect when you have an external diff
745
+command set, and some diff command alternatives like
746
+[`colordiff`][cdiff] produce output that confuses `diffstat`.
747
+
748
+If you leave off the `-N` flag in the second example, the `diffstat`
749
+output won’t include info about any newly-added files.
702750
703751
[cdiff]: https://www.colordiff.org/
704752
[dcset]: https://fossil-scm.org/home/help?cmd=diff-command
705753
[dst]: https://invisible-island.net/diffstat/diffstat.html
706754
707755
--- www/gitusers.md
+++ www/gitusers.md
@@ -467,14 +467,50 @@
467 If you only want to commit _some_ of the changes, list the names
468 of the files or directories you want to commit as arguments, like this:
469
470 fossil commit src/feature.c doc/feature.md examples/feature
471
472 There are currently no interactive patching features in Fossil like
473 `git add --patch/-p` or `git commit -p`. [Contributions welcome!][ctrb]
 
 
 
474
475 [ctrb]: https://fossil-scm.org/fossil/doc/trunk/www/contribute.wiki
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
476
477
478 <a id="bneed"></a>
479 ## Create Branches At Point Of Need, Rather Than Ahead of Need
480
@@ -632,10 +668,14 @@
632 draft was written, it’s been revised multiple times to address less
633 common objections as well. Chances are not good that you are going to
634 come up with a new objection that we haven’t already considered and
635 addressed there.
636
 
 
 
 
637 [3]: ./rebaseharm.md
638
639
640 ## <a id="show"></a> Showing Information About Commits
641
@@ -687,20 +727,28 @@
687 view][infow], though.
688
689
690 #### <a name="dstat"></a> Diff Statistics
691
692 Fossil doesn’t have an internal equivalent to commands like
693 `git show --stat`, but it’s easily remedied by using
694 [the widely-available `diffstat` tool][dst]:
695
696 fossil diff -i --from 2020-04-01 | diffstat
697
698 We gave the `-i` flag here to force Fossil to use its internal diff
699 implementation, bypassing [your local `diff-command` setting][dcset].
700 If you had that set to [`colordiff`][cdiff], for example, its output
701 would confuse `diffstat`.
 
 
 
 
 
 
 
 
702
703 [cdiff]: https://www.colordiff.org/
704 [dcset]: https://fossil-scm.org/home/help?cmd=diff-command
705 [dst]: https://invisible-island.net/diffstat/diffstat.html
706
707
--- www/gitusers.md
+++ www/gitusers.md
@@ -467,14 +467,50 @@
467 If you only want to commit _some_ of the changes, list the names
468 of the files or directories you want to commit as arguments, like this:
469
470 fossil commit src/feature.c doc/feature.md examples/feature
471
472 Although there are currently no
473 <a id="csplit"></a>[commit splitting][gcspl] features in Fossil like
474 `git add -p`, `git commit -p`, or `git rebase -i`, you can get the same
475 effect by converting an uncommitted change set to a patch and then
476 running it through [Patchouli].
477
478 Rather than use `fossil diff -i` to produce such a patch, a safer and
479 more idiomatic method would be:
480
481 fossil stash save -m 'my big ball-o-hackage'
482 fossil stash diff > my-changes.patch
483
484 That stores your changes in the stash, then lets you operate on a copy
485 of that patch. Each time you re-run the second command, it will take the
486 current state of the working directory into account to produce a
487 potentially different patch, likely smaller because it leaves out patch
488 hunks already applied.
489
490 In this way, the combination of working tree and stash replaces the need
491 for Git’s index feature.
492
493 This also solves a philosophical problem with `git commit -p`: how can
494 you test that a split commit doesn’t break anything if you do it as part
495 of the commit action? Git’s lack of an autosync feature means you can
496 commit locally and then rewrite history if the commit doesn’t work out,
497 but we’d rather make changes only to the working directory, test the
498 changes there, and only commit once we’re sure it’s right.
499
500 This also explains why we don’t have anything like `git rebase -i`
501 to split an existing commit: in Fossil, commits are *commitments,* not
502 something you want to go back and rewrite later.
503
504 If someone does [contribute][ctrb] a commit splitting feature to Fossil,
505 we’d expect it to be an interactive form of
506 [`fossil stash apply`][stash], rather than follow Git’s ill-considered
507 design leads.
508
509 [ctrb]: https://fossil-scm.org/fossil/doc/trunk/www/contribute.wiki
510 [gcspl]: https://git-scm.com/docs/git-rebase#_splitting_commits
511 [Patchouli]: https://pypi.org/project/patchouli/
512
513
514 <a id="bneed"></a>
515 ## Create Branches At Point Of Need, Rather Than Ahead of Need
516
@@ -632,10 +668,14 @@
668 draft was written, it’s been revised multiple times to address less
669 common objections as well. Chances are not good that you are going to
670 come up with a new objection that we haven’t already considered and
671 addressed there.
672
673 There is only one sub-feature of `git rebase` that is philosophically
674 compatible with Fossil yet which currently has no functional equivalent.
675 We cover [this and the workaround for it](#csplit) above.
676
677 [3]: ./rebaseharm.md
678
679
680 ## <a id="show"></a> Showing Information About Commits
681
@@ -687,20 +727,28 @@
727 view][infow], though.
728
729
730 #### <a name="dstat"></a> Diff Statistics
731
732 Fossil’s closest internal equivalent to commands like
733 `git show --stat` is:
734
735 fossil diff -i --from 2020-04-01 --numstat
736
737 The `--numstat` output is a bit cryptic, so we recommend delegating
738 this task to [the widely-available `diffstat` tool][dst]:
739
740 fossil diff -i -N --from 2020-04-01 | diffstat
741
742 We gave the `-i` flag in both cases to force Fossil to use its internal
743 diff implementation, bypassing [your local `diff-command` setting][dcset].
744 The `--numstat` option has no effect when you have an external diff
745 command set, and some diff command alternatives like
746 [`colordiff`][cdiff] produce output that confuses `diffstat`.
747
748 If you leave off the `-N` flag in the second example, the `diffstat`
749 output won’t include info about any newly-added files.
750
751 [cdiff]: https://www.colordiff.org/
752 [dcset]: https://fossil-scm.org/home/help?cmd=diff-command
753 [dst]: https://invisible-island.net/diffstat/diffstat.html
754
755
+28 -45
--- www/rebaseharm.md
+++ www/rebaseharm.md
@@ -298,63 +298,46 @@
298298
## <a name="lying"></a>5.0 Rebasing is lying about the project history
299299
300300
By discarding parentage information, rebase attempts to deceive the
301301
reader about how the code actually came together.
302302
303
-The [Git rebase documentation][gitrebase] admits as much. They acknowledge
304
-that when you view a repository as record of what actually happened,
305
-doing a rebase is "blasphemous" and "you're _lying_ about what
306
-actually happened", but then goes on to justify rebase as follows:
307
-
308
->
309
-_"The opposing point of view is that the commit history is the **story of
310
-how your project was made.** You wouldn't publish the first draft of a
311
-book, and the manual for how to maintain your software deserves careful
312
-editing. This is the camp that uses tools like rebase and filter-branch
313
-to tell the story in the way that's best for future readers."_
314
-
315
-This counter-argument assumes you must
316
-change history in order to enhance readability, which is not true.
317
-
318
-In fairness to the Git documentation authors, changing the
319
-project history appears to be the only way to make editorial
320
-changes in Git.
321
-But it does not have to be that way.
322
-Fossil demonstrates how "the story of your project"
323
-can be enhanced without changing the actual history
324
-by allowing users to:
303
+You may be tempted to dismiss this as an anti-Git opinion on a Fossil
304
+web site, but it’s spelled out just like that [in the Git rebase
305
+documentation][gitrebase]. It speaks of “lying,” “telling stories,”
306
+and “blasphemy.”
307
+
308
+That section of the Git docs is contrasting rebase with merge, which we
309
+cover [above](#cap-loss), but Git’s rebase feature is more than just an
310
+alternative to merging: it also provides mechanisms for changing the
311
+project history in order to make editorial changes. Fossil shows that
312
+you can get similar effects without modifying historical records,
313
+allowing users to:
325314
326315
1. Edit check-in comments to fix typos or enhance clarity
327316
2. Attach supplemental notes to check-ins or whole branches
328
- 3. Cross-reference check-ins with each other, or with
329
- wiki, tickets, forum posts, and/or embedded documentation
330
- 4. Hide ill-conceived or now-unused branches from routine display
331
- 5. Fix faulty check-in date/times resulting from misconfigured
317
+ 3. Hide ill-conceived or now-unused branches from routine display
318
+ 4. Fix faulty check-in date/times resulting from misconfigured
332319
system clocks
320
+ 5. Cross-reference check-ins with each other, or with
321
+ wiki, tickets, forum posts, and/or embedded documentation
333322
334323
…and so forth.
335324
336
-These changes are accomplished not by removing or modifying existing
325
+Fossil allows all of this not by removing or modifying existing
337326
repository entries, but rather by adding new supplemental records.
338
-The original incorrect or unclear inputs are preserved and are
339
-readily accessible. The original history is preserved.
340
-But for routine display purposes, the more
341
-readable edited presentation is provided.
342
-
343
-A repository can be a true and accurate
344
-representation of history even without getting everything perfect
345
-on the first draft. Those are not contradictory goals, at least
346
-not in theory.
347
-
348
-Unfortunately, Git does not currently provide the ability to add
349
-corrections or clarifications or supplimental notes to historical check-ins.
350
-Hence, once again,
351
-rebase can be seen as an attempt to work around limitations
352
-of Git. Git could be enhanced to support editorial changes
353
-to check-ins.
354
-Wouldn't it be better to fix the version control tool
355
-rather than requiring users to fabricate a fictitious project history?
327
+Fossil keeps the original incorrect or unclear inputs and makes them
328
+readily accessible, preserving the original historical record. Fossil
329
+doesn’t make the user tell counter-factual “stories,” it only allows the
330
+user to provide annotations to provide a more readable edited
331
+presentation for routine display purposes.
332
+
333
+Git needs rebase because it lacks these annotation facilities. Rather
334
+than consider rebase a desirable feature missing in Fossil, ask instead
335
+why Git lacks support for making editorial changes to check-ins without
336
+modifyihng history? Wouldn't it be better to fix the version control
337
+tool rather than requiring users to fabricate a fictitious project
338
+history?
356339
357340
## <a name="collapsing"></a>6.0 Collapsing check-ins throws away valuable information
358341
359342
One of the oft-cited advantages of rebasing in Git is that it lets you
360343
collapse multiple check-ins down to a single check-in to make the
361344
--- www/rebaseharm.md
+++ www/rebaseharm.md
@@ -298,63 +298,46 @@
298 ## <a name="lying"></a>5.0 Rebasing is lying about the project history
299
300 By discarding parentage information, rebase attempts to deceive the
301 reader about how the code actually came together.
302
303 The [Git rebase documentation][gitrebase] admits as much. They acknowledge
304 that when you view a repository as record of what actually happened,
305 doing a rebase is "blasphemous" and "you're _lying_ about what
306 actually happened", but then goes on to justify rebase as follows:
307
308 >
309 _"The opposing point of view is that the commit history is the **story of
310 how your project was made.** You wouldn't publish the first draft of a
311 book, and the manual for how to maintain your software deserves careful
312 editing. This is the camp that uses tools like rebase and filter-branch
313 to tell the story in the way that's best for future readers."_
314
315 This counter-argument assumes you must
316 change history in order to enhance readability, which is not true.
317
318 In fairness to the Git documentation authors, changing the
319 project history appears to be the only way to make editorial
320 changes in Git.
321 But it does not have to be that way.
322 Fossil demonstrates how "the story of your project"
323 can be enhanced without changing the actual history
324 by allowing users to:
325
326 1. Edit check-in comments to fix typos or enhance clarity
327 2. Attach supplemental notes to check-ins or whole branches
328 3. Cross-reference check-ins with each other, or with
329 wiki, tickets, forum posts, and/or embedded documentation
330 4. Hide ill-conceived or now-unused branches from routine display
331 5. Fix faulty check-in date/times resulting from misconfigured
332 system clocks
 
 
333
334 …and so forth.
335
336 These changes are accomplished not by removing or modifying existing
337 repository entries, but rather by adding new supplemental records.
338 The original incorrect or unclear inputs are preserved and are
339 readily accessible. The original history is preserved.
340 But for routine display purposes, the more
341 readable edited presentation is provided.
342
343 A repository can be a true and accurate
344 representation of history even without getting everything perfect
345 on the first draft. Those are not contradictory goals, at least
346 not in theory.
347
348 Unfortunately, Git does not currently provide the ability to add
349 corrections or clarifications or supplimental notes to historical check-ins.
350 Hence, once again,
351 rebase can be seen as an attempt to work around limitations
352 of Git. Git could be enhanced to support editorial changes
353 to check-ins.
354 Wouldn't it be better to fix the version control tool
355 rather than requiring users to fabricate a fictitious project history?
356
357 ## <a name="collapsing"></a>6.0 Collapsing check-ins throws away valuable information
358
359 One of the oft-cited advantages of rebasing in Git is that it lets you
360 collapse multiple check-ins down to a single check-in to make the
361
--- www/rebaseharm.md
+++ www/rebaseharm.md
@@ -298,63 +298,46 @@
298 ## <a name="lying"></a>5.0 Rebasing is lying about the project history
299
300 By discarding parentage information, rebase attempts to deceive the
301 reader about how the code actually came together.
302
303 You may be tempted to dismiss this as an anti-Git opinion on a Fossil
304 web site, but it’s spelled out just like that [in the Git rebase
305 documentation][gitrebase]. It speaks of “lying,” “telling stories,”
306 and “blasphemy.”
307
308 That section of the Git docs is contrasting rebase with merge, which we
309 cover [above](#cap-loss), but Git’s rebase feature is more than just an
310 alternative to merging: it also provides mechanisms for changing the
311 project history in order to make editorial changes. Fossil shows that
312 you can get similar effects without modifying historical records,
313 allowing users to:
 
 
 
 
 
 
 
 
 
 
 
314
315 1. Edit check-in comments to fix typos or enhance clarity
316 2. Attach supplemental notes to check-ins or whole branches
317 3. Hide ill-conceived or now-unused branches from routine display
318 4. Fix faulty check-in date/times resulting from misconfigured
 
 
319 system clocks
320 5. Cross-reference check-ins with each other, or with
321 wiki, tickets, forum posts, and/or embedded documentation
322
323 …and so forth.
324
325 Fossil allows all of this not by removing or modifying existing
326 repository entries, but rather by adding new supplemental records.
327 Fossil keeps the original incorrect or unclear inputs and makes them
328 readily accessible, preserving the original historical record. Fossil
329 doesn’t make the user tell counter-factual “stories,” it only allows the
330 user to provide annotations to provide a more readable edited
331 presentation for routine display purposes.
332
333 Git needs rebase because it lacks these annotation facilities. Rather
334 than consider rebase a desirable feature missing in Fossil, ask instead
335 why Git lacks support for making editorial changes to check-ins without
336 modifyihng history? Wouldn't it be better to fix the version control
337 tool rather than requiring users to fabricate a fictitious project
338 history?
 
 
 
 
 
 
339
340 ## <a name="collapsing"></a>6.0 Collapsing check-ins throws away valuable information
341
342 One of the oft-cited advantages of rebasing in Git is that it lets you
343 collapse multiple check-ins down to a single check-in to make the
344
--- www/serverext.wiki
+++ www/serverext.wiki
@@ -129,10 +129,11 @@
129129
* AUTH_CONTENT
130130
* CONTENT_LENGTH
131131
* CONTENT_TYPE
132132
* DOCUMENT_ROOT
133133
* GATEWAY_INTERFACE
134
+ * HTTPS
134135
* HTTP_ACCEPT
135136
* HTTP_ACCEPT_ENCODING
136137
* HTTP_COOKIE
137138
* HTTP_HOST
138139
* HTTP_IF_MODIFIED_SINCE
@@ -142,10 +143,11 @@
142143
* PATH_INFO
143144
* QUERY_STRING
144145
* REMOTE_ADDR
145146
* REMOTE_USER
146147
* REQUEST_METHOD
148
+ * REQUEST_SCHEME
147149
* REQUEST_URI
148150
* SCRIPT_DIRECTORY
149151
* SCRIPT_FILENAME
150152
* SCRIPT_NAME
151153
* SERVER_NAME
@@ -209,10 +211,11 @@
209211
<h3>3.1 Input Content</h3>
210212
211213
If the HTTP request includes content (for example if this is a POST request)
212214
then the CONTENT_LENGTH value will be positive and the data for the content
213215
will be readable on standard input.
216
+
214217
215218
<h2>4.0 CGI Outputs</h2>
216219
217220
CGI programs construct a reply by writing to standard output. The first
218221
few lines of output are parameters intended for the web server that invoked
@@ -254,10 +257,22 @@
254257
"data-title" attribute.
255258
256259
Except for the three cases noted above, Fossil makes no changes or
257260
additions to the CGI-generated content. Fossil just passes the verbatim
258261
content back up the stack towards the requester.
262
+
263
+<h3>4.1 <tt>GATEWAY_INTERFACE</tt> and Recursive Calls to fossil</h3>
264
+
265
+Like many CGI-aware applications, if fossil sees the environment
266
+variable <tt>GATEWAY_INTERFACE</tt> when it starts up, it assumes it
267
+is running in a CGI environment and behaves differently than when it
268
+is run in a non-CGI interactive session. If you intend to run fossil
269
+itself from within an extension CGI script, e.g. to run a query
270
+against the repository or simply fetch the fossil binary version, make
271
+sure to <em>unset</em> the <tt>GATEWAY_INTERFACE</tt> environment
272
+variable before doing so, otherwise the invocation will behave as if
273
+it's being run in CGI mode.
259274
260275
<h2>5.0 Filename Restrictions</h2>
261276
262277
For security reasons, Fossil places restrictions on the names of files
263278
in the extroot directory that can participate in the extension CGI
264279
--- www/serverext.wiki
+++ www/serverext.wiki
@@ -129,10 +129,11 @@
129 * AUTH_CONTENT
130 * CONTENT_LENGTH
131 * CONTENT_TYPE
132 * DOCUMENT_ROOT
133 * GATEWAY_INTERFACE
 
134 * HTTP_ACCEPT
135 * HTTP_ACCEPT_ENCODING
136 * HTTP_COOKIE
137 * HTTP_HOST
138 * HTTP_IF_MODIFIED_SINCE
@@ -142,10 +143,11 @@
142 * PATH_INFO
143 * QUERY_STRING
144 * REMOTE_ADDR
145 * REMOTE_USER
146 * REQUEST_METHOD
 
147 * REQUEST_URI
148 * SCRIPT_DIRECTORY
149 * SCRIPT_FILENAME
150 * SCRIPT_NAME
151 * SERVER_NAME
@@ -209,10 +211,11 @@
209 <h3>3.1 Input Content</h3>
210
211 If the HTTP request includes content (for example if this is a POST request)
212 then the CONTENT_LENGTH value will be positive and the data for the content
213 will be readable on standard input.
 
214
215 <h2>4.0 CGI Outputs</h2>
216
217 CGI programs construct a reply by writing to standard output. The first
218 few lines of output are parameters intended for the web server that invoked
@@ -254,10 +257,22 @@
254 "data-title" attribute.
255
256 Except for the three cases noted above, Fossil makes no changes or
257 additions to the CGI-generated content. Fossil just passes the verbatim
258 content back up the stack towards the requester.
 
 
 
 
 
 
 
 
 
 
 
 
259
260 <h2>5.0 Filename Restrictions</h2>
261
262 For security reasons, Fossil places restrictions on the names of files
263 in the extroot directory that can participate in the extension CGI
264
--- www/serverext.wiki
+++ www/serverext.wiki
@@ -129,10 +129,11 @@
129 * AUTH_CONTENT
130 * CONTENT_LENGTH
131 * CONTENT_TYPE
132 * DOCUMENT_ROOT
133 * GATEWAY_INTERFACE
134 * HTTPS
135 * HTTP_ACCEPT
136 * HTTP_ACCEPT_ENCODING
137 * HTTP_COOKIE
138 * HTTP_HOST
139 * HTTP_IF_MODIFIED_SINCE
@@ -142,10 +143,11 @@
143 * PATH_INFO
144 * QUERY_STRING
145 * REMOTE_ADDR
146 * REMOTE_USER
147 * REQUEST_METHOD
148 * REQUEST_SCHEME
149 * REQUEST_URI
150 * SCRIPT_DIRECTORY
151 * SCRIPT_FILENAME
152 * SCRIPT_NAME
153 * SERVER_NAME
@@ -209,10 +211,11 @@
211 <h3>3.1 Input Content</h3>
212
213 If the HTTP request includes content (for example if this is a POST request)
214 then the CONTENT_LENGTH value will be positive and the data for the content
215 will be readable on standard input.
216
217
218 <h2>4.0 CGI Outputs</h2>
219
220 CGI programs construct a reply by writing to standard output. The first
221 few lines of output are parameters intended for the web server that invoked
@@ -254,10 +257,22 @@
257 "data-title" attribute.
258
259 Except for the three cases noted above, Fossil makes no changes or
260 additions to the CGI-generated content. Fossil just passes the verbatim
261 content back up the stack towards the requester.
262
263 <h3>4.1 <tt>GATEWAY_INTERFACE</tt> and Recursive Calls to fossil</h3>
264
265 Like many CGI-aware applications, if fossil sees the environment
266 variable <tt>GATEWAY_INTERFACE</tt> when it starts up, it assumes it
267 is running in a CGI environment and behaves differently than when it
268 is run in a non-CGI interactive session. If you intend to run fossil
269 itself from within an extension CGI script, e.g. to run a query
270 against the repository or simply fetch the fossil binary version, make
271 sure to <em>unset</em> the <tt>GATEWAY_INTERFACE</tt> environment
272 variable before doing so, otherwise the invocation will behave as if
273 it's being run in CGI mode.
274
275 <h2>5.0 Filename Restrictions</h2>
276
277 For security reasons, Fossil places restrictions on the names of files
278 in the extroot directory that can participate in the extension CGI
279

Keyboard Shortcuts

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