Fossil SCM
Merge versionable settings and empty-dirs setting from versionable-settings branch
Commit
30ebed190319313eb4c45ea10b1022387e144603
Parent
397f434a4dd6d31…
20 files changed
+3
-3
+5
-5
+2
-1
+2
-1
+1
+1
+113
-45
+113
-45
+4
-4
+4
-4
+1
-1
+1
-1
+11
-2
+11
-2
+1
-1
+1
-1
+52
+52
+1
-1
+1
-1
+3
-3
| --- src/add.c | ||
| +++ src/add.c | ||
| @@ -60,11 +60,11 @@ | ||
| 60 | 60 | "manifest.uuid", |
| 61 | 61 | }; |
| 62 | 62 | |
| 63 | 63 | if( N>=0 && N<count(azName) ) return azName[N]; |
| 64 | 64 | if( N>=count(azName) && N<count(azName)+count(azManifest) |
| 65 | - && db_get_boolean("manifest",0) ){ | |
| 65 | + && db_get_versionable_setting_boolean("manifest",0) ){ | |
| 66 | 66 | return azManifest[N-count(azName)]; |
| 67 | 67 | } |
| 68 | 68 | return 0; |
| 69 | 69 | } |
| 70 | 70 | |
| @@ -185,11 +185,11 @@ | ||
| 185 | 185 | |
| 186 | 186 | zIgnoreFlag = find_option("ignore",0,1); |
| 187 | 187 | includeDotFiles = find_option("dotfiles",0,0)!=0; |
| 188 | 188 | db_must_be_within_tree(); |
| 189 | 189 | if( zIgnoreFlag==0 ){ |
| 190 | - zIgnoreFlag = db_get("ignore-glob", 0); | |
| 190 | + zIgnoreFlag = db_get_versionable_setting("ignore-glob", 0); | |
| 191 | 191 | } |
| 192 | 192 | vid = db_lget_int("checkout",0); |
| 193 | 193 | if( vid==0 ){ |
| 194 | 194 | fossil_panic("no checkout to add to"); |
| 195 | 195 | } |
| @@ -337,11 +337,11 @@ | ||
| 337 | 337 | int nDelete = 0; |
| 338 | 338 | Glob *pIgnore; |
| 339 | 339 | |
| 340 | 340 | db_must_be_within_tree(); |
| 341 | 341 | if( zIgnoreFlag==0 ){ |
| 342 | - zIgnoreFlag = db_get("ignore-glob", 0); | |
| 342 | + zIgnoreFlag = db_get_versionable_setting("ignore-glob", 0); | |
| 343 | 343 | } |
| 344 | 344 | vid = db_lget_int("checkout",0); |
| 345 | 345 | if( vid==0 ){ |
| 346 | 346 | fossil_panic("no checkout to add to"); |
| 347 | 347 | } |
| 348 | 348 |
| --- src/add.c | |
| +++ src/add.c | |
| @@ -60,11 +60,11 @@ | |
| 60 | "manifest.uuid", |
| 61 | }; |
| 62 | |
| 63 | if( N>=0 && N<count(azName) ) return azName[N]; |
| 64 | if( N>=count(azName) && N<count(azName)+count(azManifest) |
| 65 | && db_get_boolean("manifest",0) ){ |
| 66 | return azManifest[N-count(azName)]; |
| 67 | } |
| 68 | return 0; |
| 69 | } |
| 70 | |
| @@ -185,11 +185,11 @@ | |
| 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("ignore-glob", 0); |
| 191 | } |
| 192 | vid = db_lget_int("checkout",0); |
| 193 | if( vid==0 ){ |
| 194 | fossil_panic("no checkout to add to"); |
| 195 | } |
| @@ -337,11 +337,11 @@ | |
| 337 | int nDelete = 0; |
| 338 | Glob *pIgnore; |
| 339 | |
| 340 | db_must_be_within_tree(); |
| 341 | if( zIgnoreFlag==0 ){ |
| 342 | zIgnoreFlag = db_get("ignore-glob", 0); |
| 343 | } |
| 344 | vid = db_lget_int("checkout",0); |
| 345 | if( vid==0 ){ |
| 346 | fossil_panic("no checkout to add to"); |
| 347 | } |
| 348 |
| --- src/add.c | |
| +++ src/add.c | |
| @@ -60,11 +60,11 @@ | |
| 60 | "manifest.uuid", |
| 61 | }; |
| 62 | |
| 63 | if( N>=0 && N<count(azName) ) return azName[N]; |
| 64 | if( N>=count(azName) && N<count(azName)+count(azManifest) |
| 65 | && db_get_versionable_setting_boolean("manifest",0) ){ |
| 66 | return azManifest[N-count(azName)]; |
| 67 | } |
| 68 | return 0; |
| 69 | } |
| 70 | |
| @@ -185,11 +185,11 @@ | |
| 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 ){ |
| 194 | fossil_panic("no checkout to add to"); |
| 195 | } |
| @@ -337,11 +337,11 @@ | |
| 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 ){ |
| 346 | fossil_panic("no checkout to add to"); |
| 347 | } |
| 348 |
+5
-5
| --- src/checkin.c | ||
| +++ src/checkin.c | ||
| @@ -224,16 +224,16 @@ | ||
| 224 | 224 | int allFlag = find_option("dotfiles",0,0)!=0; |
| 225 | 225 | int outputManifest; |
| 226 | 226 | Glob *pIgnore; |
| 227 | 227 | |
| 228 | 228 | db_must_be_within_tree(); |
| 229 | - outputManifest = db_get_boolean("manifest",0); | |
| 229 | + outputManifest = db_get_versionable_setting_boolean("manifest",0); | |
| 230 | 230 | db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)"); |
| 231 | 231 | n = strlen(g.zLocalRoot); |
| 232 | 232 | blob_init(&path, g.zLocalRoot, n-1); |
| 233 | 233 | if( zIgnoreFlag==0 ){ |
| 234 | - zIgnoreFlag = db_get("ignore-glob", 0); | |
| 234 | + zIgnoreFlag = db_get_versionable_setting("ignore-glob", 0); | |
| 235 | 235 | } |
| 236 | 236 | pIgnore = glob_create(zIgnoreFlag); |
| 237 | 237 | vfile_scan(&path, blob_size(&path), allFlag, pIgnore); |
| 238 | 238 | glob_free(pIgnore); |
| 239 | 239 | db_prepare(&q, |
| @@ -283,11 +283,11 @@ | ||
| 283 | 283 | allFlag = find_option("force","f",0)!=0; |
| 284 | 284 | dotfilesFlag = find_option("dotfiles",0,0)!=0; |
| 285 | 285 | zIgnoreFlag = find_option("ignore",0,1); |
| 286 | 286 | db_must_be_within_tree(); |
| 287 | 287 | if( zIgnoreFlag==0 ){ |
| 288 | - zIgnoreFlag = db_get("ignore-glob", 0); | |
| 288 | + zIgnoreFlag = db_get_versionable_setting("ignore-glob", 0); | |
| 289 | 289 | } |
| 290 | 290 | db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)"); |
| 291 | 291 | n = strlen(g.zLocalRoot); |
| 292 | 292 | blob_init(&path, g.zLocalRoot, n-1); |
| 293 | 293 | pIgnore = glob_create(zIgnoreFlag); |
| @@ -831,11 +831,11 @@ | ||
| 831 | 831 | zUserOvrd = find_option("user-override",0,1); |
| 832 | 832 | db_must_be_within_tree(); |
| 833 | 833 | noSign = db_get_boolean("omitsign", 0)|noSign; |
| 834 | 834 | if( db_get_boolean("clearsign", 0)==0 ){ noSign = 1; } |
| 835 | 835 | useCksum = db_get_boolean("repo-cksum", 1); |
| 836 | - outputManifest = db_get_boolean("manifest", 0); | |
| 836 | + outputManifest = db_get_versionable_setting_boolean("manifest", 0); | |
| 837 | 837 | verify_all_options(); |
| 838 | 838 | |
| 839 | 839 | /* So that older versions of Fossil (that do not understand delta- |
| 840 | 840 | ** manifest) can continue to use this repository, do not create a new |
| 841 | 841 | ** delta-manifest unless this repository already contains one or more |
| @@ -972,11 +972,11 @@ | ||
| 972 | 972 | ** the identified fils are inserted (if they have been modified). |
| 973 | 973 | */ |
| 974 | 974 | db_prepare(&q, |
| 975 | 975 | "SELECT id, %Q || pathname, mrid, %s FROM vfile " |
| 976 | 976 | "WHERE chnged==1 AND NOT deleted AND file_is_selected(id)", |
| 977 | - g.zLocalRoot, glob_expr("pathname", db_get("crnl-glob","")) | |
| 977 | + g.zLocalRoot, glob_expr("pathname", db_get_versionable_setting("crnl-glob","")) | |
| 978 | 978 | ); |
| 979 | 979 | while( db_step(&q)==SQLITE_ROW ){ |
| 980 | 980 | int id, rid; |
| 981 | 981 | const char *zFullname; |
| 982 | 982 | Blob content; |
| 983 | 983 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -224,16 +224,16 @@ | |
| 224 | int allFlag = find_option("dotfiles",0,0)!=0; |
| 225 | int outputManifest; |
| 226 | Glob *pIgnore; |
| 227 | |
| 228 | db_must_be_within_tree(); |
| 229 | outputManifest = db_get_boolean("manifest",0); |
| 230 | db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)"); |
| 231 | n = strlen(g.zLocalRoot); |
| 232 | blob_init(&path, g.zLocalRoot, n-1); |
| 233 | if( zIgnoreFlag==0 ){ |
| 234 | zIgnoreFlag = db_get("ignore-glob", 0); |
| 235 | } |
| 236 | pIgnore = glob_create(zIgnoreFlag); |
| 237 | vfile_scan(&path, blob_size(&path), allFlag, pIgnore); |
| 238 | glob_free(pIgnore); |
| 239 | db_prepare(&q, |
| @@ -283,11 +283,11 @@ | |
| 283 | allFlag = find_option("force","f",0)!=0; |
| 284 | dotfilesFlag = find_option("dotfiles",0,0)!=0; |
| 285 | zIgnoreFlag = find_option("ignore",0,1); |
| 286 | db_must_be_within_tree(); |
| 287 | if( zIgnoreFlag==0 ){ |
| 288 | zIgnoreFlag = db_get("ignore-glob", 0); |
| 289 | } |
| 290 | db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)"); |
| 291 | n = strlen(g.zLocalRoot); |
| 292 | blob_init(&path, g.zLocalRoot, n-1); |
| 293 | pIgnore = glob_create(zIgnoreFlag); |
| @@ -831,11 +831,11 @@ | |
| 831 | zUserOvrd = find_option("user-override",0,1); |
| 832 | db_must_be_within_tree(); |
| 833 | noSign = db_get_boolean("omitsign", 0)|noSign; |
| 834 | if( db_get_boolean("clearsign", 0)==0 ){ noSign = 1; } |
| 835 | useCksum = db_get_boolean("repo-cksum", 1); |
| 836 | outputManifest = db_get_boolean("manifest", 0); |
| 837 | verify_all_options(); |
| 838 | |
| 839 | /* So that older versions of Fossil (that do not understand delta- |
| 840 | ** manifest) can continue to use this repository, do not create a new |
| 841 | ** delta-manifest unless this repository already contains one or more |
| @@ -972,11 +972,11 @@ | |
| 972 | ** the identified fils are inserted (if they have been modified). |
| 973 | */ |
| 974 | db_prepare(&q, |
| 975 | "SELECT id, %Q || pathname, mrid, %s FROM vfile " |
| 976 | "WHERE chnged==1 AND NOT deleted AND file_is_selected(id)", |
| 977 | g.zLocalRoot, glob_expr("pathname", db_get("crnl-glob","")) |
| 978 | ); |
| 979 | while( db_step(&q)==SQLITE_ROW ){ |
| 980 | int id, rid; |
| 981 | const char *zFullname; |
| 982 | Blob content; |
| 983 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -224,16 +224,16 @@ | |
| 224 | int allFlag = find_option("dotfiles",0,0)!=0; |
| 225 | int outputManifest; |
| 226 | Glob *pIgnore; |
| 227 | |
| 228 | db_must_be_within_tree(); |
| 229 | outputManifest = db_get_versionable_setting_boolean("manifest",0); |
| 230 | db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)"); |
| 231 | n = strlen(g.zLocalRoot); |
| 232 | blob_init(&path, g.zLocalRoot, n-1); |
| 233 | if( zIgnoreFlag==0 ){ |
| 234 | zIgnoreFlag = db_get_versionable_setting("ignore-glob", 0); |
| 235 | } |
| 236 | pIgnore = glob_create(zIgnoreFlag); |
| 237 | vfile_scan(&path, blob_size(&path), allFlag, pIgnore); |
| 238 | glob_free(pIgnore); |
| 239 | db_prepare(&q, |
| @@ -283,11 +283,11 @@ | |
| 283 | allFlag = find_option("force","f",0)!=0; |
| 284 | dotfilesFlag = find_option("dotfiles",0,0)!=0; |
| 285 | zIgnoreFlag = find_option("ignore",0,1); |
| 286 | db_must_be_within_tree(); |
| 287 | if( zIgnoreFlag==0 ){ |
| 288 | zIgnoreFlag = db_get_versionable_setting("ignore-glob", 0); |
| 289 | } |
| 290 | db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)"); |
| 291 | n = strlen(g.zLocalRoot); |
| 292 | blob_init(&path, g.zLocalRoot, n-1); |
| 293 | pIgnore = glob_create(zIgnoreFlag); |
| @@ -831,11 +831,11 @@ | |
| 831 | zUserOvrd = find_option("user-override",0,1); |
| 832 | db_must_be_within_tree(); |
| 833 | noSign = db_get_boolean("omitsign", 0)|noSign; |
| 834 | if( db_get_boolean("clearsign", 0)==0 ){ noSign = 1; } |
| 835 | useCksum = db_get_boolean("repo-cksum", 1); |
| 836 | outputManifest = db_get_versionable_setting_boolean("manifest", 0); |
| 837 | verify_all_options(); |
| 838 | |
| 839 | /* So that older versions of Fossil (that do not understand delta- |
| 840 | ** manifest) can continue to use this repository, do not create a new |
| 841 | ** delta-manifest unless this repository already contains one or more |
| @@ -972,11 +972,11 @@ | |
| 972 | ** the identified fils are inserted (if they have been modified). |
| 973 | */ |
| 974 | db_prepare(&q, |
| 975 | "SELECT id, %Q || pathname, mrid, %s FROM vfile " |
| 976 | "WHERE chnged==1 AND NOT deleted AND file_is_selected(id)", |
| 977 | g.zLocalRoot, glob_expr("pathname", db_get_versionable_setting("crnl-glob","")) |
| 978 | ); |
| 979 | while( db_step(&q)==SQLITE_ROW ){ |
| 980 | int id, rid; |
| 981 | const char *zFullname; |
| 982 | Blob content; |
| 983 |
+2
-1
| --- src/checkout.c | ||
| +++ src/checkout.c | ||
| @@ -141,11 +141,11 @@ | ||
| 141 | 141 | void manifest_to_disk(int vid){ |
| 142 | 142 | char *zManFile; |
| 143 | 143 | Blob manifest; |
| 144 | 144 | Blob hash; |
| 145 | 145 | |
| 146 | - if( db_get_boolean("manifest",0) ){ | |
| 146 | + if( db_get_versionable_setting_boolean("manifest",0) ){ | |
| 147 | 147 | blob_zero(&manifest); |
| 148 | 148 | content_get(vid, &manifest); |
| 149 | 149 | zManFile = mprintf("%smanifest", g.zLocalRoot); |
| 150 | 150 | blob_write_to_file(&manifest, zManFile); |
| 151 | 151 | free(zManFile); |
| @@ -242,10 +242,11 @@ | ||
| 242 | 242 | if( !keepFlag ){ |
| 243 | 243 | vfile_to_disk(vid, 0, 1, promptFlag); |
| 244 | 244 | } |
| 245 | 245 | checkout_set_all_exe(vid); |
| 246 | 246 | manifest_to_disk(vid); |
| 247 | + ensure_empty_dirs_created(); | |
| 247 | 248 | db_lset_int("checkout", vid); |
| 248 | 249 | undo_reset(); |
| 249 | 250 | db_multi_exec("DELETE FROM vmerge"); |
| 250 | 251 | if( !keepFlag && db_get_boolean("repo-cksum",1) ){ |
| 251 | 252 | vfile_aggregate_checksum_manifest(vid, &cksum1, &cksum1b); |
| 252 | 253 |
| --- src/checkout.c | |
| +++ src/checkout.c | |
| @@ -141,11 +141,11 @@ | |
| 141 | void manifest_to_disk(int vid){ |
| 142 | char *zManFile; |
| 143 | Blob manifest; |
| 144 | Blob hash; |
| 145 | |
| 146 | if( db_get_boolean("manifest",0) ){ |
| 147 | blob_zero(&manifest); |
| 148 | content_get(vid, &manifest); |
| 149 | zManFile = mprintf("%smanifest", g.zLocalRoot); |
| 150 | blob_write_to_file(&manifest, zManFile); |
| 151 | free(zManFile); |
| @@ -242,10 +242,11 @@ | |
| 242 | if( !keepFlag ){ |
| 243 | vfile_to_disk(vid, 0, 1, promptFlag); |
| 244 | } |
| 245 | checkout_set_all_exe(vid); |
| 246 | manifest_to_disk(vid); |
| 247 | db_lset_int("checkout", vid); |
| 248 | undo_reset(); |
| 249 | db_multi_exec("DELETE FROM vmerge"); |
| 250 | if( !keepFlag && db_get_boolean("repo-cksum",1) ){ |
| 251 | vfile_aggregate_checksum_manifest(vid, &cksum1, &cksum1b); |
| 252 |
| --- src/checkout.c | |
| +++ src/checkout.c | |
| @@ -141,11 +141,11 @@ | |
| 141 | void manifest_to_disk(int vid){ |
| 142 | char *zManFile; |
| 143 | Blob manifest; |
| 144 | Blob hash; |
| 145 | |
| 146 | if( db_get_versionable_setting_boolean("manifest",0) ){ |
| 147 | blob_zero(&manifest); |
| 148 | content_get(vid, &manifest); |
| 149 | zManFile = mprintf("%smanifest", g.zLocalRoot); |
| 150 | blob_write_to_file(&manifest, zManFile); |
| 151 | free(zManFile); |
| @@ -242,10 +242,11 @@ | |
| 242 | if( !keepFlag ){ |
| 243 | vfile_to_disk(vid, 0, 1, promptFlag); |
| 244 | } |
| 245 | checkout_set_all_exe(vid); |
| 246 | manifest_to_disk(vid); |
| 247 | ensure_empty_dirs_created(); |
| 248 | db_lset_int("checkout", vid); |
| 249 | undo_reset(); |
| 250 | db_multi_exec("DELETE FROM vmerge"); |
| 251 | if( !keepFlag && db_get_boolean("repo-cksum",1) ){ |
| 252 | vfile_aggregate_checksum_manifest(vid, &cksum1, &cksum1b); |
| 253 |
+2
-1
| --- src/checkout.c | ||
| +++ src/checkout.c | ||
| @@ -141,11 +141,11 @@ | ||
| 141 | 141 | void manifest_to_disk(int vid){ |
| 142 | 142 | char *zManFile; |
| 143 | 143 | Blob manifest; |
| 144 | 144 | Blob hash; |
| 145 | 145 | |
| 146 | - if( db_get_boolean("manifest",0) ){ | |
| 146 | + if( db_get_versionable_setting_boolean("manifest",0) ){ | |
| 147 | 147 | blob_zero(&manifest); |
| 148 | 148 | content_get(vid, &manifest); |
| 149 | 149 | zManFile = mprintf("%smanifest", g.zLocalRoot); |
| 150 | 150 | blob_write_to_file(&manifest, zManFile); |
| 151 | 151 | free(zManFile); |
| @@ -242,10 +242,11 @@ | ||
| 242 | 242 | if( !keepFlag ){ |
| 243 | 243 | vfile_to_disk(vid, 0, 1, promptFlag); |
| 244 | 244 | } |
| 245 | 245 | checkout_set_all_exe(vid); |
| 246 | 246 | manifest_to_disk(vid); |
| 247 | + ensure_empty_dirs_created(); | |
| 247 | 248 | db_lset_int("checkout", vid); |
| 248 | 249 | undo_reset(); |
| 249 | 250 | db_multi_exec("DELETE FROM vmerge"); |
| 250 | 251 | if( !keepFlag && db_get_boolean("repo-cksum",1) ){ |
| 251 | 252 | vfile_aggregate_checksum_manifest(vid, &cksum1, &cksum1b); |
| 252 | 253 |
| --- src/checkout.c | |
| +++ src/checkout.c | |
| @@ -141,11 +141,11 @@ | |
| 141 | void manifest_to_disk(int vid){ |
| 142 | char *zManFile; |
| 143 | Blob manifest; |
| 144 | Blob hash; |
| 145 | |
| 146 | if( db_get_boolean("manifest",0) ){ |
| 147 | blob_zero(&manifest); |
| 148 | content_get(vid, &manifest); |
| 149 | zManFile = mprintf("%smanifest", g.zLocalRoot); |
| 150 | blob_write_to_file(&manifest, zManFile); |
| 151 | free(zManFile); |
| @@ -242,10 +242,11 @@ | |
| 242 | if( !keepFlag ){ |
| 243 | vfile_to_disk(vid, 0, 1, promptFlag); |
| 244 | } |
| 245 | checkout_set_all_exe(vid); |
| 246 | manifest_to_disk(vid); |
| 247 | db_lset_int("checkout", vid); |
| 248 | undo_reset(); |
| 249 | db_multi_exec("DELETE FROM vmerge"); |
| 250 | if( !keepFlag && db_get_boolean("repo-cksum",1) ){ |
| 251 | vfile_aggregate_checksum_manifest(vid, &cksum1, &cksum1b); |
| 252 |
| --- src/checkout.c | |
| +++ src/checkout.c | |
| @@ -141,11 +141,11 @@ | |
| 141 | void manifest_to_disk(int vid){ |
| 142 | char *zManFile; |
| 143 | Blob manifest; |
| 144 | Blob hash; |
| 145 | |
| 146 | if( db_get_versionable_setting_boolean("manifest",0) ){ |
| 147 | blob_zero(&manifest); |
| 148 | content_get(vid, &manifest); |
| 149 | zManFile = mprintf("%smanifest", g.zLocalRoot); |
| 150 | blob_write_to_file(&manifest, zManFile); |
| 151 | free(zManFile); |
| @@ -242,10 +242,11 @@ | |
| 242 | if( !keepFlag ){ |
| 243 | vfile_to_disk(vid, 0, 1, promptFlag); |
| 244 | } |
| 245 | checkout_set_all_exe(vid); |
| 246 | manifest_to_disk(vid); |
| 247 | ensure_empty_dirs_created(); |
| 248 | db_lset_int("checkout", vid); |
| 249 | undo_reset(); |
| 250 | db_multi_exec("DELETE FROM vmerge"); |
| 251 | if( !keepFlag && db_get_boolean("repo-cksum",1) ){ |
| 252 | vfile_aggregate_checksum_manifest(vid, &cksum1, &cksum1b); |
| 253 |
+1
| --- src/configure.c | ||
| +++ src/configure.c | ||
| @@ -81,10 +81,11 @@ | ||
| 81 | 81 | { "project-name", CONFIGSET_PROJ }, |
| 82 | 82 | { "project-description", CONFIGSET_PROJ }, |
| 83 | 83 | { "manifest", CONFIGSET_PROJ }, |
| 84 | 84 | { "ignore-glob", CONFIGSET_PROJ }, |
| 85 | 85 | { "crnl-glob", CONFIGSET_PROJ }, |
| 86 | + { "empty-dirs", CONFIGSET_PROJ }, | |
| 86 | 87 | { "index-page", CONFIGSET_SKIN }, |
| 87 | 88 | { "timeline-block-markup", CONFIGSET_SKIN }, |
| 88 | 89 | { "timeline-max-comment", CONFIGSET_SKIN }, |
| 89 | 90 | { "ticket-table", CONFIGSET_TKT }, |
| 90 | 91 | { "ticket-common", CONFIGSET_TKT }, |
| 91 | 92 |
| --- src/configure.c | |
| +++ src/configure.c | |
| @@ -81,10 +81,11 @@ | |
| 81 | { "project-name", CONFIGSET_PROJ }, |
| 82 | { "project-description", CONFIGSET_PROJ }, |
| 83 | { "manifest", CONFIGSET_PROJ }, |
| 84 | { "ignore-glob", CONFIGSET_PROJ }, |
| 85 | { "crnl-glob", CONFIGSET_PROJ }, |
| 86 | { "index-page", CONFIGSET_SKIN }, |
| 87 | { "timeline-block-markup", CONFIGSET_SKIN }, |
| 88 | { "timeline-max-comment", CONFIGSET_SKIN }, |
| 89 | { "ticket-table", CONFIGSET_TKT }, |
| 90 | { "ticket-common", CONFIGSET_TKT }, |
| 91 |
| --- src/configure.c | |
| +++ src/configure.c | |
| @@ -81,10 +81,11 @@ | |
| 81 | { "project-name", CONFIGSET_PROJ }, |
| 82 | { "project-description", CONFIGSET_PROJ }, |
| 83 | { "manifest", CONFIGSET_PROJ }, |
| 84 | { "ignore-glob", CONFIGSET_PROJ }, |
| 85 | { "crnl-glob", CONFIGSET_PROJ }, |
| 86 | { "empty-dirs", CONFIGSET_PROJ }, |
| 87 | { "index-page", CONFIGSET_SKIN }, |
| 88 | { "timeline-block-markup", CONFIGSET_SKIN }, |
| 89 | { "timeline-max-comment", CONFIGSET_SKIN }, |
| 90 | { "ticket-table", CONFIGSET_TKT }, |
| 91 | { "ticket-common", CONFIGSET_TKT }, |
| 92 |
+1
| --- src/configure.c | ||
| +++ src/configure.c | ||
| @@ -81,10 +81,11 @@ | ||
| 81 | 81 | { "project-name", CONFIGSET_PROJ }, |
| 82 | 82 | { "project-description", CONFIGSET_PROJ }, |
| 83 | 83 | { "manifest", CONFIGSET_PROJ }, |
| 84 | 84 | { "ignore-glob", CONFIGSET_PROJ }, |
| 85 | 85 | { "crnl-glob", CONFIGSET_PROJ }, |
| 86 | + { "empty-dirs", CONFIGSET_PROJ }, | |
| 86 | 87 | { "index-page", CONFIGSET_SKIN }, |
| 87 | 88 | { "timeline-block-markup", CONFIGSET_SKIN }, |
| 88 | 89 | { "timeline-max-comment", CONFIGSET_SKIN }, |
| 89 | 90 | { "ticket-table", CONFIGSET_TKT }, |
| 90 | 91 | { "ticket-common", CONFIGSET_TKT }, |
| 91 | 92 |
| --- src/configure.c | |
| +++ src/configure.c | |
| @@ -81,10 +81,11 @@ | |
| 81 | { "project-name", CONFIGSET_PROJ }, |
| 82 | { "project-description", CONFIGSET_PROJ }, |
| 83 | { "manifest", CONFIGSET_PROJ }, |
| 84 | { "ignore-glob", CONFIGSET_PROJ }, |
| 85 | { "crnl-glob", CONFIGSET_PROJ }, |
| 86 | { "index-page", CONFIGSET_SKIN }, |
| 87 | { "timeline-block-markup", CONFIGSET_SKIN }, |
| 88 | { "timeline-max-comment", CONFIGSET_SKIN }, |
| 89 | { "ticket-table", CONFIGSET_TKT }, |
| 90 | { "ticket-common", CONFIGSET_TKT }, |
| 91 |
| --- src/configure.c | |
| +++ src/configure.c | |
| @@ -81,10 +81,11 @@ | |
| 81 | { "project-name", CONFIGSET_PROJ }, |
| 82 | { "project-description", CONFIGSET_PROJ }, |
| 83 | { "manifest", CONFIGSET_PROJ }, |
| 84 | { "ignore-glob", CONFIGSET_PROJ }, |
| 85 | { "crnl-glob", CONFIGSET_PROJ }, |
| 86 | { "empty-dirs", CONFIGSET_PROJ }, |
| 87 | { "index-page", CONFIGSET_SKIN }, |
| 88 | { "timeline-block-markup", CONFIGSET_SKIN }, |
| 89 | { "timeline-max-comment", CONFIGSET_SKIN }, |
| 90 | { "ticket-table", CONFIGSET_TKT }, |
| 91 | { "ticket-common", CONFIGSET_TKT }, |
| 92 |
M
src/db.c
+113
-45
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -1392,10 +1392,57 @@ | ||
| 1392 | 1392 | sqlite3 *dbTemp = g.db; |
| 1393 | 1393 | g.db = g.dbConfig; |
| 1394 | 1394 | g.dbConfig = dbTemp; |
| 1395 | 1395 | } |
| 1396 | 1396 | } |
| 1397 | + | |
| 1398 | +/* | |
| 1399 | +** Get a potentially versioned setting - either from .fossil-settings/<name> | |
| 1400 | +*/ | |
| 1401 | +char *db_get_versionable_setting(const char *zName, char *zDefault){ | |
| 1402 | + /* Attempt to load the versioned setting from a checked out file */ | |
| 1403 | + char *zVersionedSetting = 0; | |
| 1404 | + int noWarn = 0; | |
| 1405 | + if( db_open_local() ){ | |
| 1406 | + Blob versionedPathname; | |
| 1407 | + blob_zero(&versionedPathname); | |
| 1408 | + blob_appendf(&versionedPathname, "%s/.fossil-settings/%s", g.zLocalRoot, zName); | |
| 1409 | + char *zVersionedPathname = blob_str(&versionedPathname); | |
| 1410 | + if( file_size(zVersionedPathname)>=0 ){ | |
| 1411 | + /* File exists, and contains the value for this setting. Load from the file. */ | |
| 1412 | + Blob setting; | |
| 1413 | + blob_zero(&setting); | |
| 1414 | + if( blob_read_from_file(&setting, zVersionedPathname) >= 0 ){ | |
| 1415 | + blob_trim(&setting); /* Avoid non-obvious problems with line endings on boolean properties */ | |
| 1416 | + zVersionedSetting = strdup(blob_str(&setting)); | |
| 1417 | + } | |
| 1418 | + blob_reset(&setting); | |
| 1419 | + /* See if there's a no-warn flag */ | |
| 1420 | + blob_append(&versionedPathname, ".no-warn", -1); | |
| 1421 | + if( file_size(blob_str(&versionedPathname))>=0 ){ | |
| 1422 | + noWarn = 1; | |
| 1423 | + } | |
| 1424 | + } | |
| 1425 | + blob_reset(&versionedPathname); | |
| 1426 | + } | |
| 1427 | + /* Load the normal, non-versioned setting */ | |
| 1428 | + char *zSetting = db_get(zName, zDefault); | |
| 1429 | + /* Display a warning? */ | |
| 1430 | + if( zVersionedSetting!=0 && zSetting!=0 && zSetting[0]!='\0' && zSetting!=zDefault && !noWarn ){ | |
| 1431 | + /* There's a versioned setting, and a non-versioned setting. Tell the user about the conflict */ | |
| 1432 | + fossil_warning("Setting %s has both versioned and non-versioned values: using versioned value from file .fossil-settings/%s (To silence this warning, either create an empty file named .fossil-settings/%s.no-warn or delete the non-versioned setting with \"fossil unset %s\")", zName, zName, zName, zName); | |
| 1433 | + } | |
| 1434 | + /* Prefer the versioned setting */ | |
| 1435 | + return ( zVersionedSetting!=0 ) ? zVersionedSetting : zSetting; | |
| 1436 | +} | |
| 1437 | +int db_get_versionable_setting_boolean(const char *zName, int dflt){ | |
| 1438 | + char *zVal = db_get_versionable_setting(zName, dflt ? "on" : "off"); | |
| 1439 | + if( is_truth(zVal) ) return 1; | |
| 1440 | + if( is_false(zVal) ) return 0; | |
| 1441 | + return dflt; | |
| 1442 | +} | |
| 1443 | + | |
| 1397 | 1444 | |
| 1398 | 1445 | /* |
| 1399 | 1446 | ** Get and set values from the CONFIG, GLOBAL_CONFIG and VVAR table in the |
| 1400 | 1447 | ** repository and local databases. |
| 1401 | 1448 | */ |
| @@ -1596,30 +1643,39 @@ | ||
| 1596 | 1643 | } |
| 1597 | 1644 | |
| 1598 | 1645 | /* |
| 1599 | 1646 | ** Print the value of a setting named zName |
| 1600 | 1647 | */ |
| 1601 | -static void print_setting(const char *zName){ | |
| 1648 | +static void print_setting(const struct stControlSettings *ctrlSetting, int localOpen){ | |
| 1602 | 1649 | Stmt q; |
| 1603 | 1650 | if( g.repositoryOpen ){ |
| 1604 | 1651 | db_prepare(&q, |
| 1605 | 1652 | "SELECT '(local)', value FROM config WHERE name=%Q" |
| 1606 | 1653 | " UNION ALL " |
| 1607 | 1654 | "SELECT '(global)', value FROM global_config WHERE name=%Q", |
| 1608 | - zName, zName | |
| 1655 | + ctrlSetting->name, ctrlSetting->name | |
| 1609 | 1656 | ); |
| 1610 | 1657 | }else{ |
| 1611 | 1658 | db_prepare(&q, |
| 1612 | 1659 | "SELECT '(global)', value FROM global_config WHERE name=%Q", |
| 1613 | - zName | |
| 1660 | + ctrlSetting->name | |
| 1614 | 1661 | ); |
| 1615 | 1662 | } |
| 1616 | 1663 | if( db_step(&q)==SQLITE_ROW ){ |
| 1617 | - fossil_print("%-20s %-8s %s\n", zName, db_column_text(&q, 0), | |
| 1664 | + fossil_print("%-20s %-8s %s\n", ctrlSetting->name, db_column_text(&q, 0), | |
| 1618 | 1665 | db_column_text(&q, 1)); |
| 1619 | 1666 | }else{ |
| 1620 | - fossil_print("%-20s\n", zName); | |
| 1667 | + fossil_print("%-20s\n", ctrlSetting->name); | |
| 1668 | + } | |
| 1669 | + if( ctrlSetting->versionable && localOpen ){ | |
| 1670 | + /* Check to see if this is overridden by a versionable settings file */ | |
| 1671 | + Blob versionedPathname; | |
| 1672 | + blob_zero(&versionedPathname); | |
| 1673 | + blob_appendf(&versionedPathname, "%s/.fossil-settings/%s", g.zLocalRoot, ctrlSetting->name); | |
| 1674 | + if( file_size(blob_str(&versionedPathname))>=0 ){ | |
| 1675 | + fossil_print(" (overridden by contents of file .fossil-settings/%s)\n", ctrlSetting->name); | |
| 1676 | + } | |
| 1621 | 1677 | } |
| 1622 | 1678 | db_finalize(&q); |
| 1623 | 1679 | } |
| 1624 | 1680 | |
| 1625 | 1681 | |
| @@ -1635,43 +1691,45 @@ | ||
| 1635 | 1691 | #if INTERFACE |
| 1636 | 1692 | struct stControlSettings { |
| 1637 | 1693 | char const *name; /* Name of the setting */ |
| 1638 | 1694 | char const *var; /* Internal variable name used by db_set() */ |
| 1639 | 1695 | int width; /* Width of display. 0 for boolean values */ |
| 1696 | + int versionable; /* Is this setting versionable? */ | |
| 1640 | 1697 | char const *def; /* Default value */ |
| 1641 | 1698 | }; |
| 1642 | 1699 | #endif /* INTERFACE */ |
| 1643 | 1700 | struct stControlSettings const ctrlSettings[] = { |
| 1644 | - { "access-log", 0, 0, "off" }, | |
| 1645 | - { "auto-captcha", "autocaptcha", 0, "on" }, | |
| 1646 | - { "auto-shun", 0, 0, "on" }, | |
| 1647 | - { "autosync", 0, 0, "on" }, | |
| 1648 | - { "binary-glob", 0, 32, "" }, | |
| 1649 | - { "clearsign", 0, 0, "off" }, | |
| 1650 | - { "crnl-glob", 0, 16, "" }, | |
| 1651 | - { "default-perms", 0, 16, "u" }, | |
| 1652 | - { "diff-command", 0, 16, "" }, | |
| 1653 | - { "dont-push", 0, 0, "off" }, | |
| 1654 | - { "editor", 0, 16, "" }, | |
| 1655 | - { "gdiff-command", 0, 16, "gdiff" }, | |
| 1656 | - { "gmerge-command",0, 40, "" }, | |
| 1657 | - { "https-login", 0, 0, "off" }, | |
| 1658 | - { "ignore-glob", 0, 40, "" }, | |
| 1659 | - { "http-port", 0, 16, "8080" }, | |
| 1660 | - { "localauth", 0, 0, "off" }, | |
| 1661 | - { "main-branch", 0, 40, "trunk" }, | |
| 1662 | - { "manifest", 0, 0, "off" }, | |
| 1663 | - { "max-upload", 0, 25, "250000" }, | |
| 1664 | - { "mtime-changes", 0, 0, "on" }, | |
| 1665 | - { "pgp-command", 0, 32, "gpg --clearsign -o " }, | |
| 1666 | - { "proxy", 0, 32, "off" }, | |
| 1667 | - { "repo-cksum", 0, 0, "on" }, | |
| 1668 | - { "self-register", 0, 0, "off" }, | |
| 1669 | - { "ssl-identity", 0, 40, "" }, | |
| 1670 | - { "ssh-command", 0, 32, "" }, | |
| 1671 | - { "web-browser", 0, 32, "" }, | |
| 1672 | - { 0,0,0,0 } | |
| 1701 | + { "access-log", 0, 0, 0, "off" }, | |
| 1702 | + { "auto-captcha", "autocaptcha", 0, 0, "on" }, | |
| 1703 | + { "auto-shun", 0, 0, 0, "on" }, | |
| 1704 | + { "autosync", 0, 0, 0, "on" }, | |
| 1705 | + { "binary-glob", 0, 32, 1, "" }, | |
| 1706 | + { "clearsign", 0, 0, 0, "off" }, | |
| 1707 | + { "crnl-glob", 0, 16, 1, "" }, | |
| 1708 | + { "default-perms", 0, 16, 0, "u" }, | |
| 1709 | + { "diff-command", 0, 16, 0, "" }, | |
| 1710 | + { "dont-push", 0, 0, 0, "off" }, | |
| 1711 | + { "editor", 0, 16, 0, "" }, | |
| 1712 | + { "gdiff-command", 0, 16, 0, "gdiff" }, | |
| 1713 | + { "gmerge-command",0, 40, 0, "" }, | |
| 1714 | + { "https-login", 0, 0, 0, "off" }, | |
| 1715 | + { "ignore-glob", 0, 40, 1, "" }, | |
| 1716 | + { "empty-dirs", 0, 40, 1, "" }, | |
| 1717 | + { "http-port", 0, 16, 0, "8080" }, | |
| 1718 | + { "localauth", 0, 0, 0, "off" }, | |
| 1719 | + { "main-branch", 0, 40, 0, "trunk" }, | |
| 1720 | + { "manifest", 0, 0, 1, "off" }, | |
| 1721 | + { "max-upload", 0, 25, 0, "250000" }, | |
| 1722 | + { "mtime-changes", 0, 0, 0, "on" }, | |
| 1723 | + { "pgp-command", 0, 32, 0, "gpg --clearsign -o " }, | |
| 1724 | + { "proxy", 0, 32, 0, "off" }, | |
| 1725 | + { "repo-cksum", 0, 0, 0, "on" }, | |
| 1726 | + { "self-register", 0, 0, 0, "off" }, | |
| 1727 | + { "ssl-identity", 0, 40, 0, "" }, | |
| 1728 | + { "ssh-command", 0, 32, 0, "" }, | |
| 1729 | + { "web-browser", 0, 32, 0, "" }, | |
| 1730 | + { 0,0,0,0,0 } | |
| 1673 | 1731 | }; |
| 1674 | 1732 | |
| 1675 | 1733 | /* |
| 1676 | 1734 | ** COMMAND: settings |
| 1677 | 1735 | ** COMMAND: unset |
| @@ -1680,10 +1738,14 @@ | ||
| 1680 | 1738 | ** %fossil unset PROPERTY ?-global? |
| 1681 | 1739 | ** |
| 1682 | 1740 | ** The "settings" command with no arguments lists all properties and their |
| 1683 | 1741 | ** values. With just a property name it shows the value of that property. |
| 1684 | 1742 | ** With a value argument it changes the property for the current repository. |
| 1743 | +** | |
| 1744 | +** Settings marked as versionable are overridden by the contents of the | |
| 1745 | +** file named .fossil-settings/PROPERTY in the checked out files, if that | |
| 1746 | +** file exists. | |
| 1685 | 1747 | ** |
| 1686 | 1748 | ** The "unset" command clears a property setting. |
| 1687 | 1749 | ** |
| 1688 | 1750 | ** |
| 1689 | 1751 | ** auto-captcha If enabled, the Login page provides a button to |
| @@ -1697,20 +1759,20 @@ | ||
| 1697 | 1759 | ** or update and automatically push after commit or |
| 1698 | 1760 | ** tag or branch creation. If the value is "pullonly" |
| 1699 | 1761 | ** then only pull operations occur automatically. |
| 1700 | 1762 | ** Default: on |
| 1701 | 1763 | ** |
| 1702 | -** binary-glob The VALUE is a comma-separated list of GLOB patterns | |
| 1703 | -** that should be treated as binary files for merging | |
| 1704 | -** purposes. Example: *.xml | |
| 1764 | +** binary-glob The VALUE is a comma or newline-separated list of | |
| 1765 | +** (versionable) GLOB patterns that should be treated as binary files | |
| 1766 | +** for merging purposes. Example: *.xml | |
| 1705 | 1767 | ** |
| 1706 | 1768 | ** clearsign When enabled, fossil will attempt to sign all commits |
| 1707 | 1769 | ** with gpg. When disabled (the default), commits will |
| 1708 | 1770 | ** be unsigned. Default: off |
| 1709 | 1771 | ** |
| 1710 | -** crnl-glob A comma-separated list of GLOB patterns for text files | |
| 1711 | -** in which it is ok to have CR+NL line endings. | |
| 1772 | +** crnl-glob A comma or newline-separated list of GLOB patterns for | |
| 1773 | +** (versionable) text files in which it is ok to have CR+NL line endings. | |
| 1712 | 1774 | ** Set to "*" to disable CR+NL checking. |
| 1713 | 1775 | ** |
| 1714 | 1776 | ** default-perms Permissions given automatically to new users. For more |
| 1715 | 1777 | ** information on permissions see Users page in Server |
| 1716 | 1778 | ** Administration of the HTTP UI. Default: u. |
| @@ -1718,10 +1780,15 @@ | ||
| 1718 | 1780 | ** diff-command External command to run when performing a diff. |
| 1719 | 1781 | ** If undefined, the internal text diff will be used. |
| 1720 | 1782 | ** |
| 1721 | 1783 | ** dont-push Prevent this repository from pushing from client to |
| 1722 | 1784 | ** server. Useful when setting up a private branch. |
| 1785 | +** | |
| 1786 | +** empty-dirs A comma or newline-separated list of pathnames. On | |
| 1787 | +** (versionable) update and checkout commands, if no file or directory | |
| 1788 | +** exists with that name, an empty directory will be | |
| 1789 | +** created. | |
| 1723 | 1790 | ** |
| 1724 | 1791 | ** editor Text editor command used for check-in comments. |
| 1725 | 1792 | ** |
| 1726 | 1793 | ** gdiff-command External command to run when performing a graphical |
| 1727 | 1794 | ** diff. If undefined, text diff will be used. |
| @@ -1736,23 +1803,23 @@ | ||
| 1736 | 1803 | ** and "ui" commands. Default: 8080 |
| 1737 | 1804 | ** |
| 1738 | 1805 | ** https-login Send login creditials using HTTPS instead of HTTP |
| 1739 | 1806 | ** even if the login page request came via HTTP. |
| 1740 | 1807 | ** |
| 1741 | -** ignore-glob The VALUE is a comma-separated list of GLOB patterns | |
| 1742 | -** specifying files that the "extra" command will ignore. | |
| 1743 | -** Example: *.o,*.obj,*.exe | |
| 1808 | +** ignore-glob The VALUE is a comma or newline-separated list of GLOB | |
| 1809 | +** (versionable) patterns specifying files that the "extra" command will | |
| 1810 | +** ignore. Example: *.o,*.obj,*.exe | |
| 1744 | 1811 | ** |
| 1745 | 1812 | ** localauth If enabled, require that HTTP connections from |
| 1746 | 1813 | ** 127.0.0.1 be authenticated by password. If |
| 1747 | 1814 | ** false, all HTTP requests from localhost have |
| 1748 | 1815 | ** unrestricted access to the repository. |
| 1749 | 1816 | ** |
| 1750 | 1817 | ** main-branch The primary branch for the project. Default: trunk |
| 1751 | 1818 | ** |
| 1752 | 1819 | ** manifest If enabled, automatically create files "manifest" and |
| 1753 | -** "manifest.uuid" in every checkout. The SQLite and | |
| 1820 | +** (versionable) "manifest.uuid" in every checkout. The SQLite and | |
| 1754 | 1821 | ** Fossil repositories both require this. Default: off. |
| 1755 | 1822 | ** |
| 1756 | 1823 | ** max-upload A limit on the size of uplink HTTP requests. The |
| 1757 | 1824 | ** default is 250000 bytes. |
| 1758 | 1825 | ** |
| @@ -1805,12 +1872,13 @@ | ||
| 1805 | 1872 | } |
| 1806 | 1873 | if( unsetFlag && g.argc!=3 ){ |
| 1807 | 1874 | usage("PROPERTY ?-global?"); |
| 1808 | 1875 | } |
| 1809 | 1876 | if( g.argc==2 ){ |
| 1877 | + int openLocal = db_open_local(); | |
| 1810 | 1878 | for(i=0; ctrlSettings[i].name; i++){ |
| 1811 | - print_setting(ctrlSettings[i].name); | |
| 1879 | + print_setting(&ctrlSettings[i], openLocal); | |
| 1812 | 1880 | } |
| 1813 | 1881 | }else if( g.argc==3 || g.argc==4 ){ |
| 1814 | 1882 | const char *zName = g.argv[2]; |
| 1815 | 1883 | int isManifest; |
| 1816 | 1884 | int n = strlen(zName); |
| @@ -1828,11 +1896,11 @@ | ||
| 1828 | 1896 | db_unset(ctrlSettings[i].name, globalFlag); |
| 1829 | 1897 | }else if( g.argc==4 ){ |
| 1830 | 1898 | db_set(ctrlSettings[i].name, g.argv[3], globalFlag); |
| 1831 | 1899 | }else{ |
| 1832 | 1900 | isManifest = 0; |
| 1833 | - print_setting(ctrlSettings[i].name); | |
| 1901 | + print_setting(&ctrlSettings[i], db_open_local()); | |
| 1834 | 1902 | } |
| 1835 | 1903 | if( isManifest ){ |
| 1836 | 1904 | manifest_to_disk(db_lget_int("checkout", 0)); |
| 1837 | 1905 | } |
| 1838 | 1906 | }else{ |
| 1839 | 1907 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -1392,10 +1392,57 @@ | |
| 1392 | sqlite3 *dbTemp = g.db; |
| 1393 | g.db = g.dbConfig; |
| 1394 | g.dbConfig = dbTemp; |
| 1395 | } |
| 1396 | } |
| 1397 | |
| 1398 | /* |
| 1399 | ** Get and set values from the CONFIG, GLOBAL_CONFIG and VVAR table in the |
| 1400 | ** repository and local databases. |
| 1401 | */ |
| @@ -1596,30 +1643,39 @@ | |
| 1596 | } |
| 1597 | |
| 1598 | /* |
| 1599 | ** Print the value of a setting named zName |
| 1600 | */ |
| 1601 | static void print_setting(const char *zName){ |
| 1602 | Stmt q; |
| 1603 | if( g.repositoryOpen ){ |
| 1604 | db_prepare(&q, |
| 1605 | "SELECT '(local)', value FROM config WHERE name=%Q" |
| 1606 | " UNION ALL " |
| 1607 | "SELECT '(global)', value FROM global_config WHERE name=%Q", |
| 1608 | zName, zName |
| 1609 | ); |
| 1610 | }else{ |
| 1611 | db_prepare(&q, |
| 1612 | "SELECT '(global)', value FROM global_config WHERE name=%Q", |
| 1613 | zName |
| 1614 | ); |
| 1615 | } |
| 1616 | if( db_step(&q)==SQLITE_ROW ){ |
| 1617 | fossil_print("%-20s %-8s %s\n", zName, db_column_text(&q, 0), |
| 1618 | db_column_text(&q, 1)); |
| 1619 | }else{ |
| 1620 | fossil_print("%-20s\n", zName); |
| 1621 | } |
| 1622 | db_finalize(&q); |
| 1623 | } |
| 1624 | |
| 1625 | |
| @@ -1635,43 +1691,45 @@ | |
| 1635 | #if INTERFACE |
| 1636 | struct stControlSettings { |
| 1637 | char const *name; /* Name of the setting */ |
| 1638 | char const *var; /* Internal variable name used by db_set() */ |
| 1639 | int width; /* Width of display. 0 for boolean values */ |
| 1640 | char const *def; /* Default value */ |
| 1641 | }; |
| 1642 | #endif /* INTERFACE */ |
| 1643 | struct stControlSettings const ctrlSettings[] = { |
| 1644 | { "access-log", 0, 0, "off" }, |
| 1645 | { "auto-captcha", "autocaptcha", 0, "on" }, |
| 1646 | { "auto-shun", 0, 0, "on" }, |
| 1647 | { "autosync", 0, 0, "on" }, |
| 1648 | { "binary-glob", 0, 32, "" }, |
| 1649 | { "clearsign", 0, 0, "off" }, |
| 1650 | { "crnl-glob", 0, 16, "" }, |
| 1651 | { "default-perms", 0, 16, "u" }, |
| 1652 | { "diff-command", 0, 16, "" }, |
| 1653 | { "dont-push", 0, 0, "off" }, |
| 1654 | { "editor", 0, 16, "" }, |
| 1655 | { "gdiff-command", 0, 16, "gdiff" }, |
| 1656 | { "gmerge-command",0, 40, "" }, |
| 1657 | { "https-login", 0, 0, "off" }, |
| 1658 | { "ignore-glob", 0, 40, "" }, |
| 1659 | { "http-port", 0, 16, "8080" }, |
| 1660 | { "localauth", 0, 0, "off" }, |
| 1661 | { "main-branch", 0, 40, "trunk" }, |
| 1662 | { "manifest", 0, 0, "off" }, |
| 1663 | { "max-upload", 0, 25, "250000" }, |
| 1664 | { "mtime-changes", 0, 0, "on" }, |
| 1665 | { "pgp-command", 0, 32, "gpg --clearsign -o " }, |
| 1666 | { "proxy", 0, 32, "off" }, |
| 1667 | { "repo-cksum", 0, 0, "on" }, |
| 1668 | { "self-register", 0, 0, "off" }, |
| 1669 | { "ssl-identity", 0, 40, "" }, |
| 1670 | { "ssh-command", 0, 32, "" }, |
| 1671 | { "web-browser", 0, 32, "" }, |
| 1672 | { 0,0,0,0 } |
| 1673 | }; |
| 1674 | |
| 1675 | /* |
| 1676 | ** COMMAND: settings |
| 1677 | ** COMMAND: unset |
| @@ -1680,10 +1738,14 @@ | |
| 1680 | ** %fossil unset PROPERTY ?-global? |
| 1681 | ** |
| 1682 | ** The "settings" command with no arguments lists all properties and their |
| 1683 | ** values. With just a property name it shows the value of that property. |
| 1684 | ** With a value argument it changes the property for the current repository. |
| 1685 | ** |
| 1686 | ** The "unset" command clears a property setting. |
| 1687 | ** |
| 1688 | ** |
| 1689 | ** auto-captcha If enabled, the Login page provides a button to |
| @@ -1697,20 +1759,20 @@ | |
| 1697 | ** or update and automatically push after commit or |
| 1698 | ** tag or branch creation. If the value is "pullonly" |
| 1699 | ** then only pull operations occur automatically. |
| 1700 | ** Default: on |
| 1701 | ** |
| 1702 | ** binary-glob The VALUE is a comma-separated list of GLOB patterns |
| 1703 | ** that should be treated as binary files for merging |
| 1704 | ** purposes. Example: *.xml |
| 1705 | ** |
| 1706 | ** clearsign When enabled, fossil will attempt to sign all commits |
| 1707 | ** with gpg. When disabled (the default), commits will |
| 1708 | ** be unsigned. Default: off |
| 1709 | ** |
| 1710 | ** crnl-glob A comma-separated list of GLOB patterns for text files |
| 1711 | ** in which it is ok to have CR+NL line endings. |
| 1712 | ** Set to "*" to disable CR+NL checking. |
| 1713 | ** |
| 1714 | ** default-perms Permissions given automatically to new users. For more |
| 1715 | ** information on permissions see Users page in Server |
| 1716 | ** Administration of the HTTP UI. Default: u. |
| @@ -1718,10 +1780,15 @@ | |
| 1718 | ** diff-command External command to run when performing a diff. |
| 1719 | ** If undefined, the internal text diff will be used. |
| 1720 | ** |
| 1721 | ** dont-push Prevent this repository from pushing from client to |
| 1722 | ** server. Useful when setting up a private branch. |
| 1723 | ** |
| 1724 | ** editor Text editor command used for check-in comments. |
| 1725 | ** |
| 1726 | ** gdiff-command External command to run when performing a graphical |
| 1727 | ** diff. If undefined, text diff will be used. |
| @@ -1736,23 +1803,23 @@ | |
| 1736 | ** and "ui" commands. Default: 8080 |
| 1737 | ** |
| 1738 | ** https-login Send login creditials using HTTPS instead of HTTP |
| 1739 | ** even if the login page request came via HTTP. |
| 1740 | ** |
| 1741 | ** ignore-glob The VALUE is a comma-separated list of GLOB patterns |
| 1742 | ** specifying files that the "extra" command will ignore. |
| 1743 | ** Example: *.o,*.obj,*.exe |
| 1744 | ** |
| 1745 | ** localauth If enabled, require that HTTP connections from |
| 1746 | ** 127.0.0.1 be authenticated by password. If |
| 1747 | ** false, all HTTP requests from localhost have |
| 1748 | ** unrestricted access to the repository. |
| 1749 | ** |
| 1750 | ** main-branch The primary branch for the project. Default: trunk |
| 1751 | ** |
| 1752 | ** manifest If enabled, automatically create files "manifest" and |
| 1753 | ** "manifest.uuid" in every checkout. The SQLite and |
| 1754 | ** Fossil repositories both require this. Default: off. |
| 1755 | ** |
| 1756 | ** max-upload A limit on the size of uplink HTTP requests. The |
| 1757 | ** default is 250000 bytes. |
| 1758 | ** |
| @@ -1805,12 +1872,13 @@ | |
| 1805 | } |
| 1806 | if( unsetFlag && g.argc!=3 ){ |
| 1807 | usage("PROPERTY ?-global?"); |
| 1808 | } |
| 1809 | if( g.argc==2 ){ |
| 1810 | for(i=0; ctrlSettings[i].name; i++){ |
| 1811 | print_setting(ctrlSettings[i].name); |
| 1812 | } |
| 1813 | }else if( g.argc==3 || g.argc==4 ){ |
| 1814 | const char *zName = g.argv[2]; |
| 1815 | int isManifest; |
| 1816 | int n = strlen(zName); |
| @@ -1828,11 +1896,11 @@ | |
| 1828 | db_unset(ctrlSettings[i].name, globalFlag); |
| 1829 | }else if( g.argc==4 ){ |
| 1830 | db_set(ctrlSettings[i].name, g.argv[3], globalFlag); |
| 1831 | }else{ |
| 1832 | isManifest = 0; |
| 1833 | print_setting(ctrlSettings[i].name); |
| 1834 | } |
| 1835 | if( isManifest ){ |
| 1836 | manifest_to_disk(db_lget_int("checkout", 0)); |
| 1837 | } |
| 1838 | }else{ |
| 1839 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -1392,10 +1392,57 @@ | |
| 1392 | sqlite3 *dbTemp = g.db; |
| 1393 | g.db = g.dbConfig; |
| 1394 | g.dbConfig = dbTemp; |
| 1395 | } |
| 1396 | } |
| 1397 | |
| 1398 | /* |
| 1399 | ** Get a potentially versioned setting - either from .fossil-settings/<name> |
| 1400 | */ |
| 1401 | char *db_get_versionable_setting(const char *zName, char *zDefault){ |
| 1402 | /* Attempt to load the versioned setting from a checked out file */ |
| 1403 | char *zVersionedSetting = 0; |
| 1404 | int noWarn = 0; |
| 1405 | if( db_open_local() ){ |
| 1406 | Blob versionedPathname; |
| 1407 | blob_zero(&versionedPathname); |
| 1408 | blob_appendf(&versionedPathname, "%s/.fossil-settings/%s", g.zLocalRoot, zName); |
| 1409 | char *zVersionedPathname = blob_str(&versionedPathname); |
| 1410 | if( file_size(zVersionedPathname)>=0 ){ |
| 1411 | /* File exists, and contains the value for this setting. Load from the file. */ |
| 1412 | Blob setting; |
| 1413 | blob_zero(&setting); |
| 1414 | if( blob_read_from_file(&setting, zVersionedPathname) >= 0 ){ |
| 1415 | blob_trim(&setting); /* Avoid non-obvious problems with line endings on boolean properties */ |
| 1416 | zVersionedSetting = strdup(blob_str(&setting)); |
| 1417 | } |
| 1418 | blob_reset(&setting); |
| 1419 | /* See if there's a no-warn flag */ |
| 1420 | blob_append(&versionedPathname, ".no-warn", -1); |
| 1421 | if( file_size(blob_str(&versionedPathname))>=0 ){ |
| 1422 | noWarn = 1; |
| 1423 | } |
| 1424 | } |
| 1425 | blob_reset(&versionedPathname); |
| 1426 | } |
| 1427 | /* Load the normal, non-versioned setting */ |
| 1428 | char *zSetting = db_get(zName, zDefault); |
| 1429 | /* Display a warning? */ |
| 1430 | if( zVersionedSetting!=0 && zSetting!=0 && zSetting[0]!='\0' && zSetting!=zDefault && !noWarn ){ |
| 1431 | /* There's a versioned setting, and a non-versioned setting. Tell the user about the conflict */ |
| 1432 | fossil_warning("Setting %s has both versioned and non-versioned values: using versioned value from file .fossil-settings/%s (To silence this warning, either create an empty file named .fossil-settings/%s.no-warn or delete the non-versioned setting with \"fossil unset %s\")", zName, zName, zName, zName); |
| 1433 | } |
| 1434 | /* Prefer the versioned setting */ |
| 1435 | return ( zVersionedSetting!=0 ) ? zVersionedSetting : zSetting; |
| 1436 | } |
| 1437 | int db_get_versionable_setting_boolean(const char *zName, int dflt){ |
| 1438 | char *zVal = db_get_versionable_setting(zName, dflt ? "on" : "off"); |
| 1439 | if( is_truth(zVal) ) return 1; |
| 1440 | if( is_false(zVal) ) return 0; |
| 1441 | return dflt; |
| 1442 | } |
| 1443 | |
| 1444 | |
| 1445 | /* |
| 1446 | ** Get and set values from the CONFIG, GLOBAL_CONFIG and VVAR table in the |
| 1447 | ** repository and local databases. |
| 1448 | */ |
| @@ -1596,30 +1643,39 @@ | |
| 1643 | } |
| 1644 | |
| 1645 | /* |
| 1646 | ** Print the value of a setting named zName |
| 1647 | */ |
| 1648 | static void print_setting(const struct stControlSettings *ctrlSetting, int localOpen){ |
| 1649 | Stmt q; |
| 1650 | if( g.repositoryOpen ){ |
| 1651 | db_prepare(&q, |
| 1652 | "SELECT '(local)', value FROM config WHERE name=%Q" |
| 1653 | " UNION ALL " |
| 1654 | "SELECT '(global)', value FROM global_config WHERE name=%Q", |
| 1655 | ctrlSetting->name, ctrlSetting->name |
| 1656 | ); |
| 1657 | }else{ |
| 1658 | db_prepare(&q, |
| 1659 | "SELECT '(global)', value FROM global_config WHERE name=%Q", |
| 1660 | ctrlSetting->name |
| 1661 | ); |
| 1662 | } |
| 1663 | if( db_step(&q)==SQLITE_ROW ){ |
| 1664 | fossil_print("%-20s %-8s %s\n", ctrlSetting->name, db_column_text(&q, 0), |
| 1665 | db_column_text(&q, 1)); |
| 1666 | }else{ |
| 1667 | fossil_print("%-20s\n", ctrlSetting->name); |
| 1668 | } |
| 1669 | if( ctrlSetting->versionable && localOpen ){ |
| 1670 | /* Check to see if this is overridden by a versionable settings file */ |
| 1671 | Blob versionedPathname; |
| 1672 | blob_zero(&versionedPathname); |
| 1673 | blob_appendf(&versionedPathname, "%s/.fossil-settings/%s", g.zLocalRoot, ctrlSetting->name); |
| 1674 | if( file_size(blob_str(&versionedPathname))>=0 ){ |
| 1675 | fossil_print(" (overridden by contents of file .fossil-settings/%s)\n", ctrlSetting->name); |
| 1676 | } |
| 1677 | } |
| 1678 | db_finalize(&q); |
| 1679 | } |
| 1680 | |
| 1681 | |
| @@ -1635,43 +1691,45 @@ | |
| 1691 | #if INTERFACE |
| 1692 | struct stControlSettings { |
| 1693 | char const *name; /* Name of the setting */ |
| 1694 | char const *var; /* Internal variable name used by db_set() */ |
| 1695 | int width; /* Width of display. 0 for boolean values */ |
| 1696 | int versionable; /* Is this setting versionable? */ |
| 1697 | char const *def; /* Default value */ |
| 1698 | }; |
| 1699 | #endif /* INTERFACE */ |
| 1700 | struct stControlSettings const ctrlSettings[] = { |
| 1701 | { "access-log", 0, 0, 0, "off" }, |
| 1702 | { "auto-captcha", "autocaptcha", 0, 0, "on" }, |
| 1703 | { "auto-shun", 0, 0, 0, "on" }, |
| 1704 | { "autosync", 0, 0, 0, "on" }, |
| 1705 | { "binary-glob", 0, 32, 1, "" }, |
| 1706 | { "clearsign", 0, 0, 0, "off" }, |
| 1707 | { "crnl-glob", 0, 16, 1, "" }, |
| 1708 | { "default-perms", 0, 16, 0, "u" }, |
| 1709 | { "diff-command", 0, 16, 0, "" }, |
| 1710 | { "dont-push", 0, 0, 0, "off" }, |
| 1711 | { "editor", 0, 16, 0, "" }, |
| 1712 | { "gdiff-command", 0, 16, 0, "gdiff" }, |
| 1713 | { "gmerge-command",0, 40, 0, "" }, |
| 1714 | { "https-login", 0, 0, 0, "off" }, |
| 1715 | { "ignore-glob", 0, 40, 1, "" }, |
| 1716 | { "empty-dirs", 0, 40, 1, "" }, |
| 1717 | { "http-port", 0, 16, 0, "8080" }, |
| 1718 | { "localauth", 0, 0, 0, "off" }, |
| 1719 | { "main-branch", 0, 40, 0, "trunk" }, |
| 1720 | { "manifest", 0, 0, 1, "off" }, |
| 1721 | { "max-upload", 0, 25, 0, "250000" }, |
| 1722 | { "mtime-changes", 0, 0, 0, "on" }, |
| 1723 | { "pgp-command", 0, 32, 0, "gpg --clearsign -o " }, |
| 1724 | { "proxy", 0, 32, 0, "off" }, |
| 1725 | { "repo-cksum", 0, 0, 0, "on" }, |
| 1726 | { "self-register", 0, 0, 0, "off" }, |
| 1727 | { "ssl-identity", 0, 40, 0, "" }, |
| 1728 | { "ssh-command", 0, 32, 0, "" }, |
| 1729 | { "web-browser", 0, 32, 0, "" }, |
| 1730 | { 0,0,0,0,0 } |
| 1731 | }; |
| 1732 | |
| 1733 | /* |
| 1734 | ** COMMAND: settings |
| 1735 | ** COMMAND: unset |
| @@ -1680,10 +1738,14 @@ | |
| 1738 | ** %fossil unset PROPERTY ?-global? |
| 1739 | ** |
| 1740 | ** The "settings" command with no arguments lists all properties and their |
| 1741 | ** values. With just a property name it shows the value of that property. |
| 1742 | ** With a value argument it changes the property for the current repository. |
| 1743 | ** |
| 1744 | ** Settings marked as versionable are overridden by the contents of the |
| 1745 | ** file named .fossil-settings/PROPERTY in the checked out files, if that |
| 1746 | ** file exists. |
| 1747 | ** |
| 1748 | ** The "unset" command clears a property setting. |
| 1749 | ** |
| 1750 | ** |
| 1751 | ** auto-captcha If enabled, the Login page provides a button to |
| @@ -1697,20 +1759,20 @@ | |
| 1759 | ** or update and automatically push after commit or |
| 1760 | ** tag or branch creation. If the value is "pullonly" |
| 1761 | ** then only pull operations occur automatically. |
| 1762 | ** Default: on |
| 1763 | ** |
| 1764 | ** binary-glob The VALUE is a comma or newline-separated list of |
| 1765 | ** (versionable) GLOB patterns that should be treated as binary files |
| 1766 | ** for merging purposes. Example: *.xml |
| 1767 | ** |
| 1768 | ** clearsign When enabled, fossil will attempt to sign all commits |
| 1769 | ** with gpg. When disabled (the default), commits will |
| 1770 | ** be unsigned. Default: off |
| 1771 | ** |
| 1772 | ** crnl-glob A comma or newline-separated list of GLOB patterns for |
| 1773 | ** (versionable) text files in which it is ok to have CR+NL line endings. |
| 1774 | ** Set to "*" to disable CR+NL checking. |
| 1775 | ** |
| 1776 | ** default-perms Permissions given automatically to new users. For more |
| 1777 | ** information on permissions see Users page in Server |
| 1778 | ** Administration of the HTTP UI. Default: u. |
| @@ -1718,10 +1780,15 @@ | |
| 1780 | ** diff-command External command to run when performing a diff. |
| 1781 | ** If undefined, the internal text diff will be used. |
| 1782 | ** |
| 1783 | ** dont-push Prevent this repository from pushing from client to |
| 1784 | ** server. Useful when setting up a private branch. |
| 1785 | ** |
| 1786 | ** empty-dirs A comma or newline-separated list of pathnames. On |
| 1787 | ** (versionable) update and checkout commands, if no file or directory |
| 1788 | ** exists with that name, an empty directory will be |
| 1789 | ** created. |
| 1790 | ** |
| 1791 | ** editor Text editor command used for check-in comments. |
| 1792 | ** |
| 1793 | ** gdiff-command External command to run when performing a graphical |
| 1794 | ** diff. If undefined, text diff will be used. |
| @@ -1736,23 +1803,23 @@ | |
| 1803 | ** and "ui" commands. Default: 8080 |
| 1804 | ** |
| 1805 | ** https-login Send login creditials using HTTPS instead of HTTP |
| 1806 | ** even if the login page request came via HTTP. |
| 1807 | ** |
| 1808 | ** ignore-glob The VALUE is a comma or newline-separated list of GLOB |
| 1809 | ** (versionable) patterns specifying files that the "extra" command will |
| 1810 | ** ignore. Example: *.o,*.obj,*.exe |
| 1811 | ** |
| 1812 | ** localauth If enabled, require that HTTP connections from |
| 1813 | ** 127.0.0.1 be authenticated by password. If |
| 1814 | ** false, all HTTP requests from localhost have |
| 1815 | ** unrestricted access to the repository. |
| 1816 | ** |
| 1817 | ** main-branch The primary branch for the project. Default: trunk |
| 1818 | ** |
| 1819 | ** manifest If enabled, automatically create files "manifest" and |
| 1820 | ** (versionable) "manifest.uuid" in every checkout. The SQLite and |
| 1821 | ** Fossil repositories both require this. Default: off. |
| 1822 | ** |
| 1823 | ** max-upload A limit on the size of uplink HTTP requests. The |
| 1824 | ** default is 250000 bytes. |
| 1825 | ** |
| @@ -1805,12 +1872,13 @@ | |
| 1872 | } |
| 1873 | if( unsetFlag && g.argc!=3 ){ |
| 1874 | usage("PROPERTY ?-global?"); |
| 1875 | } |
| 1876 | if( g.argc==2 ){ |
| 1877 | int openLocal = db_open_local(); |
| 1878 | for(i=0; ctrlSettings[i].name; i++){ |
| 1879 | print_setting(&ctrlSettings[i], openLocal); |
| 1880 | } |
| 1881 | }else if( g.argc==3 || g.argc==4 ){ |
| 1882 | const char *zName = g.argv[2]; |
| 1883 | int isManifest; |
| 1884 | int n = strlen(zName); |
| @@ -1828,11 +1896,11 @@ | |
| 1896 | db_unset(ctrlSettings[i].name, globalFlag); |
| 1897 | }else if( g.argc==4 ){ |
| 1898 | db_set(ctrlSettings[i].name, g.argv[3], globalFlag); |
| 1899 | }else{ |
| 1900 | isManifest = 0; |
| 1901 | print_setting(&ctrlSettings[i], db_open_local()); |
| 1902 | } |
| 1903 | if( isManifest ){ |
| 1904 | manifest_to_disk(db_lget_int("checkout", 0)); |
| 1905 | } |
| 1906 | }else{ |
| 1907 |
M
src/db.c
+113
-45
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -1392,10 +1392,57 @@ | ||
| 1392 | 1392 | sqlite3 *dbTemp = g.db; |
| 1393 | 1393 | g.db = g.dbConfig; |
| 1394 | 1394 | g.dbConfig = dbTemp; |
| 1395 | 1395 | } |
| 1396 | 1396 | } |
| 1397 | + | |
| 1398 | +/* | |
| 1399 | +** Get a potentially versioned setting - either from .fossil-settings/<name> | |
| 1400 | +*/ | |
| 1401 | +char *db_get_versionable_setting(const char *zName, char *zDefault){ | |
| 1402 | + /* Attempt to load the versioned setting from a checked out file */ | |
| 1403 | + char *zVersionedSetting = 0; | |
| 1404 | + int noWarn = 0; | |
| 1405 | + if( db_open_local() ){ | |
| 1406 | + Blob versionedPathname; | |
| 1407 | + blob_zero(&versionedPathname); | |
| 1408 | + blob_appendf(&versionedPathname, "%s/.fossil-settings/%s", g.zLocalRoot, zName); | |
| 1409 | + char *zVersionedPathname = blob_str(&versionedPathname); | |
| 1410 | + if( file_size(zVersionedPathname)>=0 ){ | |
| 1411 | + /* File exists, and contains the value for this setting. Load from the file. */ | |
| 1412 | + Blob setting; | |
| 1413 | + blob_zero(&setting); | |
| 1414 | + if( blob_read_from_file(&setting, zVersionedPathname) >= 0 ){ | |
| 1415 | + blob_trim(&setting); /* Avoid non-obvious problems with line endings on boolean properties */ | |
| 1416 | + zVersionedSetting = strdup(blob_str(&setting)); | |
| 1417 | + } | |
| 1418 | + blob_reset(&setting); | |
| 1419 | + /* See if there's a no-warn flag */ | |
| 1420 | + blob_append(&versionedPathname, ".no-warn", -1); | |
| 1421 | + if( file_size(blob_str(&versionedPathname))>=0 ){ | |
| 1422 | + noWarn = 1; | |
| 1423 | + } | |
| 1424 | + } | |
| 1425 | + blob_reset(&versionedPathname); | |
| 1426 | + } | |
| 1427 | + /* Load the normal, non-versioned setting */ | |
| 1428 | + char *zSetting = db_get(zName, zDefault); | |
| 1429 | + /* Display a warning? */ | |
| 1430 | + if( zVersionedSetting!=0 && zSetting!=0 && zSetting[0]!='\0' && zSetting!=zDefault && !noWarn ){ | |
| 1431 | + /* There's a versioned setting, and a non-versioned setting. Tell the user about the conflict */ | |
| 1432 | + fossil_warning("Setting %s has both versioned and non-versioned values: using versioned value from file .fossil-settings/%s (To silence this warning, either create an empty file named .fossil-settings/%s.no-warn or delete the non-versioned setting with \"fossil unset %s\")", zName, zName, zName, zName); | |
| 1433 | + } | |
| 1434 | + /* Prefer the versioned setting */ | |
| 1435 | + return ( zVersionedSetting!=0 ) ? zVersionedSetting : zSetting; | |
| 1436 | +} | |
| 1437 | +int db_get_versionable_setting_boolean(const char *zName, int dflt){ | |
| 1438 | + char *zVal = db_get_versionable_setting(zName, dflt ? "on" : "off"); | |
| 1439 | + if( is_truth(zVal) ) return 1; | |
| 1440 | + if( is_false(zVal) ) return 0; | |
| 1441 | + return dflt; | |
| 1442 | +} | |
| 1443 | + | |
| 1397 | 1444 | |
| 1398 | 1445 | /* |
| 1399 | 1446 | ** Get and set values from the CONFIG, GLOBAL_CONFIG and VVAR table in the |
| 1400 | 1447 | ** repository and local databases. |
| 1401 | 1448 | */ |
| @@ -1596,30 +1643,39 @@ | ||
| 1596 | 1643 | } |
| 1597 | 1644 | |
| 1598 | 1645 | /* |
| 1599 | 1646 | ** Print the value of a setting named zName |
| 1600 | 1647 | */ |
| 1601 | -static void print_setting(const char *zName){ | |
| 1648 | +static void print_setting(const struct stControlSettings *ctrlSetting, int localOpen){ | |
| 1602 | 1649 | Stmt q; |
| 1603 | 1650 | if( g.repositoryOpen ){ |
| 1604 | 1651 | db_prepare(&q, |
| 1605 | 1652 | "SELECT '(local)', value FROM config WHERE name=%Q" |
| 1606 | 1653 | " UNION ALL " |
| 1607 | 1654 | "SELECT '(global)', value FROM global_config WHERE name=%Q", |
| 1608 | - zName, zName | |
| 1655 | + ctrlSetting->name, ctrlSetting->name | |
| 1609 | 1656 | ); |
| 1610 | 1657 | }else{ |
| 1611 | 1658 | db_prepare(&q, |
| 1612 | 1659 | "SELECT '(global)', value FROM global_config WHERE name=%Q", |
| 1613 | - zName | |
| 1660 | + ctrlSetting->name | |
| 1614 | 1661 | ); |
| 1615 | 1662 | } |
| 1616 | 1663 | if( db_step(&q)==SQLITE_ROW ){ |
| 1617 | - fossil_print("%-20s %-8s %s\n", zName, db_column_text(&q, 0), | |
| 1664 | + fossil_print("%-20s %-8s %s\n", ctrlSetting->name, db_column_text(&q, 0), | |
| 1618 | 1665 | db_column_text(&q, 1)); |
| 1619 | 1666 | }else{ |
| 1620 | - fossil_print("%-20s\n", zName); | |
| 1667 | + fossil_print("%-20s\n", ctrlSetting->name); | |
| 1668 | + } | |
| 1669 | + if( ctrlSetting->versionable && localOpen ){ | |
| 1670 | + /* Check to see if this is overridden by a versionable settings file */ | |
| 1671 | + Blob versionedPathname; | |
| 1672 | + blob_zero(&versionedPathname); | |
| 1673 | + blob_appendf(&versionedPathname, "%s/.fossil-settings/%s", g.zLocalRoot, ctrlSetting->name); | |
| 1674 | + if( file_size(blob_str(&versionedPathname))>=0 ){ | |
| 1675 | + fossil_print(" (overridden by contents of file .fossil-settings/%s)\n", ctrlSetting->name); | |
| 1676 | + } | |
| 1621 | 1677 | } |
| 1622 | 1678 | db_finalize(&q); |
| 1623 | 1679 | } |
| 1624 | 1680 | |
| 1625 | 1681 | |
| @@ -1635,43 +1691,45 @@ | ||
| 1635 | 1691 | #if INTERFACE |
| 1636 | 1692 | struct stControlSettings { |
| 1637 | 1693 | char const *name; /* Name of the setting */ |
| 1638 | 1694 | char const *var; /* Internal variable name used by db_set() */ |
| 1639 | 1695 | int width; /* Width of display. 0 for boolean values */ |
| 1696 | + int versionable; /* Is this setting versionable? */ | |
| 1640 | 1697 | char const *def; /* Default value */ |
| 1641 | 1698 | }; |
| 1642 | 1699 | #endif /* INTERFACE */ |
| 1643 | 1700 | struct stControlSettings const ctrlSettings[] = { |
| 1644 | - { "access-log", 0, 0, "off" }, | |
| 1645 | - { "auto-captcha", "autocaptcha", 0, "on" }, | |
| 1646 | - { "auto-shun", 0, 0, "on" }, | |
| 1647 | - { "autosync", 0, 0, "on" }, | |
| 1648 | - { "binary-glob", 0, 32, "" }, | |
| 1649 | - { "clearsign", 0, 0, "off" }, | |
| 1650 | - { "crnl-glob", 0, 16, "" }, | |
| 1651 | - { "default-perms", 0, 16, "u" }, | |
| 1652 | - { "diff-command", 0, 16, "" }, | |
| 1653 | - { "dont-push", 0, 0, "off" }, | |
| 1654 | - { "editor", 0, 16, "" }, | |
| 1655 | - { "gdiff-command", 0, 16, "gdiff" }, | |
| 1656 | - { "gmerge-command",0, 40, "" }, | |
| 1657 | - { "https-login", 0, 0, "off" }, | |
| 1658 | - { "ignore-glob", 0, 40, "" }, | |
| 1659 | - { "http-port", 0, 16, "8080" }, | |
| 1660 | - { "localauth", 0, 0, "off" }, | |
| 1661 | - { "main-branch", 0, 40, "trunk" }, | |
| 1662 | - { "manifest", 0, 0, "off" }, | |
| 1663 | - { "max-upload", 0, 25, "250000" }, | |
| 1664 | - { "mtime-changes", 0, 0, "on" }, | |
| 1665 | - { "pgp-command", 0, 32, "gpg --clearsign -o " }, | |
| 1666 | - { "proxy", 0, 32, "off" }, | |
| 1667 | - { "repo-cksum", 0, 0, "on" }, | |
| 1668 | - { "self-register", 0, 0, "off" }, | |
| 1669 | - { "ssl-identity", 0, 40, "" }, | |
| 1670 | - { "ssh-command", 0, 32, "" }, | |
| 1671 | - { "web-browser", 0, 32, "" }, | |
| 1672 | - { 0,0,0,0 } | |
| 1701 | + { "access-log", 0, 0, 0, "off" }, | |
| 1702 | + { "auto-captcha", "autocaptcha", 0, 0, "on" }, | |
| 1703 | + { "auto-shun", 0, 0, 0, "on" }, | |
| 1704 | + { "autosync", 0, 0, 0, "on" }, | |
| 1705 | + { "binary-glob", 0, 32, 1, "" }, | |
| 1706 | + { "clearsign", 0, 0, 0, "off" }, | |
| 1707 | + { "crnl-glob", 0, 16, 1, "" }, | |
| 1708 | + { "default-perms", 0, 16, 0, "u" }, | |
| 1709 | + { "diff-command", 0, 16, 0, "" }, | |
| 1710 | + { "dont-push", 0, 0, 0, "off" }, | |
| 1711 | + { "editor", 0, 16, 0, "" }, | |
| 1712 | + { "gdiff-command", 0, 16, 0, "gdiff" }, | |
| 1713 | + { "gmerge-command",0, 40, 0, "" }, | |
| 1714 | + { "https-login", 0, 0, 0, "off" }, | |
| 1715 | + { "ignore-glob", 0, 40, 1, "" }, | |
| 1716 | + { "empty-dirs", 0, 40, 1, "" }, | |
| 1717 | + { "http-port", 0, 16, 0, "8080" }, | |
| 1718 | + { "localauth", 0, 0, 0, "off" }, | |
| 1719 | + { "main-branch", 0, 40, 0, "trunk" }, | |
| 1720 | + { "manifest", 0, 0, 1, "off" }, | |
| 1721 | + { "max-upload", 0, 25, 0, "250000" }, | |
| 1722 | + { "mtime-changes", 0, 0, 0, "on" }, | |
| 1723 | + { "pgp-command", 0, 32, 0, "gpg --clearsign -o " }, | |
| 1724 | + { "proxy", 0, 32, 0, "off" }, | |
| 1725 | + { "repo-cksum", 0, 0, 0, "on" }, | |
| 1726 | + { "self-register", 0, 0, 0, "off" }, | |
| 1727 | + { "ssl-identity", 0, 40, 0, "" }, | |
| 1728 | + { "ssh-command", 0, 32, 0, "" }, | |
| 1729 | + { "web-browser", 0, 32, 0, "" }, | |
| 1730 | + { 0,0,0,0,0 } | |
| 1673 | 1731 | }; |
| 1674 | 1732 | |
| 1675 | 1733 | /* |
| 1676 | 1734 | ** COMMAND: settings |
| 1677 | 1735 | ** COMMAND: unset |
| @@ -1680,10 +1738,14 @@ | ||
| 1680 | 1738 | ** %fossil unset PROPERTY ?-global? |
| 1681 | 1739 | ** |
| 1682 | 1740 | ** The "settings" command with no arguments lists all properties and their |
| 1683 | 1741 | ** values. With just a property name it shows the value of that property. |
| 1684 | 1742 | ** With a value argument it changes the property for the current repository. |
| 1743 | +** | |
| 1744 | +** Settings marked as versionable are overridden by the contents of the | |
| 1745 | +** file named .fossil-settings/PROPERTY in the checked out files, if that | |
| 1746 | +** file exists. | |
| 1685 | 1747 | ** |
| 1686 | 1748 | ** The "unset" command clears a property setting. |
| 1687 | 1749 | ** |
| 1688 | 1750 | ** |
| 1689 | 1751 | ** auto-captcha If enabled, the Login page provides a button to |
| @@ -1697,20 +1759,20 @@ | ||
| 1697 | 1759 | ** or update and automatically push after commit or |
| 1698 | 1760 | ** tag or branch creation. If the value is "pullonly" |
| 1699 | 1761 | ** then only pull operations occur automatically. |
| 1700 | 1762 | ** Default: on |
| 1701 | 1763 | ** |
| 1702 | -** binary-glob The VALUE is a comma-separated list of GLOB patterns | |
| 1703 | -** that should be treated as binary files for merging | |
| 1704 | -** purposes. Example: *.xml | |
| 1764 | +** binary-glob The VALUE is a comma or newline-separated list of | |
| 1765 | +** (versionable) GLOB patterns that should be treated as binary files | |
| 1766 | +** for merging purposes. Example: *.xml | |
| 1705 | 1767 | ** |
| 1706 | 1768 | ** clearsign When enabled, fossil will attempt to sign all commits |
| 1707 | 1769 | ** with gpg. When disabled (the default), commits will |
| 1708 | 1770 | ** be unsigned. Default: off |
| 1709 | 1771 | ** |
| 1710 | -** crnl-glob A comma-separated list of GLOB patterns for text files | |
| 1711 | -** in which it is ok to have CR+NL line endings. | |
| 1772 | +** crnl-glob A comma or newline-separated list of GLOB patterns for | |
| 1773 | +** (versionable) text files in which it is ok to have CR+NL line endings. | |
| 1712 | 1774 | ** Set to "*" to disable CR+NL checking. |
| 1713 | 1775 | ** |
| 1714 | 1776 | ** default-perms Permissions given automatically to new users. For more |
| 1715 | 1777 | ** information on permissions see Users page in Server |
| 1716 | 1778 | ** Administration of the HTTP UI. Default: u. |
| @@ -1718,10 +1780,15 @@ | ||
| 1718 | 1780 | ** diff-command External command to run when performing a diff. |
| 1719 | 1781 | ** If undefined, the internal text diff will be used. |
| 1720 | 1782 | ** |
| 1721 | 1783 | ** dont-push Prevent this repository from pushing from client to |
| 1722 | 1784 | ** server. Useful when setting up a private branch. |
| 1785 | +** | |
| 1786 | +** empty-dirs A comma or newline-separated list of pathnames. On | |
| 1787 | +** (versionable) update and checkout commands, if no file or directory | |
| 1788 | +** exists with that name, an empty directory will be | |
| 1789 | +** created. | |
| 1723 | 1790 | ** |
| 1724 | 1791 | ** editor Text editor command used for check-in comments. |
| 1725 | 1792 | ** |
| 1726 | 1793 | ** gdiff-command External command to run when performing a graphical |
| 1727 | 1794 | ** diff. If undefined, text diff will be used. |
| @@ -1736,23 +1803,23 @@ | ||
| 1736 | 1803 | ** and "ui" commands. Default: 8080 |
| 1737 | 1804 | ** |
| 1738 | 1805 | ** https-login Send login creditials using HTTPS instead of HTTP |
| 1739 | 1806 | ** even if the login page request came via HTTP. |
| 1740 | 1807 | ** |
| 1741 | -** ignore-glob The VALUE is a comma-separated list of GLOB patterns | |
| 1742 | -** specifying files that the "extra" command will ignore. | |
| 1743 | -** Example: *.o,*.obj,*.exe | |
| 1808 | +** ignore-glob The VALUE is a comma or newline-separated list of GLOB | |
| 1809 | +** (versionable) patterns specifying files that the "extra" command will | |
| 1810 | +** ignore. Example: *.o,*.obj,*.exe | |
| 1744 | 1811 | ** |
| 1745 | 1812 | ** localauth If enabled, require that HTTP connections from |
| 1746 | 1813 | ** 127.0.0.1 be authenticated by password. If |
| 1747 | 1814 | ** false, all HTTP requests from localhost have |
| 1748 | 1815 | ** unrestricted access to the repository. |
| 1749 | 1816 | ** |
| 1750 | 1817 | ** main-branch The primary branch for the project. Default: trunk |
| 1751 | 1818 | ** |
| 1752 | 1819 | ** manifest If enabled, automatically create files "manifest" and |
| 1753 | -** "manifest.uuid" in every checkout. The SQLite and | |
| 1820 | +** (versionable) "manifest.uuid" in every checkout. The SQLite and | |
| 1754 | 1821 | ** Fossil repositories both require this. Default: off. |
| 1755 | 1822 | ** |
| 1756 | 1823 | ** max-upload A limit on the size of uplink HTTP requests. The |
| 1757 | 1824 | ** default is 250000 bytes. |
| 1758 | 1825 | ** |
| @@ -1805,12 +1872,13 @@ | ||
| 1805 | 1872 | } |
| 1806 | 1873 | if( unsetFlag && g.argc!=3 ){ |
| 1807 | 1874 | usage("PROPERTY ?-global?"); |
| 1808 | 1875 | } |
| 1809 | 1876 | if( g.argc==2 ){ |
| 1877 | + int openLocal = db_open_local(); | |
| 1810 | 1878 | for(i=0; ctrlSettings[i].name; i++){ |
| 1811 | - print_setting(ctrlSettings[i].name); | |
| 1879 | + print_setting(&ctrlSettings[i], openLocal); | |
| 1812 | 1880 | } |
| 1813 | 1881 | }else if( g.argc==3 || g.argc==4 ){ |
| 1814 | 1882 | const char *zName = g.argv[2]; |
| 1815 | 1883 | int isManifest; |
| 1816 | 1884 | int n = strlen(zName); |
| @@ -1828,11 +1896,11 @@ | ||
| 1828 | 1896 | db_unset(ctrlSettings[i].name, globalFlag); |
| 1829 | 1897 | }else if( g.argc==4 ){ |
| 1830 | 1898 | db_set(ctrlSettings[i].name, g.argv[3], globalFlag); |
| 1831 | 1899 | }else{ |
| 1832 | 1900 | isManifest = 0; |
| 1833 | - print_setting(ctrlSettings[i].name); | |
| 1901 | + print_setting(&ctrlSettings[i], db_open_local()); | |
| 1834 | 1902 | } |
| 1835 | 1903 | if( isManifest ){ |
| 1836 | 1904 | manifest_to_disk(db_lget_int("checkout", 0)); |
| 1837 | 1905 | } |
| 1838 | 1906 | }else{ |
| 1839 | 1907 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -1392,10 +1392,57 @@ | |
| 1392 | sqlite3 *dbTemp = g.db; |
| 1393 | g.db = g.dbConfig; |
| 1394 | g.dbConfig = dbTemp; |
| 1395 | } |
| 1396 | } |
| 1397 | |
| 1398 | /* |
| 1399 | ** Get and set values from the CONFIG, GLOBAL_CONFIG and VVAR table in the |
| 1400 | ** repository and local databases. |
| 1401 | */ |
| @@ -1596,30 +1643,39 @@ | |
| 1596 | } |
| 1597 | |
| 1598 | /* |
| 1599 | ** Print the value of a setting named zName |
| 1600 | */ |
| 1601 | static void print_setting(const char *zName){ |
| 1602 | Stmt q; |
| 1603 | if( g.repositoryOpen ){ |
| 1604 | db_prepare(&q, |
| 1605 | "SELECT '(local)', value FROM config WHERE name=%Q" |
| 1606 | " UNION ALL " |
| 1607 | "SELECT '(global)', value FROM global_config WHERE name=%Q", |
| 1608 | zName, zName |
| 1609 | ); |
| 1610 | }else{ |
| 1611 | db_prepare(&q, |
| 1612 | "SELECT '(global)', value FROM global_config WHERE name=%Q", |
| 1613 | zName |
| 1614 | ); |
| 1615 | } |
| 1616 | if( db_step(&q)==SQLITE_ROW ){ |
| 1617 | fossil_print("%-20s %-8s %s\n", zName, db_column_text(&q, 0), |
| 1618 | db_column_text(&q, 1)); |
| 1619 | }else{ |
| 1620 | fossil_print("%-20s\n", zName); |
| 1621 | } |
| 1622 | db_finalize(&q); |
| 1623 | } |
| 1624 | |
| 1625 | |
| @@ -1635,43 +1691,45 @@ | |
| 1635 | #if INTERFACE |
| 1636 | struct stControlSettings { |
| 1637 | char const *name; /* Name of the setting */ |
| 1638 | char const *var; /* Internal variable name used by db_set() */ |
| 1639 | int width; /* Width of display. 0 for boolean values */ |
| 1640 | char const *def; /* Default value */ |
| 1641 | }; |
| 1642 | #endif /* INTERFACE */ |
| 1643 | struct stControlSettings const ctrlSettings[] = { |
| 1644 | { "access-log", 0, 0, "off" }, |
| 1645 | { "auto-captcha", "autocaptcha", 0, "on" }, |
| 1646 | { "auto-shun", 0, 0, "on" }, |
| 1647 | { "autosync", 0, 0, "on" }, |
| 1648 | { "binary-glob", 0, 32, "" }, |
| 1649 | { "clearsign", 0, 0, "off" }, |
| 1650 | { "crnl-glob", 0, 16, "" }, |
| 1651 | { "default-perms", 0, 16, "u" }, |
| 1652 | { "diff-command", 0, 16, "" }, |
| 1653 | { "dont-push", 0, 0, "off" }, |
| 1654 | { "editor", 0, 16, "" }, |
| 1655 | { "gdiff-command", 0, 16, "gdiff" }, |
| 1656 | { "gmerge-command",0, 40, "" }, |
| 1657 | { "https-login", 0, 0, "off" }, |
| 1658 | { "ignore-glob", 0, 40, "" }, |
| 1659 | { "http-port", 0, 16, "8080" }, |
| 1660 | { "localauth", 0, 0, "off" }, |
| 1661 | { "main-branch", 0, 40, "trunk" }, |
| 1662 | { "manifest", 0, 0, "off" }, |
| 1663 | { "max-upload", 0, 25, "250000" }, |
| 1664 | { "mtime-changes", 0, 0, "on" }, |
| 1665 | { "pgp-command", 0, 32, "gpg --clearsign -o " }, |
| 1666 | { "proxy", 0, 32, "off" }, |
| 1667 | { "repo-cksum", 0, 0, "on" }, |
| 1668 | { "self-register", 0, 0, "off" }, |
| 1669 | { "ssl-identity", 0, 40, "" }, |
| 1670 | { "ssh-command", 0, 32, "" }, |
| 1671 | { "web-browser", 0, 32, "" }, |
| 1672 | { 0,0,0,0 } |
| 1673 | }; |
| 1674 | |
| 1675 | /* |
| 1676 | ** COMMAND: settings |
| 1677 | ** COMMAND: unset |
| @@ -1680,10 +1738,14 @@ | |
| 1680 | ** %fossil unset PROPERTY ?-global? |
| 1681 | ** |
| 1682 | ** The "settings" command with no arguments lists all properties and their |
| 1683 | ** values. With just a property name it shows the value of that property. |
| 1684 | ** With a value argument it changes the property for the current repository. |
| 1685 | ** |
| 1686 | ** The "unset" command clears a property setting. |
| 1687 | ** |
| 1688 | ** |
| 1689 | ** auto-captcha If enabled, the Login page provides a button to |
| @@ -1697,20 +1759,20 @@ | |
| 1697 | ** or update and automatically push after commit or |
| 1698 | ** tag or branch creation. If the value is "pullonly" |
| 1699 | ** then only pull operations occur automatically. |
| 1700 | ** Default: on |
| 1701 | ** |
| 1702 | ** binary-glob The VALUE is a comma-separated list of GLOB patterns |
| 1703 | ** that should be treated as binary files for merging |
| 1704 | ** purposes. Example: *.xml |
| 1705 | ** |
| 1706 | ** clearsign When enabled, fossil will attempt to sign all commits |
| 1707 | ** with gpg. When disabled (the default), commits will |
| 1708 | ** be unsigned. Default: off |
| 1709 | ** |
| 1710 | ** crnl-glob A comma-separated list of GLOB patterns for text files |
| 1711 | ** in which it is ok to have CR+NL line endings. |
| 1712 | ** Set to "*" to disable CR+NL checking. |
| 1713 | ** |
| 1714 | ** default-perms Permissions given automatically to new users. For more |
| 1715 | ** information on permissions see Users page in Server |
| 1716 | ** Administration of the HTTP UI. Default: u. |
| @@ -1718,10 +1780,15 @@ | |
| 1718 | ** diff-command External command to run when performing a diff. |
| 1719 | ** If undefined, the internal text diff will be used. |
| 1720 | ** |
| 1721 | ** dont-push Prevent this repository from pushing from client to |
| 1722 | ** server. Useful when setting up a private branch. |
| 1723 | ** |
| 1724 | ** editor Text editor command used for check-in comments. |
| 1725 | ** |
| 1726 | ** gdiff-command External command to run when performing a graphical |
| 1727 | ** diff. If undefined, text diff will be used. |
| @@ -1736,23 +1803,23 @@ | |
| 1736 | ** and "ui" commands. Default: 8080 |
| 1737 | ** |
| 1738 | ** https-login Send login creditials using HTTPS instead of HTTP |
| 1739 | ** even if the login page request came via HTTP. |
| 1740 | ** |
| 1741 | ** ignore-glob The VALUE is a comma-separated list of GLOB patterns |
| 1742 | ** specifying files that the "extra" command will ignore. |
| 1743 | ** Example: *.o,*.obj,*.exe |
| 1744 | ** |
| 1745 | ** localauth If enabled, require that HTTP connections from |
| 1746 | ** 127.0.0.1 be authenticated by password. If |
| 1747 | ** false, all HTTP requests from localhost have |
| 1748 | ** unrestricted access to the repository. |
| 1749 | ** |
| 1750 | ** main-branch The primary branch for the project. Default: trunk |
| 1751 | ** |
| 1752 | ** manifest If enabled, automatically create files "manifest" and |
| 1753 | ** "manifest.uuid" in every checkout. The SQLite and |
| 1754 | ** Fossil repositories both require this. Default: off. |
| 1755 | ** |
| 1756 | ** max-upload A limit on the size of uplink HTTP requests. The |
| 1757 | ** default is 250000 bytes. |
| 1758 | ** |
| @@ -1805,12 +1872,13 @@ | |
| 1805 | } |
| 1806 | if( unsetFlag && g.argc!=3 ){ |
| 1807 | usage("PROPERTY ?-global?"); |
| 1808 | } |
| 1809 | if( g.argc==2 ){ |
| 1810 | for(i=0; ctrlSettings[i].name; i++){ |
| 1811 | print_setting(ctrlSettings[i].name); |
| 1812 | } |
| 1813 | }else if( g.argc==3 || g.argc==4 ){ |
| 1814 | const char *zName = g.argv[2]; |
| 1815 | int isManifest; |
| 1816 | int n = strlen(zName); |
| @@ -1828,11 +1896,11 @@ | |
| 1828 | db_unset(ctrlSettings[i].name, globalFlag); |
| 1829 | }else if( g.argc==4 ){ |
| 1830 | db_set(ctrlSettings[i].name, g.argv[3], globalFlag); |
| 1831 | }else{ |
| 1832 | isManifest = 0; |
| 1833 | print_setting(ctrlSettings[i].name); |
| 1834 | } |
| 1835 | if( isManifest ){ |
| 1836 | manifest_to_disk(db_lget_int("checkout", 0)); |
| 1837 | } |
| 1838 | }else{ |
| 1839 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -1392,10 +1392,57 @@ | |
| 1392 | sqlite3 *dbTemp = g.db; |
| 1393 | g.db = g.dbConfig; |
| 1394 | g.dbConfig = dbTemp; |
| 1395 | } |
| 1396 | } |
| 1397 | |
| 1398 | /* |
| 1399 | ** Get a potentially versioned setting - either from .fossil-settings/<name> |
| 1400 | */ |
| 1401 | char *db_get_versionable_setting(const char *zName, char *zDefault){ |
| 1402 | /* Attempt to load the versioned setting from a checked out file */ |
| 1403 | char *zVersionedSetting = 0; |
| 1404 | int noWarn = 0; |
| 1405 | if( db_open_local() ){ |
| 1406 | Blob versionedPathname; |
| 1407 | blob_zero(&versionedPathname); |
| 1408 | blob_appendf(&versionedPathname, "%s/.fossil-settings/%s", g.zLocalRoot, zName); |
| 1409 | char *zVersionedPathname = blob_str(&versionedPathname); |
| 1410 | if( file_size(zVersionedPathname)>=0 ){ |
| 1411 | /* File exists, and contains the value for this setting. Load from the file. */ |
| 1412 | Blob setting; |
| 1413 | blob_zero(&setting); |
| 1414 | if( blob_read_from_file(&setting, zVersionedPathname) >= 0 ){ |
| 1415 | blob_trim(&setting); /* Avoid non-obvious problems with line endings on boolean properties */ |
| 1416 | zVersionedSetting = strdup(blob_str(&setting)); |
| 1417 | } |
| 1418 | blob_reset(&setting); |
| 1419 | /* See if there's a no-warn flag */ |
| 1420 | blob_append(&versionedPathname, ".no-warn", -1); |
| 1421 | if( file_size(blob_str(&versionedPathname))>=0 ){ |
| 1422 | noWarn = 1; |
| 1423 | } |
| 1424 | } |
| 1425 | blob_reset(&versionedPathname); |
| 1426 | } |
| 1427 | /* Load the normal, non-versioned setting */ |
| 1428 | char *zSetting = db_get(zName, zDefault); |
| 1429 | /* Display a warning? */ |
| 1430 | if( zVersionedSetting!=0 && zSetting!=0 && zSetting[0]!='\0' && zSetting!=zDefault && !noWarn ){ |
| 1431 | /* There's a versioned setting, and a non-versioned setting. Tell the user about the conflict */ |
| 1432 | fossil_warning("Setting %s has both versioned and non-versioned values: using versioned value from file .fossil-settings/%s (To silence this warning, either create an empty file named .fossil-settings/%s.no-warn or delete the non-versioned setting with \"fossil unset %s\")", zName, zName, zName, zName); |
| 1433 | } |
| 1434 | /* Prefer the versioned setting */ |
| 1435 | return ( zVersionedSetting!=0 ) ? zVersionedSetting : zSetting; |
| 1436 | } |
| 1437 | int db_get_versionable_setting_boolean(const char *zName, int dflt){ |
| 1438 | char *zVal = db_get_versionable_setting(zName, dflt ? "on" : "off"); |
| 1439 | if( is_truth(zVal) ) return 1; |
| 1440 | if( is_false(zVal) ) return 0; |
| 1441 | return dflt; |
| 1442 | } |
| 1443 | |
| 1444 | |
| 1445 | /* |
| 1446 | ** Get and set values from the CONFIG, GLOBAL_CONFIG and VVAR table in the |
| 1447 | ** repository and local databases. |
| 1448 | */ |
| @@ -1596,30 +1643,39 @@ | |
| 1643 | } |
| 1644 | |
| 1645 | /* |
| 1646 | ** Print the value of a setting named zName |
| 1647 | */ |
| 1648 | static void print_setting(const struct stControlSettings *ctrlSetting, int localOpen){ |
| 1649 | Stmt q; |
| 1650 | if( g.repositoryOpen ){ |
| 1651 | db_prepare(&q, |
| 1652 | "SELECT '(local)', value FROM config WHERE name=%Q" |
| 1653 | " UNION ALL " |
| 1654 | "SELECT '(global)', value FROM global_config WHERE name=%Q", |
| 1655 | ctrlSetting->name, ctrlSetting->name |
| 1656 | ); |
| 1657 | }else{ |
| 1658 | db_prepare(&q, |
| 1659 | "SELECT '(global)', value FROM global_config WHERE name=%Q", |
| 1660 | ctrlSetting->name |
| 1661 | ); |
| 1662 | } |
| 1663 | if( db_step(&q)==SQLITE_ROW ){ |
| 1664 | fossil_print("%-20s %-8s %s\n", ctrlSetting->name, db_column_text(&q, 0), |
| 1665 | db_column_text(&q, 1)); |
| 1666 | }else{ |
| 1667 | fossil_print("%-20s\n", ctrlSetting->name); |
| 1668 | } |
| 1669 | if( ctrlSetting->versionable && localOpen ){ |
| 1670 | /* Check to see if this is overridden by a versionable settings file */ |
| 1671 | Blob versionedPathname; |
| 1672 | blob_zero(&versionedPathname); |
| 1673 | blob_appendf(&versionedPathname, "%s/.fossil-settings/%s", g.zLocalRoot, ctrlSetting->name); |
| 1674 | if( file_size(blob_str(&versionedPathname))>=0 ){ |
| 1675 | fossil_print(" (overridden by contents of file .fossil-settings/%s)\n", ctrlSetting->name); |
| 1676 | } |
| 1677 | } |
| 1678 | db_finalize(&q); |
| 1679 | } |
| 1680 | |
| 1681 | |
| @@ -1635,43 +1691,45 @@ | |
| 1691 | #if INTERFACE |
| 1692 | struct stControlSettings { |
| 1693 | char const *name; /* Name of the setting */ |
| 1694 | char const *var; /* Internal variable name used by db_set() */ |
| 1695 | int width; /* Width of display. 0 for boolean values */ |
| 1696 | int versionable; /* Is this setting versionable? */ |
| 1697 | char const *def; /* Default value */ |
| 1698 | }; |
| 1699 | #endif /* INTERFACE */ |
| 1700 | struct stControlSettings const ctrlSettings[] = { |
| 1701 | { "access-log", 0, 0, 0, "off" }, |
| 1702 | { "auto-captcha", "autocaptcha", 0, 0, "on" }, |
| 1703 | { "auto-shun", 0, 0, 0, "on" }, |
| 1704 | { "autosync", 0, 0, 0, "on" }, |
| 1705 | { "binary-glob", 0, 32, 1, "" }, |
| 1706 | { "clearsign", 0, 0, 0, "off" }, |
| 1707 | { "crnl-glob", 0, 16, 1, "" }, |
| 1708 | { "default-perms", 0, 16, 0, "u" }, |
| 1709 | { "diff-command", 0, 16, 0, "" }, |
| 1710 | { "dont-push", 0, 0, 0, "off" }, |
| 1711 | { "editor", 0, 16, 0, "" }, |
| 1712 | { "gdiff-command", 0, 16, 0, "gdiff" }, |
| 1713 | { "gmerge-command",0, 40, 0, "" }, |
| 1714 | { "https-login", 0, 0, 0, "off" }, |
| 1715 | { "ignore-glob", 0, 40, 1, "" }, |
| 1716 | { "empty-dirs", 0, 40, 1, "" }, |
| 1717 | { "http-port", 0, 16, 0, "8080" }, |
| 1718 | { "localauth", 0, 0, 0, "off" }, |
| 1719 | { "main-branch", 0, 40, 0, "trunk" }, |
| 1720 | { "manifest", 0, 0, 1, "off" }, |
| 1721 | { "max-upload", 0, 25, 0, "250000" }, |
| 1722 | { "mtime-changes", 0, 0, 0, "on" }, |
| 1723 | { "pgp-command", 0, 32, 0, "gpg --clearsign -o " }, |
| 1724 | { "proxy", 0, 32, 0, "off" }, |
| 1725 | { "repo-cksum", 0, 0, 0, "on" }, |
| 1726 | { "self-register", 0, 0, 0, "off" }, |
| 1727 | { "ssl-identity", 0, 40, 0, "" }, |
| 1728 | { "ssh-command", 0, 32, 0, "" }, |
| 1729 | { "web-browser", 0, 32, 0, "" }, |
| 1730 | { 0,0,0,0,0 } |
| 1731 | }; |
| 1732 | |
| 1733 | /* |
| 1734 | ** COMMAND: settings |
| 1735 | ** COMMAND: unset |
| @@ -1680,10 +1738,14 @@ | |
| 1738 | ** %fossil unset PROPERTY ?-global? |
| 1739 | ** |
| 1740 | ** The "settings" command with no arguments lists all properties and their |
| 1741 | ** values. With just a property name it shows the value of that property. |
| 1742 | ** With a value argument it changes the property for the current repository. |
| 1743 | ** |
| 1744 | ** Settings marked as versionable are overridden by the contents of the |
| 1745 | ** file named .fossil-settings/PROPERTY in the checked out files, if that |
| 1746 | ** file exists. |
| 1747 | ** |
| 1748 | ** The "unset" command clears a property setting. |
| 1749 | ** |
| 1750 | ** |
| 1751 | ** auto-captcha If enabled, the Login page provides a button to |
| @@ -1697,20 +1759,20 @@ | |
| 1759 | ** or update and automatically push after commit or |
| 1760 | ** tag or branch creation. If the value is "pullonly" |
| 1761 | ** then only pull operations occur automatically. |
| 1762 | ** Default: on |
| 1763 | ** |
| 1764 | ** binary-glob The VALUE is a comma or newline-separated list of |
| 1765 | ** (versionable) GLOB patterns that should be treated as binary files |
| 1766 | ** for merging purposes. Example: *.xml |
| 1767 | ** |
| 1768 | ** clearsign When enabled, fossil will attempt to sign all commits |
| 1769 | ** with gpg. When disabled (the default), commits will |
| 1770 | ** be unsigned. Default: off |
| 1771 | ** |
| 1772 | ** crnl-glob A comma or newline-separated list of GLOB patterns for |
| 1773 | ** (versionable) text files in which it is ok to have CR+NL line endings. |
| 1774 | ** Set to "*" to disable CR+NL checking. |
| 1775 | ** |
| 1776 | ** default-perms Permissions given automatically to new users. For more |
| 1777 | ** information on permissions see Users page in Server |
| 1778 | ** Administration of the HTTP UI. Default: u. |
| @@ -1718,10 +1780,15 @@ | |
| 1780 | ** diff-command External command to run when performing a diff. |
| 1781 | ** If undefined, the internal text diff will be used. |
| 1782 | ** |
| 1783 | ** dont-push Prevent this repository from pushing from client to |
| 1784 | ** server. Useful when setting up a private branch. |
| 1785 | ** |
| 1786 | ** empty-dirs A comma or newline-separated list of pathnames. On |
| 1787 | ** (versionable) update and checkout commands, if no file or directory |
| 1788 | ** exists with that name, an empty directory will be |
| 1789 | ** created. |
| 1790 | ** |
| 1791 | ** editor Text editor command used for check-in comments. |
| 1792 | ** |
| 1793 | ** gdiff-command External command to run when performing a graphical |
| 1794 | ** diff. If undefined, text diff will be used. |
| @@ -1736,23 +1803,23 @@ | |
| 1803 | ** and "ui" commands. Default: 8080 |
| 1804 | ** |
| 1805 | ** https-login Send login creditials using HTTPS instead of HTTP |
| 1806 | ** even if the login page request came via HTTP. |
| 1807 | ** |
| 1808 | ** ignore-glob The VALUE is a comma or newline-separated list of GLOB |
| 1809 | ** (versionable) patterns specifying files that the "extra" command will |
| 1810 | ** ignore. Example: *.o,*.obj,*.exe |
| 1811 | ** |
| 1812 | ** localauth If enabled, require that HTTP connections from |
| 1813 | ** 127.0.0.1 be authenticated by password. If |
| 1814 | ** false, all HTTP requests from localhost have |
| 1815 | ** unrestricted access to the repository. |
| 1816 | ** |
| 1817 | ** main-branch The primary branch for the project. Default: trunk |
| 1818 | ** |
| 1819 | ** manifest If enabled, automatically create files "manifest" and |
| 1820 | ** (versionable) "manifest.uuid" in every checkout. The SQLite and |
| 1821 | ** Fossil repositories both require this. Default: off. |
| 1822 | ** |
| 1823 | ** max-upload A limit on the size of uplink HTTP requests. The |
| 1824 | ** default is 250000 bytes. |
| 1825 | ** |
| @@ -1805,12 +1872,13 @@ | |
| 1872 | } |
| 1873 | if( unsetFlag && g.argc!=3 ){ |
| 1874 | usage("PROPERTY ?-global?"); |
| 1875 | } |
| 1876 | if( g.argc==2 ){ |
| 1877 | int openLocal = db_open_local(); |
| 1878 | for(i=0; ctrlSettings[i].name; i++){ |
| 1879 | print_setting(&ctrlSettings[i], openLocal); |
| 1880 | } |
| 1881 | }else if( g.argc==3 || g.argc==4 ){ |
| 1882 | const char *zName = g.argv[2]; |
| 1883 | int isManifest; |
| 1884 | int n = strlen(zName); |
| @@ -1828,11 +1896,11 @@ | |
| 1896 | db_unset(ctrlSettings[i].name, globalFlag); |
| 1897 | }else if( g.argc==4 ){ |
| 1898 | db_set(ctrlSettings[i].name, g.argv[3], globalFlag); |
| 1899 | }else{ |
| 1900 | isManifest = 0; |
| 1901 | print_setting(&ctrlSettings[i], db_open_local()); |
| 1902 | } |
| 1903 | if( isManifest ){ |
| 1904 | manifest_to_disk(db_lget_int("checkout", 0)); |
| 1905 | } |
| 1906 | }else{ |
| 1907 |
+4
-4
| --- src/glob.c | ||
| +++ src/glob.c | ||
| @@ -110,24 +110,24 @@ | ||
| 110 | 110 | p = fossil_malloc( sizeof(*p) + nList+1 ); |
| 111 | 111 | memset(p, 0, sizeof(*p)); |
| 112 | 112 | z = (char*)&p[1]; |
| 113 | 113 | memcpy(z, zPatternList, nList+1); |
| 114 | 114 | while( z[0] ){ |
| 115 | - while( z[0]==',' || z[0]==' ' ) z++; /* Skip leading spaces */ | |
| 115 | + while( z[0]==',' || z[0]==' ' || z[0]=='\n' || z[0]=='\r' ) z++; /* Skip leading spaces and newlines */ | |
| 116 | 116 | if( z[0]=='\'' || z[0]=='"' ){ |
| 117 | 117 | delimiter = z[0]; |
| 118 | 118 | z++; |
| 119 | 119 | }else{ |
| 120 | 120 | delimiter = ','; |
| 121 | 121 | } |
| 122 | 122 | if( z[0]==0 ) break; |
| 123 | 123 | p->azPattern = fossil_realloc(p->azPattern, (p->nPattern+1)*sizeof(char*) ); |
| 124 | 124 | p->azPattern[p->nPattern++] = z; |
| 125 | - for(i=0; z[i] && z[i]!=delimiter; i++){} | |
| 125 | + for(i=0; z[i] && z[i]!=delimiter && z[i]!='\n' && z[i]!='\r'; i++){} | |
| 126 | 126 | if( delimiter==',' ){ |
| 127 | - /* Remove trailing spaces on a comma-delimited pattern */ | |
| 128 | - for(j=i; j>1 && z[j-1]==' '; j--){} | |
| 127 | + /* Remove trailing spaces / newlines on a comma-delimited pattern */ | |
| 128 | + for(j=i; j>1 && (z[j-1]==' ' || z[j-1]=='\n' || z[j-1]=='\r'); j--){} | |
| 129 | 129 | if( j<i ) z[j] = 0; |
| 130 | 130 | } |
| 131 | 131 | if( z[i]==0 ) break; |
| 132 | 132 | z[i] = 0; |
| 133 | 133 | z += i+1; |
| 134 | 134 |
| --- src/glob.c | |
| +++ src/glob.c | |
| @@ -110,24 +110,24 @@ | |
| 110 | p = fossil_malloc( sizeof(*p) + nList+1 ); |
| 111 | memset(p, 0, sizeof(*p)); |
| 112 | z = (char*)&p[1]; |
| 113 | memcpy(z, zPatternList, nList+1); |
| 114 | while( z[0] ){ |
| 115 | while( z[0]==',' || z[0]==' ' ) z++; /* Skip leading spaces */ |
| 116 | if( z[0]=='\'' || z[0]=='"' ){ |
| 117 | delimiter = z[0]; |
| 118 | z++; |
| 119 | }else{ |
| 120 | delimiter = ','; |
| 121 | } |
| 122 | if( z[0]==0 ) break; |
| 123 | p->azPattern = fossil_realloc(p->azPattern, (p->nPattern+1)*sizeof(char*) ); |
| 124 | p->azPattern[p->nPattern++] = z; |
| 125 | for(i=0; z[i] && z[i]!=delimiter; i++){} |
| 126 | if( delimiter==',' ){ |
| 127 | /* Remove trailing spaces on a comma-delimited pattern */ |
| 128 | for(j=i; j>1 && z[j-1]==' '; j--){} |
| 129 | if( j<i ) z[j] = 0; |
| 130 | } |
| 131 | if( z[i]==0 ) break; |
| 132 | z[i] = 0; |
| 133 | z += i+1; |
| 134 |
| --- src/glob.c | |
| +++ src/glob.c | |
| @@ -110,24 +110,24 @@ | |
| 110 | p = fossil_malloc( sizeof(*p) + nList+1 ); |
| 111 | memset(p, 0, sizeof(*p)); |
| 112 | z = (char*)&p[1]; |
| 113 | memcpy(z, zPatternList, nList+1); |
| 114 | while( z[0] ){ |
| 115 | while( z[0]==',' || z[0]==' ' || z[0]=='\n' || z[0]=='\r' ) z++; /* Skip leading spaces and newlines */ |
| 116 | if( z[0]=='\'' || z[0]=='"' ){ |
| 117 | delimiter = z[0]; |
| 118 | z++; |
| 119 | }else{ |
| 120 | delimiter = ','; |
| 121 | } |
| 122 | if( z[0]==0 ) break; |
| 123 | p->azPattern = fossil_realloc(p->azPattern, (p->nPattern+1)*sizeof(char*) ); |
| 124 | p->azPattern[p->nPattern++] = z; |
| 125 | for(i=0; z[i] && z[i]!=delimiter && z[i]!='\n' && z[i]!='\r'; i++){} |
| 126 | if( delimiter==',' ){ |
| 127 | /* Remove trailing spaces / newlines on a comma-delimited pattern */ |
| 128 | for(j=i; j>1 && (z[j-1]==' ' || z[j-1]=='\n' || z[j-1]=='\r'); j--){} |
| 129 | if( j<i ) z[j] = 0; |
| 130 | } |
| 131 | if( z[i]==0 ) break; |
| 132 | z[i] = 0; |
| 133 | z += i+1; |
| 134 |
+4
-4
| --- src/glob.c | ||
| +++ src/glob.c | ||
| @@ -110,24 +110,24 @@ | ||
| 110 | 110 | p = fossil_malloc( sizeof(*p) + nList+1 ); |
| 111 | 111 | memset(p, 0, sizeof(*p)); |
| 112 | 112 | z = (char*)&p[1]; |
| 113 | 113 | memcpy(z, zPatternList, nList+1); |
| 114 | 114 | while( z[0] ){ |
| 115 | - while( z[0]==',' || z[0]==' ' ) z++; /* Skip leading spaces */ | |
| 115 | + while( z[0]==',' || z[0]==' ' || z[0]=='\n' || z[0]=='\r' ) z++; /* Skip leading spaces and newlines */ | |
| 116 | 116 | if( z[0]=='\'' || z[0]=='"' ){ |
| 117 | 117 | delimiter = z[0]; |
| 118 | 118 | z++; |
| 119 | 119 | }else{ |
| 120 | 120 | delimiter = ','; |
| 121 | 121 | } |
| 122 | 122 | if( z[0]==0 ) break; |
| 123 | 123 | p->azPattern = fossil_realloc(p->azPattern, (p->nPattern+1)*sizeof(char*) ); |
| 124 | 124 | p->azPattern[p->nPattern++] = z; |
| 125 | - for(i=0; z[i] && z[i]!=delimiter; i++){} | |
| 125 | + for(i=0; z[i] && z[i]!=delimiter && z[i]!='\n' && z[i]!='\r'; i++){} | |
| 126 | 126 | if( delimiter==',' ){ |
| 127 | - /* Remove trailing spaces on a comma-delimited pattern */ | |
| 128 | - for(j=i; j>1 && z[j-1]==' '; j--){} | |
| 127 | + /* Remove trailing spaces / newlines on a comma-delimited pattern */ | |
| 128 | + for(j=i; j>1 && (z[j-1]==' ' || z[j-1]=='\n' || z[j-1]=='\r'); j--){} | |
| 129 | 129 | if( j<i ) z[j] = 0; |
| 130 | 130 | } |
| 131 | 131 | if( z[i]==0 ) break; |
| 132 | 132 | z[i] = 0; |
| 133 | 133 | z += i+1; |
| 134 | 134 |
| --- src/glob.c | |
| +++ src/glob.c | |
| @@ -110,24 +110,24 @@ | |
| 110 | p = fossil_malloc( sizeof(*p) + nList+1 ); |
| 111 | memset(p, 0, sizeof(*p)); |
| 112 | z = (char*)&p[1]; |
| 113 | memcpy(z, zPatternList, nList+1); |
| 114 | while( z[0] ){ |
| 115 | while( z[0]==',' || z[0]==' ' ) z++; /* Skip leading spaces */ |
| 116 | if( z[0]=='\'' || z[0]=='"' ){ |
| 117 | delimiter = z[0]; |
| 118 | z++; |
| 119 | }else{ |
| 120 | delimiter = ','; |
| 121 | } |
| 122 | if( z[0]==0 ) break; |
| 123 | p->azPattern = fossil_realloc(p->azPattern, (p->nPattern+1)*sizeof(char*) ); |
| 124 | p->azPattern[p->nPattern++] = z; |
| 125 | for(i=0; z[i] && z[i]!=delimiter; i++){} |
| 126 | if( delimiter==',' ){ |
| 127 | /* Remove trailing spaces on a comma-delimited pattern */ |
| 128 | for(j=i; j>1 && z[j-1]==' '; j--){} |
| 129 | if( j<i ) z[j] = 0; |
| 130 | } |
| 131 | if( z[i]==0 ) break; |
| 132 | z[i] = 0; |
| 133 | z += i+1; |
| 134 |
| --- src/glob.c | |
| +++ src/glob.c | |
| @@ -110,24 +110,24 @@ | |
| 110 | p = fossil_malloc( sizeof(*p) + nList+1 ); |
| 111 | memset(p, 0, sizeof(*p)); |
| 112 | z = (char*)&p[1]; |
| 113 | memcpy(z, zPatternList, nList+1); |
| 114 | while( z[0] ){ |
| 115 | while( z[0]==',' || z[0]==' ' || z[0]=='\n' || z[0]=='\r' ) z++; /* Skip leading spaces and newlines */ |
| 116 | if( z[0]=='\'' || z[0]=='"' ){ |
| 117 | delimiter = z[0]; |
| 118 | z++; |
| 119 | }else{ |
| 120 | delimiter = ','; |
| 121 | } |
| 122 | if( z[0]==0 ) break; |
| 123 | p->azPattern = fossil_realloc(p->azPattern, (p->nPattern+1)*sizeof(char*) ); |
| 124 | p->azPattern[p->nPattern++] = z; |
| 125 | for(i=0; z[i] && z[i]!=delimiter && z[i]!='\n' && z[i]!='\r'; i++){} |
| 126 | if( delimiter==',' ){ |
| 127 | /* Remove trailing spaces / newlines on a comma-delimited pattern */ |
| 128 | for(j=i; j>1 && (z[j-1]==' ' || z[j-1]=='\n' || z[j-1]=='\r'); j--){} |
| 129 | if( j<i ) z[j] = 0; |
| 130 | } |
| 131 | if( z[i]==0 ) break; |
| 132 | z[i] = 0; |
| 133 | z += i+1; |
| 134 |
+1
-1
| --- src/merge.c | ||
| +++ src/merge.c | ||
| @@ -91,11 +91,11 @@ | ||
| 91 | 91 | zPivot = find_option("baseline",0,1); |
| 92 | 92 | if( g.argc!=3 ){ |
| 93 | 93 | usage("VERSION"); |
| 94 | 94 | } |
| 95 | 95 | db_must_be_within_tree(); |
| 96 | - if( zBinGlob==0 ) zBinGlob = db_get("binary-glob",0); | |
| 96 | + if( zBinGlob==0 ) zBinGlob = db_get_versionable_setting("binary-glob",0); | |
| 97 | 97 | vid = db_lget_int("checkout", 0); |
| 98 | 98 | if( vid==0 ){ |
| 99 | 99 | fossil_fatal("nothing is checked out"); |
| 100 | 100 | } |
| 101 | 101 | mid = name_to_typed_rid(g.argv[2], "ci"); |
| 102 | 102 |
| --- src/merge.c | |
| +++ src/merge.c | |
| @@ -91,11 +91,11 @@ | |
| 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("binary-glob",0); |
| 97 | vid = db_lget_int("checkout", 0); |
| 98 | if( vid==0 ){ |
| 99 | fossil_fatal("nothing is checked out"); |
| 100 | } |
| 101 | mid = name_to_typed_rid(g.argv[2], "ci"); |
| 102 |
| --- src/merge.c | |
| +++ src/merge.c | |
| @@ -91,11 +91,11 @@ | |
| 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 | } |
| 101 | mid = name_to_typed_rid(g.argv[2], "ci"); |
| 102 |
+1
-1
| --- src/merge.c | ||
| +++ src/merge.c | ||
| @@ -91,11 +91,11 @@ | ||
| 91 | 91 | zPivot = find_option("baseline",0,1); |
| 92 | 92 | if( g.argc!=3 ){ |
| 93 | 93 | usage("VERSION"); |
| 94 | 94 | } |
| 95 | 95 | db_must_be_within_tree(); |
| 96 | - if( zBinGlob==0 ) zBinGlob = db_get("binary-glob",0); | |
| 96 | + if( zBinGlob==0 ) zBinGlob = db_get_versionable_setting("binary-glob",0); | |
| 97 | 97 | vid = db_lget_int("checkout", 0); |
| 98 | 98 | if( vid==0 ){ |
| 99 | 99 | fossil_fatal("nothing is checked out"); |
| 100 | 100 | } |
| 101 | 101 | mid = name_to_typed_rid(g.argv[2], "ci"); |
| 102 | 102 |
| --- src/merge.c | |
| +++ src/merge.c | |
| @@ -91,11 +91,11 @@ | |
| 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("binary-glob",0); |
| 97 | vid = db_lget_int("checkout", 0); |
| 98 | if( vid==0 ){ |
| 99 | fossil_fatal("nothing is checked out"); |
| 100 | } |
| 101 | mid = name_to_typed_rid(g.argv[2], "ci"); |
| 102 |
| --- src/merge.c | |
| +++ src/merge.c | |
| @@ -91,11 +91,11 @@ | |
| 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 | } |
| 101 | mid = name_to_typed_rid(g.argv[2], "ci"); |
| 102 |
+11
-2
| --- src/setup.c | ||
| +++ src/setup.c | ||
| @@ -1062,25 +1062,34 @@ | ||
| 1062 | 1062 | for(pSet=ctrlSettings; pSet->name!=0; pSet++){ |
| 1063 | 1063 | if( pSet->width==0 ){ |
| 1064 | 1064 | onoff_attribute(pSet->name, pSet->name, |
| 1065 | 1065 | pSet->var!=0 ? pSet->var : pSet->name, |
| 1066 | 1066 | is_truth(pSet->def)); |
| 1067 | - @ <br /> | |
| 1067 | + if( pSet->versionable ){ | |
| 1068 | + @ (v)<br /> | |
| 1069 | + } else { | |
| 1070 | + @ <br /> | |
| 1071 | + } | |
| 1068 | 1072 | } |
| 1069 | 1073 | } |
| 1070 | 1074 | @ </td><td style="width: 30;"></td><td valign="top"> |
| 1071 | 1075 | for(pSet=ctrlSettings; pSet->name!=0; pSet++){ |
| 1072 | 1076 | if( pSet->width!=0 ){ |
| 1073 | 1077 | entry_attribute(pSet->name, /*pSet->width*/ 40, pSet->name, |
| 1074 | 1078 | pSet->var!=0 ? pSet->var : pSet->name, |
| 1075 | 1079 | (char*)pSet->def); |
| 1076 | - @ <br /> | |
| 1080 | + if( pSet->versionable ){ | |
| 1081 | + @ (v)<br /> | |
| 1082 | + } else { | |
| 1083 | + @ <br /> | |
| 1084 | + } | |
| 1077 | 1085 | } |
| 1078 | 1086 | } |
| 1079 | 1087 | @ </td></tr></table> |
| 1080 | 1088 | @ <p><input type="submit" name="submit" value="Apply Changes" /></p> |
| 1081 | 1089 | @ </div></form> |
| 1090 | + @ <p>Settings marked with (v) are 'versionable' and will be overridden by the contents of files named <tt>.fossil-settings/PROPERTY</tt>.</p> | |
| 1082 | 1091 | @ <hr /><p> |
| 1083 | 1092 | @ These settings work in the same way, as the <kbd>set</kbd> commandline:<br /> |
| 1084 | 1093 | @ </p><pre>%s(zHelp_setting_cmd)</pre> |
| 1085 | 1094 | db_end_transaction(0); |
| 1086 | 1095 | style_footer(); |
| 1087 | 1096 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -1062,25 +1062,34 @@ | |
| 1062 | for(pSet=ctrlSettings; pSet->name!=0; pSet++){ |
| 1063 | if( pSet->width==0 ){ |
| 1064 | onoff_attribute(pSet->name, pSet->name, |
| 1065 | pSet->var!=0 ? pSet->var : pSet->name, |
| 1066 | is_truth(pSet->def)); |
| 1067 | @ <br /> |
| 1068 | } |
| 1069 | } |
| 1070 | @ </td><td style="width: 30;"></td><td valign="top"> |
| 1071 | for(pSet=ctrlSettings; pSet->name!=0; pSet++){ |
| 1072 | if( pSet->width!=0 ){ |
| 1073 | entry_attribute(pSet->name, /*pSet->width*/ 40, pSet->name, |
| 1074 | pSet->var!=0 ? pSet->var : pSet->name, |
| 1075 | (char*)pSet->def); |
| 1076 | @ <br /> |
| 1077 | } |
| 1078 | } |
| 1079 | @ </td></tr></table> |
| 1080 | @ <p><input type="submit" name="submit" value="Apply Changes" /></p> |
| 1081 | @ </div></form> |
| 1082 | @ <hr /><p> |
| 1083 | @ These settings work in the same way, as the <kbd>set</kbd> commandline:<br /> |
| 1084 | @ </p><pre>%s(zHelp_setting_cmd)</pre> |
| 1085 | db_end_transaction(0); |
| 1086 | style_footer(); |
| 1087 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -1062,25 +1062,34 @@ | |
| 1062 | for(pSet=ctrlSettings; pSet->name!=0; pSet++){ |
| 1063 | if( pSet->width==0 ){ |
| 1064 | onoff_attribute(pSet->name, pSet->name, |
| 1065 | pSet->var!=0 ? pSet->var : pSet->name, |
| 1066 | is_truth(pSet->def)); |
| 1067 | if( pSet->versionable ){ |
| 1068 | @ (v)<br /> |
| 1069 | } else { |
| 1070 | @ <br /> |
| 1071 | } |
| 1072 | } |
| 1073 | } |
| 1074 | @ </td><td style="width: 30;"></td><td valign="top"> |
| 1075 | for(pSet=ctrlSettings; pSet->name!=0; pSet++){ |
| 1076 | if( pSet->width!=0 ){ |
| 1077 | entry_attribute(pSet->name, /*pSet->width*/ 40, pSet->name, |
| 1078 | pSet->var!=0 ? pSet->var : pSet->name, |
| 1079 | (char*)pSet->def); |
| 1080 | if( pSet->versionable ){ |
| 1081 | @ (v)<br /> |
| 1082 | } else { |
| 1083 | @ <br /> |
| 1084 | } |
| 1085 | } |
| 1086 | } |
| 1087 | @ </td></tr></table> |
| 1088 | @ <p><input type="submit" name="submit" value="Apply Changes" /></p> |
| 1089 | @ </div></form> |
| 1090 | @ <p>Settings marked with (v) are 'versionable' and will be overridden by the contents of files named <tt>.fossil-settings/PROPERTY</tt>.</p> |
| 1091 | @ <hr /><p> |
| 1092 | @ These settings work in the same way, as the <kbd>set</kbd> commandline:<br /> |
| 1093 | @ </p><pre>%s(zHelp_setting_cmd)</pre> |
| 1094 | db_end_transaction(0); |
| 1095 | style_footer(); |
| 1096 |
+11
-2
| --- src/setup.c | ||
| +++ src/setup.c | ||
| @@ -1062,25 +1062,34 @@ | ||
| 1062 | 1062 | for(pSet=ctrlSettings; pSet->name!=0; pSet++){ |
| 1063 | 1063 | if( pSet->width==0 ){ |
| 1064 | 1064 | onoff_attribute(pSet->name, pSet->name, |
| 1065 | 1065 | pSet->var!=0 ? pSet->var : pSet->name, |
| 1066 | 1066 | is_truth(pSet->def)); |
| 1067 | - @ <br /> | |
| 1067 | + if( pSet->versionable ){ | |
| 1068 | + @ (v)<br /> | |
| 1069 | + } else { | |
| 1070 | + @ <br /> | |
| 1071 | + } | |
| 1068 | 1072 | } |
| 1069 | 1073 | } |
| 1070 | 1074 | @ </td><td style="width: 30;"></td><td valign="top"> |
| 1071 | 1075 | for(pSet=ctrlSettings; pSet->name!=0; pSet++){ |
| 1072 | 1076 | if( pSet->width!=0 ){ |
| 1073 | 1077 | entry_attribute(pSet->name, /*pSet->width*/ 40, pSet->name, |
| 1074 | 1078 | pSet->var!=0 ? pSet->var : pSet->name, |
| 1075 | 1079 | (char*)pSet->def); |
| 1076 | - @ <br /> | |
| 1080 | + if( pSet->versionable ){ | |
| 1081 | + @ (v)<br /> | |
| 1082 | + } else { | |
| 1083 | + @ <br /> | |
| 1084 | + } | |
| 1077 | 1085 | } |
| 1078 | 1086 | } |
| 1079 | 1087 | @ </td></tr></table> |
| 1080 | 1088 | @ <p><input type="submit" name="submit" value="Apply Changes" /></p> |
| 1081 | 1089 | @ </div></form> |
| 1090 | + @ <p>Settings marked with (v) are 'versionable' and will be overridden by the contents of files named <tt>.fossil-settings/PROPERTY</tt>.</p> | |
| 1082 | 1091 | @ <hr /><p> |
| 1083 | 1092 | @ These settings work in the same way, as the <kbd>set</kbd> commandline:<br /> |
| 1084 | 1093 | @ </p><pre>%s(zHelp_setting_cmd)</pre> |
| 1085 | 1094 | db_end_transaction(0); |
| 1086 | 1095 | style_footer(); |
| 1087 | 1096 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -1062,25 +1062,34 @@ | |
| 1062 | for(pSet=ctrlSettings; pSet->name!=0; pSet++){ |
| 1063 | if( pSet->width==0 ){ |
| 1064 | onoff_attribute(pSet->name, pSet->name, |
| 1065 | pSet->var!=0 ? pSet->var : pSet->name, |
| 1066 | is_truth(pSet->def)); |
| 1067 | @ <br /> |
| 1068 | } |
| 1069 | } |
| 1070 | @ </td><td style="width: 30;"></td><td valign="top"> |
| 1071 | for(pSet=ctrlSettings; pSet->name!=0; pSet++){ |
| 1072 | if( pSet->width!=0 ){ |
| 1073 | entry_attribute(pSet->name, /*pSet->width*/ 40, pSet->name, |
| 1074 | pSet->var!=0 ? pSet->var : pSet->name, |
| 1075 | (char*)pSet->def); |
| 1076 | @ <br /> |
| 1077 | } |
| 1078 | } |
| 1079 | @ </td></tr></table> |
| 1080 | @ <p><input type="submit" name="submit" value="Apply Changes" /></p> |
| 1081 | @ </div></form> |
| 1082 | @ <hr /><p> |
| 1083 | @ These settings work in the same way, as the <kbd>set</kbd> commandline:<br /> |
| 1084 | @ </p><pre>%s(zHelp_setting_cmd)</pre> |
| 1085 | db_end_transaction(0); |
| 1086 | style_footer(); |
| 1087 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -1062,25 +1062,34 @@ | |
| 1062 | for(pSet=ctrlSettings; pSet->name!=0; pSet++){ |
| 1063 | if( pSet->width==0 ){ |
| 1064 | onoff_attribute(pSet->name, pSet->name, |
| 1065 | pSet->var!=0 ? pSet->var : pSet->name, |
| 1066 | is_truth(pSet->def)); |
| 1067 | if( pSet->versionable ){ |
| 1068 | @ (v)<br /> |
| 1069 | } else { |
| 1070 | @ <br /> |
| 1071 | } |
| 1072 | } |
| 1073 | } |
| 1074 | @ </td><td style="width: 30;"></td><td valign="top"> |
| 1075 | for(pSet=ctrlSettings; pSet->name!=0; pSet++){ |
| 1076 | if( pSet->width!=0 ){ |
| 1077 | entry_attribute(pSet->name, /*pSet->width*/ 40, pSet->name, |
| 1078 | pSet->var!=0 ? pSet->var : pSet->name, |
| 1079 | (char*)pSet->def); |
| 1080 | if( pSet->versionable ){ |
| 1081 | @ (v)<br /> |
| 1082 | } else { |
| 1083 | @ <br /> |
| 1084 | } |
| 1085 | } |
| 1086 | } |
| 1087 | @ </td></tr></table> |
| 1088 | @ <p><input type="submit" name="submit" value="Apply Changes" /></p> |
| 1089 | @ </div></form> |
| 1090 | @ <p>Settings marked with (v) are 'versionable' and will be overridden by the contents of files named <tt>.fossil-settings/PROPERTY</tt>.</p> |
| 1091 | @ <hr /><p> |
| 1092 | @ These settings work in the same way, as the <kbd>set</kbd> commandline:<br /> |
| 1093 | @ </p><pre>%s(zHelp_setting_cmd)</pre> |
| 1094 | db_end_transaction(0); |
| 1095 | style_footer(); |
| 1096 |
+1
-1
| --- src/tar.c | ||
| +++ src/tar.c | ||
| @@ -215,11 +215,11 @@ | ||
| 215 | 215 | nPrefix = blob_size(&filename); |
| 216 | 216 | |
| 217 | 217 | pManifest = manifest_get(rid, CFTYPE_MANIFEST); |
| 218 | 218 | if( pManifest ){ |
| 219 | 219 | mTime = (pManifest->rDate - 2440587.5)*86400.0; |
| 220 | - if( db_get_boolean("manifest", 0) ){ | |
| 220 | + if( db_get_versionable_setting_boolean("manifest", 0) ){ | |
| 221 | 221 | blob_append(&filename, "manifest", -1); |
| 222 | 222 | zName = blob_str(&filename); |
| 223 | 223 | tar_add_file(zName, &mfile, 0, mTime); |
| 224 | 224 | sha1sum_blob(&mfile, &hash); |
| 225 | 225 | blob_reset(&mfile); |
| 226 | 226 |
| --- src/tar.c | |
| +++ src/tar.c | |
| @@ -215,11 +215,11 @@ | |
| 215 | nPrefix = blob_size(&filename); |
| 216 | |
| 217 | pManifest = manifest_get(rid, CFTYPE_MANIFEST); |
| 218 | if( pManifest ){ |
| 219 | mTime = (pManifest->rDate - 2440587.5)*86400.0; |
| 220 | if( db_get_boolean("manifest", 0) ){ |
| 221 | blob_append(&filename, "manifest", -1); |
| 222 | zName = blob_str(&filename); |
| 223 | tar_add_file(zName, &mfile, 0, mTime); |
| 224 | sha1sum_blob(&mfile, &hash); |
| 225 | blob_reset(&mfile); |
| 226 |
| --- src/tar.c | |
| +++ src/tar.c | |
| @@ -215,11 +215,11 @@ | |
| 215 | nPrefix = blob_size(&filename); |
| 216 | |
| 217 | pManifest = manifest_get(rid, CFTYPE_MANIFEST); |
| 218 | if( pManifest ){ |
| 219 | mTime = (pManifest->rDate - 2440587.5)*86400.0; |
| 220 | if( db_get_versionable_setting_boolean("manifest", 0) ){ |
| 221 | blob_append(&filename, "manifest", -1); |
| 222 | zName = blob_str(&filename); |
| 223 | tar_add_file(zName, &mfile, 0, mTime); |
| 224 | sha1sum_blob(&mfile, &hash); |
| 225 | blob_reset(&mfile); |
| 226 |
+1
-1
| --- src/tar.c | ||
| +++ src/tar.c | ||
| @@ -215,11 +215,11 @@ | ||
| 215 | 215 | nPrefix = blob_size(&filename); |
| 216 | 216 | |
| 217 | 217 | pManifest = manifest_get(rid, CFTYPE_MANIFEST); |
| 218 | 218 | if( pManifest ){ |
| 219 | 219 | mTime = (pManifest->rDate - 2440587.5)*86400.0; |
| 220 | - if( db_get_boolean("manifest", 0) ){ | |
| 220 | + if( db_get_versionable_setting_boolean("manifest", 0) ){ | |
| 221 | 221 | blob_append(&filename, "manifest", -1); |
| 222 | 222 | zName = blob_str(&filename); |
| 223 | 223 | tar_add_file(zName, &mfile, 0, mTime); |
| 224 | 224 | sha1sum_blob(&mfile, &hash); |
| 225 | 225 | blob_reset(&mfile); |
| 226 | 226 |
| --- src/tar.c | |
| +++ src/tar.c | |
| @@ -215,11 +215,11 @@ | |
| 215 | nPrefix = blob_size(&filename); |
| 216 | |
| 217 | pManifest = manifest_get(rid, CFTYPE_MANIFEST); |
| 218 | if( pManifest ){ |
| 219 | mTime = (pManifest->rDate - 2440587.5)*86400.0; |
| 220 | if( db_get_boolean("manifest", 0) ){ |
| 221 | blob_append(&filename, "manifest", -1); |
| 222 | zName = blob_str(&filename); |
| 223 | tar_add_file(zName, &mfile, 0, mTime); |
| 224 | sha1sum_blob(&mfile, &hash); |
| 225 | blob_reset(&mfile); |
| 226 |
| --- src/tar.c | |
| +++ src/tar.c | |
| @@ -215,11 +215,11 @@ | |
| 215 | nPrefix = blob_size(&filename); |
| 216 | |
| 217 | pManifest = manifest_get(rid, CFTYPE_MANIFEST); |
| 218 | if( pManifest ){ |
| 219 | mTime = (pManifest->rDate - 2440587.5)*86400.0; |
| 220 | if( db_get_versionable_setting_boolean("manifest", 0) ){ |
| 221 | blob_append(&filename, "manifest", -1); |
| 222 | zName = blob_str(&filename); |
| 223 | tar_add_file(zName, &mfile, 0, mTime); |
| 224 | sha1sum_blob(&mfile, &hash); |
| 225 | blob_reset(&mfile); |
| 226 |
+52
| --- src/update.c | ||
| +++ src/update.c | ||
| @@ -115,10 +115,13 @@ | ||
| 115 | 115 | } |
| 116 | 116 | if( !nochangeFlag && db_exists("SELECT 1 FROM vmerge") ){ |
| 117 | 117 | fossil_fatal("cannot update an uncommitted merge"); |
| 118 | 118 | } |
| 119 | 119 | if( !nochangeFlag && !internalUpdate ) autosync(AUTOSYNC_PULL); |
| 120 | + | |
| 121 | + /* Create any empty directories now, as well as after the update, so changes in settings are reflected now */ | |
| 122 | + ensure_empty_dirs_created(); | |
| 120 | 123 | |
| 121 | 124 | if( internalUpdate ){ |
| 122 | 125 | tid = internalUpdate; |
| 123 | 126 | }else if( g.argc>=3 ){ |
| 124 | 127 | if( fossil_strcmp(g.argv[2], "current")==0 ){ |
| @@ -440,10 +443,11 @@ | ||
| 440 | 443 | ** Clean up the mid and pid VFILE entries. Then commit the changes. |
| 441 | 444 | */ |
| 442 | 445 | if( nochangeFlag ){ |
| 443 | 446 | db_end_transaction(1); /* With --nochange, rollback changes */ |
| 444 | 447 | }else{ |
| 448 | + ensure_empty_dirs_created(); | |
| 445 | 449 | if( g.argc<=3 ){ |
| 446 | 450 | /* All files updated. Shift the current checkout to the target. */ |
| 447 | 451 | db_multi_exec("DELETE FROM vfile WHERE vid!=%d", tid); |
| 448 | 452 | checkout_set_all_exe(vid); |
| 449 | 453 | manifest_to_disk(tid); |
| @@ -455,10 +459,58 @@ | ||
| 455 | 459 | } |
| 456 | 460 | if( !internalUpdate ) undo_finish(); |
| 457 | 461 | db_end_transaction(0); |
| 458 | 462 | } |
| 459 | 463 | } |
| 464 | + | |
| 465 | +/* | |
| 466 | +** Make sure empty directories are created | |
| 467 | +*/ | |
| 468 | +void ensure_empty_dirs_created() | |
| 469 | +{ | |
| 470 | + /* Make empty directories? */ | |
| 471 | + char *zEmptyDirs = db_get_versionable_setting("empty-dirs", 0); | |
| 472 | + if( zEmptyDirs!=0 ){ | |
| 473 | + Blob dirsList; | |
| 474 | + blob_zero(&dirsList); | |
| 475 | + blob_init(&dirsList, zEmptyDirs, strlen(zEmptyDirs)); | |
| 476 | + /* Replace commas by spaces */ | |
| 477 | + char *bc = blob_str(&dirsList); | |
| 478 | + while( (*bc)!='\0' ){ | |
| 479 | + if( (*bc)==',' ) { *bc = ' '; } | |
| 480 | + ++bc; | |
| 481 | + } | |
| 482 | + /* Make directories */ | |
| 483 | + Blob dirName; | |
| 484 | + blob_zero(&dirName); | |
| 485 | + while( blob_token(&dirsList, &dirName) ){ | |
| 486 | + const char *zDir = blob_str(&dirName); | |
| 487 | + /* Make full pathname of the directory */ | |
| 488 | + Blob path; | |
| 489 | + blob_zero(&path); | |
| 490 | + blob_appendf(&path, "%s/%s", g.zLocalRoot, zDir); | |
| 491 | + const char *zPath = blob_str(&path); | |
| 492 | + /* Handle various cases of existence of the directory */ | |
| 493 | + switch( file_isdir(zPath) ){ | |
| 494 | + case 0: { /* doesn't exist */ | |
| 495 | + if( file_mkdir(zPath, 0)!=0 ) { | |
| 496 | + fossil_warning("couldn't create directory %s as required by empty-dirs setting", zDir); | |
| 497 | + } | |
| 498 | + break; | |
| 499 | + } | |
| 500 | + case 1: { /* exists, and is a directory */ | |
| 501 | + /* do nothing - required directory exists already */ | |
| 502 | + break; | |
| 503 | + } | |
| 504 | + case 2: { /* exists, but isn't a directory */ | |
| 505 | + fossil_warning("file %s found, but a directory is required by empty-dirs setting", zDir); | |
| 506 | + } | |
| 507 | + } | |
| 508 | + blob_reset(&path); | |
| 509 | + } | |
| 510 | + } | |
| 511 | +} | |
| 460 | 512 | |
| 461 | 513 | |
| 462 | 514 | /* |
| 463 | 515 | ** Get the contents of a file within the checking "revision". If |
| 464 | 516 | ** revision==NULL then get the file content for the current checkout. |
| 465 | 517 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -115,10 +115,13 @@ | |
| 115 | } |
| 116 | if( !nochangeFlag && db_exists("SELECT 1 FROM vmerge") ){ |
| 117 | fossil_fatal("cannot update an uncommitted merge"); |
| 118 | } |
| 119 | if( !nochangeFlag && !internalUpdate ) autosync(AUTOSYNC_PULL); |
| 120 | |
| 121 | if( internalUpdate ){ |
| 122 | tid = internalUpdate; |
| 123 | }else if( g.argc>=3 ){ |
| 124 | if( fossil_strcmp(g.argv[2], "current")==0 ){ |
| @@ -440,10 +443,11 @@ | |
| 440 | ** Clean up the mid and pid VFILE entries. Then commit the changes. |
| 441 | */ |
| 442 | if( nochangeFlag ){ |
| 443 | db_end_transaction(1); /* With --nochange, rollback changes */ |
| 444 | }else{ |
| 445 | if( g.argc<=3 ){ |
| 446 | /* All files updated. Shift the current checkout to the target. */ |
| 447 | db_multi_exec("DELETE FROM vfile WHERE vid!=%d", tid); |
| 448 | checkout_set_all_exe(vid); |
| 449 | manifest_to_disk(tid); |
| @@ -455,10 +459,58 @@ | |
| 455 | } |
| 456 | if( !internalUpdate ) undo_finish(); |
| 457 | db_end_transaction(0); |
| 458 | } |
| 459 | } |
| 460 | |
| 461 | |
| 462 | /* |
| 463 | ** Get the contents of a file within the checking "revision". If |
| 464 | ** revision==NULL then get the file content for the current checkout. |
| 465 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -115,10 +115,13 @@ | |
| 115 | } |
| 116 | if( !nochangeFlag && db_exists("SELECT 1 FROM vmerge") ){ |
| 117 | fossil_fatal("cannot update an uncommitted merge"); |
| 118 | } |
| 119 | if( !nochangeFlag && !internalUpdate ) autosync(AUTOSYNC_PULL); |
| 120 | |
| 121 | /* Create any empty directories now, as well as after the update, so changes in settings are reflected now */ |
| 122 | ensure_empty_dirs_created(); |
| 123 | |
| 124 | if( internalUpdate ){ |
| 125 | tid = internalUpdate; |
| 126 | }else if( g.argc>=3 ){ |
| 127 | if( fossil_strcmp(g.argv[2], "current")==0 ){ |
| @@ -440,10 +443,11 @@ | |
| 443 | ** Clean up the mid and pid VFILE entries. Then commit the changes. |
| 444 | */ |
| 445 | if( nochangeFlag ){ |
| 446 | db_end_transaction(1); /* With --nochange, rollback changes */ |
| 447 | }else{ |
| 448 | ensure_empty_dirs_created(); |
| 449 | if( g.argc<=3 ){ |
| 450 | /* All files updated. Shift the current checkout to the target. */ |
| 451 | db_multi_exec("DELETE FROM vfile WHERE vid!=%d", tid); |
| 452 | checkout_set_all_exe(vid); |
| 453 | manifest_to_disk(tid); |
| @@ -455,10 +459,58 @@ | |
| 459 | } |
| 460 | if( !internalUpdate ) undo_finish(); |
| 461 | db_end_transaction(0); |
| 462 | } |
| 463 | } |
| 464 | |
| 465 | /* |
| 466 | ** Make sure empty directories are created |
| 467 | */ |
| 468 | void ensure_empty_dirs_created() |
| 469 | { |
| 470 | /* Make empty directories? */ |
| 471 | char *zEmptyDirs = db_get_versionable_setting("empty-dirs", 0); |
| 472 | if( zEmptyDirs!=0 ){ |
| 473 | Blob dirsList; |
| 474 | blob_zero(&dirsList); |
| 475 | blob_init(&dirsList, zEmptyDirs, strlen(zEmptyDirs)); |
| 476 | /* Replace commas by spaces */ |
| 477 | char *bc = blob_str(&dirsList); |
| 478 | while( (*bc)!='\0' ){ |
| 479 | if( (*bc)==',' ) { *bc = ' '; } |
| 480 | ++bc; |
| 481 | } |
| 482 | /* Make directories */ |
| 483 | Blob dirName; |
| 484 | blob_zero(&dirName); |
| 485 | while( blob_token(&dirsList, &dirName) ){ |
| 486 | const char *zDir = blob_str(&dirName); |
| 487 | /* Make full pathname of the directory */ |
| 488 | Blob path; |
| 489 | blob_zero(&path); |
| 490 | blob_appendf(&path, "%s/%s", g.zLocalRoot, zDir); |
| 491 | const char *zPath = blob_str(&path); |
| 492 | /* Handle various cases of existence of the directory */ |
| 493 | switch( file_isdir(zPath) ){ |
| 494 | case 0: { /* doesn't exist */ |
| 495 | if( file_mkdir(zPath, 0)!=0 ) { |
| 496 | fossil_warning("couldn't create directory %s as required by empty-dirs setting", zDir); |
| 497 | } |
| 498 | break; |
| 499 | } |
| 500 | case 1: { /* exists, and is a directory */ |
| 501 | /* do nothing - required directory exists already */ |
| 502 | break; |
| 503 | } |
| 504 | case 2: { /* exists, but isn't a directory */ |
| 505 | fossil_warning("file %s found, but a directory is required by empty-dirs setting", zDir); |
| 506 | } |
| 507 | } |
| 508 | blob_reset(&path); |
| 509 | } |
| 510 | } |
| 511 | } |
| 512 | |
| 513 | |
| 514 | /* |
| 515 | ** Get the contents of a file within the checking "revision". If |
| 516 | ** revision==NULL then get the file content for the current checkout. |
| 517 |
+52
| --- src/update.c | ||
| +++ src/update.c | ||
| @@ -115,10 +115,13 @@ | ||
| 115 | 115 | } |
| 116 | 116 | if( !nochangeFlag && db_exists("SELECT 1 FROM vmerge") ){ |
| 117 | 117 | fossil_fatal("cannot update an uncommitted merge"); |
| 118 | 118 | } |
| 119 | 119 | if( !nochangeFlag && !internalUpdate ) autosync(AUTOSYNC_PULL); |
| 120 | + | |
| 121 | + /* Create any empty directories now, as well as after the update, so changes in settings are reflected now */ | |
| 122 | + ensure_empty_dirs_created(); | |
| 120 | 123 | |
| 121 | 124 | if( internalUpdate ){ |
| 122 | 125 | tid = internalUpdate; |
| 123 | 126 | }else if( g.argc>=3 ){ |
| 124 | 127 | if( fossil_strcmp(g.argv[2], "current")==0 ){ |
| @@ -440,10 +443,11 @@ | ||
| 440 | 443 | ** Clean up the mid and pid VFILE entries. Then commit the changes. |
| 441 | 444 | */ |
| 442 | 445 | if( nochangeFlag ){ |
| 443 | 446 | db_end_transaction(1); /* With --nochange, rollback changes */ |
| 444 | 447 | }else{ |
| 448 | + ensure_empty_dirs_created(); | |
| 445 | 449 | if( g.argc<=3 ){ |
| 446 | 450 | /* All files updated. Shift the current checkout to the target. */ |
| 447 | 451 | db_multi_exec("DELETE FROM vfile WHERE vid!=%d", tid); |
| 448 | 452 | checkout_set_all_exe(vid); |
| 449 | 453 | manifest_to_disk(tid); |
| @@ -455,10 +459,58 @@ | ||
| 455 | 459 | } |
| 456 | 460 | if( !internalUpdate ) undo_finish(); |
| 457 | 461 | db_end_transaction(0); |
| 458 | 462 | } |
| 459 | 463 | } |
| 464 | + | |
| 465 | +/* | |
| 466 | +** Make sure empty directories are created | |
| 467 | +*/ | |
| 468 | +void ensure_empty_dirs_created() | |
| 469 | +{ | |
| 470 | + /* Make empty directories? */ | |
| 471 | + char *zEmptyDirs = db_get_versionable_setting("empty-dirs", 0); | |
| 472 | + if( zEmptyDirs!=0 ){ | |
| 473 | + Blob dirsList; | |
| 474 | + blob_zero(&dirsList); | |
| 475 | + blob_init(&dirsList, zEmptyDirs, strlen(zEmptyDirs)); | |
| 476 | + /* Replace commas by spaces */ | |
| 477 | + char *bc = blob_str(&dirsList); | |
| 478 | + while( (*bc)!='\0' ){ | |
| 479 | + if( (*bc)==',' ) { *bc = ' '; } | |
| 480 | + ++bc; | |
| 481 | + } | |
| 482 | + /* Make directories */ | |
| 483 | + Blob dirName; | |
| 484 | + blob_zero(&dirName); | |
| 485 | + while( blob_token(&dirsList, &dirName) ){ | |
| 486 | + const char *zDir = blob_str(&dirName); | |
| 487 | + /* Make full pathname of the directory */ | |
| 488 | + Blob path; | |
| 489 | + blob_zero(&path); | |
| 490 | + blob_appendf(&path, "%s/%s", g.zLocalRoot, zDir); | |
| 491 | + const char *zPath = blob_str(&path); | |
| 492 | + /* Handle various cases of existence of the directory */ | |
| 493 | + switch( file_isdir(zPath) ){ | |
| 494 | + case 0: { /* doesn't exist */ | |
| 495 | + if( file_mkdir(zPath, 0)!=0 ) { | |
| 496 | + fossil_warning("couldn't create directory %s as required by empty-dirs setting", zDir); | |
| 497 | + } | |
| 498 | + break; | |
| 499 | + } | |
| 500 | + case 1: { /* exists, and is a directory */ | |
| 501 | + /* do nothing - required directory exists already */ | |
| 502 | + break; | |
| 503 | + } | |
| 504 | + case 2: { /* exists, but isn't a directory */ | |
| 505 | + fossil_warning("file %s found, but a directory is required by empty-dirs setting", zDir); | |
| 506 | + } | |
| 507 | + } | |
| 508 | + blob_reset(&path); | |
| 509 | + } | |
| 510 | + } | |
| 511 | +} | |
| 460 | 512 | |
| 461 | 513 | |
| 462 | 514 | /* |
| 463 | 515 | ** Get the contents of a file within the checking "revision". If |
| 464 | 516 | ** revision==NULL then get the file content for the current checkout. |
| 465 | 517 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -115,10 +115,13 @@ | |
| 115 | } |
| 116 | if( !nochangeFlag && db_exists("SELECT 1 FROM vmerge") ){ |
| 117 | fossil_fatal("cannot update an uncommitted merge"); |
| 118 | } |
| 119 | if( !nochangeFlag && !internalUpdate ) autosync(AUTOSYNC_PULL); |
| 120 | |
| 121 | if( internalUpdate ){ |
| 122 | tid = internalUpdate; |
| 123 | }else if( g.argc>=3 ){ |
| 124 | if( fossil_strcmp(g.argv[2], "current")==0 ){ |
| @@ -440,10 +443,11 @@ | |
| 440 | ** Clean up the mid and pid VFILE entries. Then commit the changes. |
| 441 | */ |
| 442 | if( nochangeFlag ){ |
| 443 | db_end_transaction(1); /* With --nochange, rollback changes */ |
| 444 | }else{ |
| 445 | if( g.argc<=3 ){ |
| 446 | /* All files updated. Shift the current checkout to the target. */ |
| 447 | db_multi_exec("DELETE FROM vfile WHERE vid!=%d", tid); |
| 448 | checkout_set_all_exe(vid); |
| 449 | manifest_to_disk(tid); |
| @@ -455,10 +459,58 @@ | |
| 455 | } |
| 456 | if( !internalUpdate ) undo_finish(); |
| 457 | db_end_transaction(0); |
| 458 | } |
| 459 | } |
| 460 | |
| 461 | |
| 462 | /* |
| 463 | ** Get the contents of a file within the checking "revision". If |
| 464 | ** revision==NULL then get the file content for the current checkout. |
| 465 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -115,10 +115,13 @@ | |
| 115 | } |
| 116 | if( !nochangeFlag && db_exists("SELECT 1 FROM vmerge") ){ |
| 117 | fossil_fatal("cannot update an uncommitted merge"); |
| 118 | } |
| 119 | if( !nochangeFlag && !internalUpdate ) autosync(AUTOSYNC_PULL); |
| 120 | |
| 121 | /* Create any empty directories now, as well as after the update, so changes in settings are reflected now */ |
| 122 | ensure_empty_dirs_created(); |
| 123 | |
| 124 | if( internalUpdate ){ |
| 125 | tid = internalUpdate; |
| 126 | }else if( g.argc>=3 ){ |
| 127 | if( fossil_strcmp(g.argv[2], "current")==0 ){ |
| @@ -440,10 +443,11 @@ | |
| 443 | ** Clean up the mid and pid VFILE entries. Then commit the changes. |
| 444 | */ |
| 445 | if( nochangeFlag ){ |
| 446 | db_end_transaction(1); /* With --nochange, rollback changes */ |
| 447 | }else{ |
| 448 | ensure_empty_dirs_created(); |
| 449 | if( g.argc<=3 ){ |
| 450 | /* All files updated. Shift the current checkout to the target. */ |
| 451 | db_multi_exec("DELETE FROM vfile WHERE vid!=%d", tid); |
| 452 | checkout_set_all_exe(vid); |
| 453 | manifest_to_disk(tid); |
| @@ -455,10 +459,58 @@ | |
| 459 | } |
| 460 | if( !internalUpdate ) undo_finish(); |
| 461 | db_end_transaction(0); |
| 462 | } |
| 463 | } |
| 464 | |
| 465 | /* |
| 466 | ** Make sure empty directories are created |
| 467 | */ |
| 468 | void ensure_empty_dirs_created() |
| 469 | { |
| 470 | /* Make empty directories? */ |
| 471 | char *zEmptyDirs = db_get_versionable_setting("empty-dirs", 0); |
| 472 | if( zEmptyDirs!=0 ){ |
| 473 | Blob dirsList; |
| 474 | blob_zero(&dirsList); |
| 475 | blob_init(&dirsList, zEmptyDirs, strlen(zEmptyDirs)); |
| 476 | /* Replace commas by spaces */ |
| 477 | char *bc = blob_str(&dirsList); |
| 478 | while( (*bc)!='\0' ){ |
| 479 | if( (*bc)==',' ) { *bc = ' '; } |
| 480 | ++bc; |
| 481 | } |
| 482 | /* Make directories */ |
| 483 | Blob dirName; |
| 484 | blob_zero(&dirName); |
| 485 | while( blob_token(&dirsList, &dirName) ){ |
| 486 | const char *zDir = blob_str(&dirName); |
| 487 | /* Make full pathname of the directory */ |
| 488 | Blob path; |
| 489 | blob_zero(&path); |
| 490 | blob_appendf(&path, "%s/%s", g.zLocalRoot, zDir); |
| 491 | const char *zPath = blob_str(&path); |
| 492 | /* Handle various cases of existence of the directory */ |
| 493 | switch( file_isdir(zPath) ){ |
| 494 | case 0: { /* doesn't exist */ |
| 495 | if( file_mkdir(zPath, 0)!=0 ) { |
| 496 | fossil_warning("couldn't create directory %s as required by empty-dirs setting", zDir); |
| 497 | } |
| 498 | break; |
| 499 | } |
| 500 | case 1: { /* exists, and is a directory */ |
| 501 | /* do nothing - required directory exists already */ |
| 502 | break; |
| 503 | } |
| 504 | case 2: { /* exists, but isn't a directory */ |
| 505 | fossil_warning("file %s found, but a directory is required by empty-dirs setting", zDir); |
| 506 | } |
| 507 | } |
| 508 | blob_reset(&path); |
| 509 | } |
| 510 | } |
| 511 | } |
| 512 | |
| 513 | |
| 514 | /* |
| 515 | ** Get the contents of a file within the checking "revision". If |
| 516 | ** revision==NULL then get the file content for the current checkout. |
| 517 |
+1
-1
| --- src/zip.c | ||
| +++ src/zip.c | ||
| @@ -337,11 +337,11 @@ | ||
| 337 | 337 | |
| 338 | 338 | pManifest = manifest_get(rid, CFTYPE_MANIFEST); |
| 339 | 339 | if( pManifest ){ |
| 340 | 340 | char *zName; |
| 341 | 341 | zip_set_timedate(pManifest->rDate); |
| 342 | - if( db_get_boolean("manifest", 0) ){ | |
| 342 | + if( db_get_versionable_setting_boolean("manifest", 0) ){ | |
| 343 | 343 | blob_append(&filename, "manifest", -1); |
| 344 | 344 | zName = blob_str(&filename); |
| 345 | 345 | zip_add_folders(zName); |
| 346 | 346 | zip_add_file(zName, &mfile, 0); |
| 347 | 347 | sha1sum_blob(&mfile, &hash); |
| 348 | 348 |
| --- src/zip.c | |
| +++ src/zip.c | |
| @@ -337,11 +337,11 @@ | |
| 337 | |
| 338 | pManifest = manifest_get(rid, CFTYPE_MANIFEST); |
| 339 | if( pManifest ){ |
| 340 | char *zName; |
| 341 | zip_set_timedate(pManifest->rDate); |
| 342 | if( db_get_boolean("manifest", 0) ){ |
| 343 | blob_append(&filename, "manifest", -1); |
| 344 | zName = blob_str(&filename); |
| 345 | zip_add_folders(zName); |
| 346 | zip_add_file(zName, &mfile, 0); |
| 347 | sha1sum_blob(&mfile, &hash); |
| 348 |
| --- src/zip.c | |
| +++ src/zip.c | |
| @@ -337,11 +337,11 @@ | |
| 337 | |
| 338 | pManifest = manifest_get(rid, CFTYPE_MANIFEST); |
| 339 | if( pManifest ){ |
| 340 | char *zName; |
| 341 | zip_set_timedate(pManifest->rDate); |
| 342 | if( db_get_versionable_setting_boolean("manifest", 0) ){ |
| 343 | blob_append(&filename, "manifest", -1); |
| 344 | zName = blob_str(&filename); |
| 345 | zip_add_folders(zName); |
| 346 | zip_add_file(zName, &mfile, 0); |
| 347 | sha1sum_blob(&mfile, &hash); |
| 348 |
+1
-1
| --- src/zip.c | ||
| +++ src/zip.c | ||
| @@ -337,11 +337,11 @@ | ||
| 337 | 337 | |
| 338 | 338 | pManifest = manifest_get(rid, CFTYPE_MANIFEST); |
| 339 | 339 | if( pManifest ){ |
| 340 | 340 | char *zName; |
| 341 | 341 | zip_set_timedate(pManifest->rDate); |
| 342 | - if( db_get_boolean("manifest", 0) ){ | |
| 342 | + if( db_get_versionable_setting_boolean("manifest", 0) ){ | |
| 343 | 343 | blob_append(&filename, "manifest", -1); |
| 344 | 344 | zName = blob_str(&filename); |
| 345 | 345 | zip_add_folders(zName); |
| 346 | 346 | zip_add_file(zName, &mfile, 0); |
| 347 | 347 | sha1sum_blob(&mfile, &hash); |
| 348 | 348 |
| --- src/zip.c | |
| +++ src/zip.c | |
| @@ -337,11 +337,11 @@ | |
| 337 | |
| 338 | pManifest = manifest_get(rid, CFTYPE_MANIFEST); |
| 339 | if( pManifest ){ |
| 340 | char *zName; |
| 341 | zip_set_timedate(pManifest->rDate); |
| 342 | if( db_get_boolean("manifest", 0) ){ |
| 343 | blob_append(&filename, "manifest", -1); |
| 344 | zName = blob_str(&filename); |
| 345 | zip_add_folders(zName); |
| 346 | zip_add_file(zName, &mfile, 0); |
| 347 | sha1sum_blob(&mfile, &hash); |
| 348 |
| --- src/zip.c | |
| +++ src/zip.c | |
| @@ -337,11 +337,11 @@ | |
| 337 | |
| 338 | pManifest = manifest_get(rid, CFTYPE_MANIFEST); |
| 339 | if( pManifest ){ |
| 340 | char *zName; |
| 341 | zip_set_timedate(pManifest->rDate); |
| 342 | if( db_get_versionable_setting_boolean("manifest", 0) ){ |
| 343 | blob_append(&filename, "manifest", -1); |
| 344 | zName = blob_str(&filename); |
| 345 | zip_add_folders(zName); |
| 346 | zip_add_file(zName, &mfile, 0); |
| 347 | sha1sum_blob(&mfile, &hash); |
| 348 |