Fossil SCM

merge with latest trunk

meeks 2011-12-08 02:05 mgagnon_fix merge
Commit 4d39236638ccacfdad3d6a979f37dfb93ae333c4
+1 -1
--- VERSION
+++ VERSION
@@ -1,1 +1,1 @@
1
-1.20
1
+1.21
22
--- VERSION
+++ VERSION
@@ -1,1 +1,1 @@
1 1.20
2
--- VERSION
+++ VERSION
@@ -1,1 +1,1 @@
1 1.21
2
--- ajax/js/whajaj.js
+++ ajax/js/whajaj.js
@@ -103,11 +103,11 @@
103103
like PHP does.
104104
105105
*/
106106
WhAjaj.processUrlArgs = function(str) {
107107
if( 0 === arguments.length ) {
108
- if( (undefined === typeof window) ||
108
+ if( ('undefined' === typeof window) ||
109109
!window.location ||
110110
!window.location.search ) return false;
111111
else str = (''+window.location.search).substring(1);
112112
}
113113
if( ! str ) return false;
114114
--- ajax/js/whajaj.js
+++ ajax/js/whajaj.js
@@ -103,11 +103,11 @@
103 like PHP does.
104
105 */
106 WhAjaj.processUrlArgs = function(str) {
107 if( 0 === arguments.length ) {
108 if( (undefined === typeof window) ||
109 !window.location ||
110 !window.location.search ) return false;
111 else str = (''+window.location.search).substring(1);
112 }
113 if( ! str ) return false;
114
--- ajax/js/whajaj.js
+++ ajax/js/whajaj.js
@@ -103,11 +103,11 @@
103 like PHP does.
104
105 */
106 WhAjaj.processUrlArgs = function(str) {
107 if( 0 === arguments.length ) {
108 if( ('undefined' === typeof window) ||
109 !window.location ||
110 !window.location.search ) return false;
111 else str = (''+window.location.search).substring(1);
112 }
113 if( ! str ) return false;
114
+25 -19
--- auto.def
+++ auto.def
@@ -87,30 +87,36 @@
8787
user-error "zlib not found please install it or specify the location with --with-zlib"
8888
}
8989
9090
set tclpath [opt-val with-tcl]
9191
if {$tclpath ne ""} {
92
- if {$tclpath ne "1"} {
93
- cc-with [list -cflags [list -I$tclpath/include -L$tclpath/lib]]
94
- }
95
- if {![cc-check-includes tcl.h]} {
96
- user-error "Cannot find tcl.h"
97
- }
98
- foreach tlib {tcl8.6 tcl8.5 tcl notfound} {
99
- if {$tlib=="notfound"} {
100
- user-error "Cannot find a usable libtcl"
101
- }
102
- if {[cc-check-function-in-lib Tcl_CreateInterp $tlib]} {
103
- define-append LIBS -l$tlib
104
- break
105
- }
106
- }
92
+ # Note parse-tclconfig-sh is in autosetup/local.tcl
93
+ if {$tclpath eq "1"} {
94
+ # Use the system Tcl. Look in some likely places.
95
+ array set tclconfig [parse-tclconfig-sh /usr /usr/local /usr/share /opt/local]
96
+ set msg "on your system"
97
+ } else {
98
+ array set tclconfig [parse-tclconfig-sh $tclpath]
99
+ set msg "at $tclpath"
100
+ }
101
+ if {![info exists tclconfig(TCL_INCLUDE_SPEC)]} {
102
+ user-error "Cannot find Tcl $msg"
103
+ }
104
+ set cflags $tclconfig(TCL_INCLUDE_SPEC)
105
+ set libs "$tclconfig(TCL_LIB_SPEC) $tclconfig(TCL_LIBS)"
106
+ cc-with [list -cflags $cflags -libs $libs] {
107
+ if {![cc-check-functions Tcl_CreateInterp]} {
108
+ user-error "Cannot find a usable Tcl $msg"
109
+ }
110
+ }
111
+ set version $tclconfig(TCL_VERSION)$tclconfig(TCL_PATCH_LEVEL)
112
+ msg-result "Found Tcl $version at $tclconfig(TCL_PREFIX)"
113
+ define-append LIBS $libs
114
+ define-append EXTRA_CFLAGS $cflags
115
+ define-append EXTRA_LDFLAGS $tclconfig(TCL_LD_FLAGS)
116
+
107117
define FOSSIL_ENABLE_TCL
108
- if {$tclpath ne "1"} {
109
- define-append EXTRA_CFLAGS -I$tclpath/include
110
- define-append EXTRA_LDFLAGS -L$tclpath/lib
111
- }
112118
}
113119
114120
# Helper for openssl checking
115121
proc check-for-openssl {msg {cflags {}}} {
116122
msg-checking "Checking for $msg..."
117123
--- auto.def
+++ auto.def
@@ -87,30 +87,36 @@
87 user-error "zlib not found please install it or specify the location with --with-zlib"
88 }
89
90 set tclpath [opt-val with-tcl]
91 if {$tclpath ne ""} {
92 if {$tclpath ne "1"} {
93 cc-with [list -cflags [list -I$tclpath/include -L$tclpath/lib]]
94 }
95 if {![cc-check-includes tcl.h]} {
96 user-error "Cannot find tcl.h"
97 }
98 foreach tlib {tcl8.6 tcl8.5 tcl notfound} {
99 if {$tlib=="notfound"} {
100 user-error "Cannot find a usable libtcl"
101 }
102 if {[cc-check-function-in-lib Tcl_CreateInterp $tlib]} {
103 define-append LIBS -l$tlib
104 break
105 }
106 }
 
 
 
 
 
 
 
 
 
 
107 define FOSSIL_ENABLE_TCL
108 if {$tclpath ne "1"} {
109 define-append EXTRA_CFLAGS -I$tclpath/include
110 define-append EXTRA_LDFLAGS -L$tclpath/lib
111 }
112 }
113
114 # Helper for openssl checking
115 proc check-for-openssl {msg {cflags {}}} {
116 msg-checking "Checking for $msg..."
117
--- auto.def
+++ auto.def
@@ -87,30 +87,36 @@
87 user-error "zlib not found please install it or specify the location with --with-zlib"
88 }
89
90 set tclpath [opt-val with-tcl]
91 if {$tclpath ne ""} {
92 # Note parse-tclconfig-sh is in autosetup/local.tcl
93 if {$tclpath eq "1"} {
94 # Use the system Tcl. Look in some likely places.
95 array set tclconfig [parse-tclconfig-sh /usr /usr/local /usr/share /opt/local]
96 set msg "on your system"
97 } else {
98 array set tclconfig [parse-tclconfig-sh $tclpath]
99 set msg "at $tclpath"
100 }
101 if {![info exists tclconfig(TCL_INCLUDE_SPEC)]} {
102 user-error "Cannot find Tcl $msg"
103 }
104 set cflags $tclconfig(TCL_INCLUDE_SPEC)
105 set libs "$tclconfig(TCL_LIB_SPEC) $tclconfig(TCL_LIBS)"
106 cc-with [list -cflags $cflags -libs $libs] {
107 if {![cc-check-functions Tcl_CreateInterp]} {
108 user-error "Cannot find a usable Tcl $msg"
109 }
110 }
111 set version $tclconfig(TCL_VERSION)$tclconfig(TCL_PATCH_LEVEL)
112 msg-result "Found Tcl $version at $tclconfig(TCL_PREFIX)"
113 define-append LIBS $libs
114 define-append EXTRA_CFLAGS $cflags
115 define-append EXTRA_LDFLAGS $tclconfig(TCL_LD_FLAGS)
116
117 define FOSSIL_ENABLE_TCL
 
 
 
 
118 }
119
120 # Helper for openssl checking
121 proc check-for-openssl {msg {cflags {}}} {
122 msg-checking "Checking for $msg..."
123
--- autosetup/local.tcl
+++ autosetup/local.tcl
@@ -1,2 +1,29 @@
11
# For this project, disable the pager for --help
22
set useropts(nopager) 1
3
+
4
+# Searches for a usable Tcl (prefer 8.6, 8.5, 8.4) in the given paths
5
+# Returns a dictionary of the contents of the tclConfig.sh file, or
6
+# empty if not found
7
+proc parse-tclconfig-sh {args} {
8
+ foreach p $args {
9
+ # Allow pointing directly to the path containing tclConfig.sh
10
+ if {[file exists $p/tclConfig.sh]} {
11
+ return [parse-tclconfig-sh-file $p/tclConfig.sh]
12
+ }
13
+ # Some systems allow for multiple versions
14
+ foreach libpath {lib/tcl8.6 lib/tcl8.5 lib/tcl8.4 lib/tcl tcl lib} {
15
+ if {[file exists $p/$libpath/tclConfig.sh]} {
16
+ return [parse-tclconfig-sh-file $p/$libpath/tclConfig.sh]
17
+ }
18
+ }
19
+ }
20
+}
21
+
22
+proc parse-tclconfig-sh-file {filename} {
23
+ foreach line [split [readfile $filename] \n] {
24
+ if {[regexp {^(TCL_[^=]*)=(.*)$} $line -> name value]} {
25
+ set tclconfig($name) [string trim $value ']
26
+ }
27
+ }
28
+ return [array get tclconfig]
29
+}
330
--- autosetup/local.tcl
+++ autosetup/local.tcl
@@ -1,2 +1,29 @@
1 # For this project, disable the pager for --help
2 set useropts(nopager) 1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
--- autosetup/local.tcl
+++ autosetup/local.tcl
@@ -1,2 +1,29 @@
1 # For this project, disable the pager for --help
2 set useropts(nopager) 1
3
4 # Searches for a usable Tcl (prefer 8.6, 8.5, 8.4) in the given paths
5 # Returns a dictionary of the contents of the tclConfig.sh file, or
6 # empty if not found
7 proc parse-tclconfig-sh {args} {
8 foreach p $args {
9 # Allow pointing directly to the path containing tclConfig.sh
10 if {[file exists $p/tclConfig.sh]} {
11 return [parse-tclconfig-sh-file $p/tclConfig.sh]
12 }
13 # Some systems allow for multiple versions
14 foreach libpath {lib/tcl8.6 lib/tcl8.5 lib/tcl8.4 lib/tcl tcl lib} {
15 if {[file exists $p/$libpath/tclConfig.sh]} {
16 return [parse-tclconfig-sh-file $p/$libpath/tclConfig.sh]
17 }
18 }
19 }
20 }
21
22 proc parse-tclconfig-sh-file {filename} {
23 foreach line [split [readfile $filename] \n] {
24 if {[regexp {^(TCL_[^=]*)=(.*)$} $line -> name value]} {
25 set tclconfig($name) [string trim $value ']
26 }
27 }
28 return [array get tclconfig]
29 }
30
+22 -7
--- src/add.c
+++ src/add.c
@@ -337,24 +337,39 @@
337337
**
338338
** The --case-sensitive BOOLEAN command-line option overrides any
339339
** setting.
340340
*/
341341
int filenames_are_case_sensitive(void){
342
- int caseSensitive;
342
+ static int caseSensitive;
343
+ static int once = 1;
343344
344
- if( zCaseSensitive ){
345
- caseSensitive = is_truth(zCaseSensitive);
346
- }else{
345
+ if( once ){
346
+ once = 0;
347
+ if( zCaseSensitive ){
348
+ caseSensitive = is_truth(zCaseSensitive);
349
+ }else{
347350
#if !defined(_WIN32) && !defined(__DARWIN__) && !defined(__APPLE__)
348
- caseSensitive = 1;
351
+ caseSensitive = 1; /* Unix */
349352
#else
350
- caseSensitive = 0;
353
+ caseSensitive = 0; /* Windows and Mac */
351354
#endif
352
- caseSensitive = db_get_boolean("case-sensitive",caseSensitive);
355
+ caseSensitive = db_get_boolean("case-sensitive",caseSensitive);
356
+ }
353357
}
354358
return caseSensitive;
355359
}
360
+
361
+/*
362
+** Return one of two things:
363
+**
364
+** "" (empty string) if filenames are case sensitive
365
+**
366
+** "COLLATE nocase" if filenames are not case sensitive.
367
+*/
368
+const char *filename_collation(void){
369
+ return filenames_are_case_sensitive() ? "" : "COLLATE nocase";
370
+}
356371
357372
/*
358373
** COMMAND: addremove
359374
**
360375
** Usage: %fossil addremove ?OPTIONS?
361376
--- src/add.c
+++ src/add.c
@@ -337,24 +337,39 @@
337 **
338 ** The --case-sensitive BOOLEAN command-line option overrides any
339 ** setting.
340 */
341 int filenames_are_case_sensitive(void){
342 int caseSensitive;
 
343
344 if( zCaseSensitive ){
345 caseSensitive = is_truth(zCaseSensitive);
346 }else{
 
 
347 #if !defined(_WIN32) && !defined(__DARWIN__) && !defined(__APPLE__)
348 caseSensitive = 1;
349 #else
350 caseSensitive = 0;
351 #endif
352 caseSensitive = db_get_boolean("case-sensitive",caseSensitive);
 
353 }
354 return caseSensitive;
355 }
 
 
 
 
 
 
 
 
 
 
 
356
357 /*
358 ** COMMAND: addremove
359 **
360 ** Usage: %fossil addremove ?OPTIONS?
361
--- src/add.c
+++ src/add.c
@@ -337,24 +337,39 @@
337 **
338 ** The --case-sensitive BOOLEAN command-line option overrides any
339 ** setting.
340 */
341 int filenames_are_case_sensitive(void){
342 static int caseSensitive;
343 static int once = 1;
344
345 if( once ){
346 once = 0;
347 if( zCaseSensitive ){
348 caseSensitive = is_truth(zCaseSensitive);
349 }else{
350 #if !defined(_WIN32) && !defined(__DARWIN__) && !defined(__APPLE__)
351 caseSensitive = 1; /* Unix */
352 #else
353 caseSensitive = 0; /* Windows and Mac */
354 #endif
355 caseSensitive = db_get_boolean("case-sensitive",caseSensitive);
356 }
357 }
358 return caseSensitive;
359 }
360
361 /*
362 ** Return one of two things:
363 **
364 ** "" (empty string) if filenames are case sensitive
365 **
366 ** "COLLATE nocase" if filenames are not case sensitive.
367 */
368 const char *filename_collation(void){
369 return filenames_are_case_sensitive() ? "" : "COLLATE nocase";
370 }
371
372 /*
373 ** COMMAND: addremove
374 **
375 ** Usage: %fossil addremove ?OPTIONS?
376
+17 -7
--- src/browse.c
+++ src/browse.c
@@ -196,11 +196,12 @@
196196
** Subdirectory names begin with "/". This causes them to sort
197197
** first and it also gives us an easy way to distinguish files
198198
** from directories in the loop that follows.
199199
*/
200200
db_multi_exec(
201
- "CREATE TEMP TABLE localfiles(x UNIQUE NOT NULL, u);"
201
+ "CREATE TEMP TABLE localfiles(x UNIQUE NOT NULL %s, u);",
202
+ filename_collation()
202203
);
203204
if( zCI ){
204205
Stmt ins;
205206
ManifestFile *pFile;
206207
ManifestFile *pPrev = 0;
@@ -231,16 +232,25 @@
231232
for(nPrev=0; (c=pPrev->zName[nD+nPrev]) && c!='/'; nPrev++){}
232233
if( c=='/' ) nPrev++;
233234
}
234235
db_finalize(&ins);
235236
}else if( zD ){
236
- db_multi_exec(
237
- "INSERT OR IGNORE INTO localfiles"
238
- " SELECT pathelement(name,%d), NULL FROM filename"
239
- " WHERE name GLOB '%q/*'",
240
- nD, zD
241
- );
237
+ if( filenames_are_case_sensitive() ){
238
+ db_multi_exec(
239
+ "INSERT OR IGNORE INTO localfiles"
240
+ " SELECT pathelement(name,%d), NULL FROM filename"
241
+ " WHERE name GLOB '%q/*'",
242
+ nD, zD
243
+ );
244
+ }else{
245
+ db_multi_exec(
246
+ "INSERT OR IGNORE INTO localfiles"
247
+ " SELECT pathelement(name,%d), NULL FROM filename"
248
+ " WHERE name LIKE '%q/%%'",
249
+ nD, zD
250
+ );
251
+ }
242252
}else{
243253
db_multi_exec(
244254
"INSERT OR IGNORE INTO localfiles"
245255
" SELECT pathelement(name,0), NULL FROM filename"
246256
);
247257
--- src/browse.c
+++ src/browse.c
@@ -196,11 +196,12 @@
196 ** Subdirectory names begin with "/". This causes them to sort
197 ** first and it also gives us an easy way to distinguish files
198 ** from directories in the loop that follows.
199 */
200 db_multi_exec(
201 "CREATE TEMP TABLE localfiles(x UNIQUE NOT NULL, u);"
 
202 );
203 if( zCI ){
204 Stmt ins;
205 ManifestFile *pFile;
206 ManifestFile *pPrev = 0;
@@ -231,16 +232,25 @@
231 for(nPrev=0; (c=pPrev->zName[nD+nPrev]) && c!='/'; nPrev++){}
232 if( c=='/' ) nPrev++;
233 }
234 db_finalize(&ins);
235 }else if( zD ){
236 db_multi_exec(
237 "INSERT OR IGNORE INTO localfiles"
238 " SELECT pathelement(name,%d), NULL FROM filename"
239 " WHERE name GLOB '%q/*'",
240 nD, zD
241 );
 
 
 
 
 
 
 
 
 
242 }else{
243 db_multi_exec(
244 "INSERT OR IGNORE INTO localfiles"
245 " SELECT pathelement(name,0), NULL FROM filename"
246 );
247
--- src/browse.c
+++ src/browse.c
@@ -196,11 +196,12 @@
196 ** Subdirectory names begin with "/". This causes them to sort
197 ** first and it also gives us an easy way to distinguish files
198 ** from directories in the loop that follows.
199 */
200 db_multi_exec(
201 "CREATE TEMP TABLE localfiles(x UNIQUE NOT NULL %s, u);",
202 filename_collation()
203 );
204 if( zCI ){
205 Stmt ins;
206 ManifestFile *pFile;
207 ManifestFile *pPrev = 0;
@@ -231,16 +232,25 @@
232 for(nPrev=0; (c=pPrev->zName[nD+nPrev]) && c!='/'; nPrev++){}
233 if( c=='/' ) nPrev++;
234 }
235 db_finalize(&ins);
236 }else if( zD ){
237 if( filenames_are_case_sensitive() ){
238 db_multi_exec(
239 "INSERT OR IGNORE INTO localfiles"
240 " SELECT pathelement(name,%d), NULL FROM filename"
241 " WHERE name GLOB '%q/*'",
242 nD, zD
243 );
244 }else{
245 db_multi_exec(
246 "INSERT OR IGNORE INTO localfiles"
247 " SELECT pathelement(name,%d), NULL FROM filename"
248 " WHERE name LIKE '%q/%%'",
249 nD, zD
250 );
251 }
252 }else{
253 db_multi_exec(
254 "INSERT OR IGNORE INTO localfiles"
255 " SELECT pathelement(name,0), NULL FROM filename"
256 );
257
--- src/configure.c
+++ src/configure.c
@@ -82,11 +82,15 @@
8282
{ "project-description", CONFIGSET_PROJ },
8383
{ "manifest", CONFIGSET_PROJ },
8484
{ "ignore-glob", CONFIGSET_PROJ },
8585
{ "crnl-glob", CONFIGSET_PROJ },
8686
{ "empty-dirs", CONFIGSET_PROJ },
87
+ { "allow-symlinks", CONFIGSET_PROJ },
8788
{ "index-page", CONFIGSET_SKIN },
89
+#ifdef FOSSIL_ENABLE_TCL
90
+ { "tcl", CONFIGSET_SKIN|CONFIGSET_TKT },
91
+#endif
8892
{ "timeline-block-markup", CONFIGSET_SKIN },
8993
{ "timeline-max-comment", CONFIGSET_SKIN },
9094
{ "ticket-table", CONFIGSET_TKT },
9195
{ "ticket-common", CONFIGSET_TKT },
9296
{ "ticket-newpage", CONFIGSET_TKT },
9397
--- src/configure.c
+++ src/configure.c
@@ -82,11 +82,15 @@
82 { "project-description", CONFIGSET_PROJ },
83 { "manifest", CONFIGSET_PROJ },
84 { "ignore-glob", CONFIGSET_PROJ },
85 { "crnl-glob", CONFIGSET_PROJ },
86 { "empty-dirs", CONFIGSET_PROJ },
 
87 { "index-page", CONFIGSET_SKIN },
 
 
 
88 { "timeline-block-markup", CONFIGSET_SKIN },
89 { "timeline-max-comment", CONFIGSET_SKIN },
90 { "ticket-table", CONFIGSET_TKT },
91 { "ticket-common", CONFIGSET_TKT },
92 { "ticket-newpage", CONFIGSET_TKT },
93
--- src/configure.c
+++ src/configure.c
@@ -82,11 +82,15 @@
82 { "project-description", CONFIGSET_PROJ },
83 { "manifest", CONFIGSET_PROJ },
84 { "ignore-glob", CONFIGSET_PROJ },
85 { "crnl-glob", CONFIGSET_PROJ },
86 { "empty-dirs", CONFIGSET_PROJ },
87 { "allow-symlinks", CONFIGSET_PROJ },
88 { "index-page", CONFIGSET_SKIN },
89 #ifdef FOSSIL_ENABLE_TCL
90 { "tcl", CONFIGSET_SKIN|CONFIGSET_TKT },
91 #endif
92 { "timeline-block-markup", CONFIGSET_SKIN },
93 { "timeline-max-comment", CONFIGSET_SKIN },
94 { "ticket-table", CONFIGSET_TKT },
95 { "ticket-common", CONFIGSET_TKT },
96 { "ticket-newpage", CONFIGSET_TKT },
97
+31 -5
--- src/content.c
+++ src/content.c
@@ -828,12 +828,35 @@
828828
Stmt q;
829829
Blob content;
830830
Blob cksum;
831831
int n1 = 0;
832832
int n2 = 0;
833
+ int nErr = 0;
833834
int total;
834835
db_find_and_open_repository(OPEN_ANY_SCHEMA, 2);
836
+
837
+ /* Make sure no public artifact is a delta from a private artifact */
838
+ db_prepare(&q,
839
+ "SELECT "
840
+ " rid, (SELECT uuid FROM blob WHERE rid=delta.rid),"
841
+ " srcid, (SELECT uuid FROM blob WHERE rid=delta.srcid)"
842
+ " FROM delta"
843
+ " WHERE srcid in private AND rid NOT IN private"
844
+ );
845
+ while( db_step(&q)==SQLITE_ROW ){
846
+ int rid = db_column_int(&q, 0);
847
+ const char *zId = db_column_text(&q, 1);
848
+ int srcid = db_column_int(&q, 2);
849
+ const char *zSrc = db_column_text(&q, 3);
850
+ fossil_print(
851
+ "public artifact %S (%d) is a delta from private artifact %S (%d)\n",
852
+ zId, rid, zSrc, srcid
853
+ );
854
+ nErr++;
855
+ }
856
+ db_finalize(&q);
857
+
835858
db_prepare(&q, "SELECT rid, uuid, size FROM blob ORDER BY rid");
836859
total = db_int(0, "SELECT max(rid) FROM blob");
837860
while( db_step(&q)==SQLITE_ROW ){
838861
int rid = db_column_int(&q, 0);
839862
const char *zUuid = db_column_text(&q, 1);
@@ -845,20 +868,23 @@
845868
fossil_print("skip phantom %d %s\n", rid, zUuid);
846869
continue; /* Ignore phantoms */
847870
}
848871
content_get(rid, &content);
849872
if( blob_size(&content)!=size ){
850
- fossil_warning("size mismatch on blob rid=%d: %d vs %d",
851
- rid, blob_size(&content), size);
873
+ fossil_print("size mismatch on artifact %d: wanted %d but got %d\n",
874
+ rid, size, blob_size(&content));
875
+ nErr++;
852876
}
853877
sha1sum_blob(&content, &cksum);
854878
if( fossil_strcmp(blob_str(&cksum), zUuid)!=0 ){
855
- fossil_fatal("checksum mismatch on blob rid=%d: %s vs %s",
856
- rid, blob_str(&cksum), zUuid);
879
+ fossil_print("checksum mismatch on artifact %d: wanted %s but got %s\n",
880
+ rid, zUuid, blob_str(&cksum));
881
+ nErr++;
857882
}
858883
blob_reset(&cksum);
859884
blob_reset(&content);
860885
n2++;
861886
}
862887
db_finalize(&q);
863
- fossil_print("%d non-phantom blobs (out of %d total) verified\n", n2, n1);
888
+ fossil_print("%d non-phantom blobs (out of %d total) checked: %d errors\n",
889
+ n2, n1, nErr);
864890
}
865891
--- src/content.c
+++ src/content.c
@@ -828,12 +828,35 @@
828 Stmt q;
829 Blob content;
830 Blob cksum;
831 int n1 = 0;
832 int n2 = 0;
 
833 int total;
834 db_find_and_open_repository(OPEN_ANY_SCHEMA, 2);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
835 db_prepare(&q, "SELECT rid, uuid, size FROM blob ORDER BY rid");
836 total = db_int(0, "SELECT max(rid) FROM blob");
837 while( db_step(&q)==SQLITE_ROW ){
838 int rid = db_column_int(&q, 0);
839 const char *zUuid = db_column_text(&q, 1);
@@ -845,20 +868,23 @@
845 fossil_print("skip phantom %d %s\n", rid, zUuid);
846 continue; /* Ignore phantoms */
847 }
848 content_get(rid, &content);
849 if( blob_size(&content)!=size ){
850 fossil_warning("size mismatch on blob rid=%d: %d vs %d",
851 rid, blob_size(&content), size);
 
852 }
853 sha1sum_blob(&content, &cksum);
854 if( fossil_strcmp(blob_str(&cksum), zUuid)!=0 ){
855 fossil_fatal("checksum mismatch on blob rid=%d: %s vs %s",
856 rid, blob_str(&cksum), zUuid);
 
857 }
858 blob_reset(&cksum);
859 blob_reset(&content);
860 n2++;
861 }
862 db_finalize(&q);
863 fossil_print("%d non-phantom blobs (out of %d total) verified\n", n2, n1);
 
864 }
865
--- src/content.c
+++ src/content.c
@@ -828,12 +828,35 @@
828 Stmt q;
829 Blob content;
830 Blob cksum;
831 int n1 = 0;
832 int n2 = 0;
833 int nErr = 0;
834 int total;
835 db_find_and_open_repository(OPEN_ANY_SCHEMA, 2);
836
837 /* Make sure no public artifact is a delta from a private artifact */
838 db_prepare(&q,
839 "SELECT "
840 " rid, (SELECT uuid FROM blob WHERE rid=delta.rid),"
841 " srcid, (SELECT uuid FROM blob WHERE rid=delta.srcid)"
842 " FROM delta"
843 " WHERE srcid in private AND rid NOT IN private"
844 );
845 while( db_step(&q)==SQLITE_ROW ){
846 int rid = db_column_int(&q, 0);
847 const char *zId = db_column_text(&q, 1);
848 int srcid = db_column_int(&q, 2);
849 const char *zSrc = db_column_text(&q, 3);
850 fossil_print(
851 "public artifact %S (%d) is a delta from private artifact %S (%d)\n",
852 zId, rid, zSrc, srcid
853 );
854 nErr++;
855 }
856 db_finalize(&q);
857
858 db_prepare(&q, "SELECT rid, uuid, size FROM blob ORDER BY rid");
859 total = db_int(0, "SELECT max(rid) FROM blob");
860 while( db_step(&q)==SQLITE_ROW ){
861 int rid = db_column_int(&q, 0);
862 const char *zUuid = db_column_text(&q, 1);
@@ -845,20 +868,23 @@
868 fossil_print("skip phantom %d %s\n", rid, zUuid);
869 continue; /* Ignore phantoms */
870 }
871 content_get(rid, &content);
872 if( blob_size(&content)!=size ){
873 fossil_print("size mismatch on artifact %d: wanted %d but got %d\n",
874 rid, size, blob_size(&content));
875 nErr++;
876 }
877 sha1sum_blob(&content, &cksum);
878 if( fossil_strcmp(blob_str(&cksum), zUuid)!=0 ){
879 fossil_print("checksum mismatch on artifact %d: wanted %s but got %s\n",
880 rid, zUuid, blob_str(&cksum));
881 nErr++;
882 }
883 blob_reset(&cksum);
884 blob_reset(&content);
885 n2++;
886 }
887 db_finalize(&q);
888 fossil_print("%d non-phantom blobs (out of %d total) checked: %d errors\n",
889 n2, n1, nErr);
890 }
891
--- src/cson_amalgamation.c
+++ src/cson_amalgamation.c
@@ -1396,10 +1396,11 @@
13961396
/* end file parser/JSON_parser.c */
13971397
/* begin file ./cson.c */
13981398
#include <assert.h>
13991399
#include <stdlib.h> /* malloc()/free() */
14001400
#include <string.h>
1401
+#include <errno.h>
14011402
14021403
#ifdef _MSC_VER
14031404
# if _MSC_VER >= 1400 /* Visual Studio 2005 and up */
14041405
# pragma warning( push )
14051406
# pragma warning(disable:4996) /* unsecure sscanf (but snscanf() isn't in c89) */
@@ -4950,10 +4951,81 @@
49504951
}
49514952
else continue;
49524953
}
49534954
return 0;
49544955
}
4956
+
4957
+static cson_value * cson_guess_arg_type(char const *arg){
4958
+ char * end = NULL;
4959
+ if(('0'<=*arg) && ('9'>=*arg)){
4960
+ goto do_string;
4961
+ }
4962
+ {
4963
+ long const val = strtol(arg, &end, 10);
4964
+ if(!*end){
4965
+ return cson_value_new_integer( (cson_int_t)val);
4966
+ }
4967
+ }
4968
+ {
4969
+ double const val = strtod(arg, &end);
4970
+ if(!*end){
4971
+ return cson_value_new_double(val);
4972
+ }
4973
+ }
4974
+
4975
+
4976
+ do_string:
4977
+ return cson_value_new_string(arg, strlen(arg));
4978
+}
4979
+
4980
+
4981
+int cson_parse_argv_flags( int argc, char const * const * argv,
4982
+ cson_object ** tgt, unsigned int * count ){
4983
+ cson_object * o = NULL;
4984
+ int rc = 0;
4985
+ int i = 0;
4986
+ if(argc<1 || !argc || !tgt) return cson_rc.ArgError;
4987
+ o = *tgt ? *tgt : cson_new_object();
4988
+ if(count) *count = 0;
4989
+ for( i = 0; i < argc; ++i ){
4990
+ char const * arg = argv[i];
4991
+ char const * key = arg;
4992
+ char const * pos;
4993
+ cson_string * k = NULL;
4994
+ cson_value * v = NULL;
4995
+ if('-' != *arg) continue;
4996
+ while('-'==*key) ++key;
4997
+ if(!*key) continue;
4998
+ pos = key;
4999
+ while( *pos && ('=' != *pos)) ++pos;
5000
+ k = cson_new_string(key, pos-key);
5001
+ if(!k){
5002
+ rc = cson_rc.AllocError;
5003
+ break;
5004
+ }
5005
+ if(!*pos){ /** --key */
5006
+ v = cson_value_true();
5007
+ }else{ /** --key=...*/
5008
+ assert('=' == *pos);
5009
+ ++pos /*skip '='*/;
5010
+ v = *pos
5011
+ ? cson_guess_arg_type(pos)
5012
+ : cson_value_null();
5013
+ }
5014
+ if(0 != (rc=cson_object_set_s(o, k, v))){
5015
+ cson_free_string(k);
5016
+ cson_value_free(v);
5017
+ break;
5018
+ }
5019
+ else if(count) ++*count;
5020
+ }
5021
+ if(o != *tgt){
5022
+ if(rc) cson_free_object(o);
5023
+ else *tgt = o;
5024
+ }
5025
+ return rc;
5026
+}
49555027
49565028
#if defined(__cplusplus)
49575029
} /*extern "C"*/
49585030
#endif
49595031
49605032
--- src/cson_amalgamation.c
+++ src/cson_amalgamation.c
@@ -1396,10 +1396,11 @@
1396 /* end file parser/JSON_parser.c */
1397 /* begin file ./cson.c */
1398 #include <assert.h>
1399 #include <stdlib.h> /* malloc()/free() */
1400 #include <string.h>
 
1401
1402 #ifdef _MSC_VER
1403 # if _MSC_VER >= 1400 /* Visual Studio 2005 and up */
1404 # pragma warning( push )
1405 # pragma warning(disable:4996) /* unsecure sscanf (but snscanf() isn't in c89) */
@@ -4950,10 +4951,81 @@
4950 }
4951 else continue;
4952 }
4953 return 0;
4954 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4955
4956 #if defined(__cplusplus)
4957 } /*extern "C"*/
4958 #endif
4959
4960
--- src/cson_amalgamation.c
+++ src/cson_amalgamation.c
@@ -1396,10 +1396,11 @@
1396 /* end file parser/JSON_parser.c */
1397 /* begin file ./cson.c */
1398 #include <assert.h>
1399 #include <stdlib.h> /* malloc()/free() */
1400 #include <string.h>
1401 #include <errno.h>
1402
1403 #ifdef _MSC_VER
1404 # if _MSC_VER >= 1400 /* Visual Studio 2005 and up */
1405 # pragma warning( push )
1406 # pragma warning(disable:4996) /* unsecure sscanf (but snscanf() isn't in c89) */
@@ -4950,10 +4951,81 @@
4951 }
4952 else continue;
4953 }
4954 return 0;
4955 }
4956
4957 static cson_value * cson_guess_arg_type(char const *arg){
4958 char * end = NULL;
4959 if(('0'<=*arg) && ('9'>=*arg)){
4960 goto do_string;
4961 }
4962 {
4963 long const val = strtol(arg, &end, 10);
4964 if(!*end){
4965 return cson_value_new_integer( (cson_int_t)val);
4966 }
4967 }
4968 {
4969 double const val = strtod(arg, &end);
4970 if(!*end){
4971 return cson_value_new_double(val);
4972 }
4973 }
4974
4975
4976 do_string:
4977 return cson_value_new_string(arg, strlen(arg));
4978 }
4979
4980
4981 int cson_parse_argv_flags( int argc, char const * const * argv,
4982 cson_object ** tgt, unsigned int * count ){
4983 cson_object * o = NULL;
4984 int rc = 0;
4985 int i = 0;
4986 if(argc<1 || !argc || !tgt) return cson_rc.ArgError;
4987 o = *tgt ? *tgt : cson_new_object();
4988 if(count) *count = 0;
4989 for( i = 0; i < argc; ++i ){
4990 char const * arg = argv[i];
4991 char const * key = arg;
4992 char const * pos;
4993 cson_string * k = NULL;
4994 cson_value * v = NULL;
4995 if('-' != *arg) continue;
4996 while('-'==*key) ++key;
4997 if(!*key) continue;
4998 pos = key;
4999 while( *pos && ('=' != *pos)) ++pos;
5000 k = cson_new_string(key, pos-key);
5001 if(!k){
5002 rc = cson_rc.AllocError;
5003 break;
5004 }
5005 if(!*pos){ /** --key */
5006 v = cson_value_true();
5007 }else{ /** --key=...*/
5008 assert('=' == *pos);
5009 ++pos /*skip '='*/;
5010 v = *pos
5011 ? cson_guess_arg_type(pos)
5012 : cson_value_null();
5013 }
5014 if(0 != (rc=cson_object_set_s(o, k, v))){
5015 cson_free_string(k);
5016 cson_value_free(v);
5017 break;
5018 }
5019 else if(count) ++*count;
5020 }
5021 if(o != *tgt){
5022 if(rc) cson_free_object(o);
5023 else *tgt = o;
5024 }
5025 return rc;
5026 }
5027
5028 #if defined(__cplusplus)
5029 } /*extern "C"*/
5030 #endif
5031
5032
--- src/cson_amalgamation.h
+++ src/cson_amalgamation.h
@@ -2108,10 +2108,64 @@
21082108
necessarily increase when a new item is inserted into it. An interesting
21092109
side-effect of this is that when cson_clone()ing an array or object, the
21102110
size of the clone can actually be less than the original.
21112111
*/
21122112
unsigned int cson_value_msize(cson_value const * v);
2113
+
2114
+/**
2115
+ Parses command-line-style arguments into a JSON object.
2116
+
2117
+ It expects arguments to be in any of these forms, and any number
2118
+ of leading dashes are treated identically:
2119
+
2120
+ --key : Treats key as a boolean with a true value.
2121
+
2122
+ --key=VAL : Treats VAL as either a double, integer, or string.
2123
+
2124
+ --key= : Treats key as a JSON null (not literal NULL) value.
2125
+
2126
+ Arguments not starting with a dash are skipped.
2127
+
2128
+ Each key/value pair is inserted into an object. If a given key
2129
+ appears more than once then only the final entry is actually
2130
+ stored.
2131
+
2132
+ argc and argv are expected to be values from main() (or similar,
2133
+ possibly adjusted to remove argv[0]).
2134
+
2135
+ tgt must be either a pointer to NULL or a pointer to a
2136
+ client-provided Object. If (NULL==*tgt) then this function
2137
+ allocates a new object and on success it stores the new object in
2138
+ *tgt (it is owned by the caller). If (NULL!=*tgt) then it is
2139
+ assumed to be a properly allocated object. DO NOT pass a pointer to
2140
+ an unitialized pointer, as that will fool this function into
2141
+ thinking it is a valid object and Undefined Behaviour will ensue.
2142
+
2143
+ If count is not NULL then the number of arugments parsed by this
2144
+ function are assigned to it. On error, count will be the number of
2145
+ options successfully parsed before the error was encountered.
2146
+
2147
+ On success:
2148
+
2149
+ - 0 is returned.
2150
+
2151
+ - If (*tgt==NULL) then *tgt is assigned to a newly-allocated
2152
+ object, owned by the caller. Note that even if no arguments are
2153
+ parsed, the object is still created.
2154
+
2155
+ On error:
2156
+
2157
+ - non-0 is returned
2158
+
2159
+ - If (*tgt==NULL) then it is not modified.
2160
+
2161
+ - If (*tgt!=NULL) (i.e., the caller provides his own object) then
2162
+ it might contain partial results.
2163
+*/
2164
+int cson_parse_argv_flags( int argc, char const * const * argv,
2165
+ cson_object ** tgt, unsigned int * count );
2166
+
21132167
21142168
/* LICENSE
21152169
21162170
This software's source code, including accompanying documentation and
21172171
demonstration applications, are licensed under the following
@@ -2382,7 +2436,6 @@
23822436
#endif
23832437
23842438
#endif /* CSON_ENABLE_SQLITE3 */
23852439
#endif /* WANDERINGHORSE_NET_CSON_SQLITE3_H_INCLUDED */
23862440
/* end file include/wh/cson/cson_sqlite3.h */
2387
-
23882441
#endif /* FOSSIL_ENABLE_JSON */
23892442
--- src/cson_amalgamation.h
+++ src/cson_amalgamation.h
@@ -2108,10 +2108,64 @@
2108 necessarily increase when a new item is inserted into it. An interesting
2109 side-effect of this is that when cson_clone()ing an array or object, the
2110 size of the clone can actually be less than the original.
2111 */
2112 unsigned int cson_value_msize(cson_value const * v);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2113
2114 /* LICENSE
2115
2116 This software's source code, including accompanying documentation and
2117 demonstration applications, are licensed under the following
@@ -2382,7 +2436,6 @@
2382 #endif
2383
2384 #endif /* CSON_ENABLE_SQLITE3 */
2385 #endif /* WANDERINGHORSE_NET_CSON_SQLITE3_H_INCLUDED */
2386 /* end file include/wh/cson/cson_sqlite3.h */
2387
2388 #endif /* FOSSIL_ENABLE_JSON */
2389
--- src/cson_amalgamation.h
+++ src/cson_amalgamation.h
@@ -2108,10 +2108,64 @@
2108 necessarily increase when a new item is inserted into it. An interesting
2109 side-effect of this is that when cson_clone()ing an array or object, the
2110 size of the clone can actually be less than the original.
2111 */
2112 unsigned int cson_value_msize(cson_value const * v);
2113
2114 /**
2115 Parses command-line-style arguments into a JSON object.
2116
2117 It expects arguments to be in any of these forms, and any number
2118 of leading dashes are treated identically:
2119
2120 --key : Treats key as a boolean with a true value.
2121
2122 --key=VAL : Treats VAL as either a double, integer, or string.
2123
2124 --key= : Treats key as a JSON null (not literal NULL) value.
2125
2126 Arguments not starting with a dash are skipped.
2127
2128 Each key/value pair is inserted into an object. If a given key
2129 appears more than once then only the final entry is actually
2130 stored.
2131
2132 argc and argv are expected to be values from main() (or similar,
2133 possibly adjusted to remove argv[0]).
2134
2135 tgt must be either a pointer to NULL or a pointer to a
2136 client-provided Object. If (NULL==*tgt) then this function
2137 allocates a new object and on success it stores the new object in
2138 *tgt (it is owned by the caller). If (NULL!=*tgt) then it is
2139 assumed to be a properly allocated object. DO NOT pass a pointer to
2140 an unitialized pointer, as that will fool this function into
2141 thinking it is a valid object and Undefined Behaviour will ensue.
2142
2143 If count is not NULL then the number of arugments parsed by this
2144 function are assigned to it. On error, count will be the number of
2145 options successfully parsed before the error was encountered.
2146
2147 On success:
2148
2149 - 0 is returned.
2150
2151 - If (*tgt==NULL) then *tgt is assigned to a newly-allocated
2152 object, owned by the caller. Note that even if no arguments are
2153 parsed, the object is still created.
2154
2155 On error:
2156
2157 - non-0 is returned
2158
2159 - If (*tgt==NULL) then it is not modified.
2160
2161 - If (*tgt!=NULL) (i.e., the caller provides his own object) then
2162 it might contain partial results.
2163 */
2164 int cson_parse_argv_flags( int argc, char const * const * argv,
2165 cson_object ** tgt, unsigned int * count );
2166
2167
2168 /* LICENSE
2169
2170 This software's source code, including accompanying documentation and
2171 demonstration applications, are licensed under the following
@@ -2382,7 +2436,6 @@
2436 #endif
2437
2438 #endif /* CSON_ENABLE_SQLITE3 */
2439 #endif /* WANDERINGHORSE_NET_CSON_SQLITE3_H_INCLUDED */
2440 /* end file include/wh/cson/cson_sqlite3.h */
 
2441 #endif /* FOSSIL_ENABLE_JSON */
2442
+23 -17
--- src/finfo.c
+++ src/finfo.c
@@ -39,22 +39,25 @@
3939
** In the -p form, there's an optional flag "-r|--revision REVISION".
4040
** The specified version (or the latest checked out version) is printed
4141
** to stdout.
4242
**
4343
** Options:
44
-** --brief|-b display a brief (one line / revision) summary
45
-** --limit N display the first N changes
46
-** --log|-l select log mode (the default)
47
-** --offset P skip P changes
48
-** -p select print mode
49
-** --revision|-r R print the given revision (or ckout, if none is given)
50
-** to stdout (only in print mode)
51
-** -s select status mode (print a status indicator for FILE)
44
+** --brief|-b display a brief (one line / revision) summary
45
+** --limit N display the first N changes
46
+** --log|-l select log mode (the default)
47
+** --offset P skip P changes
48
+** -p select print mode
49
+** --revision|-r R print the given revision (or ckout, if none is given)
50
+** to stdout (only in print mode)
51
+** -s select status mode (print a status indicator for FILE)
52
+** --case-sensitive B Enable or disable case-sensitive filenames. B is a
53
+** boolean: "yes", "no", "true", "false", etc.
5254
**
5355
** See also: descendants, info, leaves
5456
*/
5557
void finfo_cmd(void){
58
+ capture_case_sensitive_option();
5659
db_must_be_within_tree();
5760
if (find_option("status","s",0)) {
5861
Stmt q;
5962
Blob line;
6063
Blob fname;
@@ -67,11 +70,12 @@
6770
}
6871
vfile_check_signature(vid, 1, 0);
6972
file_tree_name(g.argv[2], &fname, 1);
7073
db_prepare(&q,
7174
"SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)"
72
- " FROM vfile WHERE vfile.pathname=%B", &fname);
75
+ " FROM vfile WHERE vfile.pathname=%B %s",
76
+ &fname, filename_collation());
7377
blob_zero(&line);
7478
if ( db_step(&q)==SQLITE_ROW ) {
7579
Blob uuid;
7680
int isDeleted = db_column_int(&q, 1);
7781
int isNew = db_column_int(&q,2) == 0;
@@ -80,12 +84,12 @@
8084
8185
blob_zero(&uuid);
8286
db_blob(&uuid,
8387
"SELECT uuid FROM blob, mlink, vfile WHERE "
8488
"blob.rid = mlink.mid AND mlink.fid = vfile.rid AND "
85
- "vfile.pathname=%B",
86
- &fname
89
+ "vfile.pathname=%B %s",
90
+ &fname, filename_collation()
8791
);
8892
if( isNew ){
8993
blob_appendf(&line, "new");
9094
}else if( isDeleted ){
9195
blob_appendf(&line, "deleted");
@@ -113,11 +117,12 @@
113117
114118
file_tree_name(g.argv[2], &fname, 1);
115119
if( zRevision ){
116120
historical_version_of_file(zRevision, blob_str(&fname), &record, 0, 0, 0);
117121
}else{
118
- int rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B", &fname);
122
+ int rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B %s",
123
+ &fname, filename_collation());
119124
if( rid==0 ){
120125
fossil_fatal("no history for file: %b", &fname);
121126
}
122127
content_get(rid, &record);
123128
}
@@ -144,27 +149,28 @@
144149
iBrief = (find_option("brief","b",0) == 0);
145150
if( g.argc!=3 ){
146151
usage("?-l|--log? ?-b|--brief? FILENAME");
147152
}
148153
file_tree_name(g.argv[2], &fname, 1);
149
- rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B", &fname);
154
+ rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B %s",
155
+ &fname, filename_collation());
150156
if( rid==0 ){
151157
fossil_fatal("no history for file: %b", &fname);
152158
}
153159
zFilename = blob_str(&fname);
154160
db_prepare(&q,
155161
"SELECT b.uuid, ci.uuid, date(event.mtime,'localtime'),"
156162
" coalesce(event.ecomment, event.comment),"
157163
" coalesce(event.euser, event.user)"
158164
" FROM mlink, blob b, event, blob ci, filename"
159
- " WHERE filename.name=%Q"
165
+ " WHERE filename.name=%Q %s"
160166
" AND mlink.fnid=filename.fnid"
161167
" AND b.rid=mlink.fid"
162168
" AND event.objid=mlink.mid"
163169
" AND event.objid=ci.rid"
164170
" ORDER BY event.mtime DESC LIMIT %d OFFSET %d",
165
- zFilename, iLimit, iOffset
171
+ zFilename, filename_collation(), iLimit, iOffset
166172
);
167173
blob_zero(&line);
168174
if( iBrief ){
169175
fossil_print("History of %s\n", blob_str(&fname));
170176
}
@@ -243,14 +249,14 @@
243249
" (SELECT uuid FROM blob WHERE rid=mlink.mid)," /* Check-in uuid */
244250
" event.bgcolor," /* Background color */
245251
" (SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0"
246252
" AND tagxref.rid=mlink.mid)" /* Tags */
247253
" FROM mlink, event"
248
- " WHERE mlink.fnid=(SELECT fnid FROM filename WHERE name=%Q)"
254
+ " WHERE mlink.fnid IN (SELECT fnid FROM filename WHERE name=%Q %s)"
249255
" AND event.objid=mlink.mid",
250256
TAG_BRANCH,
251
- zFilename
257
+ zFilename, filename_collation()
252258
);
253259
if( (zA = P("a"))!=0 ){
254260
blob_appendf(&sql, " AND event.mtime>=julianday('%q')", zA);
255261
}
256262
if( (zB = P("b"))!=0 ){
257263
--- src/finfo.c
+++ src/finfo.c
@@ -39,22 +39,25 @@
39 ** In the -p form, there's an optional flag "-r|--revision REVISION".
40 ** The specified version (or the latest checked out version) is printed
41 ** to stdout.
42 **
43 ** Options:
44 ** --brief|-b display a brief (one line / revision) summary
45 ** --limit N display the first N changes
46 ** --log|-l select log mode (the default)
47 ** --offset P skip P changes
48 ** -p select print mode
49 ** --revision|-r R print the given revision (or ckout, if none is given)
50 ** to stdout (only in print mode)
51 ** -s select status mode (print a status indicator for FILE)
 
 
52 **
53 ** See also: descendants, info, leaves
54 */
55 void finfo_cmd(void){
 
56 db_must_be_within_tree();
57 if (find_option("status","s",0)) {
58 Stmt q;
59 Blob line;
60 Blob fname;
@@ -67,11 +70,12 @@
67 }
68 vfile_check_signature(vid, 1, 0);
69 file_tree_name(g.argv[2], &fname, 1);
70 db_prepare(&q,
71 "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)"
72 " FROM vfile WHERE vfile.pathname=%B", &fname);
 
73 blob_zero(&line);
74 if ( db_step(&q)==SQLITE_ROW ) {
75 Blob uuid;
76 int isDeleted = db_column_int(&q, 1);
77 int isNew = db_column_int(&q,2) == 0;
@@ -80,12 +84,12 @@
80
81 blob_zero(&uuid);
82 db_blob(&uuid,
83 "SELECT uuid FROM blob, mlink, vfile WHERE "
84 "blob.rid = mlink.mid AND mlink.fid = vfile.rid AND "
85 "vfile.pathname=%B",
86 &fname
87 );
88 if( isNew ){
89 blob_appendf(&line, "new");
90 }else if( isDeleted ){
91 blob_appendf(&line, "deleted");
@@ -113,11 +117,12 @@
113
114 file_tree_name(g.argv[2], &fname, 1);
115 if( zRevision ){
116 historical_version_of_file(zRevision, blob_str(&fname), &record, 0, 0, 0);
117 }else{
118 int rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B", &fname);
 
119 if( rid==0 ){
120 fossil_fatal("no history for file: %b", &fname);
121 }
122 content_get(rid, &record);
123 }
@@ -144,27 +149,28 @@
144 iBrief = (find_option("brief","b",0) == 0);
145 if( g.argc!=3 ){
146 usage("?-l|--log? ?-b|--brief? FILENAME");
147 }
148 file_tree_name(g.argv[2], &fname, 1);
149 rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B", &fname);
 
150 if( rid==0 ){
151 fossil_fatal("no history for file: %b", &fname);
152 }
153 zFilename = blob_str(&fname);
154 db_prepare(&q,
155 "SELECT b.uuid, ci.uuid, date(event.mtime,'localtime'),"
156 " coalesce(event.ecomment, event.comment),"
157 " coalesce(event.euser, event.user)"
158 " FROM mlink, blob b, event, blob ci, filename"
159 " WHERE filename.name=%Q"
160 " AND mlink.fnid=filename.fnid"
161 " AND b.rid=mlink.fid"
162 " AND event.objid=mlink.mid"
163 " AND event.objid=ci.rid"
164 " ORDER BY event.mtime DESC LIMIT %d OFFSET %d",
165 zFilename, iLimit, iOffset
166 );
167 blob_zero(&line);
168 if( iBrief ){
169 fossil_print("History of %s\n", blob_str(&fname));
170 }
@@ -243,14 +249,14 @@
243 " (SELECT uuid FROM blob WHERE rid=mlink.mid)," /* Check-in uuid */
244 " event.bgcolor," /* Background color */
245 " (SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0"
246 " AND tagxref.rid=mlink.mid)" /* Tags */
247 " FROM mlink, event"
248 " WHERE mlink.fnid=(SELECT fnid FROM filename WHERE name=%Q)"
249 " AND event.objid=mlink.mid",
250 TAG_BRANCH,
251 zFilename
252 );
253 if( (zA = P("a"))!=0 ){
254 blob_appendf(&sql, " AND event.mtime>=julianday('%q')", zA);
255 }
256 if( (zB = P("b"))!=0 ){
257
--- src/finfo.c
+++ src/finfo.c
@@ -39,22 +39,25 @@
39 ** In the -p form, there's an optional flag "-r|--revision REVISION".
40 ** The specified version (or the latest checked out version) is printed
41 ** to stdout.
42 **
43 ** Options:
44 ** --brief|-b display a brief (one line / revision) summary
45 ** --limit N display the first N changes
46 ** --log|-l select log mode (the default)
47 ** --offset P skip P changes
48 ** -p select print mode
49 ** --revision|-r R print the given revision (or ckout, if none is given)
50 ** to stdout (only in print mode)
51 ** -s select status mode (print a status indicator for FILE)
52 ** --case-sensitive B Enable or disable case-sensitive filenames. B is a
53 ** boolean: "yes", "no", "true", "false", etc.
54 **
55 ** See also: descendants, info, leaves
56 */
57 void finfo_cmd(void){
58 capture_case_sensitive_option();
59 db_must_be_within_tree();
60 if (find_option("status","s",0)) {
61 Stmt q;
62 Blob line;
63 Blob fname;
@@ -67,11 +70,12 @@
70 }
71 vfile_check_signature(vid, 1, 0);
72 file_tree_name(g.argv[2], &fname, 1);
73 db_prepare(&q,
74 "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)"
75 " FROM vfile WHERE vfile.pathname=%B %s",
76 &fname, filename_collation());
77 blob_zero(&line);
78 if ( db_step(&q)==SQLITE_ROW ) {
79 Blob uuid;
80 int isDeleted = db_column_int(&q, 1);
81 int isNew = db_column_int(&q,2) == 0;
@@ -80,12 +84,12 @@
84
85 blob_zero(&uuid);
86 db_blob(&uuid,
87 "SELECT uuid FROM blob, mlink, vfile WHERE "
88 "blob.rid = mlink.mid AND mlink.fid = vfile.rid AND "
89 "vfile.pathname=%B %s",
90 &fname, filename_collation()
91 );
92 if( isNew ){
93 blob_appendf(&line, "new");
94 }else if( isDeleted ){
95 blob_appendf(&line, "deleted");
@@ -113,11 +117,12 @@
117
118 file_tree_name(g.argv[2], &fname, 1);
119 if( zRevision ){
120 historical_version_of_file(zRevision, blob_str(&fname), &record, 0, 0, 0);
121 }else{
122 int rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B %s",
123 &fname, filename_collation());
124 if( rid==0 ){
125 fossil_fatal("no history for file: %b", &fname);
126 }
127 content_get(rid, &record);
128 }
@@ -144,27 +149,28 @@
149 iBrief = (find_option("brief","b",0) == 0);
150 if( g.argc!=3 ){
151 usage("?-l|--log? ?-b|--brief? FILENAME");
152 }
153 file_tree_name(g.argv[2], &fname, 1);
154 rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B %s",
155 &fname, filename_collation());
156 if( rid==0 ){
157 fossil_fatal("no history for file: %b", &fname);
158 }
159 zFilename = blob_str(&fname);
160 db_prepare(&q,
161 "SELECT b.uuid, ci.uuid, date(event.mtime,'localtime'),"
162 " coalesce(event.ecomment, event.comment),"
163 " coalesce(event.euser, event.user)"
164 " FROM mlink, blob b, event, blob ci, filename"
165 " WHERE filename.name=%Q %s"
166 " AND mlink.fnid=filename.fnid"
167 " AND b.rid=mlink.fid"
168 " AND event.objid=mlink.mid"
169 " AND event.objid=ci.rid"
170 " ORDER BY event.mtime DESC LIMIT %d OFFSET %d",
171 zFilename, filename_collation(), iLimit, iOffset
172 );
173 blob_zero(&line);
174 if( iBrief ){
175 fossil_print("History of %s\n", blob_str(&fname));
176 }
@@ -243,14 +249,14 @@
249 " (SELECT uuid FROM blob WHERE rid=mlink.mid)," /* Check-in uuid */
250 " event.bgcolor," /* Background color */
251 " (SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0"
252 " AND tagxref.rid=mlink.mid)" /* Tags */
253 " FROM mlink, event"
254 " WHERE mlink.fnid IN (SELECT fnid FROM filename WHERE name=%Q %s)"
255 " AND event.objid=mlink.mid",
256 TAG_BRANCH,
257 zFilename, filename_collation()
258 );
259 if( (zA = P("a"))!=0 ){
260 blob_appendf(&sql, " AND event.mtime>=julianday('%q')", zA);
261 }
262 if( (zB = P("b"))!=0 ){
263
+1 -1
--- src/http.c
+++ src/http.c
@@ -111,11 +111,11 @@
111111
fossil_free(zEncoded);
112112
fossil_free(zCredentials);
113113
}
114114
blob_appendf(pHdr, "Host: %s\r\n", g.urlHostname);
115115
blob_appendf(pHdr, "User-Agent: Fossil/" RELEASE_VERSION
116
- "-" MANIFEST_VERSION "\r\n");
116
+ " (" MANIFEST_DATE " " MANIFEST_VERSION ")\r\n");
117117
if( g.fHttpTrace ){
118118
blob_appendf(pHdr, "Content-Type: application/x-fossil-debug\r\n");
119119
}else{
120120
blob_appendf(pHdr, "Content-Type: application/x-fossil\r\n");
121121
}
122122
--- src/http.c
+++ src/http.c
@@ -111,11 +111,11 @@
111 fossil_free(zEncoded);
112 fossil_free(zCredentials);
113 }
114 blob_appendf(pHdr, "Host: %s\r\n", g.urlHostname);
115 blob_appendf(pHdr, "User-Agent: Fossil/" RELEASE_VERSION
116 "-" MANIFEST_VERSION "\r\n");
117 if( g.fHttpTrace ){
118 blob_appendf(pHdr, "Content-Type: application/x-fossil-debug\r\n");
119 }else{
120 blob_appendf(pHdr, "Content-Type: application/x-fossil\r\n");
121 }
122
--- src/http.c
+++ src/http.c
@@ -111,11 +111,11 @@
111 fossil_free(zEncoded);
112 fossil_free(zCredentials);
113 }
114 blob_appendf(pHdr, "Host: %s\r\n", g.urlHostname);
115 blob_appendf(pHdr, "User-Agent: Fossil/" RELEASE_VERSION
116 " (" MANIFEST_DATE " " MANIFEST_VERSION ")\r\n");
117 if( g.fHttpTrace ){
118 blob_appendf(pHdr, "Content-Type: application/x-fossil-debug\r\n");
119 }else{
120 blob_appendf(pHdr, "Content-Type: application/x-fossil\r\n");
121 }
122
+18 -2
--- src/json_login.c
+++ src/json_login.c
@@ -155,13 +155,29 @@
155155
payload = cson_value_new_object();
156156
po = cson_value_get_object(payload);
157157
cson_object_set(po, "authToken", json_new_string(cookie));
158158
free(cookie);
159159
cson_object_set(po, "name", json_new_string(name));
160
- cap = db_text(NULL, "SELECT cap FROM user WHERE login=%Q",name);
161
- cson_object_set(po, "capabilities", json_new_string(cap));
160
+ cap = db_text(NULL, "SELECT cap FROM user WHERE login=%Q", name);
161
+ cson_object_set(po, "capabilities", cap ? json_new_string(cap) : cson_value_null() );
162162
free(cap);
163
+ cson_object_set(po, "loginCookieName", json_new_string( login_cookie_name() ) );
164
+ /* TODO: add loginExpiryTime to the payload. To do this properly
165
+ we "should" add an ([unsigned] int *) to
166
+ login_set_user_cookie() and login_set_anon_cookie(), to which
167
+ the expiry time is assigned. (Remember that JSON doesn't do
168
+ unsigned int.)
169
+
170
+ For non-anonymous users we could also simply query the
171
+ user.cexpire db field after calling login_set_user_cookie(),
172
+ but for anonymous we need to get the time when the cookie is
173
+ set because anon does not get a db entry like normal users
174
+ do. Anonyous cookies currently have a hard-coded lifetime in
175
+ login_set_anon_cookie() (currently 6 hours), which we "should
176
+ arguably" change to use the time configured for non-anonymous
177
+ users (see login_set_user_cookie() for details).
178
+ */
163179
return payload;
164180
}
165181
}
166182
167183
/*
168184
--- src/json_login.c
+++ src/json_login.c
@@ -155,13 +155,29 @@
155 payload = cson_value_new_object();
156 po = cson_value_get_object(payload);
157 cson_object_set(po, "authToken", json_new_string(cookie));
158 free(cookie);
159 cson_object_set(po, "name", json_new_string(name));
160 cap = db_text(NULL, "SELECT cap FROM user WHERE login=%Q",name);
161 cson_object_set(po, "capabilities", json_new_string(cap));
162 free(cap);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163 return payload;
164 }
165 }
166
167 /*
168
--- src/json_login.c
+++ src/json_login.c
@@ -155,13 +155,29 @@
155 payload = cson_value_new_object();
156 po = cson_value_get_object(payload);
157 cson_object_set(po, "authToken", json_new_string(cookie));
158 free(cookie);
159 cson_object_set(po, "name", json_new_string(name));
160 cap = db_text(NULL, "SELECT cap FROM user WHERE login=%Q", name);
161 cson_object_set(po, "capabilities", cap ? json_new_string(cap) : cson_value_null() );
162 free(cap);
163 cson_object_set(po, "loginCookieName", json_new_string( login_cookie_name() ) );
164 /* TODO: add loginExpiryTime to the payload. To do this properly
165 we "should" add an ([unsigned] int *) to
166 login_set_user_cookie() and login_set_anon_cookie(), to which
167 the expiry time is assigned. (Remember that JSON doesn't do
168 unsigned int.)
169
170 For non-anonymous users we could also simply query the
171 user.cexpire db field after calling login_set_user_cookie(),
172 but for anonymous we need to get the time when the cookie is
173 set because anon does not get a db entry like normal users
174 do. Anonyous cookies currently have a hard-coded lifetime in
175 login_set_anon_cookie() (currently 6 hours), which we "should
176 arguably" change to use the time configured for non-anonymous
177 users (see login_set_user_cookie() for details).
178 */
179 return payload;
180 }
181 }
182
183 /*
184
+31 -6
--- src/login.c
+++ src/login.c
@@ -352,25 +352,50 @@
352352
** downstream problems here. We could alternately use "" here.
353353
*/
354354
;
355355
}
356356
}
357
+
358
+/*
359
+** Return true if the prefix of zStr matches zPattern. Return false if
360
+** they are different.
361
+**
362
+** A lowercase character in zPattern will match either upper or lower
363
+** case in zStr. But an uppercase in zPattern will only match an
364
+** uppercase in zStr.
365
+*/
366
+static int prefix_match(const char *zPattern, const char *zStr){
367
+ int i;
368
+ char c;
369
+ for(i=0; (c = zPattern[i])!=0; i++){
370
+ if( zStr[i]!=c && fossil_tolower(zStr[i])!=c ) return 0;
371
+ }
372
+ return 1;
373
+}
357374
358375
/*
359376
** Look at the HTTP_USER_AGENT parameter and try to determine if the user agent
360
-** is a manually operated browser or a bot. When in doubt, assume a bot. Return
361
-** true if we believe the agent is a real person.
377
+** is a manually operated browser or a bot. When in doubt, assume a bot.
378
+** Return true if we believe the agent is a real person.
362379
*/
363380
static int isHuman(const char *zAgent){
364381
int i;
365
- if( zAgent==0 ) return 0;
382
+ if( zAgent==0 ) return 0; /* If not UserAgent, the probably a bot */
366383
for(i=0; zAgent[i]; i++){
367
- if( zAgent[i]=='b' && memcmp(&zAgent[i],"bot",3)==0 ) return 0;
368
- if( zAgent[i]=='s' && memcmp(&zAgent[i],"spider",6)==0 ) return 0;
384
+ if( prefix_match("bot", zAgent+i) ) return 0;
385
+ if( prefix_match("spider", zAgent+i) ) return 0;
386
+ if( prefix_match("crawl", zAgent+i) ) return 0;
387
+ /* If a URI appears in the User-Agent, it is probably a bot */
388
+ if( memcmp("http", zAgent+i,4)==0 ) return 0;
369389
}
370390
if( memcmp(zAgent, "Mozilla/", 8)==0 ){
371
- return atoi(&zAgent[8])>=4;
391
+ if( atoi(&zAgent[8])<4 ) return 0; /* Many bots advertise as Mozilla/3 */
392
+ if( strglob("*Firefox/[1-9]*", zAgent) ) return 1;
393
+ if( strglob("*Chrome/[1-9]*", zAgent) ) return 1;
394
+ if( strglob("*(compatible;?MSIE?[1-9]*", zAgent) ) return 1;
395
+ if( strglob("*AppleWebKit/[1-9]*(KHTML*", zAgent) ) return 1;
396
+ return 0;
372397
}
373398
if( memcmp(zAgent, "Opera/", 6)==0 ) return 1;
374399
if( memcmp(zAgent, "Safari/", 7)==0 ) return 1;
375400
if( memcmp(zAgent, "Lynx/", 5)==0 ) return 1;
376401
return 0;
377402
--- src/login.c
+++ src/login.c
@@ -352,25 +352,50 @@
352 ** downstream problems here. We could alternately use "" here.
353 */
354 ;
355 }
356 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
357
358 /*
359 ** Look at the HTTP_USER_AGENT parameter and try to determine if the user agent
360 ** is a manually operated browser or a bot. When in doubt, assume a bot. Return
361 ** true if we believe the agent is a real person.
362 */
363 static int isHuman(const char *zAgent){
364 int i;
365 if( zAgent==0 ) return 0;
366 for(i=0; zAgent[i]; i++){
367 if( zAgent[i]=='b' && memcmp(&zAgent[i],"bot",3)==0 ) return 0;
368 if( zAgent[i]=='s' && memcmp(&zAgent[i],"spider",6)==0 ) return 0;
 
 
 
369 }
370 if( memcmp(zAgent, "Mozilla/", 8)==0 ){
371 return atoi(&zAgent[8])>=4;
 
 
 
 
 
372 }
373 if( memcmp(zAgent, "Opera/", 6)==0 ) return 1;
374 if( memcmp(zAgent, "Safari/", 7)==0 ) return 1;
375 if( memcmp(zAgent, "Lynx/", 5)==0 ) return 1;
376 return 0;
377
--- src/login.c
+++ src/login.c
@@ -352,25 +352,50 @@
352 ** downstream problems here. We could alternately use "" here.
353 */
354 ;
355 }
356 }
357
358 /*
359 ** Return true if the prefix of zStr matches zPattern. Return false if
360 ** they are different.
361 **
362 ** A lowercase character in zPattern will match either upper or lower
363 ** case in zStr. But an uppercase in zPattern will only match an
364 ** uppercase in zStr.
365 */
366 static int prefix_match(const char *zPattern, const char *zStr){
367 int i;
368 char c;
369 for(i=0; (c = zPattern[i])!=0; i++){
370 if( zStr[i]!=c && fossil_tolower(zStr[i])!=c ) return 0;
371 }
372 return 1;
373 }
374
375 /*
376 ** Look at the HTTP_USER_AGENT parameter and try to determine if the user agent
377 ** is a manually operated browser or a bot. When in doubt, assume a bot.
378 ** Return true if we believe the agent is a real person.
379 */
380 static int isHuman(const char *zAgent){
381 int i;
382 if( zAgent==0 ) return 0; /* If not UserAgent, the probably a bot */
383 for(i=0; zAgent[i]; i++){
384 if( prefix_match("bot", zAgent+i) ) return 0;
385 if( prefix_match("spider", zAgent+i) ) return 0;
386 if( prefix_match("crawl", zAgent+i) ) return 0;
387 /* If a URI appears in the User-Agent, it is probably a bot */
388 if( memcmp("http", zAgent+i,4)==0 ) return 0;
389 }
390 if( memcmp(zAgent, "Mozilla/", 8)==0 ){
391 if( atoi(&zAgent[8])<4 ) return 0; /* Many bots advertise as Mozilla/3 */
392 if( strglob("*Firefox/[1-9]*", zAgent) ) return 1;
393 if( strglob("*Chrome/[1-9]*", zAgent) ) return 1;
394 if( strglob("*(compatible;?MSIE?[1-9]*", zAgent) ) return 1;
395 if( strglob("*AppleWebKit/[1-9]*(KHTML*", zAgent) ) return 1;
396 return 0;
397 }
398 if( memcmp(zAgent, "Opera/", 6)==0 ) return 1;
399 if( memcmp(zAgent, "Safari/", 7)==0 ) return 1;
400 if( memcmp(zAgent, "Lynx/", 5)==0 ) return 1;
401 return 0;
402
--- src/manifest.c
+++ src/manifest.c
@@ -1223,10 +1223,38 @@
12231223
fetch_baseline(p, 1);
12241224
pFile = manifest_file_seek_base(p->pBaseline, zName);
12251225
}
12261226
return pFile;
12271227
}
1228
+
1229
+/*
1230
+** Look for a file in a manifest, taking the case-sensitive option
1231
+** into account. If case-sensitive is off, then files in any case
1232
+** will match.
1233
+*/
1234
+ManifestFile *manifest_file_find(Manifest *p, const char *zName){
1235
+ int i, n;
1236
+ Manifest *pBase;
1237
+ if( filenames_are_case_sensitive() ){
1238
+ return manifest_file_seek(p, zName);
1239
+ }
1240
+ for(i=0; i<p->nFile; i++){
1241
+ if( fossil_stricmp(zName, p->aFile[i].zName)==0 ){
1242
+ return &p->aFile[i];
1243
+ }
1244
+ }
1245
+ if( p->zBaseline==0 ) return 0;
1246
+ fetch_baseline(p, 1);
1247
+ pBase = p->pBaseline;
1248
+ if( pBase==0 ) return 0;
1249
+ for(i=0; i<pBase->nFile; i++){
1250
+ if( fossil_stricmp(zName, p->aFile[i].zName)==0 ){
1251
+ return &p->aFile[i];
1252
+ }
1253
+ }
1254
+ return 0;
1255
+}
12281256
12291257
/*
12301258
** Add mlink table entries associated with manifest cid, pChild. The
12311259
** parent manifest is pid, pParent. One of either pChild or pParent
12321260
** will be NULL and it will be computed based on cid/pid.
12331261
--- src/manifest.c
+++ src/manifest.c
@@ -1223,10 +1223,38 @@
1223 fetch_baseline(p, 1);
1224 pFile = manifest_file_seek_base(p->pBaseline, zName);
1225 }
1226 return pFile;
1227 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1228
1229 /*
1230 ** Add mlink table entries associated with manifest cid, pChild. The
1231 ** parent manifest is pid, pParent. One of either pChild or pParent
1232 ** will be NULL and it will be computed based on cid/pid.
1233
--- src/manifest.c
+++ src/manifest.c
@@ -1223,10 +1223,38 @@
1223 fetch_baseline(p, 1);
1224 pFile = manifest_file_seek_base(p->pBaseline, zName);
1225 }
1226 return pFile;
1227 }
1228
1229 /*
1230 ** Look for a file in a manifest, taking the case-sensitive option
1231 ** into account. If case-sensitive is off, then files in any case
1232 ** will match.
1233 */
1234 ManifestFile *manifest_file_find(Manifest *p, const char *zName){
1235 int i, n;
1236 Manifest *pBase;
1237 if( filenames_are_case_sensitive() ){
1238 return manifest_file_seek(p, zName);
1239 }
1240 for(i=0; i<p->nFile; i++){
1241 if( fossil_stricmp(zName, p->aFile[i].zName)==0 ){
1242 return &p->aFile[i];
1243 }
1244 }
1245 if( p->zBaseline==0 ) return 0;
1246 fetch_baseline(p, 1);
1247 pBase = p->pBaseline;
1248 if( pBase==0 ) return 0;
1249 for(i=0; i<pBase->nFile; i++){
1250 if( fossil_stricmp(zName, p->aFile[i].zName)==0 ){
1251 return &p->aFile[i];
1252 }
1253 }
1254 return 0;
1255 }
1256
1257 /*
1258 ** Add mlink table entries associated with manifest cid, pChild. The
1259 ** parent manifest is pid, pParent. One of either pChild or pParent
1260 ** will be NULL and it will be computed based on cid/pid.
1261
+13 -10
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -649,11 +649,11 @@
649649
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
650650
** [sqlite_version()] and [sqlite_source_id()].
651651
*/
652652
#define SQLITE_VERSION "3.7.9"
653653
#define SQLITE_VERSION_NUMBER 3007009
654
-#define SQLITE_SOURCE_ID "2011-10-29 19:25:08 5b82ec6fbbd2f4195ad06dd911de3817373ad5bf"
654
+#define SQLITE_SOURCE_ID "2011-11-14 02:53:54 54cc11981127b52145e39f551d958580b1d45169"
655655
656656
/*
657657
** CAPI3REF: Run-Time Library Version Numbers
658658
** KEYWORDS: sqlite3_version, sqlite3_sourceid
659659
**
@@ -1286,11 +1286,11 @@
12861286
**
12871287
** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic
12881288
** retry counts and intervals for certain disk I/O operations for the
12891289
** windows [VFS] in order to work to provide robustness against
12901290
** anti-virus programs. By default, the windows VFS will retry file read,
1291
-** file write, and file delete opertions up to 10 times, with a delay
1291
+** file write, and file delete operations up to 10 times, with a delay
12921292
** of 25 milliseconds before the first retry and with the delay increasing
12931293
** by an additional 25 milliseconds with each subsequent retry. This
12941294
** opcode allows those to values (10 retries and 25 milliseconds of delay)
12951295
** to be adjusted. The values are changed for all database connections
12961296
** within the same process. The argument is a pointer to an array of two
@@ -82100,23 +82100,26 @@
8210082100
** Allocate the index structure.
8210182101
*/
8210282102
nName = sqlite3Strlen30(zName);
8210382103
nCol = pList->nExpr;
8210482104
pIndex = sqlite3DbMallocZero(db,
82105
- sizeof(Index) + /* Index structure */
82106
- sizeof(tRowcnt)*(nCol+1) + /* Index.aiRowEst */
82107
- sizeof(int)*nCol + /* Index.aiColumn */
82108
- sizeof(char *)*nCol + /* Index.azColl */
82109
- sizeof(u8)*nCol + /* Index.aSortOrder */
82110
- nName + 1 + /* Index.zName */
82111
- nExtra /* Collation sequence names */
82105
+ sizeof(Index) + /* Index structure */
82106
+ ROUND8(sizeof(tRowcnt)*(nCol+1)) + /* Index.aiRowEst */
82107
+ sizeof(char *)*nCol + /* Index.azColl */
82108
+ sizeof(int)*nCol + /* Index.aiColumn */
82109
+ sizeof(u8)*nCol + /* Index.aSortOrder */
82110
+ nName + 1 + /* Index.zName */
82111
+ nExtra /* Collation sequence names */
8211282112
);
8211382113
if( db->mallocFailed ){
8211482114
goto exit_create_index;
8211582115
}
8211682116
pIndex->aiRowEst = (tRowcnt*)(&pIndex[1]);
82117
- pIndex->azColl = (char**)(&pIndex->aiRowEst[nCol+1]);
82117
+ pIndex->azColl = (char**)
82118
+ ((char*)pIndex->aiRowEst + ROUND8(sizeof(tRowcnt)*nCol+1));
82119
+ assert( EIGHT_BYTE_ALIGNMENT(pIndex->aiRowEst) );
82120
+ assert( EIGHT_BYTE_ALIGNMENT(pIndex->azColl) );
8211882121
pIndex->aiColumn = (int *)(&pIndex->azColl[nCol]);
8211982122
pIndex->aSortOrder = (u8 *)(&pIndex->aiColumn[nCol]);
8212082123
pIndex->zName = (char *)(&pIndex->aSortOrder[nCol]);
8212182124
zExtra = (char *)(&pIndex->zName[nName+1]);
8212282125
memcpy(pIndex->zName, zName, nName+1);
8212382126
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -649,11 +649,11 @@
649 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
650 ** [sqlite_version()] and [sqlite_source_id()].
651 */
652 #define SQLITE_VERSION "3.7.9"
653 #define SQLITE_VERSION_NUMBER 3007009
654 #define SQLITE_SOURCE_ID "2011-10-29 19:25:08 5b82ec6fbbd2f4195ad06dd911de3817373ad5bf"
655
656 /*
657 ** CAPI3REF: Run-Time Library Version Numbers
658 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
659 **
@@ -1286,11 +1286,11 @@
1286 **
1287 ** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic
1288 ** retry counts and intervals for certain disk I/O operations for the
1289 ** windows [VFS] in order to work to provide robustness against
1290 ** anti-virus programs. By default, the windows VFS will retry file read,
1291 ** file write, and file delete opertions up to 10 times, with a delay
1292 ** of 25 milliseconds before the first retry and with the delay increasing
1293 ** by an additional 25 milliseconds with each subsequent retry. This
1294 ** opcode allows those to values (10 retries and 25 milliseconds of delay)
1295 ** to be adjusted. The values are changed for all database connections
1296 ** within the same process. The argument is a pointer to an array of two
@@ -82100,23 +82100,26 @@
82100 ** Allocate the index structure.
82101 */
82102 nName = sqlite3Strlen30(zName);
82103 nCol = pList->nExpr;
82104 pIndex = sqlite3DbMallocZero(db,
82105 sizeof(Index) + /* Index structure */
82106 sizeof(tRowcnt)*(nCol+1) + /* Index.aiRowEst */
82107 sizeof(int)*nCol + /* Index.aiColumn */
82108 sizeof(char *)*nCol + /* Index.azColl */
82109 sizeof(u8)*nCol + /* Index.aSortOrder */
82110 nName + 1 + /* Index.zName */
82111 nExtra /* Collation sequence names */
82112 );
82113 if( db->mallocFailed ){
82114 goto exit_create_index;
82115 }
82116 pIndex->aiRowEst = (tRowcnt*)(&pIndex[1]);
82117 pIndex->azColl = (char**)(&pIndex->aiRowEst[nCol+1]);
 
 
 
82118 pIndex->aiColumn = (int *)(&pIndex->azColl[nCol]);
82119 pIndex->aSortOrder = (u8 *)(&pIndex->aiColumn[nCol]);
82120 pIndex->zName = (char *)(&pIndex->aSortOrder[nCol]);
82121 zExtra = (char *)(&pIndex->zName[nName+1]);
82122 memcpy(pIndex->zName, zName, nName+1);
82123
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -649,11 +649,11 @@
649 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
650 ** [sqlite_version()] and [sqlite_source_id()].
651 */
652 #define SQLITE_VERSION "3.7.9"
653 #define SQLITE_VERSION_NUMBER 3007009
654 #define SQLITE_SOURCE_ID "2011-11-14 02:53:54 54cc11981127b52145e39f551d958580b1d45169"
655
656 /*
657 ** CAPI3REF: Run-Time Library Version Numbers
658 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
659 **
@@ -1286,11 +1286,11 @@
1286 **
1287 ** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic
1288 ** retry counts and intervals for certain disk I/O operations for the
1289 ** windows [VFS] in order to work to provide robustness against
1290 ** anti-virus programs. By default, the windows VFS will retry file read,
1291 ** file write, and file delete operations up to 10 times, with a delay
1292 ** of 25 milliseconds before the first retry and with the delay increasing
1293 ** by an additional 25 milliseconds with each subsequent retry. This
1294 ** opcode allows those to values (10 retries and 25 milliseconds of delay)
1295 ** to be adjusted. The values are changed for all database connections
1296 ** within the same process. The argument is a pointer to an array of two
@@ -82100,23 +82100,26 @@
82100 ** Allocate the index structure.
82101 */
82102 nName = sqlite3Strlen30(zName);
82103 nCol = pList->nExpr;
82104 pIndex = sqlite3DbMallocZero(db,
82105 sizeof(Index) + /* Index structure */
82106 ROUND8(sizeof(tRowcnt)*(nCol+1)) + /* Index.aiRowEst */
82107 sizeof(char *)*nCol + /* Index.azColl */
82108 sizeof(int)*nCol + /* Index.aiColumn */
82109 sizeof(u8)*nCol + /* Index.aSortOrder */
82110 nName + 1 + /* Index.zName */
82111 nExtra /* Collation sequence names */
82112 );
82113 if( db->mallocFailed ){
82114 goto exit_create_index;
82115 }
82116 pIndex->aiRowEst = (tRowcnt*)(&pIndex[1]);
82117 pIndex->azColl = (char**)
82118 ((char*)pIndex->aiRowEst + ROUND8(sizeof(tRowcnt)*nCol+1));
82119 assert( EIGHT_BYTE_ALIGNMENT(pIndex->aiRowEst) );
82120 assert( EIGHT_BYTE_ALIGNMENT(pIndex->azColl) );
82121 pIndex->aiColumn = (int *)(&pIndex->azColl[nCol]);
82122 pIndex->aSortOrder = (u8 *)(&pIndex->aiColumn[nCol]);
82123 pIndex->zName = (char *)(&pIndex->aSortOrder[nCol]);
82124 zExtra = (char *)(&pIndex->zName[nName+1]);
82125 memcpy(pIndex->zName, zName, nName+1);
82126
+2 -2
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -107,11 +107,11 @@
107107
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108108
** [sqlite_version()] and [sqlite_source_id()].
109109
*/
110110
#define SQLITE_VERSION "3.7.9"
111111
#define SQLITE_VERSION_NUMBER 3007009
112
-#define SQLITE_SOURCE_ID "2011-10-29 19:25:08 5b82ec6fbbd2f4195ad06dd911de3817373ad5bf"
112
+#define SQLITE_SOURCE_ID "2011-11-14 02:53:54 54cc11981127b52145e39f551d958580b1d45169"
113113
114114
/*
115115
** CAPI3REF: Run-Time Library Version Numbers
116116
** KEYWORDS: sqlite3_version, sqlite3_sourceid
117117
**
@@ -744,11 +744,11 @@
744744
**
745745
** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic
746746
** retry counts and intervals for certain disk I/O operations for the
747747
** windows [VFS] in order to work to provide robustness against
748748
** anti-virus programs. By default, the windows VFS will retry file read,
749
-** file write, and file delete opertions up to 10 times, with a delay
749
+** file write, and file delete operations up to 10 times, with a delay
750750
** of 25 milliseconds before the first retry and with the delay increasing
751751
** by an additional 25 milliseconds with each subsequent retry. This
752752
** opcode allows those to values (10 retries and 25 milliseconds of delay)
753753
** to be adjusted. The values are changed for all database connections
754754
** within the same process. The argument is a pointer to an array of two
755755
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -107,11 +107,11 @@
107 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108 ** [sqlite_version()] and [sqlite_source_id()].
109 */
110 #define SQLITE_VERSION "3.7.9"
111 #define SQLITE_VERSION_NUMBER 3007009
112 #define SQLITE_SOURCE_ID "2011-10-29 19:25:08 5b82ec6fbbd2f4195ad06dd911de3817373ad5bf"
113
114 /*
115 ** CAPI3REF: Run-Time Library Version Numbers
116 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
117 **
@@ -744,11 +744,11 @@
744 **
745 ** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic
746 ** retry counts and intervals for certain disk I/O operations for the
747 ** windows [VFS] in order to work to provide robustness against
748 ** anti-virus programs. By default, the windows VFS will retry file read,
749 ** file write, and file delete opertions up to 10 times, with a delay
750 ** of 25 milliseconds before the first retry and with the delay increasing
751 ** by an additional 25 milliseconds with each subsequent retry. This
752 ** opcode allows those to values (10 retries and 25 milliseconds of delay)
753 ** to be adjusted. The values are changed for all database connections
754 ** within the same process. The argument is a pointer to an array of two
755
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -107,11 +107,11 @@
107 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108 ** [sqlite_version()] and [sqlite_source_id()].
109 */
110 #define SQLITE_VERSION "3.7.9"
111 #define SQLITE_VERSION_NUMBER 3007009
112 #define SQLITE_SOURCE_ID "2011-11-14 02:53:54 54cc11981127b52145e39f551d958580b1d45169"
113
114 /*
115 ** CAPI3REF: Run-Time Library Version Numbers
116 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
117 **
@@ -744,11 +744,11 @@
744 **
745 ** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic
746 ** retry counts and intervals for certain disk I/O operations for the
747 ** windows [VFS] in order to work to provide robustness against
748 ** anti-virus programs. By default, the windows VFS will retry file read,
749 ** file write, and file delete operations up to 10 times, with a delay
750 ** of 25 milliseconds before the first retry and with the delay increasing
751 ** by an additional 25 milliseconds with each subsequent retry. This
752 ** opcode allows those to values (10 retries and 25 milliseconds of delay)
753 ** to be adjusted. The values are changed for all database connections
754 ** within the same process. The argument is a pointer to an array of two
755
--- src/style.c
+++ src/style.c
@@ -893,10 +893,11 @@
893893
zCap[i] = 0;
894894
@ g.userUid = %d(g.userUid)<br />
895895
@ g.zLogin = %h(g.zLogin)<br />
896896
@ capabilities = %s(zCap)<br />
897897
@ <hr>
898
+ P("HTTP_USER_AGENT");
898899
cgi_print_all(atoi(PD("showall","0")));
899900
if( g.perm.Setup ){
900901
const char *zRedir = P("redirect");
901902
if( zRedir ) cgi_redirect(zRedir);
902903
}
903904
--- src/style.c
+++ src/style.c
@@ -893,10 +893,11 @@
893 zCap[i] = 0;
894 @ g.userUid = %d(g.userUid)<br />
895 @ g.zLogin = %h(g.zLogin)<br />
896 @ capabilities = %s(zCap)<br />
897 @ <hr>
 
898 cgi_print_all(atoi(PD("showall","0")));
899 if( g.perm.Setup ){
900 const char *zRedir = P("redirect");
901 if( zRedir ) cgi_redirect(zRedir);
902 }
903
--- src/style.c
+++ src/style.c
@@ -893,10 +893,11 @@
893 zCap[i] = 0;
894 @ g.userUid = %d(g.userUid)<br />
895 @ g.zLogin = %h(g.zLogin)<br />
896 @ capabilities = %s(zCap)<br />
897 @ <hr>
898 P("HTTP_USER_AGENT");
899 cgi_print_all(atoi(PD("showall","0")));
900 if( g.perm.Setup ){
901 const char *zRedir = P("redirect");
902 if( zRedir ) cgi_redirect(zRedir);
903 }
904
+1 -1
--- src/update.c
+++ src/update.c
@@ -575,11 +575,11 @@
575575
fossil_fatal("no such checkin: %s", revision);
576576
}
577577
pManifest = manifest_get(rid, CFTYPE_MANIFEST);
578578
579579
if( pManifest ){
580
- pFile = manifest_file_seek(pManifest, file);
580
+ pFile = manifest_file_find(pManifest, file);
581581
if( pFile ){
582582
rid = uuid_to_rid(pFile->zUuid, 0);
583583
if( pIsExe ) *pIsExe = ( manifest_file_mperm(pFile)==PERM_EXE );
584584
if( pIsLink ) *pIsLink = ( manifest_file_mperm(pFile)==PERM_LNK );
585585
manifest_destroy(pManifest);
586586
--- src/update.c
+++ src/update.c
@@ -575,11 +575,11 @@
575 fossil_fatal("no such checkin: %s", revision);
576 }
577 pManifest = manifest_get(rid, CFTYPE_MANIFEST);
578
579 if( pManifest ){
580 pFile = manifest_file_seek(pManifest, file);
581 if( pFile ){
582 rid = uuid_to_rid(pFile->zUuid, 0);
583 if( pIsExe ) *pIsExe = ( manifest_file_mperm(pFile)==PERM_EXE );
584 if( pIsLink ) *pIsLink = ( manifest_file_mperm(pFile)==PERM_LNK );
585 manifest_destroy(pManifest);
586
--- src/update.c
+++ src/update.c
@@ -575,11 +575,11 @@
575 fossil_fatal("no such checkin: %s", revision);
576 }
577 pManifest = manifest_get(rid, CFTYPE_MANIFEST);
578
579 if( pManifest ){
580 pFile = manifest_file_find(pManifest, file);
581 if( pFile ){
582 rid = uuid_to_rid(pFile->zUuid, 0);
583 if( pIsExe ) *pIsExe = ( manifest_file_mperm(pFile)==PERM_EXE );
584 if( pIsLink ) *pIsLink = ( manifest_file_mperm(pFile)==PERM_LNK );
585 manifest_destroy(pManifest);
586
+21 -8
--- src/xfer.c
+++ src/xfer.c
@@ -443,43 +443,56 @@
443443
const char *zDelta;
444444
int szU;
445445
int szC;
446446
int rc;
447447
int isPrivate;
448
+ int srcIsPrivate;
448449
static Stmt q1;
450
+ Blob fullContent;
449451
450452
isPrivate = content_is_private(rid);
451453
if( isPrivate && pXfer->syncPrivate==0 ) return;
452454
db_static_prepare(&q1,
453
- "SELECT uuid, size, content,"
454
- " (SELECT uuid FROM delta, blob"
455
- " WHERE delta.rid=:rid AND delta.srcid=blob.rid)"
456
- " FROM blob"
457
- " WHERE rid=:rid"
458
- " AND size>=0"
455
+ "SELECT uuid, size, content, delta.srcid IN private,"
456
+ " (SELECT uuid FROM blob WHERE rid=delta.srcid)"
457
+ " FROM blob LEFT JOIN delta ON (blob.rid=delta.rid)"
458
+ " WHERE blob.rid=:rid"
459
+ " AND blob.size>=0"
459460
" AND NOT EXISTS(SELECT 1 FROM shun WHERE shun.uuid=blob.uuid)"
460461
);
461462
db_bind_int(&q1, ":rid", rid);
462463
rc = db_step(&q1);
463464
if( rc==SQLITE_ROW ){
464465
zUuid = db_column_text(&q1, 0);
465466
szU = db_column_int(&q1, 1);
466467
szC = db_column_bytes(&q1, 2);
467468
zContent = db_column_raw(&q1, 2);
468
- zDelta = db_column_text(&q1, 3);
469
+ srcIsPrivate = db_column_int(&q1, 3);
470
+ zDelta = db_column_text(&q1, 4);
469471
if( isPrivate ) blob_append(pXfer->pOut, "private\n", -1);
470472
blob_appendf(pXfer->pOut, "cfile %s ", zUuid);
471
- if( zDelta ){
473
+ if( !isPrivate && srcIsPrivate ){
474
+ content_get(rid, &fullContent);
475
+ szU = blob_size(&fullContent);
476
+ blob_compress(&fullContent, &fullContent);
477
+ szC = blob_size(&fullContent);
478
+ zContent = blob_buffer(&fullContent);
479
+ zDelta = 0;
480
+ }
481
+ if( zDelta ){
472482
blob_appendf(pXfer->pOut, "%s ", zDelta);
473483
pXfer->nDeltaSent++;
474484
}else{
475485
pXfer->nFileSent++;
476486
}
477487
blob_appendf(pXfer->pOut, "%d %d\n", szU, szC);
478488
blob_append(pXfer->pOut, zContent, szC);
479489
if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){
480490
blob_appendf(pXfer->pOut, "\n", 1);
491
+ }
492
+ if( !isPrivate && srcIsPrivate ){
493
+ blob_reset(&fullContent);
481494
}
482495
}
483496
db_reset(&q1);
484497
}
485498
486499
--- src/xfer.c
+++ src/xfer.c
@@ -443,43 +443,56 @@
443 const char *zDelta;
444 int szU;
445 int szC;
446 int rc;
447 int isPrivate;
 
448 static Stmt q1;
 
449
450 isPrivate = content_is_private(rid);
451 if( isPrivate && pXfer->syncPrivate==0 ) return;
452 db_static_prepare(&q1,
453 "SELECT uuid, size, content,"
454 " (SELECT uuid FROM delta, blob"
455 " WHERE delta.rid=:rid AND delta.srcid=blob.rid)"
456 " FROM blob"
457 " WHERE rid=:rid"
458 " AND size>=0"
459 " AND NOT EXISTS(SELECT 1 FROM shun WHERE shun.uuid=blob.uuid)"
460 );
461 db_bind_int(&q1, ":rid", rid);
462 rc = db_step(&q1);
463 if( rc==SQLITE_ROW ){
464 zUuid = db_column_text(&q1, 0);
465 szU = db_column_int(&q1, 1);
466 szC = db_column_bytes(&q1, 2);
467 zContent = db_column_raw(&q1, 2);
468 zDelta = db_column_text(&q1, 3);
 
469 if( isPrivate ) blob_append(pXfer->pOut, "private\n", -1);
470 blob_appendf(pXfer->pOut, "cfile %s ", zUuid);
471 if( zDelta ){
 
 
 
 
 
 
 
 
472 blob_appendf(pXfer->pOut, "%s ", zDelta);
473 pXfer->nDeltaSent++;
474 }else{
475 pXfer->nFileSent++;
476 }
477 blob_appendf(pXfer->pOut, "%d %d\n", szU, szC);
478 blob_append(pXfer->pOut, zContent, szC);
479 if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){
480 blob_appendf(pXfer->pOut, "\n", 1);
 
 
 
481 }
482 }
483 db_reset(&q1);
484 }
485
486
--- src/xfer.c
+++ src/xfer.c
@@ -443,43 +443,56 @@
443 const char *zDelta;
444 int szU;
445 int szC;
446 int rc;
447 int isPrivate;
448 int srcIsPrivate;
449 static Stmt q1;
450 Blob fullContent;
451
452 isPrivate = content_is_private(rid);
453 if( isPrivate && pXfer->syncPrivate==0 ) return;
454 db_static_prepare(&q1,
455 "SELECT uuid, size, content, delta.srcid IN private,"
456 " (SELECT uuid FROM blob WHERE rid=delta.srcid)"
457 " FROM blob LEFT JOIN delta ON (blob.rid=delta.rid)"
458 " WHERE blob.rid=:rid"
459 " AND blob.size>=0"
 
460 " AND NOT EXISTS(SELECT 1 FROM shun WHERE shun.uuid=blob.uuid)"
461 );
462 db_bind_int(&q1, ":rid", rid);
463 rc = db_step(&q1);
464 if( rc==SQLITE_ROW ){
465 zUuid = db_column_text(&q1, 0);
466 szU = db_column_int(&q1, 1);
467 szC = db_column_bytes(&q1, 2);
468 zContent = db_column_raw(&q1, 2);
469 srcIsPrivate = db_column_int(&q1, 3);
470 zDelta = db_column_text(&q1, 4);
471 if( isPrivate ) blob_append(pXfer->pOut, "private\n", -1);
472 blob_appendf(pXfer->pOut, "cfile %s ", zUuid);
473 if( !isPrivate && srcIsPrivate ){
474 content_get(rid, &fullContent);
475 szU = blob_size(&fullContent);
476 blob_compress(&fullContent, &fullContent);
477 szC = blob_size(&fullContent);
478 zContent = blob_buffer(&fullContent);
479 zDelta = 0;
480 }
481 if( zDelta ){
482 blob_appendf(pXfer->pOut, "%s ", zDelta);
483 pXfer->nDeltaSent++;
484 }else{
485 pXfer->nFileSent++;
486 }
487 blob_appendf(pXfer->pOut, "%d %d\n", szU, szC);
488 blob_append(pXfer->pOut, zContent, szC);
489 if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){
490 blob_appendf(pXfer->pOut, "\n", 1);
491 }
492 if( !isPrivate && srcIsPrivate ){
493 blob_reset(&fullContent);
494 }
495 }
496 db_reset(&q1);
497 }
498
499
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,6 +1,31 @@
11
<title>Change Log</title>
2
+
3
+<h2>Changes For Version 1.21 (2011-12-02)</h2>
4
+ * Added side-by-side diffs in the command-line interface
5
+ * Automatically enable hyperlinks if the UserAgent string in the
6
+ HTTP header suggests that the requestor is a human and not a bot.
7
+ * Show only commonly used commands with "fossil help". Use
8
+ "fossil help --all" to see the complete list now.
9
+ * Improvements to the "stash" command: (1) Stash all files, not just
10
+ those below the working directory. (2) Add the --detail option to
11
+ "list". (3) Confirm before "drop --all". (4) Add the "help"
12
+ subcommand.
13
+ * Add an Admin/Access setting to change the number of octets of the
14
+ IP address that are saved in login cookies - allowing this setting
15
+ to be changed to zero
16
+ * Promote the "test-md5sum" command to "md5sum".
17
+ * Added the "whatis" command.
18
+ * Stop showing the server-code in status outputs - it is no longer used
19
+ for anything.
20
+ * Added a compile-time option (--with-tcl) to build in the full
21
+ TCL interpreter to augment TH1.
22
+ * Merged the JSON branch into trunk. Disabled by default. Enabled
23
+ by a compile-time option. Probably it will be enabled by default
24
+ in some future release.
25
+ * Update to use SQLite version 3.7.9 plus the alignment fix for Sparc.
26
+ align
227
328
<h2>Changes For Version 1.20 (2011-10-21)</h2>
429
* Added side-by-side diffs in HTML interface. [0bde74ea1e]
530
* Added support for symlinks. (Controlled by "allow-symlinks" setting,
631
off by default). [e4f1c1fe95]
732
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,6 +1,31 @@
1 <title>Change Log</title>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
3 <h2>Changes For Version 1.20 (2011-10-21)</h2>
4 * Added side-by-side diffs in HTML interface. [0bde74ea1e]
5 * Added support for symlinks. (Controlled by "allow-symlinks" setting,
6 off by default). [e4f1c1fe95]
7
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,6 +1,31 @@
1 <title>Change Log</title>
2
3 <h2>Changes For Version 1.21 (2011-12-02)</h2>
4 * Added side-by-side diffs in the command-line interface
5 * Automatically enable hyperlinks if the UserAgent string in the
6 HTTP header suggests that the requestor is a human and not a bot.
7 * Show only commonly used commands with "fossil help". Use
8 "fossil help --all" to see the complete list now.
9 * Improvements to the "stash" command: (1) Stash all files, not just
10 those below the working directory. (2) Add the --detail option to
11 "list". (3) Confirm before "drop --all". (4) Add the "help"
12 subcommand.
13 * Add an Admin/Access setting to change the number of octets of the
14 IP address that are saved in login cookies - allowing this setting
15 to be changed to zero
16 * Promote the "test-md5sum" command to "md5sum".
17 * Added the "whatis" command.
18 * Stop showing the server-code in status outputs - it is no longer used
19 for anything.
20 * Added a compile-time option (--with-tcl) to build in the full
21 TCL interpreter to augment TH1.
22 * Merged the JSON branch into trunk. Disabled by default. Enabled
23 by a compile-time option. Probably it will be enabled by default
24 in some future release.
25 * Update to use SQLite version 3.7.9 plus the alignment fix for Sparc.
26 align
27
28 <h2>Changes For Version 1.20 (2011-10-21)</h2>
29 * Added side-by-side diffs in HTML interface. [0bde74ea1e]
30 * Added support for symlinks. (Controlled by "allow-symlinks" setting,
31 off by default). [e4f1c1fe95]
32

Keyboard Shortcuts

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