Fossil SCM
Merge recent trunk enhancements into the diff-color-enhancement branch.
Commit
17dde4c75b81ad77762f915c8f9fd43dfc018f5ca60ad74eec8198d35adeafb7
Parent
3910360677f8a47…
12 files changed
+2
+2
-2
+2
-2
+16
+1
-1
+2
+1
-1
-2
+1
-1
+13
-6
+4
-4
+21
-15
+2
| --- src/clone.c | ||
| +++ src/clone.c | ||
| @@ -365,11 +365,13 @@ | ||
| 365 | 365 | ** Set SSH options discovered in global variables (set from command line |
| 366 | 366 | ** options). |
| 367 | 367 | */ |
| 368 | 368 | void clone_ssh_db_set_options(void){ |
| 369 | 369 | if( g.zSshCmd && g.zSshCmd[0] ){ |
| 370 | + db_unprotect(PROTECT_ALL); | |
| 370 | 371 | db_set("ssh-command", g.zSshCmd, 0); |
| 372 | + db_protect_pop(); | |
| 371 | 373 | } |
| 372 | 374 | } |
| 373 | 375 | |
| 374 | 376 | /* |
| 375 | 377 | ** WEBPAGE: download |
| 376 | 378 |
| --- src/clone.c | |
| +++ src/clone.c | |
| @@ -365,11 +365,13 @@ | |
| 365 | ** Set SSH options discovered in global variables (set from command line |
| 366 | ** options). |
| 367 | */ |
| 368 | void clone_ssh_db_set_options(void){ |
| 369 | if( g.zSshCmd && g.zSshCmd[0] ){ |
| 370 | db_set("ssh-command", g.zSshCmd, 0); |
| 371 | } |
| 372 | } |
| 373 | |
| 374 | /* |
| 375 | ** WEBPAGE: download |
| 376 |
| --- src/clone.c | |
| +++ src/clone.c | |
| @@ -365,11 +365,13 @@ | |
| 365 | ** Set SSH options discovered in global variables (set from command line |
| 366 | ** options). |
| 367 | */ |
| 368 | void clone_ssh_db_set_options(void){ |
| 369 | if( g.zSshCmd && g.zSshCmd[0] ){ |
| 370 | db_unprotect(PROTECT_ALL); |
| 371 | db_set("ssh-command", g.zSshCmd, 0); |
| 372 | db_protect_pop(); |
| 373 | } |
| 374 | } |
| 375 | |
| 376 | /* |
| 377 | ** WEBPAGE: download |
| 378 |
+2
-2
| --- src/diffcmd.c | ||
| +++ src/diffcmd.c | ||
| @@ -324,11 +324,11 @@ | ||
| 324 | 324 | */ |
| 325 | 325 | void diff_begin(u64 diffFlags){ |
| 326 | 326 | if( (diffFlags & DIFF_BROWSER)!=0 ){ |
| 327 | 327 | tempDiffFilename = fossil_temp_filename(); |
| 328 | 328 | tempDiffFilename = sqlite3_mprintf("%z.html", tempDiffFilename); |
| 329 | - diffOut = freopen(tempDiffFilename,"wb",stdout); | |
| 329 | + diffOut = fossil_freopen(tempDiffFilename,"wb",stdout); | |
| 330 | 330 | if( diffOut==0 ){ |
| 331 | 331 | fossil_fatal("unable to create temporary file \"%s\"", |
| 332 | 332 | tempDiffFilename); |
| 333 | 333 | } |
| 334 | 334 | #ifndef _WIN32 |
| @@ -362,11 +362,11 @@ | ||
| 362 | 362 | fossil_print("%s", zWebpageEnd); |
| 363 | 363 | } |
| 364 | 364 | if( (diffFlags & DIFF_BROWSER)!=0 && nErr==0 ){ |
| 365 | 365 | char *zCmd = mprintf("%s %$", fossil_web_browser(), tempDiffFilename); |
| 366 | 366 | fclose(diffOut); |
| 367 | - diffOut = freopen(NULL_DEVICE, "wb", stdout); | |
| 367 | + diffOut = fossil_freopen(NULL_DEVICE, "wb", stdout); | |
| 368 | 368 | fossil_system(zCmd); |
| 369 | 369 | fossil_free(zCmd); |
| 370 | 370 | diffOut = 0; |
| 371 | 371 | sqlite3_sleep(FOSSIL_BROWSER_DIFF_DELAY); |
| 372 | 372 | file_delete(tempDiffFilename); |
| 373 | 373 |
| --- src/diffcmd.c | |
| +++ src/diffcmd.c | |
| @@ -324,11 +324,11 @@ | |
| 324 | */ |
| 325 | void diff_begin(u64 diffFlags){ |
| 326 | if( (diffFlags & DIFF_BROWSER)!=0 ){ |
| 327 | tempDiffFilename = fossil_temp_filename(); |
| 328 | tempDiffFilename = sqlite3_mprintf("%z.html", tempDiffFilename); |
| 329 | diffOut = freopen(tempDiffFilename,"wb",stdout); |
| 330 | if( diffOut==0 ){ |
| 331 | fossil_fatal("unable to create temporary file \"%s\"", |
| 332 | tempDiffFilename); |
| 333 | } |
| 334 | #ifndef _WIN32 |
| @@ -362,11 +362,11 @@ | |
| 362 | fossil_print("%s", zWebpageEnd); |
| 363 | } |
| 364 | if( (diffFlags & DIFF_BROWSER)!=0 && nErr==0 ){ |
| 365 | char *zCmd = mprintf("%s %$", fossil_web_browser(), tempDiffFilename); |
| 366 | fclose(diffOut); |
| 367 | diffOut = freopen(NULL_DEVICE, "wb", stdout); |
| 368 | fossil_system(zCmd); |
| 369 | fossil_free(zCmd); |
| 370 | diffOut = 0; |
| 371 | sqlite3_sleep(FOSSIL_BROWSER_DIFF_DELAY); |
| 372 | file_delete(tempDiffFilename); |
| 373 |
| --- src/diffcmd.c | |
| +++ src/diffcmd.c | |
| @@ -324,11 +324,11 @@ | |
| 324 | */ |
| 325 | void diff_begin(u64 diffFlags){ |
| 326 | if( (diffFlags & DIFF_BROWSER)!=0 ){ |
| 327 | tempDiffFilename = fossil_temp_filename(); |
| 328 | tempDiffFilename = sqlite3_mprintf("%z.html", tempDiffFilename); |
| 329 | diffOut = fossil_freopen(tempDiffFilename,"wb",stdout); |
| 330 | if( diffOut==0 ){ |
| 331 | fossil_fatal("unable to create temporary file \"%s\"", |
| 332 | tempDiffFilename); |
| 333 | } |
| 334 | #ifndef _WIN32 |
| @@ -362,11 +362,11 @@ | |
| 362 | fossil_print("%s", zWebpageEnd); |
| 363 | } |
| 364 | if( (diffFlags & DIFF_BROWSER)!=0 && nErr==0 ){ |
| 365 | char *zCmd = mprintf("%s %$", fossil_web_browser(), tempDiffFilename); |
| 366 | fclose(diffOut); |
| 367 | diffOut = fossil_freopen(NULL_DEVICE, "wb", stdout); |
| 368 | fossil_system(zCmd); |
| 369 | fossil_free(zCmd); |
| 370 | diffOut = 0; |
| 371 | sqlite3_sleep(FOSSIL_BROWSER_DIFF_DELAY); |
| 372 | file_delete(tempDiffFilename); |
| 373 |
+2
-2
| --- src/diffcmd.c | ||
| +++ src/diffcmd.c | ||
| @@ -324,11 +324,11 @@ | ||
| 324 | 324 | */ |
| 325 | 325 | void diff_begin(u64 diffFlags){ |
| 326 | 326 | if( (diffFlags & DIFF_BROWSER)!=0 ){ |
| 327 | 327 | tempDiffFilename = fossil_temp_filename(); |
| 328 | 328 | tempDiffFilename = sqlite3_mprintf("%z.html", tempDiffFilename); |
| 329 | - diffOut = freopen(tempDiffFilename,"wb",stdout); | |
| 329 | + diffOut = fossil_freopen(tempDiffFilename,"wb",stdout); | |
| 330 | 330 | if( diffOut==0 ){ |
| 331 | 331 | fossil_fatal("unable to create temporary file \"%s\"", |
| 332 | 332 | tempDiffFilename); |
| 333 | 333 | } |
| 334 | 334 | #ifndef _WIN32 |
| @@ -362,11 +362,11 @@ | ||
| 362 | 362 | fossil_print("%s", zWebpageEnd); |
| 363 | 363 | } |
| 364 | 364 | if( (diffFlags & DIFF_BROWSER)!=0 && nErr==0 ){ |
| 365 | 365 | char *zCmd = mprintf("%s %$", fossil_web_browser(), tempDiffFilename); |
| 366 | 366 | fclose(diffOut); |
| 367 | - diffOut = freopen(NULL_DEVICE, "wb", stdout); | |
| 367 | + diffOut = fossil_freopen(NULL_DEVICE, "wb", stdout); | |
| 368 | 368 | fossil_system(zCmd); |
| 369 | 369 | fossil_free(zCmd); |
| 370 | 370 | diffOut = 0; |
| 371 | 371 | sqlite3_sleep(FOSSIL_BROWSER_DIFF_DELAY); |
| 372 | 372 | file_delete(tempDiffFilename); |
| 373 | 373 |
| --- src/diffcmd.c | |
| +++ src/diffcmd.c | |
| @@ -324,11 +324,11 @@ | |
| 324 | */ |
| 325 | void diff_begin(u64 diffFlags){ |
| 326 | if( (diffFlags & DIFF_BROWSER)!=0 ){ |
| 327 | tempDiffFilename = fossil_temp_filename(); |
| 328 | tempDiffFilename = sqlite3_mprintf("%z.html", tempDiffFilename); |
| 329 | diffOut = freopen(tempDiffFilename,"wb",stdout); |
| 330 | if( diffOut==0 ){ |
| 331 | fossil_fatal("unable to create temporary file \"%s\"", |
| 332 | tempDiffFilename); |
| 333 | } |
| 334 | #ifndef _WIN32 |
| @@ -362,11 +362,11 @@ | |
| 362 | fossil_print("%s", zWebpageEnd); |
| 363 | } |
| 364 | if( (diffFlags & DIFF_BROWSER)!=0 && nErr==0 ){ |
| 365 | char *zCmd = mprintf("%s %$", fossil_web_browser(), tempDiffFilename); |
| 366 | fclose(diffOut); |
| 367 | diffOut = freopen(NULL_DEVICE, "wb", stdout); |
| 368 | fossil_system(zCmd); |
| 369 | fossil_free(zCmd); |
| 370 | diffOut = 0; |
| 371 | sqlite3_sleep(FOSSIL_BROWSER_DIFF_DELAY); |
| 372 | file_delete(tempDiffFilename); |
| 373 |
| --- src/diffcmd.c | |
| +++ src/diffcmd.c | |
| @@ -324,11 +324,11 @@ | |
| 324 | */ |
| 325 | void diff_begin(u64 diffFlags){ |
| 326 | if( (diffFlags & DIFF_BROWSER)!=0 ){ |
| 327 | tempDiffFilename = fossil_temp_filename(); |
| 328 | tempDiffFilename = sqlite3_mprintf("%z.html", tempDiffFilename); |
| 329 | diffOut = fossil_freopen(tempDiffFilename,"wb",stdout); |
| 330 | if( diffOut==0 ){ |
| 331 | fossil_fatal("unable to create temporary file \"%s\"", |
| 332 | tempDiffFilename); |
| 333 | } |
| 334 | #ifndef _WIN32 |
| @@ -362,11 +362,11 @@ | |
| 362 | fossil_print("%s", zWebpageEnd); |
| 363 | } |
| 364 | if( (diffFlags & DIFF_BROWSER)!=0 && nErr==0 ){ |
| 365 | char *zCmd = mprintf("%s %$", fossil_web_browser(), tempDiffFilename); |
| 366 | fclose(diffOut); |
| 367 | diffOut = fossil_freopen(NULL_DEVICE, "wb", stdout); |
| 368 | fossil_system(zCmd); |
| 369 | fossil_free(zCmd); |
| 370 | diffOut = 0; |
| 371 | sqlite3_sleep(FOSSIL_BROWSER_DIFF_DELAY); |
| 372 | file_delete(tempDiffFilename); |
| 373 |
+16
| --- src/file.c | ||
| +++ src/file.c | ||
| @@ -2160,10 +2160,26 @@ | ||
| 2160 | 2160 | #else |
| 2161 | 2161 | FILE *f = fopen(zName, zMode); |
| 2162 | 2162 | #endif |
| 2163 | 2163 | return f; |
| 2164 | 2164 | } |
| 2165 | + | |
| 2166 | +/* | |
| 2167 | +** Wrapper for freopen() that understands UTF8 arguments. | |
| 2168 | +*/ | |
| 2169 | +FILE *fossil_freopen(const char *zName, const char *zMode, FILE *stream){ | |
| 2170 | +#ifdef _WIN32 | |
| 2171 | + wchar_t *uMode = fossil_utf8_to_unicode(zMode); | |
| 2172 | + wchar_t *uName = fossil_utf8_to_path(zName, 0); | |
| 2173 | + FILE *f = _wfreopen(uName, uMode, stream); | |
| 2174 | + fossil_path_free(uName); | |
| 2175 | + fossil_unicode_free(uMode); | |
| 2176 | +#else | |
| 2177 | + FILE *f = freopen(zName, zMode, stream); | |
| 2178 | +#endif | |
| 2179 | + return f; | |
| 2180 | +} | |
| 2165 | 2181 | |
| 2166 | 2182 | /* |
| 2167 | 2183 | ** Works like fclose() except that: |
| 2168 | 2184 | ** |
| 2169 | 2185 | ** 1) is a no-op if f is 0 or if it is stdin. |
| 2170 | 2186 |
| --- src/file.c | |
| +++ src/file.c | |
| @@ -2160,10 +2160,26 @@ | |
| 2160 | #else |
| 2161 | FILE *f = fopen(zName, zMode); |
| 2162 | #endif |
| 2163 | return f; |
| 2164 | } |
| 2165 | |
| 2166 | /* |
| 2167 | ** Works like fclose() except that: |
| 2168 | ** |
| 2169 | ** 1) is a no-op if f is 0 or if it is stdin. |
| 2170 |
| --- src/file.c | |
| +++ src/file.c | |
| @@ -2160,10 +2160,26 @@ | |
| 2160 | #else |
| 2161 | FILE *f = fopen(zName, zMode); |
| 2162 | #endif |
| 2163 | return f; |
| 2164 | } |
| 2165 | |
| 2166 | /* |
| 2167 | ** Wrapper for freopen() that understands UTF8 arguments. |
| 2168 | */ |
| 2169 | FILE *fossil_freopen(const char *zName, const char *zMode, FILE *stream){ |
| 2170 | #ifdef _WIN32 |
| 2171 | wchar_t *uMode = fossil_utf8_to_unicode(zMode); |
| 2172 | wchar_t *uName = fossil_utf8_to_path(zName, 0); |
| 2173 | FILE *f = _wfreopen(uName, uMode, stream); |
| 2174 | fossil_path_free(uName); |
| 2175 | fossil_unicode_free(uMode); |
| 2176 | #else |
| 2177 | FILE *f = freopen(zName, zMode, stream); |
| 2178 | #endif |
| 2179 | return f; |
| 2180 | } |
| 2181 | |
| 2182 | /* |
| 2183 | ** Works like fclose() except that: |
| 2184 | ** |
| 2185 | ** 1) is a no-op if f is 0 or if it is stdin. |
| 2186 |
+1
-1
| --- src/finfo.c | ||
| +++ src/finfo.c | ||
| @@ -319,11 +319,11 @@ | ||
| 319 | 319 | ** m=HASH Mark this particular file version. |
| 320 | 320 | ** n=NUM Show the first NUM changes only |
| 321 | 321 | ** name=FILENAME (Required) name of file whose history to show |
| 322 | 322 | ** brbg Background color by branch name |
| 323 | 323 | ** ubg Background color by user name |
| 324 | -** from=HASH Ancestors only (not descendents) of the version of | |
| 324 | +** from=HASH Ancestors only (not descendants) of the version of | |
| 325 | 325 | ** the file in this particular check-in. |
| 326 | 326 | ** to=HASH If both from= and to= are supplied, only show those |
| 327 | 327 | ** changes on the direct path between the two given |
| 328 | 328 | ** checkins. |
| 329 | 329 | ** showid Show RID values for debugging |
| 330 | 330 |
| --- src/finfo.c | |
| +++ src/finfo.c | |
| @@ -319,11 +319,11 @@ | |
| 319 | ** m=HASH Mark this particular file version. |
| 320 | ** n=NUM Show the first NUM changes only |
| 321 | ** name=FILENAME (Required) name of file whose history to show |
| 322 | ** brbg Background color by branch name |
| 323 | ** ubg Background color by user name |
| 324 | ** from=HASH Ancestors only (not descendents) of the version of |
| 325 | ** the file in this particular check-in. |
| 326 | ** to=HASH If both from= and to= are supplied, only show those |
| 327 | ** changes on the direct path between the two given |
| 328 | ** checkins. |
| 329 | ** showid Show RID values for debugging |
| 330 |
| --- src/finfo.c | |
| +++ src/finfo.c | |
| @@ -319,11 +319,11 @@ | |
| 319 | ** m=HASH Mark this particular file version. |
| 320 | ** n=NUM Show the first NUM changes only |
| 321 | ** name=FILENAME (Required) name of file whose history to show |
| 322 | ** brbg Background color by branch name |
| 323 | ** ubg Background color by user name |
| 324 | ** from=HASH Ancestors only (not descendants) of the version of |
| 325 | ** the file in this particular check-in. |
| 326 | ** to=HASH If both from= and to= are supplied, only show those |
| 327 | ** changes on the direct path between the two given |
| 328 | ** checkins. |
| 329 | ** showid Show RID values for debugging |
| 330 |
+2
| --- src/fossil.dom.js | ||
| +++ src/fossil.dom.js | ||
| @@ -72,10 +72,12 @@ | ||
| 72 | 72 | dom.footer = dom.createElemFactory('footer'); |
| 73 | 73 | dom.section = dom.createElemFactory('section'); |
| 74 | 74 | dom.span = dom.createElemFactory('span'); |
| 75 | 75 | dom.strong = dom.createElemFactory('strong'); |
| 76 | 76 | dom.em = dom.createElemFactory('em'); |
| 77 | + dom.ins = dom.createElemFactory('ins'); | |
| 78 | + dom.del = dom.createElemFactory('del'); | |
| 77 | 79 | /** |
| 78 | 80 | Returns a LABEL element. If passed an argument, |
| 79 | 81 | it must be an id or an HTMLElement with an id, |
| 80 | 82 | and that id is set as the 'for' attribute of the |
| 81 | 83 | label. If passed 2 arguments, the 2nd is text or |
| 82 | 84 |
| --- src/fossil.dom.js | |
| +++ src/fossil.dom.js | |
| @@ -72,10 +72,12 @@ | |
| 72 | dom.footer = dom.createElemFactory('footer'); |
| 73 | dom.section = dom.createElemFactory('section'); |
| 74 | dom.span = dom.createElemFactory('span'); |
| 75 | dom.strong = dom.createElemFactory('strong'); |
| 76 | dom.em = dom.createElemFactory('em'); |
| 77 | /** |
| 78 | Returns a LABEL element. If passed an argument, |
| 79 | it must be an id or an HTMLElement with an id, |
| 80 | and that id is set as the 'for' attribute of the |
| 81 | label. If passed 2 arguments, the 2nd is text or |
| 82 |
| --- src/fossil.dom.js | |
| +++ src/fossil.dom.js | |
| @@ -72,10 +72,12 @@ | |
| 72 | dom.footer = dom.createElemFactory('footer'); |
| 73 | dom.section = dom.createElemFactory('section'); |
| 74 | dom.span = dom.createElemFactory('span'); |
| 75 | dom.strong = dom.createElemFactory('strong'); |
| 76 | dom.em = dom.createElemFactory('em'); |
| 77 | dom.ins = dom.createElemFactory('ins'); |
| 78 | dom.del = dom.createElemFactory('del'); |
| 79 | /** |
| 80 | Returns a LABEL element. If passed an argument, |
| 81 | it must be an id or an HTMLElement with an id, |
| 82 | and that id is set as the 'for' attribute of the |
| 83 | label. If passed 2 arguments, the 2nd is text or |
| 84 |
+1
-1
| --- src/http_ssl.c | ||
| +++ src/http_ssl.c | ||
| @@ -143,11 +143,11 @@ | ||
| 143 | 143 | identityFile = g.zSSLIdentity; |
| 144 | 144 | }else{ |
| 145 | 145 | identityFile = db_get("ssl-identity", 0); |
| 146 | 146 | } |
| 147 | 147 | if( identityFile!=0 && identityFile[0]!='\0' ){ |
| 148 | - if( SSL_CTX_use_certificate_file(sslCtx,identityFile,SSL_FILETYPE_PEM)!=1 | |
| 148 | + if( SSL_CTX_use_certificate_chain_file(sslCtx,identityFile)!=1 | |
| 149 | 149 | || SSL_CTX_use_PrivateKey_file(sslCtx,identityFile,SSL_FILETYPE_PEM)!=1 |
| 150 | 150 | ){ |
| 151 | 151 | fossil_fatal("Could not load SSL identity from %s", identityFile); |
| 152 | 152 | } |
| 153 | 153 | } |
| 154 | 154 |
| --- src/http_ssl.c | |
| +++ src/http_ssl.c | |
| @@ -143,11 +143,11 @@ | |
| 143 | identityFile = g.zSSLIdentity; |
| 144 | }else{ |
| 145 | identityFile = db_get("ssl-identity", 0); |
| 146 | } |
| 147 | if( identityFile!=0 && identityFile[0]!='\0' ){ |
| 148 | if( SSL_CTX_use_certificate_file(sslCtx,identityFile,SSL_FILETYPE_PEM)!=1 |
| 149 | || SSL_CTX_use_PrivateKey_file(sslCtx,identityFile,SSL_FILETYPE_PEM)!=1 |
| 150 | ){ |
| 151 | fossil_fatal("Could not load SSL identity from %s", identityFile); |
| 152 | } |
| 153 | } |
| 154 |
| --- src/http_ssl.c | |
| +++ src/http_ssl.c | |
| @@ -143,11 +143,11 @@ | |
| 143 | identityFile = g.zSSLIdentity; |
| 144 | }else{ |
| 145 | identityFile = db_get("ssl-identity", 0); |
| 146 | } |
| 147 | if( identityFile!=0 && identityFile[0]!='\0' ){ |
| 148 | if( SSL_CTX_use_certificate_chain_file(sslCtx,identityFile)!=1 |
| 149 | || SSL_CTX_use_PrivateKey_file(sslCtx,identityFile,SSL_FILETYPE_PEM)!=1 |
| 150 | ){ |
| 151 | fossil_fatal("Could not load SSL identity from %s", identityFile); |
| 152 | } |
| 153 | } |
| 154 |
-2
| --- src/setup.c | ||
| +++ src/setup.c | ||
| @@ -134,12 +134,10 @@ | ||
| 134 | 134 | setup_menu_entry("URL Aliases", "waliassetup", |
| 135 | 135 | "Configure URL aliases"); |
| 136 | 136 | if( setup_user ){ |
| 137 | 137 | setup_menu_entry("Notification", "setup_notification", |
| 138 | 138 | "Automatic notifications of changes via outbound email"); |
| 139 | - setup_menu_entry("Email-Server", "setup_smtp", | |
| 140 | - "Activate and configure the built-in email server"); | |
| 141 | 139 | setup_menu_entry("Transfers", "xfersetup", |
| 142 | 140 | "Configure the transfer system for this repository"); |
| 143 | 141 | } |
| 144 | 142 | setup_menu_entry("Skins", "setup_skin", |
| 145 | 143 | "Select and/or modify the web interface \"skins\""); |
| 146 | 144 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -134,12 +134,10 @@ | |
| 134 | setup_menu_entry("URL Aliases", "waliassetup", |
| 135 | "Configure URL aliases"); |
| 136 | if( setup_user ){ |
| 137 | setup_menu_entry("Notification", "setup_notification", |
| 138 | "Automatic notifications of changes via outbound email"); |
| 139 | setup_menu_entry("Email-Server", "setup_smtp", |
| 140 | "Activate and configure the built-in email server"); |
| 141 | setup_menu_entry("Transfers", "xfersetup", |
| 142 | "Configure the transfer system for this repository"); |
| 143 | } |
| 144 | setup_menu_entry("Skins", "setup_skin", |
| 145 | "Select and/or modify the web interface \"skins\""); |
| 146 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -134,12 +134,10 @@ | |
| 134 | setup_menu_entry("URL Aliases", "waliassetup", |
| 135 | "Configure URL aliases"); |
| 136 | if( setup_user ){ |
| 137 | setup_menu_entry("Notification", "setup_notification", |
| 138 | "Automatic notifications of changes via outbound email"); |
| 139 | setup_menu_entry("Transfers", "xfersetup", |
| 140 | "Configure the transfer system for this repository"); |
| 141 | } |
| 142 | setup_menu_entry("Skins", "setup_skin", |
| 143 | "Select and/or modify the web interface \"skins\""); |
| 144 |
+1
-1
| --- src/utf8.c | ||
| +++ src/utf8.c | ||
| @@ -88,11 +88,11 @@ | ||
| 88 | 88 | #endif |
| 89 | 89 | } |
| 90 | 90 | |
| 91 | 91 | /* |
| 92 | 92 | ** Deallocate any memory that was previously allocated by |
| 93 | -** fossil_unicode_to_utf8(). | |
| 93 | +** fossil_unicode_to_utf8() or fossil_utf8_to_unicode(). | |
| 94 | 94 | */ |
| 95 | 95 | void fossil_unicode_free(void *pOld){ |
| 96 | 96 | fossil_free(pOld); |
| 97 | 97 | } |
| 98 | 98 | |
| 99 | 99 |
| --- src/utf8.c | |
| +++ src/utf8.c | |
| @@ -88,11 +88,11 @@ | |
| 88 | #endif |
| 89 | } |
| 90 | |
| 91 | /* |
| 92 | ** Deallocate any memory that was previously allocated by |
| 93 | ** fossil_unicode_to_utf8(). |
| 94 | */ |
| 95 | void fossil_unicode_free(void *pOld){ |
| 96 | fossil_free(pOld); |
| 97 | } |
| 98 | |
| 99 |
| --- src/utf8.c | |
| +++ src/utf8.c | |
| @@ -88,11 +88,11 @@ | |
| 88 | #endif |
| 89 | } |
| 90 | |
| 91 | /* |
| 92 | ** Deallocate any memory that was previously allocated by |
| 93 | ** fossil_unicode_to_utf8() or fossil_utf8_to_unicode(). |
| 94 | */ |
| 95 | void fossil_unicode_free(void *pOld){ |
| 96 | fossil_free(pOld); |
| 97 | } |
| 98 | |
| 99 |
+13
-6
| --- src/util.c | ||
| +++ src/util.c | ||
| @@ -655,25 +655,28 @@ | ||
| 655 | 655 | char zSep[2]; |
| 656 | 656 | size_t nDir; |
| 657 | 657 | u64 r[2]; |
| 658 | 658 | int i; |
| 659 | 659 | #ifdef _WIN32 |
| 660 | - char zTempDir[1000]; | |
| 660 | + char *zTempDirA = NULL; | |
| 661 | + WCHAR zTempDirW[MAX_PATH+1]; | |
| 662 | + const DWORD dwTempSizeW = sizeof(zTempDirW)/sizeof(zTempDirW[0]); | |
| 663 | + DWORD dwTempLenW; | |
| 661 | 664 | #else |
| 662 | 665 | static const char *azTmp[] = {"/var/tmp","/usr/tmp","/tmp"}; |
| 663 | 666 | #endif |
| 664 | 667 | if( g.db ){ |
| 665 | 668 | sqlite3_file_control(g.db, 0, SQLITE_FCNTL_TEMPFILENAME, (void*)&zTFile); |
| 666 | 669 | if( zTFile ) return zTFile; |
| 667 | 670 | } |
| 668 | 671 | sqlite3_randomness(sizeof(r), &r); |
| 669 | 672 | #if _WIN32 |
| 670 | - zTempDir[0] = 0; | |
| 671 | 673 | cDirSep = '\\'; |
| 672 | - GetTempPathA(sizeof(zTempDir), zTempDir); | |
| 673 | - if( zTempDir[0] ){ | |
| 674 | - zDir = zTempDir; | |
| 674 | + dwTempLenW = GetTempPathW(dwTempSizeW, zTempDirW); | |
| 675 | + if( dwTempLenW>0 && dwTempLenW<dwTempSizeW | |
| 676 | + && ( zTempDirA = fossil_path_to_utf8(zTempDirW) )){ | |
| 677 | + zDir = zTempDirA; | |
| 675 | 678 | }else{ |
| 676 | 679 | zDir = fossil_getenv("LOCALAPPDATA"); |
| 677 | 680 | if( zDir==0 ) zDir = "."; |
| 678 | 681 | } |
| 679 | 682 | #else |
| @@ -688,11 +691,15 @@ | ||
| 688 | 691 | cDirSep = '/'; |
| 689 | 692 | #endif |
| 690 | 693 | nDir = strlen(zDir); |
| 691 | 694 | zSep[1] = 0; |
| 692 | 695 | zSep[0] = (nDir && zDir[nDir-1]==cDirSep) ? 0 : cDirSep; |
| 693 | - return sqlite3_mprintf("%s%sfossil%016llx%016llx", zDir,zSep,r[0],r[1]); | |
| 696 | + zTFile = sqlite3_mprintf("%s%sfossil%016llx%016llx", zDir,zSep,r[0],r[1]); | |
| 697 | +#ifdef _WIN32 | |
| 698 | + if( zTempDirA ) fossil_path_free(zTempDirA); | |
| 699 | +#endif | |
| 700 | + return zTFile; | |
| 694 | 701 | } |
| 695 | 702 | |
| 696 | 703 | /* |
| 697 | 704 | ** Turn memory limits for stack and heap on and off. The argument |
| 698 | 705 | ** is true to turn memory limits on and false to turn them off. |
| 699 | 706 |
| --- src/util.c | |
| +++ src/util.c | |
| @@ -655,25 +655,28 @@ | |
| 655 | char zSep[2]; |
| 656 | size_t nDir; |
| 657 | u64 r[2]; |
| 658 | int i; |
| 659 | #ifdef _WIN32 |
| 660 | char zTempDir[1000]; |
| 661 | #else |
| 662 | static const char *azTmp[] = {"/var/tmp","/usr/tmp","/tmp"}; |
| 663 | #endif |
| 664 | if( g.db ){ |
| 665 | sqlite3_file_control(g.db, 0, SQLITE_FCNTL_TEMPFILENAME, (void*)&zTFile); |
| 666 | if( zTFile ) return zTFile; |
| 667 | } |
| 668 | sqlite3_randomness(sizeof(r), &r); |
| 669 | #if _WIN32 |
| 670 | zTempDir[0] = 0; |
| 671 | cDirSep = '\\'; |
| 672 | GetTempPathA(sizeof(zTempDir), zTempDir); |
| 673 | if( zTempDir[0] ){ |
| 674 | zDir = zTempDir; |
| 675 | }else{ |
| 676 | zDir = fossil_getenv("LOCALAPPDATA"); |
| 677 | if( zDir==0 ) zDir = "."; |
| 678 | } |
| 679 | #else |
| @@ -688,11 +691,15 @@ | |
| 688 | cDirSep = '/'; |
| 689 | #endif |
| 690 | nDir = strlen(zDir); |
| 691 | zSep[1] = 0; |
| 692 | zSep[0] = (nDir && zDir[nDir-1]==cDirSep) ? 0 : cDirSep; |
| 693 | return sqlite3_mprintf("%s%sfossil%016llx%016llx", zDir,zSep,r[0],r[1]); |
| 694 | } |
| 695 | |
| 696 | /* |
| 697 | ** Turn memory limits for stack and heap on and off. The argument |
| 698 | ** is true to turn memory limits on and false to turn them off. |
| 699 |
| --- src/util.c | |
| +++ src/util.c | |
| @@ -655,25 +655,28 @@ | |
| 655 | char zSep[2]; |
| 656 | size_t nDir; |
| 657 | u64 r[2]; |
| 658 | int i; |
| 659 | #ifdef _WIN32 |
| 660 | char *zTempDirA = NULL; |
| 661 | WCHAR zTempDirW[MAX_PATH+1]; |
| 662 | const DWORD dwTempSizeW = sizeof(zTempDirW)/sizeof(zTempDirW[0]); |
| 663 | DWORD dwTempLenW; |
| 664 | #else |
| 665 | static const char *azTmp[] = {"/var/tmp","/usr/tmp","/tmp"}; |
| 666 | #endif |
| 667 | if( g.db ){ |
| 668 | sqlite3_file_control(g.db, 0, SQLITE_FCNTL_TEMPFILENAME, (void*)&zTFile); |
| 669 | if( zTFile ) return zTFile; |
| 670 | } |
| 671 | sqlite3_randomness(sizeof(r), &r); |
| 672 | #if _WIN32 |
| 673 | cDirSep = '\\'; |
| 674 | dwTempLenW = GetTempPathW(dwTempSizeW, zTempDirW); |
| 675 | if( dwTempLenW>0 && dwTempLenW<dwTempSizeW |
| 676 | && ( zTempDirA = fossil_path_to_utf8(zTempDirW) )){ |
| 677 | zDir = zTempDirA; |
| 678 | }else{ |
| 679 | zDir = fossil_getenv("LOCALAPPDATA"); |
| 680 | if( zDir==0 ) zDir = "."; |
| 681 | } |
| 682 | #else |
| @@ -688,11 +691,15 @@ | |
| 691 | cDirSep = '/'; |
| 692 | #endif |
| 693 | nDir = strlen(zDir); |
| 694 | zSep[1] = 0; |
| 695 | zSep[0] = (nDir && zDir[nDir-1]==cDirSep) ? 0 : cDirSep; |
| 696 | zTFile = sqlite3_mprintf("%s%sfossil%016llx%016llx", zDir,zSep,r[0],r[1]); |
| 697 | #ifdef _WIN32 |
| 698 | if( zTempDirA ) fossil_path_free(zTempDirA); |
| 699 | #endif |
| 700 | return zTFile; |
| 701 | } |
| 702 | |
| 703 | /* |
| 704 | ** Turn memory limits for stack and heap on and off. The argument |
| 705 | ** is true to turn memory limits on and false to turn them off. |
| 706 |
+4
-4
| --- www/alerts.md | ||
| +++ www/alerts.md | ||
| @@ -323,11 +323,11 @@ | ||
| 323 | 323 | |
| 324 | 324 | This wide range of options allows Fossil to talk to pretty much any |
| 325 | 325 | SMTP setup. |
| 326 | 326 | |
| 327 | 327 | The first four options let Fossil delegate email handling to an existing |
| 328 | -[MTA][mta] so that Fossil does not need to implement the [roughly two | |
| 328 | +[MTA] so that Fossil does not need to implement the [roughly two | |
| 329 | 329 | dozen][mprotos] separate [RFCs][rfcs] required in order to properly |
| 330 | 330 | support SMTP email in this complex world we've built. As well, this |
| 331 | 331 | design choice means you do not need to do duplicate configuration, such |
| 332 | 332 | as to point Fossil at your server's TLS certificate in order to support |
| 333 | 333 | users behind mail servers that require STARTTLS encryption. |
| @@ -343,11 +343,11 @@ | ||
| 343 | 343 | details we ignored which we'll cover now. |
| 344 | 344 | |
| 345 | 345 | Fossil pipes the email message in [RFC 822 format][rfc822] to the |
| 346 | 346 | standard input of the command you gave as the "Email Send Method", |
| 347 | 347 | defaulting to `sendmail -ti`. This constitutes a protocol between Fossil |
| 348 | -and the SMTP [message transfer agent (MTA)][mta]. Any other MTA which | |
| 348 | +and the SMTP [message transfer agent (MTA)][MTA]. Any other MTA which | |
| 349 | 349 | speaks the same protocol can be used in place of the most common |
| 350 | 350 | options: Sendmail, Exim, and Postfix. |
| 351 | 351 | |
| 352 | 352 | The `-t` option tells the command to expect the list of email recipients |
| 353 | 353 | in a `To` header in the RFC 822 message presented on its standard input. |
| @@ -378,11 +378,11 @@ | ||
| 378 | 378 | with this protocol. If you know how to do it, a patch to this document |
| 379 | 379 | or a how-to on [the Fossil forum][ff] would be appreciated. |
| 380 | 380 | |
| 381 | 381 | [ff]: https://fossil-scm.org/forum/ |
| 382 | 382 | [msmtp]: https://marlam.de/msmtp/ |
| 383 | -[mta]: https://en.wikipedia.org/wiki/Message_transfer_agent | |
| 383 | +[MTA]: https://en.wikipedia.org/wiki/Message_transfer_agent | |
| 384 | 384 | [pmdoc]: http://pm-doc.sourceforge.net/doc/ |
| 385 | 385 | [rfc822]: https://www.w3.org/Protocols/rfc822/ |
| 386 | 386 | |
| 387 | 387 | |
| 388 | 388 | <a id="db"></a> |
| @@ -443,11 +443,11 @@ | ||
| 443 | 443 | locking properly, as long as the reading process is somehow restricted |
| 444 | 444 | from reading a message file as it's being written. |
| 445 | 445 | |
| 446 | 446 | It might be useful in testing and debugging to temporarily switch to |
| 447 | 447 | this method, since you can easily read the generated email messages |
| 448 | -without needing to involve [an MTA][mta]. | |
| 448 | +without needing to involve an [MTA]. | |
| 449 | 449 | |
| 450 | 450 | |
| 451 | 451 | <a id="relay"></a> |
| 452 | 452 | ### Method 4: SMTP Relay |
| 453 | 453 | |
| 454 | 454 |
| --- www/alerts.md | |
| +++ www/alerts.md | |
| @@ -323,11 +323,11 @@ | |
| 323 | |
| 324 | This wide range of options allows Fossil to talk to pretty much any |
| 325 | SMTP setup. |
| 326 | |
| 327 | The first four options let Fossil delegate email handling to an existing |
| 328 | [MTA][mta] so that Fossil does not need to implement the [roughly two |
| 329 | dozen][mprotos] separate [RFCs][rfcs] required in order to properly |
| 330 | support SMTP email in this complex world we've built. As well, this |
| 331 | design choice means you do not need to do duplicate configuration, such |
| 332 | as to point Fossil at your server's TLS certificate in order to support |
| 333 | users behind mail servers that require STARTTLS encryption. |
| @@ -343,11 +343,11 @@ | |
| 343 | details we ignored which we'll cover now. |
| 344 | |
| 345 | Fossil pipes the email message in [RFC 822 format][rfc822] to the |
| 346 | standard input of the command you gave as the "Email Send Method", |
| 347 | defaulting to `sendmail -ti`. This constitutes a protocol between Fossil |
| 348 | and the SMTP [message transfer agent (MTA)][mta]. Any other MTA which |
| 349 | speaks the same protocol can be used in place of the most common |
| 350 | options: Sendmail, Exim, and Postfix. |
| 351 | |
| 352 | The `-t` option tells the command to expect the list of email recipients |
| 353 | in a `To` header in the RFC 822 message presented on its standard input. |
| @@ -378,11 +378,11 @@ | |
| 378 | with this protocol. If you know how to do it, a patch to this document |
| 379 | or a how-to on [the Fossil forum][ff] would be appreciated. |
| 380 | |
| 381 | [ff]: https://fossil-scm.org/forum/ |
| 382 | [msmtp]: https://marlam.de/msmtp/ |
| 383 | [mta]: https://en.wikipedia.org/wiki/Message_transfer_agent |
| 384 | [pmdoc]: http://pm-doc.sourceforge.net/doc/ |
| 385 | [rfc822]: https://www.w3.org/Protocols/rfc822/ |
| 386 | |
| 387 | |
| 388 | <a id="db"></a> |
| @@ -443,11 +443,11 @@ | |
| 443 | locking properly, as long as the reading process is somehow restricted |
| 444 | from reading a message file as it's being written. |
| 445 | |
| 446 | It might be useful in testing and debugging to temporarily switch to |
| 447 | this method, since you can easily read the generated email messages |
| 448 | without needing to involve [an MTA][mta]. |
| 449 | |
| 450 | |
| 451 | <a id="relay"></a> |
| 452 | ### Method 4: SMTP Relay |
| 453 | |
| 454 |
| --- www/alerts.md | |
| +++ www/alerts.md | |
| @@ -323,11 +323,11 @@ | |
| 323 | |
| 324 | This wide range of options allows Fossil to talk to pretty much any |
| 325 | SMTP setup. |
| 326 | |
| 327 | The first four options let Fossil delegate email handling to an existing |
| 328 | [MTA] so that Fossil does not need to implement the [roughly two |
| 329 | dozen][mprotos] separate [RFCs][rfcs] required in order to properly |
| 330 | support SMTP email in this complex world we've built. As well, this |
| 331 | design choice means you do not need to do duplicate configuration, such |
| 332 | as to point Fossil at your server's TLS certificate in order to support |
| 333 | users behind mail servers that require STARTTLS encryption. |
| @@ -343,11 +343,11 @@ | |
| 343 | details we ignored which we'll cover now. |
| 344 | |
| 345 | Fossil pipes the email message in [RFC 822 format][rfc822] to the |
| 346 | standard input of the command you gave as the "Email Send Method", |
| 347 | defaulting to `sendmail -ti`. This constitutes a protocol between Fossil |
| 348 | and the SMTP [message transfer agent (MTA)][MTA]. Any other MTA which |
| 349 | speaks the same protocol can be used in place of the most common |
| 350 | options: Sendmail, Exim, and Postfix. |
| 351 | |
| 352 | The `-t` option tells the command to expect the list of email recipients |
| 353 | in a `To` header in the RFC 822 message presented on its standard input. |
| @@ -378,11 +378,11 @@ | |
| 378 | with this protocol. If you know how to do it, a patch to this document |
| 379 | or a how-to on [the Fossil forum][ff] would be appreciated. |
| 380 | |
| 381 | [ff]: https://fossil-scm.org/forum/ |
| 382 | [msmtp]: https://marlam.de/msmtp/ |
| 383 | [MTA]: https://en.wikipedia.org/wiki/Message_transfer_agent |
| 384 | [pmdoc]: http://pm-doc.sourceforge.net/doc/ |
| 385 | [rfc822]: https://www.w3.org/Protocols/rfc822/ |
| 386 | |
| 387 | |
| 388 | <a id="db"></a> |
| @@ -443,11 +443,11 @@ | |
| 443 | locking properly, as long as the reading process is somehow restricted |
| 444 | from reading a message file as it's being written. |
| 445 | |
| 446 | It might be useful in testing and debugging to temporarily switch to |
| 447 | this method, since you can easily read the generated email messages |
| 448 | without needing to involve an [MTA]. |
| 449 | |
| 450 | |
| 451 | <a id="relay"></a> |
| 452 | ### Method 4: SMTP Relay |
| 453 | |
| 454 |
+21
-15
| --- www/fossil-v-git.wiki | ||
| +++ www/fossil-v-git.wiki | ||
| @@ -248,19 +248,19 @@ | ||
| 248 | 248 | database file which provides ACID transactions and a high-level query |
| 249 | 249 | language. |
| 250 | 250 | This difference is more than an implementation detail. It has important |
| 251 | 251 | practical consequences. |
| 252 | 252 | |
| 253 | -One notable consequence is that it is difficult to find the descendents | |
| 253 | +One notable consequence is that it is difficult to find the descendants | |
| 254 | 254 | of check-ins in Git. |
| 255 | 255 | One can easily locate the ancestors of a particular Git check-in |
| 256 | 256 | by following the pointers embedded in the check-in object, but it is |
| 257 | 257 | difficult to go the other direction and locate the descendants of a |
| 258 | 258 | check-in. It is so difficult, in fact, that neither native Git nor |
| 259 | 259 | GitHub provide this capability short of crawling the |
| 260 | 260 | [https://www.git-scm.com/docs/git-log|commit log]. With Fossil, |
| 261 | -on the other hand, finding descendents is a simple SQL query. | |
| 261 | +on the other hand, finding descendants is a simple SQL query. | |
| 262 | 262 | It is common in Fossil to ask to see |
| 263 | 263 | [/timeline?df=release&y=ci|all check-ins since the last release]. |
| 264 | 264 | Git lets you see "what came before". Fossil makes it just as |
| 265 | 265 | easy to also see "what came after". |
| 266 | 266 | |
| @@ -403,17 +403,20 @@ | ||
| 403 | 403 | all: it may have an arbitrary number of differences relative to the |
| 404 | 404 | repository it originally cloned from. Git encourages siloed development. |
| 405 | 405 | Select work in a developer's local repository may remain private |
| 406 | 406 | indefinitely. |
| 407 | 407 | |
| 408 | -The Git preference for siloed development has been strongly adopted by Github, | |
| 408 | +The Git preference for siloed development has been strongly adopted by GitHub, | |
| 409 | 409 | who say |
| 410 | 410 | "[https://guides.github.com/activities/forking|Forking is at the core of social coding at GitHub]". |
| 411 | -As a result, as of January 2021, | |
| 412 | -[https://github.com/search?q=is:public|Github hosts 43 million distinct software projects], | |
| 413 | -most of them created as a results of Git/Github forking and very many | |
| 414 | -of them discontinued. | |
| 411 | +As of September 2021, | |
| 412 | +[https://github.com/search?q=is:public|Github hosts 46 million distinct software projects], | |
| 413 | +most of them created by forking a previously-existing project. Since | |
| 414 | +this is [https://evansdata.com/reports/viewRelease.php?reportID=9 | | |
| 415 | +roughly twice the number of developers in the world], it beggars belief | |
| 416 | +that most of these forks are still under active development. We expect | |
| 417 | +that the vast bulk of these are abandoned one-off efforts. | |
| 415 | 418 | |
| 416 | 419 | All of this is exactly what one wants when doing bazaar-style |
| 417 | 420 | development. |
| 418 | 421 | |
| 419 | 422 | Fossil's normal mode of operation differs on every one of these points, |
| @@ -440,12 +443,12 @@ | ||
| 440 | 443 | |
| 441 | 444 | <li><p><b>No easy drive-by contributions:</b> Git |
| 442 | 445 | [https://www.git-scm.com/docs/git-request-pull|pull requests] offer |
| 443 | 446 | a low-friction path to accepting |
| 444 | 447 | [https://www.jonobacon.com/2012/07/25/building-strong-community-structural-integrity/|drive-by |
| 445 | - contributions]. Fossil's closest equivalent is its unique | |
| 446 | - [/help?cmd=bundle|bundle] feature, which requires higher engagement | |
| 448 | + contributions]. Fossil's closest equivalents are its unique | |
| 449 | + [/help?cmd=bundle|bundle] and [/help?cmd=patch|patch] features, which require higher engagement | |
| 447 | 450 | than firing off a PR.⁷ This difference comes directly from the |
| 448 | 451 | initial designed purpose for each tool: the SQLite project doesn't |
| 449 | 452 | accept outside contributions from previously-unknown developers, but |
| 450 | 453 | the Linux kernel does.</p></li> |
| 451 | 454 | |
| @@ -478,11 +481,11 @@ | ||
| 478 | 481 | Fossil are not purely local labels. They sync along with everything |
| 479 | 482 | else, so everyone sees the same set of branch names. Fossil's design |
| 480 | 483 | choice here is a direct reflection of the Linux vs. SQLite project |
| 481 | 484 | outlook: SQLite's developers collaborate closely on a single |
| 482 | 485 | coherent project, whereas Linux's developers go off on tangents and |
| 483 | - occasionally sync changes up with each other.</p></li> | |
| 486 | + occasionally send selected change sets to each other.</p></li> | |
| 484 | 487 | |
| 485 | 488 | <li><p><b>Private branches are rare:</b> |
| 486 | 489 | [/doc/trunk/www/private.wiki|Private branches exist in Fossil], but |
| 487 | 490 | they're normally used to handle rare exception cases, whereas in |
| 488 | 491 | many Git projects, they're part of the straight-line development |
| @@ -506,13 +509,11 @@ | ||
| 506 | 509 | [https://en.wikipedia.org/wiki/Control_theory | control theory] to |
| 507 | 510 | directly affect the speed at which any system can safely make changes. |
| 508 | 511 | The larger the feedback loop, the slower the whole system must run in |
| 509 | 512 | order to avoid loss of control. The same concept shows up in other |
| 510 | 513 | contexts, such as in the [https://en.wikipedia.org/wiki/OODA_loop | OODA |
| 511 | -loop] concept originally developed to explain the success of the US F-86 | |
| 512 | -Sabre fighter aircraft over the on-paper superior MiG-15, then later | |
| 513 | -applied in other contexts, such as business process management. | |
| 514 | +loop] concept. | |
| 514 | 515 | Committing your changes to private branches in order to delay a public |
| 515 | 516 | push to the parent repo increases the size of your collaborators' |
| 516 | 517 | control loops, either causing them to slow their work in order to safely |
| 517 | 518 | react to your work, or to overcorrect in response to each change. |
| 518 | 519 | |
| @@ -924,12 +925,17 @@ | ||
| 924 | 925 | despite using a roughly similar amount of high-level scripting code |
| 925 | 926 | because its interpreters are compact and built into Fossil itself. |
| 926 | 927 | |
| 927 | 928 | <li><p>Both Fossil and Git support |
| 928 | 929 | [https://en.wikipedia.org/wiki/Patch_(Unix)|<tt>patch(1)</tt> |
| 929 | - files], a common way to allow drive-by contributions, but it's a | |
| 930 | + files] — unified diff formatted output — for accepting drive-by contributions, but it's a | |
| 930 | 931 | lossy contribution path for both systems. Unlike Git PRs and Fossil |
| 931 | 932 | bundles, patch files collapse multiple checkins together, they don't |
| 932 | 933 | include check-in comments, and they cannot encode changes made above |
| 933 | 934 | the individual file content layer: you lose branching decisions, |
| 934 | - tag changes, file renames, and more when using patch files.</p></li> | |
| 935 | + tag changes, file renames, and more when using patch files. Fossil | |
| 936 | + 2.16 adds [./patchcmd.md | a <tt>fossil patch</tt> command] that | |
| 937 | + also solves these problems, but it is because it works like a Fossil | |
| 938 | + bundle, only for uncommitted changes; it doesn't use Larry Wall's | |
| 939 | + <tt>patch</tt> tool to apply unified diff output to the receiving | |
| 940 | + Fossil checkout.</p></li> | |
| 935 | 941 | </ol></i></small> |
| 936 | 942 |
| --- www/fossil-v-git.wiki | |
| +++ www/fossil-v-git.wiki | |
| @@ -248,19 +248,19 @@ | |
| 248 | database file which provides ACID transactions and a high-level query |
| 249 | language. |
| 250 | This difference is more than an implementation detail. It has important |
| 251 | practical consequences. |
| 252 | |
| 253 | One notable consequence is that it is difficult to find the descendents |
| 254 | of check-ins in Git. |
| 255 | One can easily locate the ancestors of a particular Git check-in |
| 256 | by following the pointers embedded in the check-in object, but it is |
| 257 | difficult to go the other direction and locate the descendants of a |
| 258 | check-in. It is so difficult, in fact, that neither native Git nor |
| 259 | GitHub provide this capability short of crawling the |
| 260 | [https://www.git-scm.com/docs/git-log|commit log]. With Fossil, |
| 261 | on the other hand, finding descendents is a simple SQL query. |
| 262 | It is common in Fossil to ask to see |
| 263 | [/timeline?df=release&y=ci|all check-ins since the last release]. |
| 264 | Git lets you see "what came before". Fossil makes it just as |
| 265 | easy to also see "what came after". |
| 266 | |
| @@ -403,17 +403,20 @@ | |
| 403 | all: it may have an arbitrary number of differences relative to the |
| 404 | repository it originally cloned from. Git encourages siloed development. |
| 405 | Select work in a developer's local repository may remain private |
| 406 | indefinitely. |
| 407 | |
| 408 | The Git preference for siloed development has been strongly adopted by Github, |
| 409 | who say |
| 410 | "[https://guides.github.com/activities/forking|Forking is at the core of social coding at GitHub]". |
| 411 | As a result, as of January 2021, |
| 412 | [https://github.com/search?q=is:public|Github hosts 43 million distinct software projects], |
| 413 | most of them created as a results of Git/Github forking and very many |
| 414 | of them discontinued. |
| 415 | |
| 416 | All of this is exactly what one wants when doing bazaar-style |
| 417 | development. |
| 418 | |
| 419 | Fossil's normal mode of operation differs on every one of these points, |
| @@ -440,12 +443,12 @@ | |
| 440 | |
| 441 | <li><p><b>No easy drive-by contributions:</b> Git |
| 442 | [https://www.git-scm.com/docs/git-request-pull|pull requests] offer |
| 443 | a low-friction path to accepting |
| 444 | [https://www.jonobacon.com/2012/07/25/building-strong-community-structural-integrity/|drive-by |
| 445 | contributions]. Fossil's closest equivalent is its unique |
| 446 | [/help?cmd=bundle|bundle] feature, which requires higher engagement |
| 447 | than firing off a PR.⁷ This difference comes directly from the |
| 448 | initial designed purpose for each tool: the SQLite project doesn't |
| 449 | accept outside contributions from previously-unknown developers, but |
| 450 | the Linux kernel does.</p></li> |
| 451 | |
| @@ -478,11 +481,11 @@ | |
| 478 | Fossil are not purely local labels. They sync along with everything |
| 479 | else, so everyone sees the same set of branch names. Fossil's design |
| 480 | choice here is a direct reflection of the Linux vs. SQLite project |
| 481 | outlook: SQLite's developers collaborate closely on a single |
| 482 | coherent project, whereas Linux's developers go off on tangents and |
| 483 | occasionally sync changes up with each other.</p></li> |
| 484 | |
| 485 | <li><p><b>Private branches are rare:</b> |
| 486 | [/doc/trunk/www/private.wiki|Private branches exist in Fossil], but |
| 487 | they're normally used to handle rare exception cases, whereas in |
| 488 | many Git projects, they're part of the straight-line development |
| @@ -506,13 +509,11 @@ | |
| 506 | [https://en.wikipedia.org/wiki/Control_theory | control theory] to |
| 507 | directly affect the speed at which any system can safely make changes. |
| 508 | The larger the feedback loop, the slower the whole system must run in |
| 509 | order to avoid loss of control. The same concept shows up in other |
| 510 | contexts, such as in the [https://en.wikipedia.org/wiki/OODA_loop | OODA |
| 511 | loop] concept originally developed to explain the success of the US F-86 |
| 512 | Sabre fighter aircraft over the on-paper superior MiG-15, then later |
| 513 | applied in other contexts, such as business process management. |
| 514 | Committing your changes to private branches in order to delay a public |
| 515 | push to the parent repo increases the size of your collaborators' |
| 516 | control loops, either causing them to slow their work in order to safely |
| 517 | react to your work, or to overcorrect in response to each change. |
| 518 | |
| @@ -924,12 +925,17 @@ | |
| 924 | despite using a roughly similar amount of high-level scripting code |
| 925 | because its interpreters are compact and built into Fossil itself. |
| 926 | |
| 927 | <li><p>Both Fossil and Git support |
| 928 | [https://en.wikipedia.org/wiki/Patch_(Unix)|<tt>patch(1)</tt> |
| 929 | files], a common way to allow drive-by contributions, but it's a |
| 930 | lossy contribution path for both systems. Unlike Git PRs and Fossil |
| 931 | bundles, patch files collapse multiple checkins together, they don't |
| 932 | include check-in comments, and they cannot encode changes made above |
| 933 | the individual file content layer: you lose branching decisions, |
| 934 | tag changes, file renames, and more when using patch files.</p></li> |
| 935 | </ol></i></small> |
| 936 |
| --- www/fossil-v-git.wiki | |
| +++ www/fossil-v-git.wiki | |
| @@ -248,19 +248,19 @@ | |
| 248 | database file which provides ACID transactions and a high-level query |
| 249 | language. |
| 250 | This difference is more than an implementation detail. It has important |
| 251 | practical consequences. |
| 252 | |
| 253 | One notable consequence is that it is difficult to find the descendants |
| 254 | of check-ins in Git. |
| 255 | One can easily locate the ancestors of a particular Git check-in |
| 256 | by following the pointers embedded in the check-in object, but it is |
| 257 | difficult to go the other direction and locate the descendants of a |
| 258 | check-in. It is so difficult, in fact, that neither native Git nor |
| 259 | GitHub provide this capability short of crawling the |
| 260 | [https://www.git-scm.com/docs/git-log|commit log]. With Fossil, |
| 261 | on the other hand, finding descendants is a simple SQL query. |
| 262 | It is common in Fossil to ask to see |
| 263 | [/timeline?df=release&y=ci|all check-ins since the last release]. |
| 264 | Git lets you see "what came before". Fossil makes it just as |
| 265 | easy to also see "what came after". |
| 266 | |
| @@ -403,17 +403,20 @@ | |
| 403 | all: it may have an arbitrary number of differences relative to the |
| 404 | repository it originally cloned from. Git encourages siloed development. |
| 405 | Select work in a developer's local repository may remain private |
| 406 | indefinitely. |
| 407 | |
| 408 | The Git preference for siloed development has been strongly adopted by GitHub, |
| 409 | who say |
| 410 | "[https://guides.github.com/activities/forking|Forking is at the core of social coding at GitHub]". |
| 411 | As of September 2021, |
| 412 | [https://github.com/search?q=is:public|Github hosts 46 million distinct software projects], |
| 413 | most of them created by forking a previously-existing project. Since |
| 414 | this is [https://evansdata.com/reports/viewRelease.php?reportID=9 | |
| 415 | roughly twice the number of developers in the world], it beggars belief |
| 416 | that most of these forks are still under active development. We expect |
| 417 | that the vast bulk of these are abandoned one-off efforts. |
| 418 | |
| 419 | All of this is exactly what one wants when doing bazaar-style |
| 420 | development. |
| 421 | |
| 422 | Fossil's normal mode of operation differs on every one of these points, |
| @@ -440,12 +443,12 @@ | |
| 443 | |
| 444 | <li><p><b>No easy drive-by contributions:</b> Git |
| 445 | [https://www.git-scm.com/docs/git-request-pull|pull requests] offer |
| 446 | a low-friction path to accepting |
| 447 | [https://www.jonobacon.com/2012/07/25/building-strong-community-structural-integrity/|drive-by |
| 448 | contributions]. Fossil's closest equivalents are its unique |
| 449 | [/help?cmd=bundle|bundle] and [/help?cmd=patch|patch] features, which require higher engagement |
| 450 | than firing off a PR.⁷ This difference comes directly from the |
| 451 | initial designed purpose for each tool: the SQLite project doesn't |
| 452 | accept outside contributions from previously-unknown developers, but |
| 453 | the Linux kernel does.</p></li> |
| 454 | |
| @@ -478,11 +481,11 @@ | |
| 481 | Fossil are not purely local labels. They sync along with everything |
| 482 | else, so everyone sees the same set of branch names. Fossil's design |
| 483 | choice here is a direct reflection of the Linux vs. SQLite project |
| 484 | outlook: SQLite's developers collaborate closely on a single |
| 485 | coherent project, whereas Linux's developers go off on tangents and |
| 486 | occasionally send selected change sets to each other.</p></li> |
| 487 | |
| 488 | <li><p><b>Private branches are rare:</b> |
| 489 | [/doc/trunk/www/private.wiki|Private branches exist in Fossil], but |
| 490 | they're normally used to handle rare exception cases, whereas in |
| 491 | many Git projects, they're part of the straight-line development |
| @@ -506,13 +509,11 @@ | |
| 509 | [https://en.wikipedia.org/wiki/Control_theory | control theory] to |
| 510 | directly affect the speed at which any system can safely make changes. |
| 511 | The larger the feedback loop, the slower the whole system must run in |
| 512 | order to avoid loss of control. The same concept shows up in other |
| 513 | contexts, such as in the [https://en.wikipedia.org/wiki/OODA_loop | OODA |
| 514 | loop] concept. |
| 515 | Committing your changes to private branches in order to delay a public |
| 516 | push to the parent repo increases the size of your collaborators' |
| 517 | control loops, either causing them to slow their work in order to safely |
| 518 | react to your work, or to overcorrect in response to each change. |
| 519 | |
| @@ -924,12 +925,17 @@ | |
| 925 | despite using a roughly similar amount of high-level scripting code |
| 926 | because its interpreters are compact and built into Fossil itself. |
| 927 | |
| 928 | <li><p>Both Fossil and Git support |
| 929 | [https://en.wikipedia.org/wiki/Patch_(Unix)|<tt>patch(1)</tt> |
| 930 | files] — unified diff formatted output — for accepting drive-by contributions, but it's a |
| 931 | lossy contribution path for both systems. Unlike Git PRs and Fossil |
| 932 | bundles, patch files collapse multiple checkins together, they don't |
| 933 | include check-in comments, and they cannot encode changes made above |
| 934 | the individual file content layer: you lose branching decisions, |
| 935 | tag changes, file renames, and more when using patch files. Fossil |
| 936 | 2.16 adds [./patchcmd.md | a <tt>fossil patch</tt> command] that |
| 937 | also solves these problems, but it is because it works like a Fossil |
| 938 | bundle, only for uncommitted changes; it doesn't use Larry Wall's |
| 939 | <tt>patch</tt> tool to apply unified diff output to the receiving |
| 940 | Fossil checkout.</p></li> |
| 941 | </ol></i></small> |
| 942 |