Fossil SCM
Add the --ignore option to the "add" command and have "add" honor the "ignore-glob" setting. Ticket [f270321c0f74b354f05]
Commit
be3d2154da66a4cc3d1937f44f3a551efd26ca0c
Parent
ddf5f367652bf7e…
1 file changed
+56
-8
+56
-8
| --- src/add.c | ||
| +++ src/add.c | ||
| @@ -87,13 +87,42 @@ | ||
| 87 | 87 | return zAll; |
| 88 | 88 | } |
| 89 | 89 | |
| 90 | 90 | |
| 91 | 91 | /* |
| 92 | -** Add a single file | |
| 92 | +** The pIgnore statement is query of the form: | |
| 93 | +** | |
| 94 | +** SELECT (:x GLOB ... OR :x GLOB ... OR ...) | |
| 95 | +** | |
| 96 | +** In other words, it is a query that returns true if the :x value | |
| 97 | +** should be ignored. Evaluate the query and return true to ignore | |
| 98 | +** and false to not ignore. | |
| 99 | +** | |
| 100 | +** If pIgnore is NULL, then do not ignore. | |
| 101 | +*/ | |
| 102 | +static int shouldBeIgnored(Stmt *pIgnore, const char *zName){ | |
| 103 | + int rc = 0; | |
| 104 | + if( pIgnore ){ | |
| 105 | + db_bind_text(pIgnore, ":x", zName); | |
| 106 | + db_step(pIgnore); | |
| 107 | + rc = db_column_int(pIgnore, 0); | |
| 108 | + db_reset(pIgnore); | |
| 109 | + } | |
| 110 | + return rc; | |
| 111 | +} | |
| 112 | + | |
| 113 | + | |
| 114 | +/* | |
| 115 | +** Add a single file named zName to the VFILE table with vid. | |
| 116 | +** | |
| 117 | +** Omit any file whose name is pOmit. | |
| 93 | 118 | */ |
| 94 | -static void add_one_file(const char *zName, int vid, Blob *pOmit){ | |
| 119 | +static void add_one_file( | |
| 120 | + const char *zName, /* Name of file to add */ | |
| 121 | + int vid, /* Add to this VFILE */ | |
| 122 | + Blob *pOmit | |
| 123 | +){ | |
| 95 | 124 | Blob pathname; |
| 96 | 125 | const char *zPath; |
| 97 | 126 | int i; |
| 98 | 127 | const char *zReserved; |
| 99 | 128 | |
| @@ -130,11 +159,11 @@ | ||
| 130 | 159 | } |
| 131 | 160 | |
| 132 | 161 | /* |
| 133 | 162 | ** All content of the zDir directory to the SFILE table. |
| 134 | 163 | */ |
| 135 | -void add_directory_content(const char *zDir){ | |
| 164 | +void add_directory_content(const char *zDir, Stmt *pIgnore){ | |
| 136 | 165 | DIR *d; |
| 137 | 166 | int origSize; |
| 138 | 167 | struct dirent *pEntry; |
| 139 | 168 | Blob path; |
| 140 | 169 | |
| @@ -150,12 +179,14 @@ | ||
| 150 | 179 | if( pEntry->d_name[1]==0 ) continue; |
| 151 | 180 | if( pEntry->d_name[1]=='.' && pEntry->d_name[2]==0 ) continue; |
| 152 | 181 | } |
| 153 | 182 | blob_appendf(&path, "/%s", pEntry->d_name); |
| 154 | 183 | zPath = blob_str(&path); |
| 155 | - if( file_isdir(zPath)==1 ){ | |
| 156 | - add_directory_content(zPath); | |
| 184 | + if( shouldBeIgnored(pIgnore, zPath) ){ | |
| 185 | + /* Noop */ | |
| 186 | + }else if( file_isdir(zPath)==1 ){ | |
| 187 | + add_directory_content(zPath, pIgnore); | |
| 157 | 188 | }else if( file_isfile(zPath) ){ |
| 158 | 189 | db_multi_exec("INSERT INTO sfile VALUES(%Q)", zPath); |
| 159 | 190 | } |
| 160 | 191 | blob_resize(&path, origSize); |
| 161 | 192 | } |
| @@ -165,13 +196,13 @@ | ||
| 165 | 196 | } |
| 166 | 197 | |
| 167 | 198 | /* |
| 168 | 199 | ** Add all content of a directory. |
| 169 | 200 | */ |
| 170 | -void add_directory(const char *zDir, int vid, Blob *pOmit){ | |
| 201 | +void add_directory(const char *zDir, int vid, Blob *pOmit, Stmt *pIgnore){ | |
| 171 | 202 | Stmt q; |
| 172 | - add_directory_content(zDir); | |
| 203 | + add_directory_content(zDir, pIgnore); | |
| 173 | 204 | db_prepare(&q, "SELECT x FROM sfile ORDER BY x"); |
| 174 | 205 | while( db_step(&q)==SQLITE_ROW ){ |
| 175 | 206 | const char *zName = db_column_text(&q, 0); |
| 176 | 207 | add_one_file(zName, vid, pOmit); |
| 177 | 208 | } |
| @@ -188,18 +219,28 @@ | ||
| 188 | 219 | ** at the next commit. |
| 189 | 220 | ** |
| 190 | 221 | ** When adding files recursively, filenames that begin with "." are |
| 191 | 222 | ** excluded by default. To include such files, add the "--dotfiles" |
| 192 | 223 | ** option to the command-line. |
| 224 | +** | |
| 225 | +** The --ignore option overrides the "ignore-glob" setting. See | |
| 226 | +** documentation on the "setting" command for further information. | |
| 193 | 227 | */ |
| 194 | 228 | void add_cmd(void){ |
| 195 | 229 | int i; |
| 196 | 230 | int vid; |
| 231 | + const char *zIgnoreFlag; | |
| 197 | 232 | Blob repo; |
| 233 | + Stmt ignoreTest; /* Test to see if a name should be ignored */ | |
| 234 | + Stmt *pIgnore; /* Pointer to ignoreTest or to NULL */ | |
| 198 | 235 | |
| 236 | + zIgnoreFlag = find_option("ignore",0,1); | |
| 199 | 237 | includeDotFiles = find_option("dotfiles",0,0)!=0; |
| 200 | 238 | db_must_be_within_tree(); |
| 239 | + if( zIgnoreFlag==0 ){ | |
| 240 | + zIgnoreFlag = db_get("ignore-glob", 0); | |
| 241 | + } | |
| 201 | 242 | vid = db_lget_int("checkout",0); |
| 202 | 243 | if( vid==0 ){ |
| 203 | 244 | fossil_panic("no checkout to add to"); |
| 204 | 245 | } |
| 205 | 246 | db_begin_transaction(); |
| @@ -211,27 +252,34 @@ | ||
| 211 | 252 | db_multi_exec( |
| 212 | 253 | "CREATE INDEX IF NOT EXISTS vfile_pathname " |
| 213 | 254 | " ON vfile(pathname COLLATE nocase)" |
| 214 | 255 | ); |
| 215 | 256 | #endif |
| 257 | + if( zIgnoreFlag && zIgnoreFlag[0] ){ | |
| 258 | + db_prepare(&ignoreTest, "SELECT %s", glob_expr(":x", zIgnoreFlag)); | |
| 259 | + pIgnore = &ignoreTest; | |
| 260 | + }else{ | |
| 261 | + pIgnore = 0; | |
| 262 | + } | |
| 216 | 263 | for(i=2; i<g.argc; i++){ |
| 217 | 264 | char *zName; |
| 218 | 265 | int isDir; |
| 219 | 266 | |
| 220 | 267 | zName = mprintf("%/", g.argv[i]); |
| 221 | 268 | isDir = file_isdir(zName); |
| 222 | 269 | if( isDir==1 ){ |
| 223 | - add_directory(zName, vid, &repo); | |
| 270 | + add_directory(zName, vid, &repo, pIgnore); | |
| 224 | 271 | }else if( isDir==0 ){ |
| 225 | 272 | fossil_fatal("not found: %s", zName); |
| 226 | 273 | }else if( access(zName, R_OK) ){ |
| 227 | 274 | fossil_fatal("cannot open %s", zName); |
| 228 | 275 | }else{ |
| 229 | 276 | add_one_file(zName, vid, &repo); |
| 230 | 277 | } |
| 231 | 278 | free(zName); |
| 232 | 279 | } |
| 280 | + if( pIgnore ) db_finalize(pIgnore); | |
| 233 | 281 | db_end_transaction(0); |
| 234 | 282 | } |
| 235 | 283 | |
| 236 | 284 | /* |
| 237 | 285 | ** Remove all contents of zDir |
| 238 | 286 |
| --- src/add.c | |
| +++ src/add.c | |
| @@ -87,13 +87,42 @@ | |
| 87 | return zAll; |
| 88 | } |
| 89 | |
| 90 | |
| 91 | /* |
| 92 | ** Add a single file |
| 93 | */ |
| 94 | static void add_one_file(const char *zName, int vid, Blob *pOmit){ |
| 95 | Blob pathname; |
| 96 | const char *zPath; |
| 97 | int i; |
| 98 | const char *zReserved; |
| 99 | |
| @@ -130,11 +159,11 @@ | |
| 130 | } |
| 131 | |
| 132 | /* |
| 133 | ** All content of the zDir directory to the SFILE table. |
| 134 | */ |
| 135 | void add_directory_content(const char *zDir){ |
| 136 | DIR *d; |
| 137 | int origSize; |
| 138 | struct dirent *pEntry; |
| 139 | Blob path; |
| 140 | |
| @@ -150,12 +179,14 @@ | |
| 150 | if( pEntry->d_name[1]==0 ) continue; |
| 151 | if( pEntry->d_name[1]=='.' && pEntry->d_name[2]==0 ) continue; |
| 152 | } |
| 153 | blob_appendf(&path, "/%s", pEntry->d_name); |
| 154 | zPath = blob_str(&path); |
| 155 | if( file_isdir(zPath)==1 ){ |
| 156 | add_directory_content(zPath); |
| 157 | }else if( file_isfile(zPath) ){ |
| 158 | db_multi_exec("INSERT INTO sfile VALUES(%Q)", zPath); |
| 159 | } |
| 160 | blob_resize(&path, origSize); |
| 161 | } |
| @@ -165,13 +196,13 @@ | |
| 165 | } |
| 166 | |
| 167 | /* |
| 168 | ** Add all content of a directory. |
| 169 | */ |
| 170 | void add_directory(const char *zDir, int vid, Blob *pOmit){ |
| 171 | Stmt q; |
| 172 | add_directory_content(zDir); |
| 173 | db_prepare(&q, "SELECT x FROM sfile ORDER BY x"); |
| 174 | while( db_step(&q)==SQLITE_ROW ){ |
| 175 | const char *zName = db_column_text(&q, 0); |
| 176 | add_one_file(zName, vid, pOmit); |
| 177 | } |
| @@ -188,18 +219,28 @@ | |
| 188 | ** at the next commit. |
| 189 | ** |
| 190 | ** When adding files recursively, filenames that begin with "." are |
| 191 | ** excluded by default. To include such files, add the "--dotfiles" |
| 192 | ** option to the command-line. |
| 193 | */ |
| 194 | void add_cmd(void){ |
| 195 | int i; |
| 196 | int vid; |
| 197 | Blob repo; |
| 198 | |
| 199 | includeDotFiles = find_option("dotfiles",0,0)!=0; |
| 200 | db_must_be_within_tree(); |
| 201 | vid = db_lget_int("checkout",0); |
| 202 | if( vid==0 ){ |
| 203 | fossil_panic("no checkout to add to"); |
| 204 | } |
| 205 | db_begin_transaction(); |
| @@ -211,27 +252,34 @@ | |
| 211 | db_multi_exec( |
| 212 | "CREATE INDEX IF NOT EXISTS vfile_pathname " |
| 213 | " ON vfile(pathname COLLATE nocase)" |
| 214 | ); |
| 215 | #endif |
| 216 | for(i=2; i<g.argc; i++){ |
| 217 | char *zName; |
| 218 | int isDir; |
| 219 | |
| 220 | zName = mprintf("%/", g.argv[i]); |
| 221 | isDir = file_isdir(zName); |
| 222 | if( isDir==1 ){ |
| 223 | add_directory(zName, vid, &repo); |
| 224 | }else if( isDir==0 ){ |
| 225 | fossil_fatal("not found: %s", zName); |
| 226 | }else if( access(zName, R_OK) ){ |
| 227 | fossil_fatal("cannot open %s", zName); |
| 228 | }else{ |
| 229 | add_one_file(zName, vid, &repo); |
| 230 | } |
| 231 | free(zName); |
| 232 | } |
| 233 | db_end_transaction(0); |
| 234 | } |
| 235 | |
| 236 | /* |
| 237 | ** Remove all contents of zDir |
| 238 |
| --- src/add.c | |
| +++ src/add.c | |
| @@ -87,13 +87,42 @@ | |
| 87 | return zAll; |
| 88 | } |
| 89 | |
| 90 | |
| 91 | /* |
| 92 | ** The pIgnore statement is query of the form: |
| 93 | ** |
| 94 | ** SELECT (:x GLOB ... OR :x GLOB ... OR ...) |
| 95 | ** |
| 96 | ** In other words, it is a query that returns true if the :x value |
| 97 | ** should be ignored. Evaluate the query and return true to ignore |
| 98 | ** and false to not ignore. |
| 99 | ** |
| 100 | ** If pIgnore is NULL, then do not ignore. |
| 101 | */ |
| 102 | static int shouldBeIgnored(Stmt *pIgnore, const char *zName){ |
| 103 | int rc = 0; |
| 104 | if( pIgnore ){ |
| 105 | db_bind_text(pIgnore, ":x", zName); |
| 106 | db_step(pIgnore); |
| 107 | rc = db_column_int(pIgnore, 0); |
| 108 | db_reset(pIgnore); |
| 109 | } |
| 110 | return rc; |
| 111 | } |
| 112 | |
| 113 | |
| 114 | /* |
| 115 | ** Add a single file named zName to the VFILE table with vid. |
| 116 | ** |
| 117 | ** Omit any file whose name is pOmit. |
| 118 | */ |
| 119 | static void add_one_file( |
| 120 | const char *zName, /* Name of file to add */ |
| 121 | int vid, /* Add to this VFILE */ |
| 122 | Blob *pOmit |
| 123 | ){ |
| 124 | Blob pathname; |
| 125 | const char *zPath; |
| 126 | int i; |
| 127 | const char *zReserved; |
| 128 | |
| @@ -130,11 +159,11 @@ | |
| 159 | } |
| 160 | |
| 161 | /* |
| 162 | ** All content of the zDir directory to the SFILE table. |
| 163 | */ |
| 164 | void add_directory_content(const char *zDir, Stmt *pIgnore){ |
| 165 | DIR *d; |
| 166 | int origSize; |
| 167 | struct dirent *pEntry; |
| 168 | Blob path; |
| 169 | |
| @@ -150,12 +179,14 @@ | |
| 179 | if( pEntry->d_name[1]==0 ) continue; |
| 180 | if( pEntry->d_name[1]=='.' && pEntry->d_name[2]==0 ) continue; |
| 181 | } |
| 182 | blob_appendf(&path, "/%s", pEntry->d_name); |
| 183 | zPath = blob_str(&path); |
| 184 | if( shouldBeIgnored(pIgnore, zPath) ){ |
| 185 | /* Noop */ |
| 186 | }else if( file_isdir(zPath)==1 ){ |
| 187 | add_directory_content(zPath, pIgnore); |
| 188 | }else if( file_isfile(zPath) ){ |
| 189 | db_multi_exec("INSERT INTO sfile VALUES(%Q)", zPath); |
| 190 | } |
| 191 | blob_resize(&path, origSize); |
| 192 | } |
| @@ -165,13 +196,13 @@ | |
| 196 | } |
| 197 | |
| 198 | /* |
| 199 | ** Add all content of a directory. |
| 200 | */ |
| 201 | void add_directory(const char *zDir, int vid, Blob *pOmit, Stmt *pIgnore){ |
| 202 | Stmt q; |
| 203 | add_directory_content(zDir, pIgnore); |
| 204 | db_prepare(&q, "SELECT x FROM sfile ORDER BY x"); |
| 205 | while( db_step(&q)==SQLITE_ROW ){ |
| 206 | const char *zName = db_column_text(&q, 0); |
| 207 | add_one_file(zName, vid, pOmit); |
| 208 | } |
| @@ -188,18 +219,28 @@ | |
| 219 | ** at the next commit. |
| 220 | ** |
| 221 | ** When adding files recursively, filenames that begin with "." are |
| 222 | ** excluded by default. To include such files, add the "--dotfiles" |
| 223 | ** option to the command-line. |
| 224 | ** |
| 225 | ** The --ignore option overrides the "ignore-glob" setting. See |
| 226 | ** documentation on the "setting" command for further information. |
| 227 | */ |
| 228 | void add_cmd(void){ |
| 229 | int i; |
| 230 | int vid; |
| 231 | const char *zIgnoreFlag; |
| 232 | Blob repo; |
| 233 | Stmt ignoreTest; /* Test to see if a name should be ignored */ |
| 234 | Stmt *pIgnore; /* Pointer to ignoreTest or to NULL */ |
| 235 | |
| 236 | zIgnoreFlag = find_option("ignore",0,1); |
| 237 | includeDotFiles = find_option("dotfiles",0,0)!=0; |
| 238 | db_must_be_within_tree(); |
| 239 | if( zIgnoreFlag==0 ){ |
| 240 | zIgnoreFlag = db_get("ignore-glob", 0); |
| 241 | } |
| 242 | vid = db_lget_int("checkout",0); |
| 243 | if( vid==0 ){ |
| 244 | fossil_panic("no checkout to add to"); |
| 245 | } |
| 246 | db_begin_transaction(); |
| @@ -211,27 +252,34 @@ | |
| 252 | db_multi_exec( |
| 253 | "CREATE INDEX IF NOT EXISTS vfile_pathname " |
| 254 | " ON vfile(pathname COLLATE nocase)" |
| 255 | ); |
| 256 | #endif |
| 257 | if( zIgnoreFlag && zIgnoreFlag[0] ){ |
| 258 | db_prepare(&ignoreTest, "SELECT %s", glob_expr(":x", zIgnoreFlag)); |
| 259 | pIgnore = &ignoreTest; |
| 260 | }else{ |
| 261 | pIgnore = 0; |
| 262 | } |
| 263 | for(i=2; i<g.argc; i++){ |
| 264 | char *zName; |
| 265 | int isDir; |
| 266 | |
| 267 | zName = mprintf("%/", g.argv[i]); |
| 268 | isDir = file_isdir(zName); |
| 269 | if( isDir==1 ){ |
| 270 | add_directory(zName, vid, &repo, pIgnore); |
| 271 | }else if( isDir==0 ){ |
| 272 | fossil_fatal("not found: %s", zName); |
| 273 | }else if( access(zName, R_OK) ){ |
| 274 | fossil_fatal("cannot open %s", zName); |
| 275 | }else{ |
| 276 | add_one_file(zName, vid, &repo); |
| 277 | } |
| 278 | free(zName); |
| 279 | } |
| 280 | if( pIgnore ) db_finalize(pIgnore); |
| 281 | db_end_transaction(0); |
| 282 | } |
| 283 | |
| 284 | /* |
| 285 | ** Remove all contents of zDir |
| 286 |