Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Sync w/trunk. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | panic-reduction |
| Files: | files | file ages | folders |
| SHA3-256: |
79be1156a9f4dbfcc1ba23572adfe5a1 |
| User & Date: | larrybr 2021-03-31 10:57:50.744 |
Context
|
2021-03-31
| ||
| 12:42 | Merge reduction of fossil_panic() calls, for cleaner abnormal exits. check-in: 31c7bdb80b user: larrybr tags: trunk | |
| 10:57 | Sync w/trunk. Closed-Leaf check-in: 79be1156a9 user: larrybr tags: panic-reduction | |
|
2021-03-28
| ||
| 05:14 | Add example of fossil timeline + diff to get changes between specific versions check-in: 19f4b064ac user: danshearer tags: trunk | |
|
2021-03-26
| ||
| 17:53 | Merge from trunk tip. check-in: 6e1cee191d user: larrybr tags: panic-reduction | |
Changes
Changes to skins/darkmode/css.txt.
| ︙ | ︙ | |||
546 547 548 549 550 551 552 |
border: 1px inset;
padding: 0 0.5em;
}
pre.udiff {
overflow-x: auto;
}
| > > > > > | 546 547 548 549 550 551 552 553 554 555 556 557 |
border: 1px inset;
padding: 0 0.5em;
}
pre.udiff {
overflow-x: auto;
}
body.report table.report tr td { color: black }
body.report table.report a { color: blue }
body.tkt td.tktDspValue { color: black }
body.tkt td.tktDspValue a { color: blue }
|
Changes to src/add.c.
| ︙ | ︙ | |||
437 438 439 440 441 442 443 |
char *zName;
int isDir;
Blob fullName = empty_blob;
/* file_tree_name() throws a fatal error if g.argv[i] is outside of the
** checkout. */
file_tree_name(g.argv[i], &fullName, 0, 1);
| < < < < < < < < < < < | 437 438 439 440 441 442 443 444 445 446 447 448 449 450 |
char *zName;
int isDir;
Blob fullName = empty_blob;
/* file_tree_name() throws a fatal error if g.argv[i] is outside of the
** checkout. */
file_tree_name(g.argv[i], &fullName, 0, 1);
blob_reset(&fullName);
file_canonical_name(g.argv[i], &fullName, 0);
zName = blob_str(&fullName);
isDir = file_isdir(zName, RepoFILE);
if( isDir==1 ){
vfile_scan(&fullName, nRoot-1, scanFlags, pClean, pIgnore, RepoFILE);
}else if( isDir==0 ){
|
| ︙ | ︙ | |||
484 485 486 487 488 489 490 491 492 493 494 495 496 497 |
);
}
blob_reset(&fullName);
}
glob_free(pIgnore);
glob_free(pClean);
add_files_in_sfile(vid);
db_end_transaction(0);
}
/*
** This function adds a file to list of files to delete from disk after
** the other actions required for the parent operation have completed
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 |
);
}
blob_reset(&fullName);
}
glob_free(pIgnore);
glob_free(pClean);
/** Check for Windows-reserved names and warn or exit, as
** appopriate. Note that the 'add' internal machinery already
** _silently_ skips over any names for which
** file_is_reserved_name() returns true or which is in the
** fossil_reserved_name() list. We do not need to warn for those,
** as they're outright verboten. */
if(db_exists("SELECT 1 FROM sfile WHERE win_reserved(pathname)")){
Stmt q = empty_Stmt;
db_prepare(&q,"SELECT pathname FROM sfile "
"WHERE win_reserved(pathname)");
int reservedCount = 0;
while( db_step(&q)==SQLITE_ROW ){
const char * zName = db_column_text(&q, 0);
++reservedCount;
if(allowReservedFlag){
fossil_warning("WARNING: Windows-reserved "
"filename: %s", zName);
}else{
fossil_warning("ERROR: Windows-reserved filename: %s", zName);
}
}
db_finalize(&q);
if(allowReservedFlag==0){
fossil_fatal("ERROR: %d Windows-reserved filename(s) added. "
"Use --allow-reserved to permit such names.",
reservedCount);
}
}
add_files_in_sfile(vid);
db_end_transaction(0);
}
/*
** This function adds a file to list of files to delete from disk after
** the other actions required for the parent operation have completed
|
| ︙ | ︙ |
Changes to src/chat.c.
| ︙ | ︙ | |||
161 162 163 164 165 166 167 | @ <div id='chat-input-line'> @ <input type="text" name="msg" id="chat-input-single" \ @ placeholder="Type message here." autocomplete="off"> @ <textarea rows="8" id="chat-input-multi" \ @ placeholder="Type message here. Ctrl-Enter sends it." \ @ class="hidden"></textarea> @ <input type="submit" value="Send" id="chat-message-submit"> | < < | 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | @ <div id='chat-input-line'> @ <input type="text" name="msg" id="chat-input-single" \ @ placeholder="Type message here." autocomplete="off"> @ <textarea rows="8" id="chat-input-multi" \ @ placeholder="Type message here. Ctrl-Enter sends it." \ @ class="hidden"></textarea> @ <input type="submit" value="Send" id="chat-message-submit"> @ <span id="chat-settings-button" class="settings-icon" \ @ aria-label="Settings..." aria-haspopup="true" ></span> @ </div> @ <div id='chat-input-file-area'> @ <div class='file-selection-wrapper'> @ <div class='help-buttonlet'> @ Select a file to upload, drag/drop a file into this spot, |
| ︙ | ︙ |
Changes to src/chat.js.
| ︙ | ︙ | |||
105 106 107 108 109 110 111 |
messagesWrapper: E1('#chat-messages-wrapper'),
inputForm: E1('#chat-form'),
btnSubmit: E1('#chat-message-submit'),
inputSingle: E1('#chat-input-single'),
inputMulti: E1('#chat-input-multi'),
inputCurrent: undefined/*one of inputSingle or inputMulti*/,
inputFile: E1('#chat-input-file'),
| | < < | 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
messagesWrapper: E1('#chat-messages-wrapper'),
inputForm: E1('#chat-form'),
btnSubmit: E1('#chat-message-submit'),
inputSingle: E1('#chat-input-single'),
inputMulti: E1('#chat-input-multi'),
inputCurrent: undefined/*one of inputSingle or inputMulti*/,
inputFile: E1('#chat-input-file'),
contentDiv: E1('div.content')
},
me: F.user.name,
mxMsg: F.config.chat.initSize ? -F.config.chat.initSize : -50,
mnMsg: undefined/*lowest message ID we've seen so far (for history loading)*/,
pageIsActive: 'visible'===document.visibilityState,
changesSincePageHidden: 0,
notificationBubbleColor: 'white',
|
| ︙ | ︙ | |||
337 338 339 340 341 342 343 |
}else if(Chat.e.newestMessage){
Chat.e.newestMessage.scrollIntoView(false);
}
},
toggleChatOnlyMode: function(){
return this.chatOnlyMode(!this.isChatOnlyMode());
},
| < < < < < < < < | 335 336 337 338 339 340 341 342 343 344 345 346 347 348 |
}else if(Chat.e.newestMessage){
Chat.e.newestMessage.scrollIntoView(false);
}
},
toggleChatOnlyMode: function(){
return this.chatOnlyMode(!this.isChatOnlyMode());
},
messageIsInView: function(e){
return e ? overlapsElemView(e, this.e.messagesWrapper) : false;
},
settings:{
get: (k,dflt)=>F.storage.get(k,dflt),
getBool: (k,dflt)=>F.storage.getBool(k,dflt),
set: (k,v)=>F.storage.set(k,v),
|
| ︙ | ︙ | |||
963 964 965 966 967 968 969 |
},{
label: "Images inline",
boolValue: ()=>Chat.settings.getBool('images-inline'),
callback: function(){
const v = Chat.settings.toggle('images-inline');
F.toast.message("Image mode set to "+(v ? "inline" : "hyperlink")+".");
}
| < < < < | 953 954 955 956 957 958 959 960 961 962 963 964 965 966 |
},{
label: "Images inline",
boolValue: ()=>Chat.settings.getBool('images-inline'),
callback: function(){
const v = Chat.settings.toggle('images-inline');
F.toast.message("Image mode set to "+(v ? "inline" : "hyperlink")+".");
}
}];
/** Set up selection list of notification sounds. */
if(true/*flip this to false to enable selection of audio files*/){
settingsOps.push({
label: "Audible alerts",
boolValue: ()=>Chat.settings.getBool('audible-alert'),
|
| ︙ | ︙ | |||
1081 1082 1083 1084 1085 1086 1087 |
return rect.right - popupSize.width;
};
settingsPopup.options.adjustY = function(y){
const rect = settingsButton.getBoundingClientRect();
return rect.top - popupSize.height -2;
};
})()/*#chat-settings-button setup*/;
| < < < < < < < < < < < < < | 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 |
return rect.right - popupSize.width;
};
settingsPopup.options.adjustY = function(y){
const rect = settingsButton.getBoundingClientRect();
return rect.top - popupSize.height -2;
};
})()/*#chat-settings-button setup*/;
/** Callback for poll() to inject new content into the page. jx ==
the response from /chat-poll. If atEnd is true, the message is
appended to the end of the chat list (for loading older
messages), else the beginning (the default). */
const newcontent = function f(jx,atEnd){
if(!f.processPost){
|
| ︙ | ︙ |
Changes to src/db.c.
| ︙ | ︙ | |||
1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 |
alert_find_emailaddr_func, 0, 0);
sqlite3_create_function(db, "display_name", 1, SQLITE_UTF8, 0,
alert_display_name_func, 0, 0);
sqlite3_create_function(db, "obscure", 1, SQLITE_UTF8, 0,
db_obscure, 0, 0);
sqlite3_create_function(db, "protected_setting", 1, SQLITE_UTF8, 0,
db_protected_setting_func, 0, 0);
}
#if USE_SEE
/*
** This is a pointer to the saved database encryption key string.
*/
static char *zSavedKey = 0;
| > > > | 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 |
alert_find_emailaddr_func, 0, 0);
sqlite3_create_function(db, "display_name", 1, SQLITE_UTF8, 0,
alert_display_name_func, 0, 0);
sqlite3_create_function(db, "obscure", 1, SQLITE_UTF8, 0,
db_obscure, 0, 0);
sqlite3_create_function(db, "protected_setting", 1, SQLITE_UTF8, 0,
db_protected_setting_func, 0, 0);
sqlite3_create_function(db, "win_reserved", 1, SQLITE_UTF8, 0,
db_win_reserved_func,0,0
);
}
#if USE_SEE
/*
** This is a pointer to the saved database encryption key string.
*/
static char *zSavedKey = 0;
|
| ︙ | ︙ | |||
2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 |
}else{
assert( argc==3 );
assert( rc==0 || rc==1 );
if( sqlite3_value_type(argv[2-rc])==SQLITE_NULL ) rc = 1-rc;
sqlite3_result_value(context, argv[2-rc]);
}
}
/*
** Convert the input string into a artifact hash. Make a notation in the
** CONCEALED table so that the hash can be undo using the db_reveal()
** function at some later time.
**
** The value returned is stored in static space and will be overwritten
| > > > > > > > > > > > > > > > > | 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 |
}else{
assert( argc==3 );
assert( rc==0 || rc==1 );
if( sqlite3_value_type(argv[2-rc])==SQLITE_NULL ) rc = 1-rc;
sqlite3_result_value(context, argv[2-rc]);
}
}
/*
** Implementation of the "win_reserved(X)" SQL function, a wrapper
** for file_is_win_reserved(X) which returns true if X is
** a Windows-reserved filename.
*/
LOCAL void db_win_reserved_func(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
const char * zName = (const char *)sqlite3_value_text(argv[0]);
if( zName!=0 ){
sqlite3_result_int(context, file_is_win_reserved(zName)!=0);
}
}
/*
** Convert the input string into a artifact hash. Make a notation in the
** CONCEALED table so that the hash can be undo using the db_reveal()
** function at some later time.
**
** The value returned is stored in static space and will be overwritten
|
| ︙ | ︙ |
Changes to src/report.c.
| ︙ | ︙ | |||
966 967 968 969 970 971 972 | fossil_free((void *)azVals); return rc; } /* ** WEBPAGE: rptview ** | | | | > > > > | 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 |
fossil_free((void *)azVals);
return rc;
}
/*
** WEBPAGE: rptview
**
** Generate a report. The "rn" query parameter is the report number
** corresponding to REPORTFMT.RN. If the "tablist" query parameter exists,
** then the output consists of lines of tab-separated fields instead of
** an HTML table. If the "rvsmpl" query parameter is set then report's
** submenu will contain an extra hyperlink that have a value-driven
** label and target.
**
** "rvsmpl" stands for Report View SubMenu's Parametric Link.
*/
void rptview_page(void){
int count = 0;
int rn, rc;
char *zSql;
char *zTitle;
char *zOwner;
|
| ︙ | ︙ | |||
1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 |
zSql = mprintf("SELECT * FROM (%s) ORDER BY %d %s", zSql, nField, zDir);
}
}
count = 0;
if( !tabs ){
struct GenerateHTML sState = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
db_multi_exec("PRAGMA empty_result_callbacks=ON");
style_set_current_feature("report");
| > > > > > > > > > > > > | > > > > > | 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 |
zSql = mprintf("SELECT * FROM (%s) ORDER BY %d %s", zSql, nField, zDir);
}
}
count = 0;
if( !tabs ){
struct GenerateHTML sState = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
const char *zQS = PD("QUERY_STRING","");
db_multi_exec("PRAGMA empty_result_callbacks=ON");
style_set_current_feature("report");
/*
** Lets use a funcy button for /reportlist since that page may be
** heavily customized by the user. Some variants: ⊚ ⦾ ❊ ⊛ ⚛ ⸎ 💠
** Enclosing it inside of square brackets makes its position
** determenistic and clearly distincts regular submenu links from
** those that are induced by the query string parameters.
*/
if( zQS[0] ){
style_submenu_element("Raw","%R/%s?tablist=1&%s",g.zPath,zQS);
style_submenu_element("[⊚]","%R/reportlist?%s",zQS);
} else {
style_submenu_element("Raw","%R/%s?tablist=1",g.zPath);
style_submenu_element("[⊚]","%R/reportlist");
}
style_submenu_parametric("rptview_",5);
style_submenu_parametric("rv",5);
if( g.perm.Admin
|| (g.perm.TktFmt && g.zLogin && fossil_strcmp(g.zLogin,zOwner)==0) ){
style_submenu_element("Edit", "rptedit?rn=%d", rn);
}
if( g.perm.TktFmt ){
style_submenu_element("SQL", "rptsql?rn=%d",rn);
}
|
| ︙ | ︙ |
Changes to src/sqlcmd.c.
| ︙ | ︙ | |||
144 145 146 147 148 149 150 |
int argc,
sqlite3_value **argv
){
gather_artifact_stats(1);
}
/*
| | | | 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
int argc,
sqlite3_value **argv
){
gather_artifact_stats(1);
}
/*
** Add the content(), compress(), decompress(), and
** gather_artifact_stats() SQL functions to database connection db.
*/
int add_content_sql_commands(sqlite3 *db){
sqlite3_create_function(db, "content", 1, SQLITE_UTF8, 0,
sqlcmd_content, 0, 0);
sqlite3_create_function(db, "compress", 1, SQLITE_UTF8, 0,
sqlcmd_compress, 0, 0);
sqlite3_create_function(db, "decompress", 1, SQLITE_UTF8, 0,
|
| ︙ | ︙ | |||
169 170 171 172 173 174 175 | ** db_protect(X) ** db_protect_pop(X) ** ** These invoke the corresponding C routines. ** ** WARNING: ** Do not instantiate these functions for any Fossil webpage or command | | | | 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
** db_protect(X)
** db_protect_pop(X)
**
** These invoke the corresponding C routines.
**
** WARNING:
** Do not instantiate these functions for any Fossil webpage or command
** method other than the "fossil sql" command. If an attacker gains access
** to these functions, he will be able to disable other defense mechanisms.
**
** This routines are for interactiving testing only. They are experimental
** and undocumented (apart from this comments) and might go away or change
** in future releases.
**
** 2020-11-29: These functions are now only available if the "fossil sql"
** command is started with the --test option.
*/
static void sqlcmd_db_protect(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
|
| ︙ | ︙ | |||
202 203 204 205 206 207 208 |
static void sqlcmd_db_protect_pop(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
if( !local_bSqlCmdTest ) db_protect_pop();
}
| < < < | 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
static void sqlcmd_db_protect_pop(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
if( !local_bSqlCmdTest ) db_protect_pop();
}
/*
** This is the "automatic extension" initializer that runs right after
** the connection to the repository database is opened. Set up the
** database connection to be more useful to the human operator.
*/
static int sqlcmd_autoinit(
|
| ︙ | ︙ |
Changes to src/style.c.
| ︙ | ︙ | |||
327 328 329 330 331 332 333 334 335 336 337 338 339 340 |
aSubmenuCtrl[nSubmenuCtrl].iSize = n/2;
aSubmenuCtrl[nSubmenuCtrl].azChoice = (const char *const *)az;
aSubmenuCtrl[nSubmenuCtrl].eVisible = STYLE_NORMAL;
aSubmenuCtrl[nSubmenuCtrl].eType = FF_MULTI;
nSubmenuCtrl++;
}
}
/*
** Disable or enable the submenu
*/
void style_submenu_enable(int onOff){
submenuEnable = onOff;
}
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 |
aSubmenuCtrl[nSubmenuCtrl].iSize = n/2;
aSubmenuCtrl[nSubmenuCtrl].azChoice = (const char *const *)az;
aSubmenuCtrl[nSubmenuCtrl].eVisible = STYLE_NORMAL;
aSubmenuCtrl[nSubmenuCtrl].eType = FF_MULTI;
nSubmenuCtrl++;
}
}
/* Add hyperlinks depending on the existence and values of special
** parameters in the request's query string. The names of these
** parameters that are investigated are obtainted by concatenation
** of zPrefix with suffix "smplX", where X is either nothing or
** a positive digit <= nMaxDigit. zPrefix must start with a lowercase
** letter, be short and have no strange characters. A value is
** well-formed if its first filepath segment (separated by '/')
** has no strange characters. The labels of the resulting submenu items
** are equal to the well-formed values that are prepended by "✧"
** unless a value starts with a lowercase letter.
** Malformed values are silently ignored.
*/
void style_submenu_parametric(
const char *zPrefix, /* common prefix of the query parameters names */
const int nMaxDigit /* maximal digit on the end of param names */
){
const char *zQS; /* QUERY_STRING */
const char *suffix = "smpl"; /* common suffix for all parameters */
const short sfxlen = 4; /* length of the above suffix */
char zN[32]; /* short names => no dynamic allocations */
short i,l;
/* zPrefix must be tidy and short; also filter out ENV/CGI variables */
assert( zPrefix != 0 && fossil_islower(zPrefix[0]) );
l = strnlen( zPrefix, sizeof(zN) );
assert( l+sfxlen+2 <= sizeof(zN) );
assert( fossil_no_strange_characters(zPrefix) );
/* concatenate zPrefix and suffix */
strcpy( zN, zPrefix );
strcpy( zN + l, suffix );
l += sfxlen;
zN[l+1] = 0; /* nul-terminator after digit's placeholder (if any) */
zQS = PD("QUERY_STRING","");
for( i = 0; i <= 9 && i <= nMaxDigit; i++ ){
const char *zV, *z;
zN[l] = ( i == 0 ? 0 : '0' + i ); /* ...smpl instead of ...smpl0 */
zV = PD(zN,"");
if( zV[0] == 0 || zV[0] == '/' ){
continue;
}
/* require the first path segment to be unfancy ASCII string */
for( z = zV; z[0] && z[0] != '/' ;){
if( fossil_isalnum(z[0]) || z[0]=='_' || z[0]=='-' ) z++;
else break;
}
if( z[0] != 0 && z[0] != '/' )
continue;
assert( nSubmenu < count(aSubmenu) );
if(fossil_islower(zV[0])){
aSubmenu[nSubmenu].zLabel = mprintf( "%s",zV); /* memory leak? */
}else{
aSubmenu[nSubmenu].zLabel = mprintf("✧%s",zV); /* maybe: ◦✧⸰⸎ ✨ */
}
if( zQS[0] ){
aSubmenu[nSubmenu].zLink = mprintf("%R/%s?%s",zV,zQS);
}else{
aSubmenu[nSubmenu].zLink = mprintf("%R/%s",zV);
}
nSubmenu++;
}
}
/*
** Disable or enable the submenu
*/
void style_submenu_enable(int onOff){
submenuEnable = onOff;
}
|
| ︙ | ︙ |
Changes to src/wiki.c.
| ︙ | ︙ | |||
591 592 593 594 595 596 597 598 599 600 601 602 603 604 |
){
style_submenu_element("Edit", "%R/wikiedit?name=%T", zPageName);
}else if( rid && g.perm.ApndWiki ){
style_submenu_element("Edit", "%R/wikiappend?name=%T", zPageName);
}
if( g.perm.Hyperlink ){
style_submenu_element("History", "%R/whistory?name=%T", zPageName);
}
}
if( !isPopup ){
style_set_current_page("%T?name=%T", g.zPath, zPageName);
wiki_page_header(WIKITYPE_UNKNOWN, zPageName, "");
if( !noSubmenu ){
wiki_standard_submenu(submenuFlags);
| > | 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 |
){
style_submenu_element("Edit", "%R/wikiedit?name=%T", zPageName);
}else if( rid && g.perm.ApndWiki ){
style_submenu_element("Edit", "%R/wikiappend?name=%T", zPageName);
}
if( g.perm.Hyperlink ){
style_submenu_element("History", "%R/whistory?name=%T", zPageName);
style_submenu_parametric("wiki",7);
}
}
if( !isPopup ){
style_set_current_page("%T?name=%T", g.zPath, zPageName);
wiki_page_header(WIKITYPE_UNKNOWN, zPageName, "");
if( !noSubmenu ){
wiki_standard_submenu(submenuFlags);
|
| ︙ | ︙ |
Changes to www/changes.wiki.
| ︙ | ︙ | |||
69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
* Update the built-in SQLite to version 3.35.0.
* The ./configure script now has the --print-minimum-sqlite-version option
that prints the minimum SQLite version required by the current version
of Fossil. This might be used by integrators who insist on building
Fossil to link against the system SQLite library rather than the
built-in copy of SQLite, to verify that their system SQLite library
is recent enough.
<a name='v2_14'></a>
<h2>Changes for Version 2.14 (2021-01-20)</h2>
* <b>Schema Update Notice #1:</b>
This release drops a trigger from the database schema (replacing
it with a TEMP trigger that is created as needed). This
| > > > > > | 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
* Update the built-in SQLite to version 3.35.0.
* The ./configure script now has the --print-minimum-sqlite-version option
that prints the minimum SQLite version required by the current version
of Fossil. This might be used by integrators who insist on building
Fossil to link against the system SQLite library rather than the
built-in copy of SQLite, to verify that their system SQLite library
is recent enough.
* Webpage that shows [/help?cmd=/whistory|history of a wiki page]
gained client-side UI to help with comparison between two arbitrary
versions of a wiki (by the means of anchoring a "baseline" version)
and the ability to squeeze several sequential edits made by the same
user into a single "recycled" row (the latest edit in that sequence).
<a name='v2_14'></a>
<h2>Changes for Version 2.14 (2021-01-20)</h2>
* <b>Schema Update Notice #1:</b>
This release drops a trigger from the database schema (replacing
it with a TEMP trigger that is created as needed). This
|
| ︙ | ︙ |
Changes to www/quickstart.wiki.
| ︙ | ︙ | |||
240 241 242 243 244 245 246 247 248 249 250 251 252 253 |
# Original text<br>
</tt></b>
</blockquote>
<p>"fossil diff" is the difference between your tree on disk now and as the tree was
when you did "fossil open". An open is the first checkout from a repository
into a new directory. </p>
<p>To commit your changes to a local-only repository:</p>
<blockquote>
<b>
fossil commit </b><i>(... Fossil will start your editor, if defined)</i><b><br><tt>
# Enter a commit message for this check-in. Lines beginning with # are ignored.<br>
#<br>
| > > > > > > > > > > > > > > > > > > > > > > > > > > | 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 |
# Original text<br>
</tt></b>
</blockquote>
<p>"fossil diff" is the difference between your tree on disk now and as the tree was
when you did "fossil open". An open is the first checkout from a repository
into a new directory. </p>
<p>To see the most recent changes made to the repository by other users, use "fossil timeline" to
find out the most recent commit, and then "fossil diff" between that commit and the
current tree: </p>
<blockquote>
<b>
fossil timeline <br><tt>
=== 2021-03-28 === <br>
03:18:54 [ad75dfa4a0] *CURRENT* Added details to frobnicate command (user: user-one tags: trunk) <br>
=== 2021-03-27 === <br>
23:58:05 [ab975c6632] Update README.md. (user: user-two tags: trunk) <br>
⋮ <br>
</tt><br>
fossil diff --from current --to ab975c6632 <br><tt>
Index: frobnicate.c<br>
============================================================<br>
--- frobnicate.c<br>
+++ frobnicate.c<br>
@@ -1,10 +1,11 @@<br>
+/* made a change to the source file */<br>
# Original text<br>
</tt></b>
</blockquote>
"current" is an alias for the most recent version, so the command
"fossil diff --from ad75dfa4a0 --to ab975c6632" gives identical results.
<p>To commit your changes to a local-only repository:</p>
<blockquote>
<b>
fossil commit </b><i>(... Fossil will start your editor, if defined)</i><b><br><tt>
# Enter a commit message for this check-in. Lines beginning with # are ignored.<br>
#<br>
|
| ︙ | ︙ |
Changes to www/rebaseharm.md.
| ︙ | ︙ | |||
291 292 293 294 295 296 297 | system clocks, so they are not unique to rebase, but they are very confusing and so best avoided. The other option is to provide new unique timestamps for C3' and C5' but then you lose the information about when those check-ins were originally created, which can make historical analysis of changes more difficult. It might also complicate the legal defense of prior art claims. | | < < < < < < | | 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 | system clocks, so they are not unique to rebase, but they are very confusing and so best avoided. The other option is to provide new unique timestamps for C3' and C5' but then you lose the information about when those check-ins were originally created, which can make historical analysis of changes more difficult. It might also complicate the legal defense of prior art claims. ## <a name="lying"></a>5.0 Rebase misrepresents the project history By discarding parentage information, rebase attempts to deceive the reader about how the code actually came together. Git’s rebase feature is more than just an alternative to merging: it also provides mechanisms for changing the project history in order to make editorial changes. Fossil shows that you can get similar effects without modifying historical records, allowing users to: 1. Edit check-in comments to fix typos or enhance clarity 2. Attach supplemental notes to check-ins or whole branches |
| ︙ | ︙ |