Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch filename-case Excluding Merge-Ins
This is equivalent to a diff from 83c032de7f to 4fee0ce2d6
2011-08-04
| ||
22:17 | Merge the --case-sensitive feature into trunk. check-in: 874d0ca303 user: drh tags: trunk | |
17:13 | Add experimental changes to support the case-sensitive setting and the --case-sensitive command-line option for "add", "addremove", and "merge". Closed-Leaf check-in: 4fee0ce2d6 user: drh tags: filename-case | |
15:54 | Merge trunk into ben-testing check-in: 3eb07708b1 user: ben tags: ben-testing | |
14:32 | Merge the ben-minorchanges branch into trunk. check-in: 83c032de7f user: drh tags: trunk | |
2011-08-02
| ||
18:42 | Use the automatic background color algorithm for individual file timelines in addition to the global timeline. check-in: abe7b8335f user: drh tags: trunk | |
2011-07-30
| ||
10:14 | Correct the winsrv documentation to use the renamed command name. Closed-Leaf check-in: f6b8397e4b user: ben tags: ben-minorchanges | |
Changes to src/add.c.
90 90 /* 91 91 ** Add a single file named zName to the VFILE table with vid. 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); 143 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 + xCmp = caseSensitive ? fossil_strcmp : fossil_stricmp; 144 155 db_prepare(&loop, "SELECT x FROM sfile ORDER BY x"); 145 156 while( db_step(&loop)==SQLITE_ROW ){ 146 157 const char *zToAdd = db_column_text(&loop, 0); 147 158 if( fossil_strcmp(zToAdd, zRepo)==0 ) continue; 148 159 for(i=0; (zReserved = fossil_reserved_name(i))!=0; i++){ 149 - if( fossil_strcmp(zToAdd, zReserved)==0 ) break; 160 + if( xCmp(zToAdd, zReserved)==0 ) break; 150 161 } 151 162 if( zReserved ) continue; 152 - nAdd += add_one_file(zToAdd, vid); 163 + nAdd += add_one_file(zToAdd, vid, caseSensitive); 153 164 } 154 165 db_finalize(&loop); 155 166 blob_reset(&repoName); 156 167 return nAdd; 157 168 } 158 169 159 170 /* ................................................................................ 178 189 */ 179 190 void add_cmd(void){ 180 191 int i; /* Loop counter */ 181 192 int vid; /* Currently checked out version */ 182 193 int nRoot; /* Full path characters in g.zLocalRoot */ 183 194 const char *zIgnoreFlag; /* The --ignore option or ignore-glob setting */ 184 195 Glob *pIgnore; /* Ignore everything matching this glob pattern */ 196 + int caseSensitive; /* True if filenames are case sensitive */ 185 197 186 198 zIgnoreFlag = find_option("ignore",0,1); 187 199 includeDotFiles = find_option("dotfiles",0,0)!=0; 200 + capture_case_sensitive_option(); 188 201 db_must_be_within_tree(); 202 + caseSensitive = filenames_are_case_sensitive(); 189 203 if( zIgnoreFlag==0 ){ 190 204 zIgnoreFlag = db_get("ignore-glob", 0); 191 205 } 192 206 vid = db_lget_int("checkout",0); 193 207 if( vid==0 ){ 194 208 fossil_panic("no checkout to add to"); 195 209 } ................................................................................ 227 241 zTreeName, zTreeName 228 242 ); 229 243 } 230 244 blob_reset(&fullName); 231 245 } 232 246 glob_free(pIgnore); 233 247 234 - add_files_in_sfile(vid); 248 + add_files_in_sfile(vid, caseSensitive); 235 249 db_end_transaction(0); 236 250 } 237 251 238 252 /* 239 253 ** COMMAND: rm 240 254 ** COMMAND: delete 241 255 ** ................................................................................ 287 301 db_finalize(&loop); 288 302 db_multi_exec( 289 303 "UPDATE vfile SET deleted=1 WHERE pathname IN sfile;" 290 304 "DELETE FROM vfile WHERE rid=0 AND deleted;" 291 305 ); 292 306 db_end_transaction(0); 293 307 } 308 + 309 +/* 310 +** Capture the command-line --case-sensitive option. 311 +*/ 312 +static const char *zCaseSensitive = 0; 313 +void capture_case_sensitive_option(void){ 314 + if( zCaseSensitive==0 ){ 315 + zCaseSensitive = find_option("case-sensitive",0,1); 316 + } 317 +} 318 + 319 +/* 320 +** This routine determines if files should be case-sensitive or not. 321 +** In other words, this routine determines if two filenames that 322 +** differ only in case should be considered the same name or not. 323 +** 324 +** The case-sensitive setting determines the default value. If 325 +** the case-sensitive setting is undefined, then case sensitivity 326 +** defaults on for Mac and Windows and off for all other unix. 327 +** 328 +** The --case-sensitive BOOLEAN command-line option overrides any 329 +** setting. 330 +*/ 331 +int filenames_are_case_sensitive(void){ 332 + int caseSensitive; 333 + 334 + if( zCaseSensitive ){ 335 + caseSensitive = is_truth(zCaseSensitive); 336 + }else{ 337 +#if !defined(_WIN32) && !defined(__DARWIN__) && !defined(__APPLE__) 338 + caseSensitive = 1; 339 +#else 340 + caseSensitive = 0; 341 +#endif 342 + caseSensitive = db_get_boolean("case-sensitive",caseSensitive); 343 + } 344 + return caseSensitive; 345 +} 294 346 295 347 /* 296 348 ** COMMAND: addremove 297 349 ** 298 350 ** Usage: %fossil addremove ?--dotfiles? ?--ignore GLOBPATTERN? ?--test? 299 351 ** 300 352 ** Do all necessary "add" and "rm" commands to synchronize the repository ................................................................................ 317 369 ** The --ignore option overrides the "ignore-glob" setting. See 318 370 ** documentation on the "settings" command for further information. 319 371 ** 320 372 ** The --test option shows what would happen without actually doing anything. 321 373 ** 322 374 ** This command can be used to track third party software. 323 375 ** 324 -** 325 376 ** SUMMARY: fossil addremove 326 -** Options: ?--dotfiles? ?--ignore GLOBPATTERN? ?--test? 377 +** Options: ?--dotfiles? ?--ignore GLOB? ?--test? ?--case-sensitive BOOL? 327 378 */ 328 -void import_cmd(void){ 379 +void addremove_cmd(void){ 329 380 Blob path; 330 381 const char *zIgnoreFlag = find_option("ignore",0,1); 331 382 int allFlag = find_option("dotfiles",0,0)!=0; 332 383 int isTest = find_option("test",0,0)!=0; 384 + int caseSensitive; 333 385 int n; 334 386 Stmt q; 335 387 int vid; 336 388 int nAdd = 0; 337 389 int nDelete = 0; 338 390 Glob *pIgnore; 339 391 392 + capture_case_sensitive_option(); 340 393 db_must_be_within_tree(); 394 + caseSensitive = filenames_are_case_sensitive(); 341 395 if( zIgnoreFlag==0 ){ 342 396 zIgnoreFlag = db_get("ignore-glob", 0); 343 397 } 344 398 vid = db_lget_int("checkout",0); 345 399 if( vid==0 ){ 346 400 fossil_panic("no checkout to add to"); 347 401 } ................................................................................ 356 410 db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)"); 357 411 n = strlen(g.zLocalRoot); 358 412 blob_init(&path, g.zLocalRoot, n-1); 359 413 /* now we read the complete file structure into a temp table */ 360 414 pIgnore = glob_create(zIgnoreFlag); 361 415 vfile_scan(&path, blob_size(&path), allFlag, pIgnore); 362 416 glob_free(pIgnore); 363 - nAdd = add_files_in_sfile(vid); 417 + nAdd = add_files_in_sfile(vid, caseSensitive); 364 418 365 419 /* step 2: search for missing files */ 366 420 db_prepare(&q, 367 421 "SELECT pathname, %Q || pathname, deleted FROM vfile" 368 422 " WHERE NOT deleted" 369 423 " ORDER BY 1", 370 424 g.zLocalRoot
Changes to src/db.c.
1364 1364 /* 1365 1365 ** Return true if the string zVal represents "true" (or "false"). 1366 1366 */ 1367 1367 int is_truth(const char *zVal){ 1368 1368 static const char *azOn[] = { "on", "yes", "true", "1" }; 1369 1369 int i; 1370 1370 for(i=0; i<sizeof(azOn)/sizeof(azOn[0]); i++){ 1371 - if( fossil_strcmp(zVal,azOn[i])==0 ) return 1; 1371 + if( fossil_stricmp(zVal,azOn[i])==0 ) return 1; 1372 1372 } 1373 1373 return 0; 1374 1374 } 1375 1375 int is_false(const char *zVal){ 1376 1376 static const char *azOff[] = { "off", "no", "false", "0" }; 1377 1377 int i; 1378 1378 for(i=0; i<sizeof(azOff)/sizeof(azOff[0]); i++){ 1379 - if( fossil_strcmp(zVal,azOff[i])==0 ) return 1; 1379 + if( fossil_stricmp(zVal,azOff[i])==0 ) return 1; 1380 1380 } 1381 1381 return 0; 1382 1382 } 1383 1383 1384 1384 /* 1385 1385 ** Swap the g.db and g.dbConfig connections so that the various db_* routines 1386 1386 ** work on the ~/.fossil database instead of on the repository database. ................................................................................ 1645 1645 #endif /* INTERFACE */ 1646 1646 struct stControlSettings const ctrlSettings[] = { 1647 1647 { "access-log", 0, 0, "off" }, 1648 1648 { "auto-captcha", "autocaptcha", 0, "on" }, 1649 1649 { "auto-shun", 0, 0, "on" }, 1650 1650 { "autosync", 0, 0, "on" }, 1651 1651 { "binary-glob", 0, 32, "" }, 1652 + { "case-sensitive",0, 0, "on" }, 1652 1653 { "clearsign", 0, 0, "off" }, 1653 1654 { "crnl-glob", 0, 16, "" }, 1654 1655 { "default-perms", 0, 16, "u" }, 1655 1656 { "diff-command", 0, 16, "" }, 1656 1657 { "dont-push", 0, 0, "off" }, 1657 1658 { "editor", 0, 16, "" }, 1658 1659 { "gdiff-command", 0, 16, "gdiff" }, ................................................................................ 1701 1702 ** tag or branch creation. If the value is "pullonly" 1702 1703 ** then only pull operations occur automatically. 1703 1704 ** Default: on 1704 1705 ** 1705 1706 ** binary-glob The VALUE is a comma-separated list of GLOB patterns 1706 1707 ** that should be treated as binary files for merging 1707 1708 ** purposes. Example: *.xml 1709 +** 1710 +** case-sensitive If TRUE, the files whose names differ only in case 1711 +** care considered distinct. If FALSE files whose names 1712 +** differ only in case are the same file. Defaults to 1713 +** TRUE for unix and FALSE for windows and mac. 1708 1714 ** 1709 1715 ** clearsign When enabled, fossil will attempt to sign all commits 1710 1716 ** with gpg. When disabled (the default), commits will 1711 1717 ** be unsigned. Default: off 1712 1718 ** 1713 1719 ** crnl-glob A comma-separated list of GLOB patterns for text files 1714 1720 ** in which it is ok to have CR+NL line endings.
Changes to src/merge.c.
51 51 ** 52 52 ** --binary GLOBPATTERN Treat files that match GLOBPATTERN as binary 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 */ 63 67 int detailFlag; /* True if the --detail option is present */ 64 68 int pickFlag; /* True if the --cherrypick option is present */ ................................................................................ 67 71 const char *zBinGlob; /* The value of --binary */ 68 72 const char *zPivot; /* The value of --baseline */ 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 ** 79 84 ** V The current checkout 80 85 ** M The version being merged in ................................................................................ 85 90 detailFlag = find_option("detail",0,0)!=0; 86 91 pickFlag = find_option("cherrypick",0,0)!=0; 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("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 } 101 108 mid = name_to_typed_rid(g.argv[2], "ci"); 102 109 if( mid==0 || !is_a_version(mid) ){ ................................................................................ 148 155 ** The vfile.pathname field is used to match files against each other. The 149 156 ** FV table contains one row for each each unique filename in 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 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 "INSERT OR IGNORE" 173 181 " INTO fv(fn,fnp,fnm,idv,idp,idm,ridv,ridp,ridm,isexe,chnged)"