Fossil SCM
Merge trunk into ben-testing, adjusting for versionable settings.
Commit
246ac307bb0438c23cfc66fc9cb15412992219a4
Parent
42a830e76da3551…
12 files changed
+74
-21
+74
-21
+1
-1
+12
-2
+12
-2
+10
-2
+10
-2
+7
-5
+7
-5
+1
-1
+42
-14
+1
-1
+74
-21
| --- src/add.c | ||
| +++ src/add.c | ||
| @@ -92,66 +92,76 @@ | ||
| 92 | 92 | ** |
| 93 | 93 | ** Omit any file whose name is pOmit. |
| 94 | 94 | */ |
| 95 | 95 | static int add_one_file( |
| 96 | 96 | const char *zPath, /* Tree-name of file to add. */ |
| 97 | - int vid /* Add to this VFILE */ | |
| 97 | + int vid, /* Add to this VFILE */ | |
| 98 | + int caseSensitive /* True if filenames are case sensitive */ | |
| 98 | 99 | ){ |
| 100 | + const char *zCollate = caseSensitive ? "binary" : "nocase"; | |
| 99 | 101 | if( !file_is_simple_pathname(zPath) ){ |
| 100 | 102 | fossil_fatal("filename contains illegal characters: %s", zPath); |
| 101 | 103 | } |
| 102 | -#if defined(_WIN32) | |
| 103 | 104 | if( db_exists("SELECT 1 FROM vfile" |
| 104 | - " WHERE pathname=%Q COLLATE nocase", zPath) ){ | |
| 105 | + " WHERE pathname=%Q COLLATE %s", zPath, zCollate) ){ | |
| 105 | 106 | db_multi_exec("UPDATE vfile SET deleted=0" |
| 106 | - " WHERE pathname=%Q COLLATE nocase", zPath); | |
| 107 | - } | |
| 108 | -#else | |
| 109 | - if( db_exists("SELECT 1 FROM vfile WHERE pathname=%Q", zPath) ){ | |
| 110 | - db_multi_exec("UPDATE vfile SET deleted=0 WHERE pathname=%Q", zPath); | |
| 111 | - } | |
| 112 | -#endif | |
| 113 | - else{ | |
| 107 | + " WHERE pathname=%Q COLLATE %s", zPath, zCollate); | |
| 108 | + }else{ | |
| 114 | 109 | char *zFullname = mprintf("%s%s", g.zLocalRoot, zPath); |
| 115 | 110 | db_multi_exec( |
| 116 | 111 | "INSERT INTO vfile(vid,deleted,rid,mrid,pathname,isexe)" |
| 117 | 112 | "VALUES(%d,0,0,0,%Q,%d)", |
| 118 | 113 | vid, zPath, file_isexe(zFullname)); |
| 119 | 114 | fossil_free(zFullname); |
| 120 | 115 | } |
| 121 | - fossil_print("ADDED %s\n", zPath); | |
| 122 | - return 1; | |
| 116 | + if( db_changes() ){ | |
| 117 | + fossil_print("ADDED %s\n", zPath); | |
| 118 | + return 1; | |
| 119 | + }else{ | |
| 120 | + fossil_print("SKIP %s\n", zPath); | |
| 121 | + return 0; | |
| 122 | + } | |
| 123 | 123 | } |
| 124 | 124 | |
| 125 | 125 | /* |
| 126 | 126 | ** Add all files in the sfile temp table. |
| 127 | 127 | ** |
| 128 | 128 | ** Automatically exclude the repository file. |
| 129 | 129 | */ |
| 130 | -static int add_files_in_sfile(int vid){ | |
| 130 | +static int add_files_in_sfile(int vid, int caseSensitive){ | |
| 131 | 131 | const char *zRepo; /* Name of the repository database file */ |
| 132 | 132 | int nAdd = 0; /* Number of files added */ |
| 133 | 133 | int i; /* Loop counter */ |
| 134 | 134 | const char *zReserved; /* Name of a reserved file */ |
| 135 | 135 | Blob repoName; /* Treename of the repository */ |
| 136 | 136 | Stmt loop; /* SQL to loop over all files to add */ |
| 137 | + int (*xCmp)(const char*,const char*); | |
| 137 | 138 | |
| 138 | 139 | if( !file_tree_name(g.zRepositoryName, &repoName, 0) ){ |
| 139 | 140 | blob_zero(&repoName); |
| 140 | 141 | zRepo = ""; |
| 141 | 142 | }else{ |
| 142 | 143 | zRepo = blob_str(&repoName); |
| 144 | + } | |
| 145 | + if( caseSensitive ){ | |
| 146 | + xCmp = fossil_strcmp; | |
| 147 | + }else{ | |
| 148 | + xCmp = fossil_stricmp; | |
| 149 | + db_multi_exec( | |
| 150 | + "CREATE INDEX IF NOT EXISTS vfile_nocase" | |
| 151 | + " ON vfile(pathname COLLATE nocase)" | |
| 152 | + ); | |
| 143 | 153 | } |
| 144 | 154 | db_prepare(&loop, "SELECT x FROM sfile ORDER BY x"); |
| 145 | 155 | while( db_step(&loop)==SQLITE_ROW ){ |
| 146 | 156 | const char *zToAdd = db_column_text(&loop, 0); |
| 147 | 157 | if( fossil_strcmp(zToAdd, zRepo)==0 ) continue; |
| 148 | 158 | for(i=0; (zReserved = fossil_reserved_name(i))!=0; i++){ |
| 149 | - if( fossil_strcmp(zToAdd, zReserved)==0 ) break; | |
| 159 | + if( xCmp(zToAdd, zReserved)==0 ) break; | |
| 150 | 160 | } |
| 151 | 161 | if( zReserved ) continue; |
| 152 | - nAdd += add_one_file(zToAdd, vid); | |
| 162 | + nAdd += add_one_file(zToAdd, vid, caseSensitive); | |
| 153 | 163 | } |
| 154 | 164 | db_finalize(&loop); |
| 155 | 165 | blob_reset(&repoName); |
| 156 | 166 | return nAdd; |
| 157 | 167 | } |
| @@ -180,14 +190,17 @@ | ||
| 180 | 190 | int i; /* Loop counter */ |
| 181 | 191 | int vid; /* Currently checked out version */ |
| 182 | 192 | int nRoot; /* Full path characters in g.zLocalRoot */ |
| 183 | 193 | const char *zIgnoreFlag; /* The --ignore option or ignore-glob setting */ |
| 184 | 194 | Glob *pIgnore; /* Ignore everything matching this glob pattern */ |
| 195 | + int caseSensitive; /* True if filenames are case sensitive */ | |
| 185 | 196 | |
| 186 | 197 | zIgnoreFlag = find_option("ignore",0,1); |
| 187 | 198 | includeDotFiles = find_option("dotfiles",0,0)!=0; |
| 199 | + capture_case_sensitive_option(); | |
| 188 | 200 | db_must_be_within_tree(); |
| 201 | + caseSensitive = filenames_are_case_sensitive(); | |
| 189 | 202 | if( zIgnoreFlag==0 ){ |
| 190 | 203 | zIgnoreFlag = db_get_versionable_setting("ignore-glob", 0); |
| 191 | 204 | } |
| 192 | 205 | vid = db_lget_int("checkout",0); |
| 193 | 206 | if( vid==0 ){ |
| @@ -229,11 +242,11 @@ | ||
| 229 | 242 | } |
| 230 | 243 | blob_reset(&fullName); |
| 231 | 244 | } |
| 232 | 245 | glob_free(pIgnore); |
| 233 | 246 | |
| 234 | - add_files_in_sfile(vid); | |
| 247 | + add_files_in_sfile(vid, caseSensitive); | |
| 235 | 248 | db_end_transaction(0); |
| 236 | 249 | } |
| 237 | 250 | |
| 238 | 251 | /* |
| 239 | 252 | ** COMMAND: rm |
| @@ -289,10 +302,48 @@ | ||
| 289 | 302 | "UPDATE vfile SET deleted=1 WHERE pathname IN sfile;" |
| 290 | 303 | "DELETE FROM vfile WHERE rid=0 AND deleted;" |
| 291 | 304 | ); |
| 292 | 305 | db_end_transaction(0); |
| 293 | 306 | } |
| 307 | + | |
| 308 | +/* | |
| 309 | +** Capture the command-line --case-sensitive option. | |
| 310 | +*/ | |
| 311 | +static const char *zCaseSensitive = 0; | |
| 312 | +void capture_case_sensitive_option(void){ | |
| 313 | + if( zCaseSensitive==0 ){ | |
| 314 | + zCaseSensitive = find_option("case-sensitive",0,1); | |
| 315 | + } | |
| 316 | +} | |
| 317 | + | |
| 318 | +/* | |
| 319 | +** This routine determines if files should be case-sensitive or not. | |
| 320 | +** In other words, this routine determines if two filenames that | |
| 321 | +** differ only in case should be considered the same name or not. | |
| 322 | +** | |
| 323 | +** The case-sensitive setting determines the default value. If | |
| 324 | +** the case-sensitive setting is undefined, then case sensitivity | |
| 325 | +** defaults on for Mac and Windows and off for all other unix. | |
| 326 | +** | |
| 327 | +** The --case-sensitive BOOLEAN command-line option overrides any | |
| 328 | +** setting. | |
| 329 | +*/ | |
| 330 | +int filenames_are_case_sensitive(void){ | |
| 331 | + int caseSensitive; | |
| 332 | + | |
| 333 | + if( zCaseSensitive ){ | |
| 334 | + caseSensitive = is_truth(zCaseSensitive); | |
| 335 | + }else{ | |
| 336 | +#if !defined(_WIN32) && !defined(__DARWIN__) && !defined(__APPLE__) | |
| 337 | + caseSensitive = 1; | |
| 338 | +#else | |
| 339 | + caseSensitive = 0; | |
| 340 | +#endif | |
| 341 | + caseSensitive = db_get_boolean("case-sensitive",caseSensitive); | |
| 342 | + } | |
| 343 | + return caseSensitive; | |
| 344 | +} | |
| 294 | 345 | |
| 295 | 346 | /* |
| 296 | 347 | ** COMMAND: addremove |
| 297 | 348 | ** |
| 298 | 349 | ** Usage: %fossil addremove ?--dotfiles? ?--ignore GLOBPATTERN? ?--test? |
| @@ -319,27 +370,29 @@ | ||
| 319 | 370 | ** |
| 320 | 371 | ** The --test option shows what would happen without actually doing anything. |
| 321 | 372 | ** |
| 322 | 373 | ** This command can be used to track third party software. |
| 323 | 374 | ** |
| 324 | -** | |
| 325 | 375 | ** SUMMARY: fossil addremove |
| 326 | -** Options: ?--dotfiles? ?--ignore GLOBPATTERN? ?--test? | |
| 376 | +** Options: ?--dotfiles? ?--ignore GLOB? ?--test? ?--case-sensitive BOOL? | |
| 327 | 377 | */ |
| 328 | -void import_cmd(void){ | |
| 378 | +void addremove_cmd(void){ | |
| 329 | 379 | Blob path; |
| 330 | 380 | const char *zIgnoreFlag = find_option("ignore",0,1); |
| 331 | 381 | int allFlag = find_option("dotfiles",0,0)!=0; |
| 332 | 382 | int isTest = find_option("test",0,0)!=0; |
| 383 | + int caseSensitive; | |
| 333 | 384 | int n; |
| 334 | 385 | Stmt q; |
| 335 | 386 | int vid; |
| 336 | 387 | int nAdd = 0; |
| 337 | 388 | int nDelete = 0; |
| 338 | 389 | Glob *pIgnore; |
| 339 | 390 | |
| 391 | + capture_case_sensitive_option(); | |
| 340 | 392 | db_must_be_within_tree(); |
| 393 | + caseSensitive = filenames_are_case_sensitive(); | |
| 341 | 394 | if( zIgnoreFlag==0 ){ |
| 342 | 395 | zIgnoreFlag = db_get_versionable_setting("ignore-glob", 0); |
| 343 | 396 | } |
| 344 | 397 | vid = db_lget_int("checkout",0); |
| 345 | 398 | if( vid==0 ){ |
| @@ -358,11 +411,11 @@ | ||
| 358 | 411 | blob_init(&path, g.zLocalRoot, n-1); |
| 359 | 412 | /* now we read the complete file structure into a temp table */ |
| 360 | 413 | pIgnore = glob_create(zIgnoreFlag); |
| 361 | 414 | vfile_scan(&path, blob_size(&path), allFlag, pIgnore); |
| 362 | 415 | glob_free(pIgnore); |
| 363 | - nAdd = add_files_in_sfile(vid); | |
| 416 | + nAdd = add_files_in_sfile(vid, caseSensitive); | |
| 364 | 417 | |
| 365 | 418 | /* step 2: search for missing files */ |
| 366 | 419 | db_prepare(&q, |
| 367 | 420 | "SELECT pathname, %Q || pathname, deleted FROM vfile" |
| 368 | 421 | " WHERE NOT deleted" |
| 369 | 422 |
| --- src/add.c | |
| +++ src/add.c | |
| @@ -92,66 +92,76 @@ | |
| 92 | ** |
| 93 | ** Omit any file whose name is pOmit. |
| 94 | */ |
| 95 | static int add_one_file( |
| 96 | const char *zPath, /* Tree-name of file to add. */ |
| 97 | int vid /* Add to this VFILE */ |
| 98 | ){ |
| 99 | if( !file_is_simple_pathname(zPath) ){ |
| 100 | fossil_fatal("filename contains illegal characters: %s", zPath); |
| 101 | } |
| 102 | #if defined(_WIN32) |
| 103 | if( db_exists("SELECT 1 FROM vfile" |
| 104 | " WHERE pathname=%Q COLLATE nocase", zPath) ){ |
| 105 | db_multi_exec("UPDATE vfile SET deleted=0" |
| 106 | " WHERE pathname=%Q COLLATE nocase", zPath); |
| 107 | } |
| 108 | #else |
| 109 | if( db_exists("SELECT 1 FROM vfile WHERE pathname=%Q", zPath) ){ |
| 110 | db_multi_exec("UPDATE vfile SET deleted=0 WHERE pathname=%Q", zPath); |
| 111 | } |
| 112 | #endif |
| 113 | else{ |
| 114 | char *zFullname = mprintf("%s%s", g.zLocalRoot, zPath); |
| 115 | db_multi_exec( |
| 116 | "INSERT INTO vfile(vid,deleted,rid,mrid,pathname,isexe)" |
| 117 | "VALUES(%d,0,0,0,%Q,%d)", |
| 118 | vid, zPath, file_isexe(zFullname)); |
| 119 | fossil_free(zFullname); |
| 120 | } |
| 121 | fossil_print("ADDED %s\n", zPath); |
| 122 | return 1; |
| 123 | } |
| 124 | |
| 125 | /* |
| 126 | ** Add all files in the sfile temp table. |
| 127 | ** |
| 128 | ** Automatically exclude the repository file. |
| 129 | */ |
| 130 | static int add_files_in_sfile(int vid){ |
| 131 | const char *zRepo; /* Name of the repository database file */ |
| 132 | int nAdd = 0; /* Number of files added */ |
| 133 | int i; /* Loop counter */ |
| 134 | const char *zReserved; /* Name of a reserved file */ |
| 135 | Blob repoName; /* Treename of the repository */ |
| 136 | Stmt loop; /* SQL to loop over all files to add */ |
| 137 | |
| 138 | if( !file_tree_name(g.zRepositoryName, &repoName, 0) ){ |
| 139 | blob_zero(&repoName); |
| 140 | zRepo = ""; |
| 141 | }else{ |
| 142 | zRepo = blob_str(&repoName); |
| 143 | } |
| 144 | db_prepare(&loop, "SELECT x FROM sfile ORDER BY x"); |
| 145 | while( db_step(&loop)==SQLITE_ROW ){ |
| 146 | const char *zToAdd = db_column_text(&loop, 0); |
| 147 | if( fossil_strcmp(zToAdd, zRepo)==0 ) continue; |
| 148 | for(i=0; (zReserved = fossil_reserved_name(i))!=0; i++){ |
| 149 | if( fossil_strcmp(zToAdd, zReserved)==0 ) break; |
| 150 | } |
| 151 | if( zReserved ) continue; |
| 152 | nAdd += add_one_file(zToAdd, vid); |
| 153 | } |
| 154 | db_finalize(&loop); |
| 155 | blob_reset(&repoName); |
| 156 | return nAdd; |
| 157 | } |
| @@ -180,14 +190,17 @@ | |
| 180 | int i; /* Loop counter */ |
| 181 | int vid; /* Currently checked out version */ |
| 182 | int nRoot; /* Full path characters in g.zLocalRoot */ |
| 183 | const char *zIgnoreFlag; /* The --ignore option or ignore-glob setting */ |
| 184 | Glob *pIgnore; /* Ignore everything matching this glob pattern */ |
| 185 | |
| 186 | zIgnoreFlag = find_option("ignore",0,1); |
| 187 | includeDotFiles = find_option("dotfiles",0,0)!=0; |
| 188 | db_must_be_within_tree(); |
| 189 | if( zIgnoreFlag==0 ){ |
| 190 | zIgnoreFlag = db_get_versionable_setting("ignore-glob", 0); |
| 191 | } |
| 192 | vid = db_lget_int("checkout",0); |
| 193 | if( vid==0 ){ |
| @@ -229,11 +242,11 @@ | |
| 229 | } |
| 230 | blob_reset(&fullName); |
| 231 | } |
| 232 | glob_free(pIgnore); |
| 233 | |
| 234 | add_files_in_sfile(vid); |
| 235 | db_end_transaction(0); |
| 236 | } |
| 237 | |
| 238 | /* |
| 239 | ** COMMAND: rm |
| @@ -289,10 +302,48 @@ | |
| 289 | "UPDATE vfile SET deleted=1 WHERE pathname IN sfile;" |
| 290 | "DELETE FROM vfile WHERE rid=0 AND deleted;" |
| 291 | ); |
| 292 | db_end_transaction(0); |
| 293 | } |
| 294 | |
| 295 | /* |
| 296 | ** COMMAND: addremove |
| 297 | ** |
| 298 | ** Usage: %fossil addremove ?--dotfiles? ?--ignore GLOBPATTERN? ?--test? |
| @@ -319,27 +370,29 @@ | |
| 319 | ** |
| 320 | ** The --test option shows what would happen without actually doing anything. |
| 321 | ** |
| 322 | ** This command can be used to track third party software. |
| 323 | ** |
| 324 | ** |
| 325 | ** SUMMARY: fossil addremove |
| 326 | ** Options: ?--dotfiles? ?--ignore GLOBPATTERN? ?--test? |
| 327 | */ |
| 328 | void import_cmd(void){ |
| 329 | Blob path; |
| 330 | const char *zIgnoreFlag = find_option("ignore",0,1); |
| 331 | int allFlag = find_option("dotfiles",0,0)!=0; |
| 332 | int isTest = find_option("test",0,0)!=0; |
| 333 | int n; |
| 334 | Stmt q; |
| 335 | int vid; |
| 336 | int nAdd = 0; |
| 337 | int nDelete = 0; |
| 338 | Glob *pIgnore; |
| 339 | |
| 340 | db_must_be_within_tree(); |
| 341 | if( zIgnoreFlag==0 ){ |
| 342 | zIgnoreFlag = db_get_versionable_setting("ignore-glob", 0); |
| 343 | } |
| 344 | vid = db_lget_int("checkout",0); |
| 345 | if( vid==0 ){ |
| @@ -358,11 +411,11 @@ | |
| 358 | blob_init(&path, g.zLocalRoot, n-1); |
| 359 | /* now we read the complete file structure into a temp table */ |
| 360 | pIgnore = glob_create(zIgnoreFlag); |
| 361 | vfile_scan(&path, blob_size(&path), allFlag, pIgnore); |
| 362 | glob_free(pIgnore); |
| 363 | nAdd = add_files_in_sfile(vid); |
| 364 | |
| 365 | /* step 2: search for missing files */ |
| 366 | db_prepare(&q, |
| 367 | "SELECT pathname, %Q || pathname, deleted FROM vfile" |
| 368 | " WHERE NOT deleted" |
| 369 |
| --- src/add.c | |
| +++ src/add.c | |
| @@ -92,66 +92,76 @@ | |
| 92 | ** |
| 93 | ** Omit any file whose name is pOmit. |
| 94 | */ |
| 95 | static int add_one_file( |
| 96 | const char *zPath, /* Tree-name of file to add. */ |
| 97 | int vid, /* Add to this VFILE */ |
| 98 | int caseSensitive /* True if filenames are case sensitive */ |
| 99 | ){ |
| 100 | const char *zCollate = caseSensitive ? "binary" : "nocase"; |
| 101 | if( !file_is_simple_pathname(zPath) ){ |
| 102 | fossil_fatal("filename contains illegal characters: %s", zPath); |
| 103 | } |
| 104 | if( db_exists("SELECT 1 FROM vfile" |
| 105 | " WHERE pathname=%Q COLLATE %s", zPath, zCollate) ){ |
| 106 | db_multi_exec("UPDATE vfile SET deleted=0" |
| 107 | " WHERE pathname=%Q COLLATE %s", zPath, zCollate); |
| 108 | }else{ |
| 109 | char *zFullname = mprintf("%s%s", g.zLocalRoot, zPath); |
| 110 | db_multi_exec( |
| 111 | "INSERT INTO vfile(vid,deleted,rid,mrid,pathname,isexe)" |
| 112 | "VALUES(%d,0,0,0,%Q,%d)", |
| 113 | vid, zPath, file_isexe(zFullname)); |
| 114 | fossil_free(zFullname); |
| 115 | } |
| 116 | if( db_changes() ){ |
| 117 | fossil_print("ADDED %s\n", zPath); |
| 118 | return 1; |
| 119 | }else{ |
| 120 | fossil_print("SKIP %s\n", zPath); |
| 121 | return 0; |
| 122 | } |
| 123 | } |
| 124 | |
| 125 | /* |
| 126 | ** Add all files in the sfile temp table. |
| 127 | ** |
| 128 | ** Automatically exclude the repository file. |
| 129 | */ |
| 130 | static int add_files_in_sfile(int vid, int caseSensitive){ |
| 131 | const char *zRepo; /* Name of the repository database file */ |
| 132 | int nAdd = 0; /* Number of files added */ |
| 133 | int i; /* Loop counter */ |
| 134 | const char *zReserved; /* Name of a reserved file */ |
| 135 | Blob repoName; /* Treename of the repository */ |
| 136 | Stmt loop; /* SQL to loop over all files to add */ |
| 137 | int (*xCmp)(const char*,const char*); |
| 138 | |
| 139 | if( !file_tree_name(g.zRepositoryName, &repoName, 0) ){ |
| 140 | blob_zero(&repoName); |
| 141 | zRepo = ""; |
| 142 | }else{ |
| 143 | zRepo = blob_str(&repoName); |
| 144 | } |
| 145 | if( caseSensitive ){ |
| 146 | xCmp = fossil_strcmp; |
| 147 | }else{ |
| 148 | xCmp = fossil_stricmp; |
| 149 | db_multi_exec( |
| 150 | "CREATE INDEX IF NOT EXISTS vfile_nocase" |
| 151 | " ON vfile(pathname COLLATE nocase)" |
| 152 | ); |
| 153 | } |
| 154 | db_prepare(&loop, "SELECT x FROM sfile ORDER BY x"); |
| 155 | while( db_step(&loop)==SQLITE_ROW ){ |
| 156 | const char *zToAdd = db_column_text(&loop, 0); |
| 157 | if( fossil_strcmp(zToAdd, zRepo)==0 ) continue; |
| 158 | for(i=0; (zReserved = fossil_reserved_name(i))!=0; i++){ |
| 159 | if( xCmp(zToAdd, zReserved)==0 ) break; |
| 160 | } |
| 161 | if( zReserved ) continue; |
| 162 | nAdd += add_one_file(zToAdd, vid, caseSensitive); |
| 163 | } |
| 164 | db_finalize(&loop); |
| 165 | blob_reset(&repoName); |
| 166 | return nAdd; |
| 167 | } |
| @@ -180,14 +190,17 @@ | |
| 190 | int i; /* Loop counter */ |
| 191 | int vid; /* Currently checked out version */ |
| 192 | int nRoot; /* Full path characters in g.zLocalRoot */ |
| 193 | const char *zIgnoreFlag; /* The --ignore option or ignore-glob setting */ |
| 194 | Glob *pIgnore; /* Ignore everything matching this glob pattern */ |
| 195 | int caseSensitive; /* True if filenames are case sensitive */ |
| 196 | |
| 197 | zIgnoreFlag = find_option("ignore",0,1); |
| 198 | includeDotFiles = find_option("dotfiles",0,0)!=0; |
| 199 | capture_case_sensitive_option(); |
| 200 | db_must_be_within_tree(); |
| 201 | caseSensitive = filenames_are_case_sensitive(); |
| 202 | if( zIgnoreFlag==0 ){ |
| 203 | zIgnoreFlag = db_get_versionable_setting("ignore-glob", 0); |
| 204 | } |
| 205 | vid = db_lget_int("checkout",0); |
| 206 | if( vid==0 ){ |
| @@ -229,11 +242,11 @@ | |
| 242 | } |
| 243 | blob_reset(&fullName); |
| 244 | } |
| 245 | glob_free(pIgnore); |
| 246 | |
| 247 | add_files_in_sfile(vid, caseSensitive); |
| 248 | db_end_transaction(0); |
| 249 | } |
| 250 | |
| 251 | /* |
| 252 | ** COMMAND: rm |
| @@ -289,10 +302,48 @@ | |
| 302 | "UPDATE vfile SET deleted=1 WHERE pathname IN sfile;" |
| 303 | "DELETE FROM vfile WHERE rid=0 AND deleted;" |
| 304 | ); |
| 305 | db_end_transaction(0); |
| 306 | } |
| 307 | |
| 308 | /* |
| 309 | ** Capture the command-line --case-sensitive option. |
| 310 | */ |
| 311 | static const char *zCaseSensitive = 0; |
| 312 | void capture_case_sensitive_option(void){ |
| 313 | if( zCaseSensitive==0 ){ |
| 314 | zCaseSensitive = find_option("case-sensitive",0,1); |
| 315 | } |
| 316 | } |
| 317 | |
| 318 | /* |
| 319 | ** This routine determines if files should be case-sensitive or not. |
| 320 | ** In other words, this routine determines if two filenames that |
| 321 | ** differ only in case should be considered the same name or not. |
| 322 | ** |
| 323 | ** The case-sensitive setting determines the default value. If |
| 324 | ** the case-sensitive setting is undefined, then case sensitivity |
| 325 | ** defaults on for Mac and Windows and off for all other unix. |
| 326 | ** |
| 327 | ** The --case-sensitive BOOLEAN command-line option overrides any |
| 328 | ** setting. |
| 329 | */ |
| 330 | int filenames_are_case_sensitive(void){ |
| 331 | int caseSensitive; |
| 332 | |
| 333 | if( zCaseSensitive ){ |
| 334 | caseSensitive = is_truth(zCaseSensitive); |
| 335 | }else{ |
| 336 | #if !defined(_WIN32) && !defined(__DARWIN__) && !defined(__APPLE__) |
| 337 | caseSensitive = 1; |
| 338 | #else |
| 339 | caseSensitive = 0; |
| 340 | #endif |
| 341 | caseSensitive = db_get_boolean("case-sensitive",caseSensitive); |
| 342 | } |
| 343 | return caseSensitive; |
| 344 | } |
| 345 | |
| 346 | /* |
| 347 | ** COMMAND: addremove |
| 348 | ** |
| 349 | ** Usage: %fossil addremove ?--dotfiles? ?--ignore GLOBPATTERN? ?--test? |
| @@ -319,27 +370,29 @@ | |
| 370 | ** |
| 371 | ** The --test option shows what would happen without actually doing anything. |
| 372 | ** |
| 373 | ** This command can be used to track third party software. |
| 374 | ** |
| 375 | ** SUMMARY: fossil addremove |
| 376 | ** Options: ?--dotfiles? ?--ignore GLOB? ?--test? ?--case-sensitive BOOL? |
| 377 | */ |
| 378 | void addremove_cmd(void){ |
| 379 | Blob path; |
| 380 | const char *zIgnoreFlag = find_option("ignore",0,1); |
| 381 | int allFlag = find_option("dotfiles",0,0)!=0; |
| 382 | int isTest = find_option("test",0,0)!=0; |
| 383 | int caseSensitive; |
| 384 | int n; |
| 385 | Stmt q; |
| 386 | int vid; |
| 387 | int nAdd = 0; |
| 388 | int nDelete = 0; |
| 389 | Glob *pIgnore; |
| 390 | |
| 391 | capture_case_sensitive_option(); |
| 392 | db_must_be_within_tree(); |
| 393 | caseSensitive = filenames_are_case_sensitive(); |
| 394 | if( zIgnoreFlag==0 ){ |
| 395 | zIgnoreFlag = db_get_versionable_setting("ignore-glob", 0); |
| 396 | } |
| 397 | vid = db_lget_int("checkout",0); |
| 398 | if( vid==0 ){ |
| @@ -358,11 +411,11 @@ | |
| 411 | blob_init(&path, g.zLocalRoot, n-1); |
| 412 | /* now we read the complete file structure into a temp table */ |
| 413 | pIgnore = glob_create(zIgnoreFlag); |
| 414 | vfile_scan(&path, blob_size(&path), allFlag, pIgnore); |
| 415 | glob_free(pIgnore); |
| 416 | nAdd = add_files_in_sfile(vid, caseSensitive); |
| 417 | |
| 418 | /* step 2: search for missing files */ |
| 419 | db_prepare(&q, |
| 420 | "SELECT pathname, %Q || pathname, deleted FROM vfile" |
| 421 | " WHERE NOT deleted" |
| 422 |
+74
-21
| --- src/add.c | ||
| +++ src/add.c | ||
| @@ -92,66 +92,76 @@ | ||
| 92 | 92 | ** |
| 93 | 93 | ** Omit any file whose name is pOmit. |
| 94 | 94 | */ |
| 95 | 95 | static int add_one_file( |
| 96 | 96 | const char *zPath, /* Tree-name of file to add. */ |
| 97 | - int vid /* Add to this VFILE */ | |
| 97 | + int vid, /* Add to this VFILE */ | |
| 98 | + int caseSensitive /* True if filenames are case sensitive */ | |
| 98 | 99 | ){ |
| 100 | + const char *zCollate = caseSensitive ? "binary" : "nocase"; | |
| 99 | 101 | if( !file_is_simple_pathname(zPath) ){ |
| 100 | 102 | fossil_fatal("filename contains illegal characters: %s", zPath); |
| 101 | 103 | } |
| 102 | -#if defined(_WIN32) | |
| 103 | 104 | if( db_exists("SELECT 1 FROM vfile" |
| 104 | - " WHERE pathname=%Q COLLATE nocase", zPath) ){ | |
| 105 | + " WHERE pathname=%Q COLLATE %s", zPath, zCollate) ){ | |
| 105 | 106 | db_multi_exec("UPDATE vfile SET deleted=0" |
| 106 | - " WHERE pathname=%Q COLLATE nocase", zPath); | |
| 107 | - } | |
| 108 | -#else | |
| 109 | - if( db_exists("SELECT 1 FROM vfile WHERE pathname=%Q", zPath) ){ | |
| 110 | - db_multi_exec("UPDATE vfile SET deleted=0 WHERE pathname=%Q", zPath); | |
| 111 | - } | |
| 112 | -#endif | |
| 113 | - else{ | |
| 107 | + " WHERE pathname=%Q COLLATE %s", zPath, zCollate); | |
| 108 | + }else{ | |
| 114 | 109 | char *zFullname = mprintf("%s%s", g.zLocalRoot, zPath); |
| 115 | 110 | db_multi_exec( |
| 116 | 111 | "INSERT INTO vfile(vid,deleted,rid,mrid,pathname,isexe)" |
| 117 | 112 | "VALUES(%d,0,0,0,%Q,%d)", |
| 118 | 113 | vid, zPath, file_isexe(zFullname)); |
| 119 | 114 | fossil_free(zFullname); |
| 120 | 115 | } |
| 121 | - fossil_print("ADDED %s\n", zPath); | |
| 122 | - return 1; | |
| 116 | + if( db_changes() ){ | |
| 117 | + fossil_print("ADDED %s\n", zPath); | |
| 118 | + return 1; | |
| 119 | + }else{ | |
| 120 | + fossil_print("SKIP %s\n", zPath); | |
| 121 | + return 0; | |
| 122 | + } | |
| 123 | 123 | } |
| 124 | 124 | |
| 125 | 125 | /* |
| 126 | 126 | ** Add all files in the sfile temp table. |
| 127 | 127 | ** |
| 128 | 128 | ** Automatically exclude the repository file. |
| 129 | 129 | */ |
| 130 | -static int add_files_in_sfile(int vid){ | |
| 130 | +static int add_files_in_sfile(int vid, int caseSensitive){ | |
| 131 | 131 | const char *zRepo; /* Name of the repository database file */ |
| 132 | 132 | int nAdd = 0; /* Number of files added */ |
| 133 | 133 | int i; /* Loop counter */ |
| 134 | 134 | const char *zReserved; /* Name of a reserved file */ |
| 135 | 135 | Blob repoName; /* Treename of the repository */ |
| 136 | 136 | Stmt loop; /* SQL to loop over all files to add */ |
| 137 | + int (*xCmp)(const char*,const char*); | |
| 137 | 138 | |
| 138 | 139 | if( !file_tree_name(g.zRepositoryName, &repoName, 0) ){ |
| 139 | 140 | blob_zero(&repoName); |
| 140 | 141 | zRepo = ""; |
| 141 | 142 | }else{ |
| 142 | 143 | zRepo = blob_str(&repoName); |
| 144 | + } | |
| 145 | + if( caseSensitive ){ | |
| 146 | + xCmp = fossil_strcmp; | |
| 147 | + }else{ | |
| 148 | + xCmp = fossil_stricmp; | |
| 149 | + db_multi_exec( | |
| 150 | + "CREATE INDEX IF NOT EXISTS vfile_nocase" | |
| 151 | + " ON vfile(pathname COLLATE nocase)" | |
| 152 | + ); | |
| 143 | 153 | } |
| 144 | 154 | db_prepare(&loop, "SELECT x FROM sfile ORDER BY x"); |
| 145 | 155 | while( db_step(&loop)==SQLITE_ROW ){ |
| 146 | 156 | const char *zToAdd = db_column_text(&loop, 0); |
| 147 | 157 | if( fossil_strcmp(zToAdd, zRepo)==0 ) continue; |
| 148 | 158 | for(i=0; (zReserved = fossil_reserved_name(i))!=0; i++){ |
| 149 | - if( fossil_strcmp(zToAdd, zReserved)==0 ) break; | |
| 159 | + if( xCmp(zToAdd, zReserved)==0 ) break; | |
| 150 | 160 | } |
| 151 | 161 | if( zReserved ) continue; |
| 152 | - nAdd += add_one_file(zToAdd, vid); | |
| 162 | + nAdd += add_one_file(zToAdd, vid, caseSensitive); | |
| 153 | 163 | } |
| 154 | 164 | db_finalize(&loop); |
| 155 | 165 | blob_reset(&repoName); |
| 156 | 166 | return nAdd; |
| 157 | 167 | } |
| @@ -180,14 +190,17 @@ | ||
| 180 | 190 | int i; /* Loop counter */ |
| 181 | 191 | int vid; /* Currently checked out version */ |
| 182 | 192 | int nRoot; /* Full path characters in g.zLocalRoot */ |
| 183 | 193 | const char *zIgnoreFlag; /* The --ignore option or ignore-glob setting */ |
| 184 | 194 | Glob *pIgnore; /* Ignore everything matching this glob pattern */ |
| 195 | + int caseSensitive; /* True if filenames are case sensitive */ | |
| 185 | 196 | |
| 186 | 197 | zIgnoreFlag = find_option("ignore",0,1); |
| 187 | 198 | includeDotFiles = find_option("dotfiles",0,0)!=0; |
| 199 | + capture_case_sensitive_option(); | |
| 188 | 200 | db_must_be_within_tree(); |
| 201 | + caseSensitive = filenames_are_case_sensitive(); | |
| 189 | 202 | if( zIgnoreFlag==0 ){ |
| 190 | 203 | zIgnoreFlag = db_get_versionable_setting("ignore-glob", 0); |
| 191 | 204 | } |
| 192 | 205 | vid = db_lget_int("checkout",0); |
| 193 | 206 | if( vid==0 ){ |
| @@ -229,11 +242,11 @@ | ||
| 229 | 242 | } |
| 230 | 243 | blob_reset(&fullName); |
| 231 | 244 | } |
| 232 | 245 | glob_free(pIgnore); |
| 233 | 246 | |
| 234 | - add_files_in_sfile(vid); | |
| 247 | + add_files_in_sfile(vid, caseSensitive); | |
| 235 | 248 | db_end_transaction(0); |
| 236 | 249 | } |
| 237 | 250 | |
| 238 | 251 | /* |
| 239 | 252 | ** COMMAND: rm |
| @@ -289,10 +302,48 @@ | ||
| 289 | 302 | "UPDATE vfile SET deleted=1 WHERE pathname IN sfile;" |
| 290 | 303 | "DELETE FROM vfile WHERE rid=0 AND deleted;" |
| 291 | 304 | ); |
| 292 | 305 | db_end_transaction(0); |
| 293 | 306 | } |
| 307 | + | |
| 308 | +/* | |
| 309 | +** Capture the command-line --case-sensitive option. | |
| 310 | +*/ | |
| 311 | +static const char *zCaseSensitive = 0; | |
| 312 | +void capture_case_sensitive_option(void){ | |
| 313 | + if( zCaseSensitive==0 ){ | |
| 314 | + zCaseSensitive = find_option("case-sensitive",0,1); | |
| 315 | + } | |
| 316 | +} | |
| 317 | + | |
| 318 | +/* | |
| 319 | +** This routine determines if files should be case-sensitive or not. | |
| 320 | +** In other words, this routine determines if two filenames that | |
| 321 | +** differ only in case should be considered the same name or not. | |
| 322 | +** | |
| 323 | +** The case-sensitive setting determines the default value. If | |
| 324 | +** the case-sensitive setting is undefined, then case sensitivity | |
| 325 | +** defaults on for Mac and Windows and off for all other unix. | |
| 326 | +** | |
| 327 | +** The --case-sensitive BOOLEAN command-line option overrides any | |
| 328 | +** setting. | |
| 329 | +*/ | |
| 330 | +int filenames_are_case_sensitive(void){ | |
| 331 | + int caseSensitive; | |
| 332 | + | |
| 333 | + if( zCaseSensitive ){ | |
| 334 | + caseSensitive = is_truth(zCaseSensitive); | |
| 335 | + }else{ | |
| 336 | +#if !defined(_WIN32) && !defined(__DARWIN__) && !defined(__APPLE__) | |
| 337 | + caseSensitive = 1; | |
| 338 | +#else | |
| 339 | + caseSensitive = 0; | |
| 340 | +#endif | |
| 341 | + caseSensitive = db_get_boolean("case-sensitive",caseSensitive); | |
| 342 | + } | |
| 343 | + return caseSensitive; | |
| 344 | +} | |
| 294 | 345 | |
| 295 | 346 | /* |
| 296 | 347 | ** COMMAND: addremove |
| 297 | 348 | ** |
| 298 | 349 | ** Usage: %fossil addremove ?--dotfiles? ?--ignore GLOBPATTERN? ?--test? |
| @@ -319,27 +370,29 @@ | ||
| 319 | 370 | ** |
| 320 | 371 | ** The --test option shows what would happen without actually doing anything. |
| 321 | 372 | ** |
| 322 | 373 | ** This command can be used to track third party software. |
| 323 | 374 | ** |
| 324 | -** | |
| 325 | 375 | ** SUMMARY: fossil addremove |
| 326 | -** Options: ?--dotfiles? ?--ignore GLOBPATTERN? ?--test? | |
| 376 | +** Options: ?--dotfiles? ?--ignore GLOB? ?--test? ?--case-sensitive BOOL? | |
| 327 | 377 | */ |
| 328 | -void import_cmd(void){ | |
| 378 | +void addremove_cmd(void){ | |
| 329 | 379 | Blob path; |
| 330 | 380 | const char *zIgnoreFlag = find_option("ignore",0,1); |
| 331 | 381 | int allFlag = find_option("dotfiles",0,0)!=0; |
| 332 | 382 | int isTest = find_option("test",0,0)!=0; |
| 383 | + int caseSensitive; | |
| 333 | 384 | int n; |
| 334 | 385 | Stmt q; |
| 335 | 386 | int vid; |
| 336 | 387 | int nAdd = 0; |
| 337 | 388 | int nDelete = 0; |
| 338 | 389 | Glob *pIgnore; |
| 339 | 390 | |
| 391 | + capture_case_sensitive_option(); | |
| 340 | 392 | db_must_be_within_tree(); |
| 393 | + caseSensitive = filenames_are_case_sensitive(); | |
| 341 | 394 | if( zIgnoreFlag==0 ){ |
| 342 | 395 | zIgnoreFlag = db_get_versionable_setting("ignore-glob", 0); |
| 343 | 396 | } |
| 344 | 397 | vid = db_lget_int("checkout",0); |
| 345 | 398 | if( vid==0 ){ |
| @@ -358,11 +411,11 @@ | ||
| 358 | 411 | blob_init(&path, g.zLocalRoot, n-1); |
| 359 | 412 | /* now we read the complete file structure into a temp table */ |
| 360 | 413 | pIgnore = glob_create(zIgnoreFlag); |
| 361 | 414 | vfile_scan(&path, blob_size(&path), allFlag, pIgnore); |
| 362 | 415 | glob_free(pIgnore); |
| 363 | - nAdd = add_files_in_sfile(vid); | |
| 416 | + nAdd = add_files_in_sfile(vid, caseSensitive); | |
| 364 | 417 | |
| 365 | 418 | /* step 2: search for missing files */ |
| 366 | 419 | db_prepare(&q, |
| 367 | 420 | "SELECT pathname, %Q || pathname, deleted FROM vfile" |
| 368 | 421 | " WHERE NOT deleted" |
| 369 | 422 |
| --- src/add.c | |
| +++ src/add.c | |
| @@ -92,66 +92,76 @@ | |
| 92 | ** |
| 93 | ** Omit any file whose name is pOmit. |
| 94 | */ |
| 95 | static int add_one_file( |
| 96 | const char *zPath, /* Tree-name of file to add. */ |
| 97 | int vid /* Add to this VFILE */ |
| 98 | ){ |
| 99 | if( !file_is_simple_pathname(zPath) ){ |
| 100 | fossil_fatal("filename contains illegal characters: %s", zPath); |
| 101 | } |
| 102 | #if defined(_WIN32) |
| 103 | if( db_exists("SELECT 1 FROM vfile" |
| 104 | " WHERE pathname=%Q COLLATE nocase", zPath) ){ |
| 105 | db_multi_exec("UPDATE vfile SET deleted=0" |
| 106 | " WHERE pathname=%Q COLLATE nocase", zPath); |
| 107 | } |
| 108 | #else |
| 109 | if( db_exists("SELECT 1 FROM vfile WHERE pathname=%Q", zPath) ){ |
| 110 | db_multi_exec("UPDATE vfile SET deleted=0 WHERE pathname=%Q", zPath); |
| 111 | } |
| 112 | #endif |
| 113 | else{ |
| 114 | char *zFullname = mprintf("%s%s", g.zLocalRoot, zPath); |
| 115 | db_multi_exec( |
| 116 | "INSERT INTO vfile(vid,deleted,rid,mrid,pathname,isexe)" |
| 117 | "VALUES(%d,0,0,0,%Q,%d)", |
| 118 | vid, zPath, file_isexe(zFullname)); |
| 119 | fossil_free(zFullname); |
| 120 | } |
| 121 | fossil_print("ADDED %s\n", zPath); |
| 122 | return 1; |
| 123 | } |
| 124 | |
| 125 | /* |
| 126 | ** Add all files in the sfile temp table. |
| 127 | ** |
| 128 | ** Automatically exclude the repository file. |
| 129 | */ |
| 130 | static int add_files_in_sfile(int vid){ |
| 131 | const char *zRepo; /* Name of the repository database file */ |
| 132 | int nAdd = 0; /* Number of files added */ |
| 133 | int i; /* Loop counter */ |
| 134 | const char *zReserved; /* Name of a reserved file */ |
| 135 | Blob repoName; /* Treename of the repository */ |
| 136 | Stmt loop; /* SQL to loop over all files to add */ |
| 137 | |
| 138 | if( !file_tree_name(g.zRepositoryName, &repoName, 0) ){ |
| 139 | blob_zero(&repoName); |
| 140 | zRepo = ""; |
| 141 | }else{ |
| 142 | zRepo = blob_str(&repoName); |
| 143 | } |
| 144 | db_prepare(&loop, "SELECT x FROM sfile ORDER BY x"); |
| 145 | while( db_step(&loop)==SQLITE_ROW ){ |
| 146 | const char *zToAdd = db_column_text(&loop, 0); |
| 147 | if( fossil_strcmp(zToAdd, zRepo)==0 ) continue; |
| 148 | for(i=0; (zReserved = fossil_reserved_name(i))!=0; i++){ |
| 149 | if( fossil_strcmp(zToAdd, zReserved)==0 ) break; |
| 150 | } |
| 151 | if( zReserved ) continue; |
| 152 | nAdd += add_one_file(zToAdd, vid); |
| 153 | } |
| 154 | db_finalize(&loop); |
| 155 | blob_reset(&repoName); |
| 156 | return nAdd; |
| 157 | } |
| @@ -180,14 +190,17 @@ | |
| 180 | int i; /* Loop counter */ |
| 181 | int vid; /* Currently checked out version */ |
| 182 | int nRoot; /* Full path characters in g.zLocalRoot */ |
| 183 | const char *zIgnoreFlag; /* The --ignore option or ignore-glob setting */ |
| 184 | Glob *pIgnore; /* Ignore everything matching this glob pattern */ |
| 185 | |
| 186 | zIgnoreFlag = find_option("ignore",0,1); |
| 187 | includeDotFiles = find_option("dotfiles",0,0)!=0; |
| 188 | db_must_be_within_tree(); |
| 189 | if( zIgnoreFlag==0 ){ |
| 190 | zIgnoreFlag = db_get_versionable_setting("ignore-glob", 0); |
| 191 | } |
| 192 | vid = db_lget_int("checkout",0); |
| 193 | if( vid==0 ){ |
| @@ -229,11 +242,11 @@ | |
| 229 | } |
| 230 | blob_reset(&fullName); |
| 231 | } |
| 232 | glob_free(pIgnore); |
| 233 | |
| 234 | add_files_in_sfile(vid); |
| 235 | db_end_transaction(0); |
| 236 | } |
| 237 | |
| 238 | /* |
| 239 | ** COMMAND: rm |
| @@ -289,10 +302,48 @@ | |
| 289 | "UPDATE vfile SET deleted=1 WHERE pathname IN sfile;" |
| 290 | "DELETE FROM vfile WHERE rid=0 AND deleted;" |
| 291 | ); |
| 292 | db_end_transaction(0); |
| 293 | } |
| 294 | |
| 295 | /* |
| 296 | ** COMMAND: addremove |
| 297 | ** |
| 298 | ** Usage: %fossil addremove ?--dotfiles? ?--ignore GLOBPATTERN? ?--test? |
| @@ -319,27 +370,29 @@ | |
| 319 | ** |
| 320 | ** The --test option shows what would happen without actually doing anything. |
| 321 | ** |
| 322 | ** This command can be used to track third party software. |
| 323 | ** |
| 324 | ** |
| 325 | ** SUMMARY: fossil addremove |
| 326 | ** Options: ?--dotfiles? ?--ignore GLOBPATTERN? ?--test? |
| 327 | */ |
| 328 | void import_cmd(void){ |
| 329 | Blob path; |
| 330 | const char *zIgnoreFlag = find_option("ignore",0,1); |
| 331 | int allFlag = find_option("dotfiles",0,0)!=0; |
| 332 | int isTest = find_option("test",0,0)!=0; |
| 333 | int n; |
| 334 | Stmt q; |
| 335 | int vid; |
| 336 | int nAdd = 0; |
| 337 | int nDelete = 0; |
| 338 | Glob *pIgnore; |
| 339 | |
| 340 | db_must_be_within_tree(); |
| 341 | if( zIgnoreFlag==0 ){ |
| 342 | zIgnoreFlag = db_get_versionable_setting("ignore-glob", 0); |
| 343 | } |
| 344 | vid = db_lget_int("checkout",0); |
| 345 | if( vid==0 ){ |
| @@ -358,11 +411,11 @@ | |
| 358 | blob_init(&path, g.zLocalRoot, n-1); |
| 359 | /* now we read the complete file structure into a temp table */ |
| 360 | pIgnore = glob_create(zIgnoreFlag); |
| 361 | vfile_scan(&path, blob_size(&path), allFlag, pIgnore); |
| 362 | glob_free(pIgnore); |
| 363 | nAdd = add_files_in_sfile(vid); |
| 364 | |
| 365 | /* step 2: search for missing files */ |
| 366 | db_prepare(&q, |
| 367 | "SELECT pathname, %Q || pathname, deleted FROM vfile" |
| 368 | " WHERE NOT deleted" |
| 369 |
| --- src/add.c | |
| +++ src/add.c | |
| @@ -92,66 +92,76 @@ | |
| 92 | ** |
| 93 | ** Omit any file whose name is pOmit. |
| 94 | */ |
| 95 | static int add_one_file( |
| 96 | const char *zPath, /* Tree-name of file to add. */ |
| 97 | int vid, /* Add to this VFILE */ |
| 98 | int caseSensitive /* True if filenames are case sensitive */ |
| 99 | ){ |
| 100 | const char *zCollate = caseSensitive ? "binary" : "nocase"; |
| 101 | if( !file_is_simple_pathname(zPath) ){ |
| 102 | fossil_fatal("filename contains illegal characters: %s", zPath); |
| 103 | } |
| 104 | if( db_exists("SELECT 1 FROM vfile" |
| 105 | " WHERE pathname=%Q COLLATE %s", zPath, zCollate) ){ |
| 106 | db_multi_exec("UPDATE vfile SET deleted=0" |
| 107 | " WHERE pathname=%Q COLLATE %s", zPath, zCollate); |
| 108 | }else{ |
| 109 | char *zFullname = mprintf("%s%s", g.zLocalRoot, zPath); |
| 110 | db_multi_exec( |
| 111 | "INSERT INTO vfile(vid,deleted,rid,mrid,pathname,isexe)" |
| 112 | "VALUES(%d,0,0,0,%Q,%d)", |
| 113 | vid, zPath, file_isexe(zFullname)); |
| 114 | fossil_free(zFullname); |
| 115 | } |
| 116 | if( db_changes() ){ |
| 117 | fossil_print("ADDED %s\n", zPath); |
| 118 | return 1; |
| 119 | }else{ |
| 120 | fossil_print("SKIP %s\n", zPath); |
| 121 | return 0; |
| 122 | } |
| 123 | } |
| 124 | |
| 125 | /* |
| 126 | ** Add all files in the sfile temp table. |
| 127 | ** |
| 128 | ** Automatically exclude the repository file. |
| 129 | */ |
| 130 | static int add_files_in_sfile(int vid, int caseSensitive){ |
| 131 | const char *zRepo; /* Name of the repository database file */ |
| 132 | int nAdd = 0; /* Number of files added */ |
| 133 | int i; /* Loop counter */ |
| 134 | const char *zReserved; /* Name of a reserved file */ |
| 135 | Blob repoName; /* Treename of the repository */ |
| 136 | Stmt loop; /* SQL to loop over all files to add */ |
| 137 | int (*xCmp)(const char*,const char*); |
| 138 | |
| 139 | if( !file_tree_name(g.zRepositoryName, &repoName, 0) ){ |
| 140 | blob_zero(&repoName); |
| 141 | zRepo = ""; |
| 142 | }else{ |
| 143 | zRepo = blob_str(&repoName); |
| 144 | } |
| 145 | if( caseSensitive ){ |
| 146 | xCmp = fossil_strcmp; |
| 147 | }else{ |
| 148 | xCmp = fossil_stricmp; |
| 149 | db_multi_exec( |
| 150 | "CREATE INDEX IF NOT EXISTS vfile_nocase" |
| 151 | " ON vfile(pathname COLLATE nocase)" |
| 152 | ); |
| 153 | } |
| 154 | db_prepare(&loop, "SELECT x FROM sfile ORDER BY x"); |
| 155 | while( db_step(&loop)==SQLITE_ROW ){ |
| 156 | const char *zToAdd = db_column_text(&loop, 0); |
| 157 | if( fossil_strcmp(zToAdd, zRepo)==0 ) continue; |
| 158 | for(i=0; (zReserved = fossil_reserved_name(i))!=0; i++){ |
| 159 | if( xCmp(zToAdd, zReserved)==0 ) break; |
| 160 | } |
| 161 | if( zReserved ) continue; |
| 162 | nAdd += add_one_file(zToAdd, vid, caseSensitive); |
| 163 | } |
| 164 | db_finalize(&loop); |
| 165 | blob_reset(&repoName); |
| 166 | return nAdd; |
| 167 | } |
| @@ -180,14 +190,17 @@ | |
| 190 | int i; /* Loop counter */ |
| 191 | int vid; /* Currently checked out version */ |
| 192 | int nRoot; /* Full path characters in g.zLocalRoot */ |
| 193 | const char *zIgnoreFlag; /* The --ignore option or ignore-glob setting */ |
| 194 | Glob *pIgnore; /* Ignore everything matching this glob pattern */ |
| 195 | int caseSensitive; /* True if filenames are case sensitive */ |
| 196 | |
| 197 | zIgnoreFlag = find_option("ignore",0,1); |
| 198 | includeDotFiles = find_option("dotfiles",0,0)!=0; |
| 199 | capture_case_sensitive_option(); |
| 200 | db_must_be_within_tree(); |
| 201 | caseSensitive = filenames_are_case_sensitive(); |
| 202 | if( zIgnoreFlag==0 ){ |
| 203 | zIgnoreFlag = db_get_versionable_setting("ignore-glob", 0); |
| 204 | } |
| 205 | vid = db_lget_int("checkout",0); |
| 206 | if( vid==0 ){ |
| @@ -229,11 +242,11 @@ | |
| 242 | } |
| 243 | blob_reset(&fullName); |
| 244 | } |
| 245 | glob_free(pIgnore); |
| 246 | |
| 247 | add_files_in_sfile(vid, caseSensitive); |
| 248 | db_end_transaction(0); |
| 249 | } |
| 250 | |
| 251 | /* |
| 252 | ** COMMAND: rm |
| @@ -289,10 +302,48 @@ | |
| 302 | "UPDATE vfile SET deleted=1 WHERE pathname IN sfile;" |
| 303 | "DELETE FROM vfile WHERE rid=0 AND deleted;" |
| 304 | ); |
| 305 | db_end_transaction(0); |
| 306 | } |
| 307 | |
| 308 | /* |
| 309 | ** Capture the command-line --case-sensitive option. |
| 310 | */ |
| 311 | static const char *zCaseSensitive = 0; |
| 312 | void capture_case_sensitive_option(void){ |
| 313 | if( zCaseSensitive==0 ){ |
| 314 | zCaseSensitive = find_option("case-sensitive",0,1); |
| 315 | } |
| 316 | } |
| 317 | |
| 318 | /* |
| 319 | ** This routine determines if files should be case-sensitive or not. |
| 320 | ** In other words, this routine determines if two filenames that |
| 321 | ** differ only in case should be considered the same name or not. |
| 322 | ** |
| 323 | ** The case-sensitive setting determines the default value. If |
| 324 | ** the case-sensitive setting is undefined, then case sensitivity |
| 325 | ** defaults on for Mac and Windows and off for all other unix. |
| 326 | ** |
| 327 | ** The --case-sensitive BOOLEAN command-line option overrides any |
| 328 | ** setting. |
| 329 | */ |
| 330 | int filenames_are_case_sensitive(void){ |
| 331 | int caseSensitive; |
| 332 | |
| 333 | if( zCaseSensitive ){ |
| 334 | caseSensitive = is_truth(zCaseSensitive); |
| 335 | }else{ |
| 336 | #if !defined(_WIN32) && !defined(__DARWIN__) && !defined(__APPLE__) |
| 337 | caseSensitive = 1; |
| 338 | #else |
| 339 | caseSensitive = 0; |
| 340 | #endif |
| 341 | caseSensitive = db_get_boolean("case-sensitive",caseSensitive); |
| 342 | } |
| 343 | return caseSensitive; |
| 344 | } |
| 345 | |
| 346 | /* |
| 347 | ** COMMAND: addremove |
| 348 | ** |
| 349 | ** Usage: %fossil addremove ?--dotfiles? ?--ignore GLOBPATTERN? ?--test? |
| @@ -319,27 +370,29 @@ | |
| 370 | ** |
| 371 | ** The --test option shows what would happen without actually doing anything. |
| 372 | ** |
| 373 | ** This command can be used to track third party software. |
| 374 | ** |
| 375 | ** SUMMARY: fossil addremove |
| 376 | ** Options: ?--dotfiles? ?--ignore GLOB? ?--test? ?--case-sensitive BOOL? |
| 377 | */ |
| 378 | void addremove_cmd(void){ |
| 379 | Blob path; |
| 380 | const char *zIgnoreFlag = find_option("ignore",0,1); |
| 381 | int allFlag = find_option("dotfiles",0,0)!=0; |
| 382 | int isTest = find_option("test",0,0)!=0; |
| 383 | int caseSensitive; |
| 384 | int n; |
| 385 | Stmt q; |
| 386 | int vid; |
| 387 | int nAdd = 0; |
| 388 | int nDelete = 0; |
| 389 | Glob *pIgnore; |
| 390 | |
| 391 | capture_case_sensitive_option(); |
| 392 | db_must_be_within_tree(); |
| 393 | caseSensitive = filenames_are_case_sensitive(); |
| 394 | if( zIgnoreFlag==0 ){ |
| 395 | zIgnoreFlag = db_get_versionable_setting("ignore-glob", 0); |
| 396 | } |
| 397 | vid = db_lget_int("checkout",0); |
| 398 | if( vid==0 ){ |
| @@ -358,11 +411,11 @@ | |
| 411 | blob_init(&path, g.zLocalRoot, n-1); |
| 412 | /* now we read the complete file structure into a temp table */ |
| 413 | pIgnore = glob_create(zIgnoreFlag); |
| 414 | vfile_scan(&path, blob_size(&path), allFlag, pIgnore); |
| 415 | glob_free(pIgnore); |
| 416 | nAdd = add_files_in_sfile(vid, caseSensitive); |
| 417 | |
| 418 | /* step 2: search for missing files */ |
| 419 | db_prepare(&q, |
| 420 | "SELECT pathname, %Q || pathname, deleted FROM vfile" |
| 421 | " WHERE NOT deleted" |
| 422 |
+1
-1
| --- src/cgi.c | ||
| +++ src/cgi.c | ||
| @@ -295,11 +295,11 @@ | ||
| 295 | 295 | if( blob_size(&extraHeader)>0 ){ |
| 296 | 296 | fprintf(g.httpOut, "%s", blob_buffer(&extraHeader)); |
| 297 | 297 | } |
| 298 | 298 | |
| 299 | 299 | /* Add headers to turn on useful security options in browsers. */ |
| 300 | - fprintf(g.httpOut, "X-Frame-Options: DENY\r\n"); | |
| 300 | + fprintf(g.httpOut, "X-Frame-Options: SAMEORIGIN\r\n"); | |
| 301 | 301 | /* This stops fossil pages appearing in frames or iframes, preventing |
| 302 | 302 | ** click-jacking attacks on supporting browsers. |
| 303 | 303 | ** |
| 304 | 304 | ** Other good headers would be |
| 305 | 305 | ** Strict-Transport-Security: max-age=62208000 |
| 306 | 306 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -295,11 +295,11 @@ | |
| 295 | if( blob_size(&extraHeader)>0 ){ |
| 296 | fprintf(g.httpOut, "%s", blob_buffer(&extraHeader)); |
| 297 | } |
| 298 | |
| 299 | /* Add headers to turn on useful security options in browsers. */ |
| 300 | fprintf(g.httpOut, "X-Frame-Options: DENY\r\n"); |
| 301 | /* This stops fossil pages appearing in frames or iframes, preventing |
| 302 | ** click-jacking attacks on supporting browsers. |
| 303 | ** |
| 304 | ** Other good headers would be |
| 305 | ** Strict-Transport-Security: max-age=62208000 |
| 306 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -295,11 +295,11 @@ | |
| 295 | if( blob_size(&extraHeader)>0 ){ |
| 296 | fprintf(g.httpOut, "%s", blob_buffer(&extraHeader)); |
| 297 | } |
| 298 | |
| 299 | /* Add headers to turn on useful security options in browsers. */ |
| 300 | fprintf(g.httpOut, "X-Frame-Options: SAMEORIGIN\r\n"); |
| 301 | /* This stops fossil pages appearing in frames or iframes, preventing |
| 302 | ** click-jacking attacks on supporting browsers. |
| 303 | ** |
| 304 | ** Other good headers would be |
| 305 | ** Strict-Transport-Security: max-age=62208000 |
| 306 |
M
src/db.c
+12
-2
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -153,13 +153,17 @@ | ||
| 153 | 153 | ** Force a rollback and shutdown the database |
| 154 | 154 | */ |
| 155 | 155 | void db_force_rollback(void){ |
| 156 | 156 | int i; |
| 157 | 157 | static int busy = 0; |
| 158 | + sqlite3_stmt *pStmt = 0; | |
| 158 | 159 | if( busy || g.db==0 ) return; |
| 159 | 160 | busy = 1; |
| 160 | 161 | undo_rollback(); |
| 162 | + while( (pStmt = sqlite3_next_stmt(g.db,pStmt))!=0 ){ | |
| 163 | + sqlite3_reset(pStmt); | |
| 164 | + } | |
| 161 | 165 | while( pAllStmt ){ |
| 162 | 166 | db_finalize(pAllStmt); |
| 163 | 167 | } |
| 164 | 168 | if( nBegin ){ |
| 165 | 169 | sqlite3_exec(g.db, "ROLLBACK", 0, 0, 0); |
| @@ -1366,19 +1370,19 @@ | ||
| 1366 | 1370 | */ |
| 1367 | 1371 | int is_truth(const char *zVal){ |
| 1368 | 1372 | static const char *azOn[] = { "on", "yes", "true", "1" }; |
| 1369 | 1373 | int i; |
| 1370 | 1374 | for(i=0; i<sizeof(azOn)/sizeof(azOn[0]); i++){ |
| 1371 | - if( fossil_strcmp(zVal,azOn[i])==0 ) return 1; | |
| 1375 | + if( fossil_stricmp(zVal,azOn[i])==0 ) return 1; | |
| 1372 | 1376 | } |
| 1373 | 1377 | return 0; |
| 1374 | 1378 | } |
| 1375 | 1379 | int is_false(const char *zVal){ |
| 1376 | 1380 | static const char *azOff[] = { "off", "no", "false", "0" }; |
| 1377 | 1381 | int i; |
| 1378 | 1382 | for(i=0; i<sizeof(azOff)/sizeof(azOff[0]); i++){ |
| 1379 | - if( fossil_strcmp(zVal,azOff[i])==0 ) return 1; | |
| 1383 | + if( fossil_stricmp(zVal,azOff[i])==0 ) return 1; | |
| 1380 | 1384 | } |
| 1381 | 1385 | return 0; |
| 1382 | 1386 | } |
| 1383 | 1387 | |
| 1384 | 1388 | /* |
| @@ -1723,10 +1727,11 @@ | ||
| 1723 | 1727 | { "auto-captcha", "autocaptcha", 0, 0, "on" }, |
| 1724 | 1728 | { "auto-shun", 0, 0, 0, "on" }, |
| 1725 | 1729 | { "autosync", 0, 0, 0, "on" }, |
| 1726 | 1730 | { "binary-glob", 0, 32, 1, "" }, |
| 1727 | 1731 | { "clearsign", 0, 0, 0, "off" }, |
| 1732 | + { "case-sensitive",0, 0, 0, "on" }, | |
| 1728 | 1733 | { "crnl-glob", 0, 16, 1, "" }, |
| 1729 | 1734 | { "default-perms", 0, 16, 0, "u" }, |
| 1730 | 1735 | { "diff-command", 0, 16, 0, "" }, |
| 1731 | 1736 | { "dont-push", 0, 0, 0, "off" }, |
| 1732 | 1737 | { "editor", 0, 16, 0, "" }, |
| @@ -1786,10 +1791,15 @@ | ||
| 1786 | 1791 | ** Default: on |
| 1787 | 1792 | ** |
| 1788 | 1793 | ** binary-glob The VALUE is a comma or newline-separated list of |
| 1789 | 1794 | ** (versionable) GLOB patterns that should be treated as binary files |
| 1790 | 1795 | ** for merging purposes. Example: *.xml |
| 1796 | +** | |
| 1797 | +** case-sensitive If TRUE, the files whose names differ only in case | |
| 1798 | +** care considered distinct. If FALSE files whose names | |
| 1799 | +** differ only in case are the same file. Defaults to | |
| 1800 | +** TRUE for unix and FALSE for windows and mac. | |
| 1791 | 1801 | ** |
| 1792 | 1802 | ** clearsign When enabled, fossil will attempt to sign all commits |
| 1793 | 1803 | ** with gpg. When disabled (the default), commits will |
| 1794 | 1804 | ** be unsigned. Default: off |
| 1795 | 1805 | ** |
| 1796 | 1806 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -153,13 +153,17 @@ | |
| 153 | ** Force a rollback and shutdown the database |
| 154 | */ |
| 155 | void db_force_rollback(void){ |
| 156 | int i; |
| 157 | static int busy = 0; |
| 158 | if( busy || g.db==0 ) return; |
| 159 | busy = 1; |
| 160 | undo_rollback(); |
| 161 | while( pAllStmt ){ |
| 162 | db_finalize(pAllStmt); |
| 163 | } |
| 164 | if( nBegin ){ |
| 165 | sqlite3_exec(g.db, "ROLLBACK", 0, 0, 0); |
| @@ -1366,19 +1370,19 @@ | |
| 1366 | */ |
| 1367 | int is_truth(const char *zVal){ |
| 1368 | static const char *azOn[] = { "on", "yes", "true", "1" }; |
| 1369 | int i; |
| 1370 | for(i=0; i<sizeof(azOn)/sizeof(azOn[0]); i++){ |
| 1371 | if( fossil_strcmp(zVal,azOn[i])==0 ) return 1; |
| 1372 | } |
| 1373 | return 0; |
| 1374 | } |
| 1375 | int is_false(const char *zVal){ |
| 1376 | static const char *azOff[] = { "off", "no", "false", "0" }; |
| 1377 | int i; |
| 1378 | for(i=0; i<sizeof(azOff)/sizeof(azOff[0]); i++){ |
| 1379 | if( fossil_strcmp(zVal,azOff[i])==0 ) return 1; |
| 1380 | } |
| 1381 | return 0; |
| 1382 | } |
| 1383 | |
| 1384 | /* |
| @@ -1723,10 +1727,11 @@ | |
| 1723 | { "auto-captcha", "autocaptcha", 0, 0, "on" }, |
| 1724 | { "auto-shun", 0, 0, 0, "on" }, |
| 1725 | { "autosync", 0, 0, 0, "on" }, |
| 1726 | { "binary-glob", 0, 32, 1, "" }, |
| 1727 | { "clearsign", 0, 0, 0, "off" }, |
| 1728 | { "crnl-glob", 0, 16, 1, "" }, |
| 1729 | { "default-perms", 0, 16, 0, "u" }, |
| 1730 | { "diff-command", 0, 16, 0, "" }, |
| 1731 | { "dont-push", 0, 0, 0, "off" }, |
| 1732 | { "editor", 0, 16, 0, "" }, |
| @@ -1786,10 +1791,15 @@ | |
| 1786 | ** Default: on |
| 1787 | ** |
| 1788 | ** binary-glob The VALUE is a comma or newline-separated list of |
| 1789 | ** (versionable) GLOB patterns that should be treated as binary files |
| 1790 | ** for merging purposes. Example: *.xml |
| 1791 | ** |
| 1792 | ** clearsign When enabled, fossil will attempt to sign all commits |
| 1793 | ** with gpg. When disabled (the default), commits will |
| 1794 | ** be unsigned. Default: off |
| 1795 | ** |
| 1796 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -153,13 +153,17 @@ | |
| 153 | ** Force a rollback and shutdown the database |
| 154 | */ |
| 155 | void db_force_rollback(void){ |
| 156 | int i; |
| 157 | static int busy = 0; |
| 158 | sqlite3_stmt *pStmt = 0; |
| 159 | if( busy || g.db==0 ) return; |
| 160 | busy = 1; |
| 161 | undo_rollback(); |
| 162 | while( (pStmt = sqlite3_next_stmt(g.db,pStmt))!=0 ){ |
| 163 | sqlite3_reset(pStmt); |
| 164 | } |
| 165 | while( pAllStmt ){ |
| 166 | db_finalize(pAllStmt); |
| 167 | } |
| 168 | if( nBegin ){ |
| 169 | sqlite3_exec(g.db, "ROLLBACK", 0, 0, 0); |
| @@ -1366,19 +1370,19 @@ | |
| 1370 | */ |
| 1371 | int is_truth(const char *zVal){ |
| 1372 | static const char *azOn[] = { "on", "yes", "true", "1" }; |
| 1373 | int i; |
| 1374 | for(i=0; i<sizeof(azOn)/sizeof(azOn[0]); i++){ |
| 1375 | if( fossil_stricmp(zVal,azOn[i])==0 ) return 1; |
| 1376 | } |
| 1377 | return 0; |
| 1378 | } |
| 1379 | int is_false(const char *zVal){ |
| 1380 | static const char *azOff[] = { "off", "no", "false", "0" }; |
| 1381 | int i; |
| 1382 | for(i=0; i<sizeof(azOff)/sizeof(azOff[0]); i++){ |
| 1383 | if( fossil_stricmp(zVal,azOff[i])==0 ) return 1; |
| 1384 | } |
| 1385 | return 0; |
| 1386 | } |
| 1387 | |
| 1388 | /* |
| @@ -1723,10 +1727,11 @@ | |
| 1727 | { "auto-captcha", "autocaptcha", 0, 0, "on" }, |
| 1728 | { "auto-shun", 0, 0, 0, "on" }, |
| 1729 | { "autosync", 0, 0, 0, "on" }, |
| 1730 | { "binary-glob", 0, 32, 1, "" }, |
| 1731 | { "clearsign", 0, 0, 0, "off" }, |
| 1732 | { "case-sensitive",0, 0, 0, "on" }, |
| 1733 | { "crnl-glob", 0, 16, 1, "" }, |
| 1734 | { "default-perms", 0, 16, 0, "u" }, |
| 1735 | { "diff-command", 0, 16, 0, "" }, |
| 1736 | { "dont-push", 0, 0, 0, "off" }, |
| 1737 | { "editor", 0, 16, 0, "" }, |
| @@ -1786,10 +1791,15 @@ | |
| 1791 | ** Default: on |
| 1792 | ** |
| 1793 | ** binary-glob The VALUE is a comma or newline-separated list of |
| 1794 | ** (versionable) GLOB patterns that should be treated as binary files |
| 1795 | ** for merging purposes. Example: *.xml |
| 1796 | ** |
| 1797 | ** case-sensitive If TRUE, the files whose names differ only in case |
| 1798 | ** care considered distinct. If FALSE files whose names |
| 1799 | ** differ only in case are the same file. Defaults to |
| 1800 | ** TRUE for unix and FALSE for windows and mac. |
| 1801 | ** |
| 1802 | ** clearsign When enabled, fossil will attempt to sign all commits |
| 1803 | ** with gpg. When disabled (the default), commits will |
| 1804 | ** be unsigned. Default: off |
| 1805 | ** |
| 1806 |
M
src/db.c
+12
-2
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -153,13 +153,17 @@ | ||
| 153 | 153 | ** Force a rollback and shutdown the database |
| 154 | 154 | */ |
| 155 | 155 | void db_force_rollback(void){ |
| 156 | 156 | int i; |
| 157 | 157 | static int busy = 0; |
| 158 | + sqlite3_stmt *pStmt = 0; | |
| 158 | 159 | if( busy || g.db==0 ) return; |
| 159 | 160 | busy = 1; |
| 160 | 161 | undo_rollback(); |
| 162 | + while( (pStmt = sqlite3_next_stmt(g.db,pStmt))!=0 ){ | |
| 163 | + sqlite3_reset(pStmt); | |
| 164 | + } | |
| 161 | 165 | while( pAllStmt ){ |
| 162 | 166 | db_finalize(pAllStmt); |
| 163 | 167 | } |
| 164 | 168 | if( nBegin ){ |
| 165 | 169 | sqlite3_exec(g.db, "ROLLBACK", 0, 0, 0); |
| @@ -1366,19 +1370,19 @@ | ||
| 1366 | 1370 | */ |
| 1367 | 1371 | int is_truth(const char *zVal){ |
| 1368 | 1372 | static const char *azOn[] = { "on", "yes", "true", "1" }; |
| 1369 | 1373 | int i; |
| 1370 | 1374 | for(i=0; i<sizeof(azOn)/sizeof(azOn[0]); i++){ |
| 1371 | - if( fossil_strcmp(zVal,azOn[i])==0 ) return 1; | |
| 1375 | + if( fossil_stricmp(zVal,azOn[i])==0 ) return 1; | |
| 1372 | 1376 | } |
| 1373 | 1377 | return 0; |
| 1374 | 1378 | } |
| 1375 | 1379 | int is_false(const char *zVal){ |
| 1376 | 1380 | static const char *azOff[] = { "off", "no", "false", "0" }; |
| 1377 | 1381 | int i; |
| 1378 | 1382 | for(i=0; i<sizeof(azOff)/sizeof(azOff[0]); i++){ |
| 1379 | - if( fossil_strcmp(zVal,azOff[i])==0 ) return 1; | |
| 1383 | + if( fossil_stricmp(zVal,azOff[i])==0 ) return 1; | |
| 1380 | 1384 | } |
| 1381 | 1385 | return 0; |
| 1382 | 1386 | } |
| 1383 | 1387 | |
| 1384 | 1388 | /* |
| @@ -1723,10 +1727,11 @@ | ||
| 1723 | 1727 | { "auto-captcha", "autocaptcha", 0, 0, "on" }, |
| 1724 | 1728 | { "auto-shun", 0, 0, 0, "on" }, |
| 1725 | 1729 | { "autosync", 0, 0, 0, "on" }, |
| 1726 | 1730 | { "binary-glob", 0, 32, 1, "" }, |
| 1727 | 1731 | { "clearsign", 0, 0, 0, "off" }, |
| 1732 | + { "case-sensitive",0, 0, 0, "on" }, | |
| 1728 | 1733 | { "crnl-glob", 0, 16, 1, "" }, |
| 1729 | 1734 | { "default-perms", 0, 16, 0, "u" }, |
| 1730 | 1735 | { "diff-command", 0, 16, 0, "" }, |
| 1731 | 1736 | { "dont-push", 0, 0, 0, "off" }, |
| 1732 | 1737 | { "editor", 0, 16, 0, "" }, |
| @@ -1786,10 +1791,15 @@ | ||
| 1786 | 1791 | ** Default: on |
| 1787 | 1792 | ** |
| 1788 | 1793 | ** binary-glob The VALUE is a comma or newline-separated list of |
| 1789 | 1794 | ** (versionable) GLOB patterns that should be treated as binary files |
| 1790 | 1795 | ** for merging purposes. Example: *.xml |
| 1796 | +** | |
| 1797 | +** case-sensitive If TRUE, the files whose names differ only in case | |
| 1798 | +** care considered distinct. If FALSE files whose names | |
| 1799 | +** differ only in case are the same file. Defaults to | |
| 1800 | +** TRUE for unix and FALSE for windows and mac. | |
| 1791 | 1801 | ** |
| 1792 | 1802 | ** clearsign When enabled, fossil will attempt to sign all commits |
| 1793 | 1803 | ** with gpg. When disabled (the default), commits will |
| 1794 | 1804 | ** be unsigned. Default: off |
| 1795 | 1805 | ** |
| 1796 | 1806 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -153,13 +153,17 @@ | |
| 153 | ** Force a rollback and shutdown the database |
| 154 | */ |
| 155 | void db_force_rollback(void){ |
| 156 | int i; |
| 157 | static int busy = 0; |
| 158 | if( busy || g.db==0 ) return; |
| 159 | busy = 1; |
| 160 | undo_rollback(); |
| 161 | while( pAllStmt ){ |
| 162 | db_finalize(pAllStmt); |
| 163 | } |
| 164 | if( nBegin ){ |
| 165 | sqlite3_exec(g.db, "ROLLBACK", 0, 0, 0); |
| @@ -1366,19 +1370,19 @@ | |
| 1366 | */ |
| 1367 | int is_truth(const char *zVal){ |
| 1368 | static const char *azOn[] = { "on", "yes", "true", "1" }; |
| 1369 | int i; |
| 1370 | for(i=0; i<sizeof(azOn)/sizeof(azOn[0]); i++){ |
| 1371 | if( fossil_strcmp(zVal,azOn[i])==0 ) return 1; |
| 1372 | } |
| 1373 | return 0; |
| 1374 | } |
| 1375 | int is_false(const char *zVal){ |
| 1376 | static const char *azOff[] = { "off", "no", "false", "0" }; |
| 1377 | int i; |
| 1378 | for(i=0; i<sizeof(azOff)/sizeof(azOff[0]); i++){ |
| 1379 | if( fossil_strcmp(zVal,azOff[i])==0 ) return 1; |
| 1380 | } |
| 1381 | return 0; |
| 1382 | } |
| 1383 | |
| 1384 | /* |
| @@ -1723,10 +1727,11 @@ | |
| 1723 | { "auto-captcha", "autocaptcha", 0, 0, "on" }, |
| 1724 | { "auto-shun", 0, 0, 0, "on" }, |
| 1725 | { "autosync", 0, 0, 0, "on" }, |
| 1726 | { "binary-glob", 0, 32, 1, "" }, |
| 1727 | { "clearsign", 0, 0, 0, "off" }, |
| 1728 | { "crnl-glob", 0, 16, 1, "" }, |
| 1729 | { "default-perms", 0, 16, 0, "u" }, |
| 1730 | { "diff-command", 0, 16, 0, "" }, |
| 1731 | { "dont-push", 0, 0, 0, "off" }, |
| 1732 | { "editor", 0, 16, 0, "" }, |
| @@ -1786,10 +1791,15 @@ | |
| 1786 | ** Default: on |
| 1787 | ** |
| 1788 | ** binary-glob The VALUE is a comma or newline-separated list of |
| 1789 | ** (versionable) GLOB patterns that should be treated as binary files |
| 1790 | ** for merging purposes. Example: *.xml |
| 1791 | ** |
| 1792 | ** clearsign When enabled, fossil will attempt to sign all commits |
| 1793 | ** with gpg. When disabled (the default), commits will |
| 1794 | ** be unsigned. Default: off |
| 1795 | ** |
| 1796 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -153,13 +153,17 @@ | |
| 153 | ** Force a rollback and shutdown the database |
| 154 | */ |
| 155 | void db_force_rollback(void){ |
| 156 | int i; |
| 157 | static int busy = 0; |
| 158 | sqlite3_stmt *pStmt = 0; |
| 159 | if( busy || g.db==0 ) return; |
| 160 | busy = 1; |
| 161 | undo_rollback(); |
| 162 | while( (pStmt = sqlite3_next_stmt(g.db,pStmt))!=0 ){ |
| 163 | sqlite3_reset(pStmt); |
| 164 | } |
| 165 | while( pAllStmt ){ |
| 166 | db_finalize(pAllStmt); |
| 167 | } |
| 168 | if( nBegin ){ |
| 169 | sqlite3_exec(g.db, "ROLLBACK", 0, 0, 0); |
| @@ -1366,19 +1370,19 @@ | |
| 1370 | */ |
| 1371 | int is_truth(const char *zVal){ |
| 1372 | static const char *azOn[] = { "on", "yes", "true", "1" }; |
| 1373 | int i; |
| 1374 | for(i=0; i<sizeof(azOn)/sizeof(azOn[0]); i++){ |
| 1375 | if( fossil_stricmp(zVal,azOn[i])==0 ) return 1; |
| 1376 | } |
| 1377 | return 0; |
| 1378 | } |
| 1379 | int is_false(const char *zVal){ |
| 1380 | static const char *azOff[] = { "off", "no", "false", "0" }; |
| 1381 | int i; |
| 1382 | for(i=0; i<sizeof(azOff)/sizeof(azOff[0]); i++){ |
| 1383 | if( fossil_stricmp(zVal,azOff[i])==0 ) return 1; |
| 1384 | } |
| 1385 | return 0; |
| 1386 | } |
| 1387 | |
| 1388 | /* |
| @@ -1723,10 +1727,11 @@ | |
| 1727 | { "auto-captcha", "autocaptcha", 0, 0, "on" }, |
| 1728 | { "auto-shun", 0, 0, 0, "on" }, |
| 1729 | { "autosync", 0, 0, 0, "on" }, |
| 1730 | { "binary-glob", 0, 32, 1, "" }, |
| 1731 | { "clearsign", 0, 0, 0, "off" }, |
| 1732 | { "case-sensitive",0, 0, 0, "on" }, |
| 1733 | { "crnl-glob", 0, 16, 1, "" }, |
| 1734 | { "default-perms", 0, 16, 0, "u" }, |
| 1735 | { "diff-command", 0, 16, 0, "" }, |
| 1736 | { "dont-push", 0, 0, 0, "off" }, |
| 1737 | { "editor", 0, 16, 0, "" }, |
| @@ -1786,10 +1791,15 @@ | |
| 1791 | ** Default: on |
| 1792 | ** |
| 1793 | ** binary-glob The VALUE is a comma or newline-separated list of |
| 1794 | ** (versionable) GLOB patterns that should be treated as binary files |
| 1795 | ** for merging purposes. Example: *.xml |
| 1796 | ** |
| 1797 | ** case-sensitive If TRUE, the files whose names differ only in case |
| 1798 | ** care considered distinct. If FALSE files whose names |
| 1799 | ** differ only in case are the same file. Defaults to |
| 1800 | ** TRUE for unix and FALSE for windows and mac. |
| 1801 | ** |
| 1802 | ** clearsign When enabled, fossil will attempt to sign all commits |
| 1803 | ** with gpg. When disabled (the default), commits will |
| 1804 | ** be unsigned. Default: off |
| 1805 | ** |
| 1806 |
+10
-2
| --- src/merge.c | ||
| +++ src/merge.c | ||
| @@ -53,10 +53,14 @@ | ||
| 53 | 53 | ** and do not try to merge parallel changes. This |
| 54 | 54 | ** option overrides the "binary-glob" setting. |
| 55 | 55 | ** |
| 56 | 56 | ** --nochange | -n Dryrun: do not actually make any changes; just |
| 57 | 57 | ** show what would have happened. |
| 58 | +** | |
| 59 | +** --case-sensitive BOOL Overwrite the case-sensitive setting. If false, | |
| 60 | +** files whose names differ only in case are taken | |
| 61 | +** to be the same file. | |
| 58 | 62 | */ |
| 59 | 63 | void merge_cmd(void){ |
| 60 | 64 | int vid; /* Current version "V" */ |
| 61 | 65 | int mid; /* Version we are merging from "M" */ |
| 62 | 66 | int pid; /* The pivot version - most recent common ancestor P */ |
| @@ -69,10 +73,11 @@ | ||
| 69 | 73 | int debugFlag; /* True if --debug is present */ |
| 70 | 74 | int nChng; /* Number of file name changes */ |
| 71 | 75 | int *aChng; /* An array of file name changes */ |
| 72 | 76 | int i; /* Loop counter */ |
| 73 | 77 | int nConflict = 0; /* Number of conflicts seen */ |
| 78 | + int caseSensitive; /* True for case-sensitive filenames */ | |
| 74 | 79 | Stmt q; |
| 75 | 80 | |
| 76 | 81 | |
| 77 | 82 | /* Notation: |
| 78 | 83 | ** |
| @@ -87,14 +92,16 @@ | ||
| 87 | 92 | backoutFlag = find_option("backout",0,0)!=0; |
| 88 | 93 | debugFlag = find_option("debug",0,0)!=0; |
| 89 | 94 | zBinGlob = find_option("binary",0,1); |
| 90 | 95 | nochangeFlag = find_option("nochange","n",0)!=0; |
| 91 | 96 | zPivot = find_option("baseline",0,1); |
| 97 | + capture_case_sensitive_option(); | |
| 92 | 98 | if( g.argc!=3 ){ |
| 93 | 99 | usage("VERSION"); |
| 94 | 100 | } |
| 95 | 101 | db_must_be_within_tree(); |
| 102 | + caseSensitive = filenames_are_case_sensitive(); | |
| 96 | 103 | if( zBinGlob==0 ) zBinGlob = db_get_versionable_setting("binary-glob",0); |
| 97 | 104 | vid = db_lget_int("checkout", 0); |
| 98 | 105 | if( vid==0 ){ |
| 99 | 106 | fossil_fatal("nothing is checked out"); |
| 100 | 107 | } |
| @@ -150,11 +157,11 @@ | ||
| 150 | 157 | ** in the current checkout, the pivot, and the version being merged. |
| 151 | 158 | */ |
| 152 | 159 | db_multi_exec( |
| 153 | 160 | "DROP TABLE IF EXISTS fv;" |
| 154 | 161 | "CREATE TEMP TABLE fv(" |
| 155 | - " fn TEXT PRIMARY KEY," /* The filename */ | |
| 162 | + " fn TEXT PRIMARY KEY COLLATE %s," /* The filename */ | |
| 156 | 163 | " idv INTEGER," /* VFILE entry for current version */ |
| 157 | 164 | " idp INTEGER," /* VFILE entry for the pivot */ |
| 158 | 165 | " idm INTEGER," /* VFILE entry for version merging in */ |
| 159 | 166 | " chnged BOOLEAN," /* True if current version has been edited */ |
| 160 | 167 | " ridv INTEGER," /* Record ID for current version */ |
| @@ -161,11 +168,12 @@ | ||
| 161 | 168 | " ridp INTEGER," /* Record ID for pivot */ |
| 162 | 169 | " ridm INTEGER," /* Record ID for merge */ |
| 163 | 170 | " isexe BOOLEAN," /* Execute permission enabled */ |
| 164 | 171 | " fnp TEXT," /* The filename in the pivot */ |
| 165 | 172 | " fnm TEXT" /* the filename in the merged version */ |
| 166 | - ");" | |
| 173 | + ");", | |
| 174 | + caseSensitive ? "binary" : "nocase" | |
| 167 | 175 | ); |
| 168 | 176 | |
| 169 | 177 | /* Add files found in V |
| 170 | 178 | */ |
| 171 | 179 | db_multi_exec( |
| 172 | 180 |
| --- src/merge.c | |
| +++ src/merge.c | |
| @@ -53,10 +53,14 @@ | |
| 53 | ** and do not try to merge parallel changes. This |
| 54 | ** option overrides the "binary-glob" setting. |
| 55 | ** |
| 56 | ** --nochange | -n Dryrun: do not actually make any changes; just |
| 57 | ** show what would have happened. |
| 58 | */ |
| 59 | void merge_cmd(void){ |
| 60 | int vid; /* Current version "V" */ |
| 61 | int mid; /* Version we are merging from "M" */ |
| 62 | int pid; /* The pivot version - most recent common ancestor P */ |
| @@ -69,10 +73,11 @@ | |
| 69 | int debugFlag; /* True if --debug is present */ |
| 70 | int nChng; /* Number of file name changes */ |
| 71 | int *aChng; /* An array of file name changes */ |
| 72 | int i; /* Loop counter */ |
| 73 | int nConflict = 0; /* Number of conflicts seen */ |
| 74 | Stmt q; |
| 75 | |
| 76 | |
| 77 | /* Notation: |
| 78 | ** |
| @@ -87,14 +92,16 @@ | |
| 87 | backoutFlag = find_option("backout",0,0)!=0; |
| 88 | debugFlag = find_option("debug",0,0)!=0; |
| 89 | zBinGlob = find_option("binary",0,1); |
| 90 | nochangeFlag = find_option("nochange","n",0)!=0; |
| 91 | zPivot = find_option("baseline",0,1); |
| 92 | if( g.argc!=3 ){ |
| 93 | usage("VERSION"); |
| 94 | } |
| 95 | db_must_be_within_tree(); |
| 96 | if( zBinGlob==0 ) zBinGlob = db_get_versionable_setting("binary-glob",0); |
| 97 | vid = db_lget_int("checkout", 0); |
| 98 | if( vid==0 ){ |
| 99 | fossil_fatal("nothing is checked out"); |
| 100 | } |
| @@ -150,11 +157,11 @@ | |
| 150 | ** in the current checkout, the pivot, and the version being merged. |
| 151 | */ |
| 152 | db_multi_exec( |
| 153 | "DROP TABLE IF EXISTS fv;" |
| 154 | "CREATE TEMP TABLE fv(" |
| 155 | " fn TEXT PRIMARY KEY," /* The filename */ |
| 156 | " idv INTEGER," /* VFILE entry for current version */ |
| 157 | " idp INTEGER," /* VFILE entry for the pivot */ |
| 158 | " idm INTEGER," /* VFILE entry for version merging in */ |
| 159 | " chnged BOOLEAN," /* True if current version has been edited */ |
| 160 | " ridv INTEGER," /* Record ID for current version */ |
| @@ -161,11 +168,12 @@ | |
| 161 | " ridp INTEGER," /* Record ID for pivot */ |
| 162 | " ridm INTEGER," /* Record ID for merge */ |
| 163 | " isexe BOOLEAN," /* Execute permission enabled */ |
| 164 | " fnp TEXT," /* The filename in the pivot */ |
| 165 | " fnm TEXT" /* the filename in the merged version */ |
| 166 | ");" |
| 167 | ); |
| 168 | |
| 169 | /* Add files found in V |
| 170 | */ |
| 171 | db_multi_exec( |
| 172 |
| --- src/merge.c | |
| +++ src/merge.c | |
| @@ -53,10 +53,14 @@ | |
| 53 | ** and do not try to merge parallel changes. This |
| 54 | ** option overrides the "binary-glob" setting. |
| 55 | ** |
| 56 | ** --nochange | -n Dryrun: do not actually make any changes; just |
| 57 | ** show what would have happened. |
| 58 | ** |
| 59 | ** --case-sensitive BOOL Overwrite the case-sensitive setting. If false, |
| 60 | ** files whose names differ only in case are taken |
| 61 | ** to be the same file. |
| 62 | */ |
| 63 | void merge_cmd(void){ |
| 64 | int vid; /* Current version "V" */ |
| 65 | int mid; /* Version we are merging from "M" */ |
| 66 | int pid; /* The pivot version - most recent common ancestor P */ |
| @@ -69,10 +73,11 @@ | |
| 73 | int debugFlag; /* True if --debug is present */ |
| 74 | int nChng; /* Number of file name changes */ |
| 75 | int *aChng; /* An array of file name changes */ |
| 76 | int i; /* Loop counter */ |
| 77 | int nConflict = 0; /* Number of conflicts seen */ |
| 78 | int caseSensitive; /* True for case-sensitive filenames */ |
| 79 | Stmt q; |
| 80 | |
| 81 | |
| 82 | /* Notation: |
| 83 | ** |
| @@ -87,14 +92,16 @@ | |
| 92 | backoutFlag = find_option("backout",0,0)!=0; |
| 93 | debugFlag = find_option("debug",0,0)!=0; |
| 94 | zBinGlob = find_option("binary",0,1); |
| 95 | nochangeFlag = find_option("nochange","n",0)!=0; |
| 96 | zPivot = find_option("baseline",0,1); |
| 97 | capture_case_sensitive_option(); |
| 98 | if( g.argc!=3 ){ |
| 99 | usage("VERSION"); |
| 100 | } |
| 101 | db_must_be_within_tree(); |
| 102 | caseSensitive = filenames_are_case_sensitive(); |
| 103 | if( zBinGlob==0 ) zBinGlob = db_get_versionable_setting("binary-glob",0); |
| 104 | vid = db_lget_int("checkout", 0); |
| 105 | if( vid==0 ){ |
| 106 | fossil_fatal("nothing is checked out"); |
| 107 | } |
| @@ -150,11 +157,11 @@ | |
| 157 | ** in the current checkout, the pivot, and the version being merged. |
| 158 | */ |
| 159 | db_multi_exec( |
| 160 | "DROP TABLE IF EXISTS fv;" |
| 161 | "CREATE TEMP TABLE fv(" |
| 162 | " fn TEXT PRIMARY KEY COLLATE %s," /* The filename */ |
| 163 | " idv INTEGER," /* VFILE entry for current version */ |
| 164 | " idp INTEGER," /* VFILE entry for the pivot */ |
| 165 | " idm INTEGER," /* VFILE entry for version merging in */ |
| 166 | " chnged BOOLEAN," /* True if current version has been edited */ |
| 167 | " ridv INTEGER," /* Record ID for current version */ |
| @@ -161,11 +168,12 @@ | |
| 168 | " ridp INTEGER," /* Record ID for pivot */ |
| 169 | " ridm INTEGER," /* Record ID for merge */ |
| 170 | " isexe BOOLEAN," /* Execute permission enabled */ |
| 171 | " fnp TEXT," /* The filename in the pivot */ |
| 172 | " fnm TEXT" /* the filename in the merged version */ |
| 173 | ");", |
| 174 | caseSensitive ? "binary" : "nocase" |
| 175 | ); |
| 176 | |
| 177 | /* Add files found in V |
| 178 | */ |
| 179 | db_multi_exec( |
| 180 |
+10
-2
| --- src/merge.c | ||
| +++ src/merge.c | ||
| @@ -53,10 +53,14 @@ | ||
| 53 | 53 | ** and do not try to merge parallel changes. This |
| 54 | 54 | ** option overrides the "binary-glob" setting. |
| 55 | 55 | ** |
| 56 | 56 | ** --nochange | -n Dryrun: do not actually make any changes; just |
| 57 | 57 | ** show what would have happened. |
| 58 | +** | |
| 59 | +** --case-sensitive BOOL Overwrite the case-sensitive setting. If false, | |
| 60 | +** files whose names differ only in case are taken | |
| 61 | +** to be the same file. | |
| 58 | 62 | */ |
| 59 | 63 | void merge_cmd(void){ |
| 60 | 64 | int vid; /* Current version "V" */ |
| 61 | 65 | int mid; /* Version we are merging from "M" */ |
| 62 | 66 | int pid; /* The pivot version - most recent common ancestor P */ |
| @@ -69,10 +73,11 @@ | ||
| 69 | 73 | int debugFlag; /* True if --debug is present */ |
| 70 | 74 | int nChng; /* Number of file name changes */ |
| 71 | 75 | int *aChng; /* An array of file name changes */ |
| 72 | 76 | int i; /* Loop counter */ |
| 73 | 77 | int nConflict = 0; /* Number of conflicts seen */ |
| 78 | + int caseSensitive; /* True for case-sensitive filenames */ | |
| 74 | 79 | Stmt q; |
| 75 | 80 | |
| 76 | 81 | |
| 77 | 82 | /* Notation: |
| 78 | 83 | ** |
| @@ -87,14 +92,16 @@ | ||
| 87 | 92 | backoutFlag = find_option("backout",0,0)!=0; |
| 88 | 93 | debugFlag = find_option("debug",0,0)!=0; |
| 89 | 94 | zBinGlob = find_option("binary",0,1); |
| 90 | 95 | nochangeFlag = find_option("nochange","n",0)!=0; |
| 91 | 96 | zPivot = find_option("baseline",0,1); |
| 97 | + capture_case_sensitive_option(); | |
| 92 | 98 | if( g.argc!=3 ){ |
| 93 | 99 | usage("VERSION"); |
| 94 | 100 | } |
| 95 | 101 | db_must_be_within_tree(); |
| 102 | + caseSensitive = filenames_are_case_sensitive(); | |
| 96 | 103 | if( zBinGlob==0 ) zBinGlob = db_get_versionable_setting("binary-glob",0); |
| 97 | 104 | vid = db_lget_int("checkout", 0); |
| 98 | 105 | if( vid==0 ){ |
| 99 | 106 | fossil_fatal("nothing is checked out"); |
| 100 | 107 | } |
| @@ -150,11 +157,11 @@ | ||
| 150 | 157 | ** in the current checkout, the pivot, and the version being merged. |
| 151 | 158 | */ |
| 152 | 159 | db_multi_exec( |
| 153 | 160 | "DROP TABLE IF EXISTS fv;" |
| 154 | 161 | "CREATE TEMP TABLE fv(" |
| 155 | - " fn TEXT PRIMARY KEY," /* The filename */ | |
| 162 | + " fn TEXT PRIMARY KEY COLLATE %s," /* The filename */ | |
| 156 | 163 | " idv INTEGER," /* VFILE entry for current version */ |
| 157 | 164 | " idp INTEGER," /* VFILE entry for the pivot */ |
| 158 | 165 | " idm INTEGER," /* VFILE entry for version merging in */ |
| 159 | 166 | " chnged BOOLEAN," /* True if current version has been edited */ |
| 160 | 167 | " ridv INTEGER," /* Record ID for current version */ |
| @@ -161,11 +168,12 @@ | ||
| 161 | 168 | " ridp INTEGER," /* Record ID for pivot */ |
| 162 | 169 | " ridm INTEGER," /* Record ID for merge */ |
| 163 | 170 | " isexe BOOLEAN," /* Execute permission enabled */ |
| 164 | 171 | " fnp TEXT," /* The filename in the pivot */ |
| 165 | 172 | " fnm TEXT" /* the filename in the merged version */ |
| 166 | - ");" | |
| 173 | + ");", | |
| 174 | + caseSensitive ? "binary" : "nocase" | |
| 167 | 175 | ); |
| 168 | 176 | |
| 169 | 177 | /* Add files found in V |
| 170 | 178 | */ |
| 171 | 179 | db_multi_exec( |
| 172 | 180 |
| --- src/merge.c | |
| +++ src/merge.c | |
| @@ -53,10 +53,14 @@ | |
| 53 | ** and do not try to merge parallel changes. This |
| 54 | ** option overrides the "binary-glob" setting. |
| 55 | ** |
| 56 | ** --nochange | -n Dryrun: do not actually make any changes; just |
| 57 | ** show what would have happened. |
| 58 | */ |
| 59 | void merge_cmd(void){ |
| 60 | int vid; /* Current version "V" */ |
| 61 | int mid; /* Version we are merging from "M" */ |
| 62 | int pid; /* The pivot version - most recent common ancestor P */ |
| @@ -69,10 +73,11 @@ | |
| 69 | int debugFlag; /* True if --debug is present */ |
| 70 | int nChng; /* Number of file name changes */ |
| 71 | int *aChng; /* An array of file name changes */ |
| 72 | int i; /* Loop counter */ |
| 73 | int nConflict = 0; /* Number of conflicts seen */ |
| 74 | Stmt q; |
| 75 | |
| 76 | |
| 77 | /* Notation: |
| 78 | ** |
| @@ -87,14 +92,16 @@ | |
| 87 | backoutFlag = find_option("backout",0,0)!=0; |
| 88 | debugFlag = find_option("debug",0,0)!=0; |
| 89 | zBinGlob = find_option("binary",0,1); |
| 90 | nochangeFlag = find_option("nochange","n",0)!=0; |
| 91 | zPivot = find_option("baseline",0,1); |
| 92 | if( g.argc!=3 ){ |
| 93 | usage("VERSION"); |
| 94 | } |
| 95 | db_must_be_within_tree(); |
| 96 | if( zBinGlob==0 ) zBinGlob = db_get_versionable_setting("binary-glob",0); |
| 97 | vid = db_lget_int("checkout", 0); |
| 98 | if( vid==0 ){ |
| 99 | fossil_fatal("nothing is checked out"); |
| 100 | } |
| @@ -150,11 +157,11 @@ | |
| 150 | ** in the current checkout, the pivot, and the version being merged. |
| 151 | */ |
| 152 | db_multi_exec( |
| 153 | "DROP TABLE IF EXISTS fv;" |
| 154 | "CREATE TEMP TABLE fv(" |
| 155 | " fn TEXT PRIMARY KEY," /* The filename */ |
| 156 | " idv INTEGER," /* VFILE entry for current version */ |
| 157 | " idp INTEGER," /* VFILE entry for the pivot */ |
| 158 | " idm INTEGER," /* VFILE entry for version merging in */ |
| 159 | " chnged BOOLEAN," /* True if current version has been edited */ |
| 160 | " ridv INTEGER," /* Record ID for current version */ |
| @@ -161,11 +168,12 @@ | |
| 161 | " ridp INTEGER," /* Record ID for pivot */ |
| 162 | " ridm INTEGER," /* Record ID for merge */ |
| 163 | " isexe BOOLEAN," /* Execute permission enabled */ |
| 164 | " fnp TEXT," /* The filename in the pivot */ |
| 165 | " fnm TEXT" /* the filename in the merged version */ |
| 166 | ");" |
| 167 | ); |
| 168 | |
| 169 | /* Add files found in V |
| 170 | */ |
| 171 | db_multi_exec( |
| 172 |
| --- src/merge.c | |
| +++ src/merge.c | |
| @@ -53,10 +53,14 @@ | |
| 53 | ** and do not try to merge parallel changes. This |
| 54 | ** option overrides the "binary-glob" setting. |
| 55 | ** |
| 56 | ** --nochange | -n Dryrun: do not actually make any changes; just |
| 57 | ** show what would have happened. |
| 58 | ** |
| 59 | ** --case-sensitive BOOL Overwrite the case-sensitive setting. If false, |
| 60 | ** files whose names differ only in case are taken |
| 61 | ** to be the same file. |
| 62 | */ |
| 63 | void merge_cmd(void){ |
| 64 | int vid; /* Current version "V" */ |
| 65 | int mid; /* Version we are merging from "M" */ |
| 66 | int pid; /* The pivot version - most recent common ancestor P */ |
| @@ -69,10 +73,11 @@ | |
| 73 | int debugFlag; /* True if --debug is present */ |
| 74 | int nChng; /* Number of file name changes */ |
| 75 | int *aChng; /* An array of file name changes */ |
| 76 | int i; /* Loop counter */ |
| 77 | int nConflict = 0; /* Number of conflicts seen */ |
| 78 | int caseSensitive; /* True for case-sensitive filenames */ |
| 79 | Stmt q; |
| 80 | |
| 81 | |
| 82 | /* Notation: |
| 83 | ** |
| @@ -87,14 +92,16 @@ | |
| 92 | backoutFlag = find_option("backout",0,0)!=0; |
| 93 | debugFlag = find_option("debug",0,0)!=0; |
| 94 | zBinGlob = find_option("binary",0,1); |
| 95 | nochangeFlag = find_option("nochange","n",0)!=0; |
| 96 | zPivot = find_option("baseline",0,1); |
| 97 | capture_case_sensitive_option(); |
| 98 | if( g.argc!=3 ){ |
| 99 | usage("VERSION"); |
| 100 | } |
| 101 | db_must_be_within_tree(); |
| 102 | caseSensitive = filenames_are_case_sensitive(); |
| 103 | if( zBinGlob==0 ) zBinGlob = db_get_versionable_setting("binary-glob",0); |
| 104 | vid = db_lget_int("checkout", 0); |
| 105 | if( vid==0 ){ |
| 106 | fossil_fatal("nothing is checked out"); |
| 107 | } |
| @@ -150,11 +157,11 @@ | |
| 157 | ** in the current checkout, the pivot, and the version being merged. |
| 158 | */ |
| 159 | db_multi_exec( |
| 160 | "DROP TABLE IF EXISTS fv;" |
| 161 | "CREATE TEMP TABLE fv(" |
| 162 | " fn TEXT PRIMARY KEY COLLATE %s," /* The filename */ |
| 163 | " idv INTEGER," /* VFILE entry for current version */ |
| 164 | " idp INTEGER," /* VFILE entry for the pivot */ |
| 165 | " idm INTEGER," /* VFILE entry for version merging in */ |
| 166 | " chnged BOOLEAN," /* True if current version has been edited */ |
| 167 | " ridv INTEGER," /* Record ID for current version */ |
| @@ -161,11 +168,12 @@ | |
| 168 | " ridp INTEGER," /* Record ID for pivot */ |
| 169 | " ridm INTEGER," /* Record ID for merge */ |
| 170 | " isexe BOOLEAN," /* Execute permission enabled */ |
| 171 | " fnp TEXT," /* The filename in the pivot */ |
| 172 | " fnm TEXT" /* the filename in the merged version */ |
| 173 | ");", |
| 174 | caseSensitive ? "binary" : "nocase" |
| 175 | ); |
| 176 | |
| 177 | /* Add files found in V |
| 178 | */ |
| 179 | db_multi_exec( |
| 180 |
+7
-5
| --- src/tar.c | ||
| +++ src/tar.c | ||
| @@ -201,11 +201,10 @@ | ||
| 201 | 201 | int split; |
| 202 | 202 | |
| 203 | 203 | /* if this is a Pax Interchange header prepend "PaxHeader/" |
| 204 | 204 | ** so we can tell files apart from metadata */ |
| 205 | 205 | if( bHeader ){ |
| 206 | - int n; | |
| 207 | 206 | blob_reset(&tball.pax); |
| 208 | 207 | blob_appendf(&tball.pax, "PaxHeader/%*.*s", nName, nName, zName); |
| 209 | 208 | zName = blob_buffer(&tball.pax); |
| 210 | 209 | nName = blob_size(&tball.pax); |
| 211 | 210 | } |
| @@ -288,15 +287,17 @@ | ||
| 288 | 287 | /* set mode and modification time */ |
| 289 | 288 | sqlite3_snprintf(8, (char*)&tball.aHdr[100], "%07o", iMode); |
| 290 | 289 | sqlite3_snprintf(12, (char*)&tball.aHdr[136], "%011o", mTime); |
| 291 | 290 | |
| 292 | 291 | /* see if we need to output a Pax Interchange Header */ |
| 293 | - if( !is_iso646_name(zName, nName) || | |
| 294 | - !tar_split_path(zName, nName, tball.aHdr, &tball.aHdr[345]) ){ | |
| 292 | + if( !is_iso646_name(zName, nName) | |
| 293 | + || !tar_split_path(zName, nName, (char*)tball.aHdr, (char*)&tball.aHdr[345]) | |
| 294 | + ){ | |
| 295 | 295 | int lastPage; |
| 296 | 296 | /* add a file name for interoperability with older programs */ |
| 297 | - approximate_split_path(zName, nName, tball.aHdr, &tball.aHdr[345], 1); | |
| 297 | + approximate_split_path(zName, nName, (char*)tball.aHdr, | |
| 298 | + (char*)&tball.aHdr[345], 1); | |
| 298 | 299 | |
| 299 | 300 | /* generate the Pax Interchange path header */ |
| 300 | 301 | blob_reset(&tball.pax); |
| 301 | 302 | add_pax_header("path", zName, nName); |
| 302 | 303 | |
| @@ -311,11 +312,12 @@ | ||
| 311 | 312 | if( lastPage!=0 ){ |
| 312 | 313 | gzip_step(tball.zSpaces, 512 - lastPage); |
| 313 | 314 | } |
| 314 | 315 | |
| 315 | 316 | /* generate an approximate path for the regular header */ |
| 316 | - approximate_split_path(zName, nName, tball.aHdr, &tball.aHdr[345], 0); | |
| 317 | + approximate_split_path(zName, nName, (char*)tball.aHdr, | |
| 318 | + (char*)&tball.aHdr[345], 0); | |
| 317 | 319 | } |
| 318 | 320 | /* set the size */ |
| 319 | 321 | sqlite3_snprintf(12, (char*)&tball.aHdr[124], "%011o", iSize); |
| 320 | 322 | |
| 321 | 323 | /* write the regular header */ |
| 322 | 324 |
| --- src/tar.c | |
| +++ src/tar.c | |
| @@ -201,11 +201,10 @@ | |
| 201 | int split; |
| 202 | |
| 203 | /* if this is a Pax Interchange header prepend "PaxHeader/" |
| 204 | ** so we can tell files apart from metadata */ |
| 205 | if( bHeader ){ |
| 206 | int n; |
| 207 | blob_reset(&tball.pax); |
| 208 | blob_appendf(&tball.pax, "PaxHeader/%*.*s", nName, nName, zName); |
| 209 | zName = blob_buffer(&tball.pax); |
| 210 | nName = blob_size(&tball.pax); |
| 211 | } |
| @@ -288,15 +287,17 @@ | |
| 288 | /* set mode and modification time */ |
| 289 | sqlite3_snprintf(8, (char*)&tball.aHdr[100], "%07o", iMode); |
| 290 | sqlite3_snprintf(12, (char*)&tball.aHdr[136], "%011o", mTime); |
| 291 | |
| 292 | /* see if we need to output a Pax Interchange Header */ |
| 293 | if( !is_iso646_name(zName, nName) || |
| 294 | !tar_split_path(zName, nName, tball.aHdr, &tball.aHdr[345]) ){ |
| 295 | int lastPage; |
| 296 | /* add a file name for interoperability with older programs */ |
| 297 | approximate_split_path(zName, nName, tball.aHdr, &tball.aHdr[345], 1); |
| 298 | |
| 299 | /* generate the Pax Interchange path header */ |
| 300 | blob_reset(&tball.pax); |
| 301 | add_pax_header("path", zName, nName); |
| 302 | |
| @@ -311,11 +312,12 @@ | |
| 311 | if( lastPage!=0 ){ |
| 312 | gzip_step(tball.zSpaces, 512 - lastPage); |
| 313 | } |
| 314 | |
| 315 | /* generate an approximate path for the regular header */ |
| 316 | approximate_split_path(zName, nName, tball.aHdr, &tball.aHdr[345], 0); |
| 317 | } |
| 318 | /* set the size */ |
| 319 | sqlite3_snprintf(12, (char*)&tball.aHdr[124], "%011o", iSize); |
| 320 | |
| 321 | /* write the regular header */ |
| 322 |
| --- src/tar.c | |
| +++ src/tar.c | |
| @@ -201,11 +201,10 @@ | |
| 201 | int split; |
| 202 | |
| 203 | /* if this is a Pax Interchange header prepend "PaxHeader/" |
| 204 | ** so we can tell files apart from metadata */ |
| 205 | if( bHeader ){ |
| 206 | blob_reset(&tball.pax); |
| 207 | blob_appendf(&tball.pax, "PaxHeader/%*.*s", nName, nName, zName); |
| 208 | zName = blob_buffer(&tball.pax); |
| 209 | nName = blob_size(&tball.pax); |
| 210 | } |
| @@ -288,15 +287,17 @@ | |
| 287 | /* set mode and modification time */ |
| 288 | sqlite3_snprintf(8, (char*)&tball.aHdr[100], "%07o", iMode); |
| 289 | sqlite3_snprintf(12, (char*)&tball.aHdr[136], "%011o", mTime); |
| 290 | |
| 291 | /* see if we need to output a Pax Interchange Header */ |
| 292 | if( !is_iso646_name(zName, nName) |
| 293 | || !tar_split_path(zName, nName, (char*)tball.aHdr, (char*)&tball.aHdr[345]) |
| 294 | ){ |
| 295 | int lastPage; |
| 296 | /* add a file name for interoperability with older programs */ |
| 297 | approximate_split_path(zName, nName, (char*)tball.aHdr, |
| 298 | (char*)&tball.aHdr[345], 1); |
| 299 | |
| 300 | /* generate the Pax Interchange path header */ |
| 301 | blob_reset(&tball.pax); |
| 302 | add_pax_header("path", zName, nName); |
| 303 | |
| @@ -311,11 +312,12 @@ | |
| 312 | if( lastPage!=0 ){ |
| 313 | gzip_step(tball.zSpaces, 512 - lastPage); |
| 314 | } |
| 315 | |
| 316 | /* generate an approximate path for the regular header */ |
| 317 | approximate_split_path(zName, nName, (char*)tball.aHdr, |
| 318 | (char*)&tball.aHdr[345], 0); |
| 319 | } |
| 320 | /* set the size */ |
| 321 | sqlite3_snprintf(12, (char*)&tball.aHdr[124], "%011o", iSize); |
| 322 | |
| 323 | /* write the regular header */ |
| 324 |
+7
-5
| --- src/tar.c | ||
| +++ src/tar.c | ||
| @@ -201,11 +201,10 @@ | ||
| 201 | 201 | int split; |
| 202 | 202 | |
| 203 | 203 | /* if this is a Pax Interchange header prepend "PaxHeader/" |
| 204 | 204 | ** so we can tell files apart from metadata */ |
| 205 | 205 | if( bHeader ){ |
| 206 | - int n; | |
| 207 | 206 | blob_reset(&tball.pax); |
| 208 | 207 | blob_appendf(&tball.pax, "PaxHeader/%*.*s", nName, nName, zName); |
| 209 | 208 | zName = blob_buffer(&tball.pax); |
| 210 | 209 | nName = blob_size(&tball.pax); |
| 211 | 210 | } |
| @@ -288,15 +287,17 @@ | ||
| 288 | 287 | /* set mode and modification time */ |
| 289 | 288 | sqlite3_snprintf(8, (char*)&tball.aHdr[100], "%07o", iMode); |
| 290 | 289 | sqlite3_snprintf(12, (char*)&tball.aHdr[136], "%011o", mTime); |
| 291 | 290 | |
| 292 | 291 | /* see if we need to output a Pax Interchange Header */ |
| 293 | - if( !is_iso646_name(zName, nName) || | |
| 294 | - !tar_split_path(zName, nName, tball.aHdr, &tball.aHdr[345]) ){ | |
| 292 | + if( !is_iso646_name(zName, nName) | |
| 293 | + || !tar_split_path(zName, nName, (char*)tball.aHdr, (char*)&tball.aHdr[345]) | |
| 294 | + ){ | |
| 295 | 295 | int lastPage; |
| 296 | 296 | /* add a file name for interoperability with older programs */ |
| 297 | - approximate_split_path(zName, nName, tball.aHdr, &tball.aHdr[345], 1); | |
| 297 | + approximate_split_path(zName, nName, (char*)tball.aHdr, | |
| 298 | + (char*)&tball.aHdr[345], 1); | |
| 298 | 299 | |
| 299 | 300 | /* generate the Pax Interchange path header */ |
| 300 | 301 | blob_reset(&tball.pax); |
| 301 | 302 | add_pax_header("path", zName, nName); |
| 302 | 303 | |
| @@ -311,11 +312,12 @@ | ||
| 311 | 312 | if( lastPage!=0 ){ |
| 312 | 313 | gzip_step(tball.zSpaces, 512 - lastPage); |
| 313 | 314 | } |
| 314 | 315 | |
| 315 | 316 | /* generate an approximate path for the regular header */ |
| 316 | - approximate_split_path(zName, nName, tball.aHdr, &tball.aHdr[345], 0); | |
| 317 | + approximate_split_path(zName, nName, (char*)tball.aHdr, | |
| 318 | + (char*)&tball.aHdr[345], 0); | |
| 317 | 319 | } |
| 318 | 320 | /* set the size */ |
| 319 | 321 | sqlite3_snprintf(12, (char*)&tball.aHdr[124], "%011o", iSize); |
| 320 | 322 | |
| 321 | 323 | /* write the regular header */ |
| 322 | 324 |
| --- src/tar.c | |
| +++ src/tar.c | |
| @@ -201,11 +201,10 @@ | |
| 201 | int split; |
| 202 | |
| 203 | /* if this is a Pax Interchange header prepend "PaxHeader/" |
| 204 | ** so we can tell files apart from metadata */ |
| 205 | if( bHeader ){ |
| 206 | int n; |
| 207 | blob_reset(&tball.pax); |
| 208 | blob_appendf(&tball.pax, "PaxHeader/%*.*s", nName, nName, zName); |
| 209 | zName = blob_buffer(&tball.pax); |
| 210 | nName = blob_size(&tball.pax); |
| 211 | } |
| @@ -288,15 +287,17 @@ | |
| 288 | /* set mode and modification time */ |
| 289 | sqlite3_snprintf(8, (char*)&tball.aHdr[100], "%07o", iMode); |
| 290 | sqlite3_snprintf(12, (char*)&tball.aHdr[136], "%011o", mTime); |
| 291 | |
| 292 | /* see if we need to output a Pax Interchange Header */ |
| 293 | if( !is_iso646_name(zName, nName) || |
| 294 | !tar_split_path(zName, nName, tball.aHdr, &tball.aHdr[345]) ){ |
| 295 | int lastPage; |
| 296 | /* add a file name for interoperability with older programs */ |
| 297 | approximate_split_path(zName, nName, tball.aHdr, &tball.aHdr[345], 1); |
| 298 | |
| 299 | /* generate the Pax Interchange path header */ |
| 300 | blob_reset(&tball.pax); |
| 301 | add_pax_header("path", zName, nName); |
| 302 | |
| @@ -311,11 +312,12 @@ | |
| 311 | if( lastPage!=0 ){ |
| 312 | gzip_step(tball.zSpaces, 512 - lastPage); |
| 313 | } |
| 314 | |
| 315 | /* generate an approximate path for the regular header */ |
| 316 | approximate_split_path(zName, nName, tball.aHdr, &tball.aHdr[345], 0); |
| 317 | } |
| 318 | /* set the size */ |
| 319 | sqlite3_snprintf(12, (char*)&tball.aHdr[124], "%011o", iSize); |
| 320 | |
| 321 | /* write the regular header */ |
| 322 |
| --- src/tar.c | |
| +++ src/tar.c | |
| @@ -201,11 +201,10 @@ | |
| 201 | int split; |
| 202 | |
| 203 | /* if this is a Pax Interchange header prepend "PaxHeader/" |
| 204 | ** so we can tell files apart from metadata */ |
| 205 | if( bHeader ){ |
| 206 | blob_reset(&tball.pax); |
| 207 | blob_appendf(&tball.pax, "PaxHeader/%*.*s", nName, nName, zName); |
| 208 | zName = blob_buffer(&tball.pax); |
| 209 | nName = blob_size(&tball.pax); |
| 210 | } |
| @@ -288,15 +287,17 @@ | |
| 287 | /* set mode and modification time */ |
| 288 | sqlite3_snprintf(8, (char*)&tball.aHdr[100], "%07o", iMode); |
| 289 | sqlite3_snprintf(12, (char*)&tball.aHdr[136], "%011o", mTime); |
| 290 | |
| 291 | /* see if we need to output a Pax Interchange Header */ |
| 292 | if( !is_iso646_name(zName, nName) |
| 293 | || !tar_split_path(zName, nName, (char*)tball.aHdr, (char*)&tball.aHdr[345]) |
| 294 | ){ |
| 295 | int lastPage; |
| 296 | /* add a file name for interoperability with older programs */ |
| 297 | approximate_split_path(zName, nName, (char*)tball.aHdr, |
| 298 | (char*)&tball.aHdr[345], 1); |
| 299 | |
| 300 | /* generate the Pax Interchange path header */ |
| 301 | blob_reset(&tball.pax); |
| 302 | add_pax_header("path", zName, nName); |
| 303 | |
| @@ -311,11 +312,12 @@ | |
| 312 | if( lastPage!=0 ){ |
| 313 | gzip_step(tball.zSpaces, 512 - lastPage); |
| 314 | } |
| 315 | |
| 316 | /* generate an approximate path for the regular header */ |
| 317 | approximate_split_path(zName, nName, (char*)tball.aHdr, |
| 318 | (char*)&tball.aHdr[345], 0); |
| 319 | } |
| 320 | /* set the size */ |
| 321 | sqlite3_snprintf(12, (char*)&tball.aHdr[124], "%011o", iSize); |
| 322 | |
| 323 | /* write the regular header */ |
| 324 |
+1
-1
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -454,11 +454,11 @@ | ||
| 454 | 454 | /* |
| 455 | 455 | ** Generate all of the necessary javascript to generate a timeline |
| 456 | 456 | ** graph. |
| 457 | 457 | */ |
| 458 | 458 | void timeline_output_graph_javascript(GraphContext *pGraph, int omitDescenders){ |
| 459 | - if( pGraph && pGraph->nErr==0 ){ | |
| 459 | + if( pGraph && pGraph->nErr==0 && pGraph->nRow>0 ){ | |
| 460 | 460 | GraphRow *pRow; |
| 461 | 461 | int i; |
| 462 | 462 | char cSep; |
| 463 | 463 | @ <script type="text/JavaScript"> |
| 464 | 464 | @ /* <![CDATA[ */ |
| 465 | 465 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -454,11 +454,11 @@ | |
| 454 | /* |
| 455 | ** Generate all of the necessary javascript to generate a timeline |
| 456 | ** graph. |
| 457 | */ |
| 458 | void timeline_output_graph_javascript(GraphContext *pGraph, int omitDescenders){ |
| 459 | if( pGraph && pGraph->nErr==0 ){ |
| 460 | GraphRow *pRow; |
| 461 | int i; |
| 462 | char cSep; |
| 463 | @ <script type="text/JavaScript"> |
| 464 | @ /* <![CDATA[ */ |
| 465 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -454,11 +454,11 @@ | |
| 454 | /* |
| 455 | ** Generate all of the necessary javascript to generate a timeline |
| 456 | ** graph. |
| 457 | */ |
| 458 | void timeline_output_graph_javascript(GraphContext *pGraph, int omitDescenders){ |
| 459 | if( pGraph && pGraph->nErr==0 && pGraph->nRow>0 ){ |
| 460 | GraphRow *pRow; |
| 461 | int i; |
| 462 | char cSep; |
| 463 | @ <script type="text/JavaScript"> |
| 464 | @ /* <![CDATA[ */ |
| 465 |
+42
-14
| --- www/build.wiki | ||
| +++ www/build.wiki | ||
| @@ -1,16 +1,29 @@ | ||
| 1 | 1 | <title>Building and Installing Fossil</title> |
| 2 | 2 | |
| 3 | -<p>This page describes how to build and install Fossil. The | |
| 4 | -whole process is designed to be very easy.</p> | |
| 5 | - | |
| 6 | 3 | <h2>0.0 Using A Pre-compiled Binary</h2> |
| 7 | 4 | |
| 8 | -<p>You can skip steps 1.0 and 2.0 below by downloading | |
| 5 | +<p>You can skip all of the following by downloading | |
| 9 | 6 | a <a href="http://www.fossil-scm.org/download.html">pre-compiled binary</a> |
| 10 | -appropriate for your platform. If you use a pre-compiled binary | |
| 11 | -jump immediate to step 3.0.</p> | |
| 7 | +appropriate for your platform and putting that self-contained binary | |
| 8 | +someplace on your $PATH. | |
| 9 | +To uninstall, simply delete the binary. | |
| 10 | +To upgrade from an older release, just overwrite the older binary with | |
| 11 | +the newer one.</p> | |
| 12 | + | |
| 13 | +<h2>0.1 Executive Summary</h2> | |
| 14 | + | |
| 15 | +<p>Building and installing is very simple. Three steps:</p> | |
| 16 | + | |
| 17 | +<ol> | |
| 18 | +<li> Download and unpack a source tarball or ZIP. | |
| 19 | +<li> <b>./configure; make</b> | |
| 20 | +<li> Move or copy the resulting "fossil" executable to someplace | |
| 21 | + on your $PATH. | |
| 22 | +</ol> | |
| 23 | + | |
| 24 | +<p><hr> | |
| 12 | 25 | |
| 13 | 26 | <h2>1.0 Obtaining The Source Code</h2> |
| 14 | 27 | |
| 15 | 28 | <p>Fossil is self-hosting, so you can obtain a ZIP archive containing |
| 16 | 29 | a snapshot of the latest version directly from fossil's own fossil |
| @@ -47,22 +60,37 @@ | ||
| 47 | 60 | <li value="6"> |
| 48 | 61 | <p>Create a directory to hold the source code. Then unarchive the |
| 49 | 62 | ZIP or tarball you downloaded into that directory. You should be |
| 50 | 63 | in the top-level folder of that directory</p></li> |
| 51 | 64 | |
| 52 | -<li><p><b>(Optional:)</b> | |
| 53 | -Edit the Makefile to set it up like you want. You probably do not | |
| 54 | -need to do anything. Do not be intimidated: There are less than 10 | |
| 55 | -variables in the makefile that can be changed. The whole Makefile | |
| 56 | -is only a few dozen lines long and most of those lines are comments.</p> | |
| 65 | +<li><i>(Optional, unix only)</i> | |
| 66 | +Run <b>./configure</b> to construct a makefile. | |
| 67 | + | |
| 68 | +<ol type="a"> | |
| 69 | +<li><p> | |
| 70 | +If you do not have the OpenSSL library installed on your system, then | |
| 71 | +add <b>--with-openssl=none</b> to omit the https functionality. | |
| 72 | + | |
| 73 | +<li><p> | |
| 74 | +To build a statically linked binary (suitable for use inside a chroot | |
| 75 | +jail) add the <b>--static</b> option. | |
| 76 | + | |
| 77 | +<li><p> | |
| 78 | +Other configuration options can be seen by running | |
| 79 | +<b>./configure --help</b> | |
| 80 | +</ol> | |
| 57 | 81 | |
| 58 | 82 | <li><p>Run make to build the "fossil" or "fossil.exe" executable. The |
| 59 | -details depend on your platform and compiler: | |
| 83 | +details depend on your platform and compiler. | |
| 60 | 84 | |
| 61 | 85 | <ol type="a"> |
| 62 | -<li><p><i>Unix</i> → the default Makefile works on most unix and | |
| 63 | -unix-like systems. Simply type "<b>make</b>". | |
| 86 | +<li><p><i>Unix</i> → the configure-generated Makefile should work on | |
| 87 | +all unix and unix-like systems. Simply type "<b>make</b>". | |
| 88 | + | |
| 89 | +<li><p><i>Unix without running "configure"</i> → if you prefer to avoid running configure, you | |
| 90 | +can also use: <b>make -f Makefile.classic</b>. You may want to make minor | |
| 91 | +edits to Makefile.classic to configure the build for your system. | |
| 64 | 92 | |
| 65 | 93 | <li><p><i>Msys/MinGW</i> → Use the |
| 66 | 94 | mingw makefile: "<b>make -f win/Makefile.mingw</b>" |
| 67 | 95 | |
| 68 | 96 | <li><p><i>VC++</i> → Use the msc makefile. First |
| 69 | 97 |
| --- www/build.wiki | |
| +++ www/build.wiki | |
| @@ -1,16 +1,29 @@ | |
| 1 | <title>Building and Installing Fossil</title> |
| 2 | |
| 3 | <p>This page describes how to build and install Fossil. The |
| 4 | whole process is designed to be very easy.</p> |
| 5 | |
| 6 | <h2>0.0 Using A Pre-compiled Binary</h2> |
| 7 | |
| 8 | <p>You can skip steps 1.0 and 2.0 below by downloading |
| 9 | a <a href="http://www.fossil-scm.org/download.html">pre-compiled binary</a> |
| 10 | appropriate for your platform. If you use a pre-compiled binary |
| 11 | jump immediate to step 3.0.</p> |
| 12 | |
| 13 | <h2>1.0 Obtaining The Source Code</h2> |
| 14 | |
| 15 | <p>Fossil is self-hosting, so you can obtain a ZIP archive containing |
| 16 | a snapshot of the latest version directly from fossil's own fossil |
| @@ -47,22 +60,37 @@ | |
| 47 | <li value="6"> |
| 48 | <p>Create a directory to hold the source code. Then unarchive the |
| 49 | ZIP or tarball you downloaded into that directory. You should be |
| 50 | in the top-level folder of that directory</p></li> |
| 51 | |
| 52 | <li><p><b>(Optional:)</b> |
| 53 | Edit the Makefile to set it up like you want. You probably do not |
| 54 | need to do anything. Do not be intimidated: There are less than 10 |
| 55 | variables in the makefile that can be changed. The whole Makefile |
| 56 | is only a few dozen lines long and most of those lines are comments.</p> |
| 57 | |
| 58 | <li><p>Run make to build the "fossil" or "fossil.exe" executable. The |
| 59 | details depend on your platform and compiler: |
| 60 | |
| 61 | <ol type="a"> |
| 62 | <li><p><i>Unix</i> → the default Makefile works on most unix and |
| 63 | unix-like systems. Simply type "<b>make</b>". |
| 64 | |
| 65 | <li><p><i>Msys/MinGW</i> → Use the |
| 66 | mingw makefile: "<b>make -f win/Makefile.mingw</b>" |
| 67 | |
| 68 | <li><p><i>VC++</i> → Use the msc makefile. First |
| 69 |
| --- www/build.wiki | |
| +++ www/build.wiki | |
| @@ -1,16 +1,29 @@ | |
| 1 | <title>Building and Installing Fossil</title> |
| 2 | |
| 3 | <h2>0.0 Using A Pre-compiled Binary</h2> |
| 4 | |
| 5 | <p>You can skip all of the following by downloading |
| 6 | a <a href="http://www.fossil-scm.org/download.html">pre-compiled binary</a> |
| 7 | appropriate for your platform and putting that self-contained binary |
| 8 | someplace on your $PATH. |
| 9 | To uninstall, simply delete the binary. |
| 10 | To upgrade from an older release, just overwrite the older binary with |
| 11 | the newer one.</p> |
| 12 | |
| 13 | <h2>0.1 Executive Summary</h2> |
| 14 | |
| 15 | <p>Building and installing is very simple. Three steps:</p> |
| 16 | |
| 17 | <ol> |
| 18 | <li> Download and unpack a source tarball or ZIP. |
| 19 | <li> <b>./configure; make</b> |
| 20 | <li> Move or copy the resulting "fossil" executable to someplace |
| 21 | on your $PATH. |
| 22 | </ol> |
| 23 | |
| 24 | <p><hr> |
| 25 | |
| 26 | <h2>1.0 Obtaining The Source Code</h2> |
| 27 | |
| 28 | <p>Fossil is self-hosting, so you can obtain a ZIP archive containing |
| 29 | a snapshot of the latest version directly from fossil's own fossil |
| @@ -47,22 +60,37 @@ | |
| 60 | <li value="6"> |
| 61 | <p>Create a directory to hold the source code. Then unarchive the |
| 62 | ZIP or tarball you downloaded into that directory. You should be |
| 63 | in the top-level folder of that directory</p></li> |
| 64 | |
| 65 | <li><i>(Optional, unix only)</i> |
| 66 | Run <b>./configure</b> to construct a makefile. |
| 67 | |
| 68 | <ol type="a"> |
| 69 | <li><p> |
| 70 | If you do not have the OpenSSL library installed on your system, then |
| 71 | add <b>--with-openssl=none</b> to omit the https functionality. |
| 72 | |
| 73 | <li><p> |
| 74 | To build a statically linked binary (suitable for use inside a chroot |
| 75 | jail) add the <b>--static</b> option. |
| 76 | |
| 77 | <li><p> |
| 78 | Other configuration options can be seen by running |
| 79 | <b>./configure --help</b> |
| 80 | </ol> |
| 81 | |
| 82 | <li><p>Run make to build the "fossil" or "fossil.exe" executable. The |
| 83 | details depend on your platform and compiler. |
| 84 | |
| 85 | <ol type="a"> |
| 86 | <li><p><i>Unix</i> → the configure-generated Makefile should work on |
| 87 | all unix and unix-like systems. Simply type "<b>make</b>". |
| 88 | |
| 89 | <li><p><i>Unix without running "configure"</i> → if you prefer to avoid running configure, you |
| 90 | can also use: <b>make -f Makefile.classic</b>. You may want to make minor |
| 91 | edits to Makefile.classic to configure the build for your system. |
| 92 | |
| 93 | <li><p><i>Msys/MinGW</i> → Use the |
| 94 | mingw makefile: "<b>make -f win/Makefile.mingw</b>" |
| 95 | |
| 96 | <li><p><i>VC++</i> → Use the msc makefile. First |
| 97 |
+1
-1
| --- www/makefile.wiki | ||
| +++ www/makefile.wiki | ||
| @@ -126,11 +126,11 @@ | ||
| 126 | 126 | preprocessor must be run after translate. |
| 127 | 127 | |
| 128 | 128 | <h2>4.1 The mkindex preprocessor</h2> |
| 129 | 129 | |
| 130 | 130 | The mkindex program scans the "src.c" source files looking for special |
| 131 | -comments that identify routines that implement of various Fossil commands, | |
| 131 | +comments that identify routines that implement various Fossil commands, | |
| 132 | 132 | web interface methods, and help text comments. The mkindex program |
| 133 | 133 | generates some C code that Fossil uses in order to dispatch commands and |
| 134 | 134 | HTTP requests and to show on-line help. Compile the mkindex program |
| 135 | 135 | from the mkindex.c source file. Then run: |
| 136 | 136 | |
| 137 | 137 |
| --- www/makefile.wiki | |
| +++ www/makefile.wiki | |
| @@ -126,11 +126,11 @@ | |
| 126 | preprocessor must be run after translate. |
| 127 | |
| 128 | <h2>4.1 The mkindex preprocessor</h2> |
| 129 | |
| 130 | The mkindex program scans the "src.c" source files looking for special |
| 131 | comments that identify routines that implement of various Fossil commands, |
| 132 | web interface methods, and help text comments. The mkindex program |
| 133 | generates some C code that Fossil uses in order to dispatch commands and |
| 134 | HTTP requests and to show on-line help. Compile the mkindex program |
| 135 | from the mkindex.c source file. Then run: |
| 136 | |
| 137 |
| --- www/makefile.wiki | |
| +++ www/makefile.wiki | |
| @@ -126,11 +126,11 @@ | |
| 126 | preprocessor must be run after translate. |
| 127 | |
| 128 | <h2>4.1 The mkindex preprocessor</h2> |
| 129 | |
| 130 | The mkindex program scans the "src.c" source files looking for special |
| 131 | comments that identify routines that implement various Fossil commands, |
| 132 | web interface methods, and help text comments. The mkindex program |
| 133 | generates some C code that Fossil uses in order to dispatch commands and |
| 134 | HTTP requests and to show on-line help. Compile the mkindex program |
| 135 | from the mkindex.c source file. Then run: |
| 136 | |
| 137 |