Fossil SCM
fossil rm can now remove entire directories.
Commit
6dbd362de9edaef511859cb49691b0ad62e6b78f
Parent
f51bd59613cf9a2…
1 file changed
+67
-20
+67
-20
| --- src/add.c | ||
| +++ src/add.c | ||
| @@ -7,11 +7,11 @@ | ||
| 7 | 7 | ** |
| 8 | 8 | ** This program is distributed in the hope that it will be useful, |
| 9 | 9 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 10 | 10 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 11 | 11 | ** General Public License for more details. |
| 12 | -** | |
| 12 | +** | |
| 13 | 13 | ** You should have received a copy of the GNU General Public |
| 14 | 14 | ** License along with this library; if not, write to the |
| 15 | 15 | ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
| 16 | 16 | ** Boston, MA 02111-1307, USA. |
| 17 | 17 | ** |
| @@ -32,18 +32,18 @@ | ||
| 32 | 32 | /* |
| 33 | 33 | ** Set to true if files whose names begin with "." should be |
| 34 | 34 | ** included when processing a recursive "add" command. |
| 35 | 35 | */ |
| 36 | 36 | static int includeDotFiles = 0; |
| 37 | - | |
| 37 | + | |
| 38 | 38 | /* |
| 39 | 39 | ** Add a single file |
| 40 | 40 | */ |
| 41 | 41 | static void add_one_file(const char *zName, int vid, Blob *pOmit){ |
| 42 | 42 | Blob pathname; |
| 43 | 43 | const char *zPath; |
| 44 | - | |
| 44 | + | |
| 45 | 45 | file_tree_name(zName, &pathname, 1); |
| 46 | 46 | zPath = blob_str(&pathname); |
| 47 | 47 | if( strcmp(zPath, "manifest")==0 |
| 48 | 48 | || strcmp(zPath, "_FOSSIL_")==0 |
| 49 | 49 | || strcmp(zPath, "manifest.uuid")==0 |
| @@ -126,11 +126,11 @@ | ||
| 126 | 126 | /* |
| 127 | 127 | ** COMMAND: add |
| 128 | 128 | ** |
| 129 | 129 | ** Usage: %fossil add FILE... |
| 130 | 130 | ** |
| 131 | -** Make arrangements to add one or more files to the current checkout | |
| 131 | +** Make arrangements to add one or more files to the current checkout | |
| 132 | 132 | ** at the next commit. |
| 133 | 133 | ** |
| 134 | 134 | ** When adding files recursively, filenames that begin with "." are |
| 135 | 135 | ** excluded by default. To include such files, add the "--dotfiles" |
| 136 | 136 | ** option to the command-line. |
| @@ -174,10 +174,57 @@ | ||
| 174 | 174 | } |
| 175 | 175 | free(zName); |
| 176 | 176 | } |
| 177 | 177 | db_end_transaction(0); |
| 178 | 178 | } |
| 179 | + | |
| 180 | +/* | |
| 181 | +** Remove all contents of zDir | |
| 182 | +*/ | |
| 183 | +void del_directory_content(const char *zDir){ | |
| 184 | + DIR *d; | |
| 185 | + int origSize; | |
| 186 | + struct dirent *pEntry; | |
| 187 | + Blob path; | |
| 188 | + | |
| 189 | + blob_zero(&path); | |
| 190 | + blob_append(&path, zDir, -1); | |
| 191 | + origSize = blob_size(&path); | |
| 192 | + d = opendir(zDir); | |
| 193 | + if( d ){ | |
| 194 | + while( (pEntry=readdir(d))!=0 ){ | |
| 195 | + char *zPath; | |
| 196 | + if( pEntry->d_name[0]=='.'){ | |
| 197 | + if( !includeDotFiles ) continue; | |
| 198 | + if( pEntry->d_name[1]==0 ) continue; | |
| 199 | + if( pEntry->d_name[1]=='.' && pEntry->d_name[2]==0 ) continue; | |
| 200 | + } | |
| 201 | + blob_appendf(&path, "/%s", pEntry->d_name); | |
| 202 | + zPath = blob_str(&path); | |
| 203 | + if( file_isdir(zPath)==1 ){ | |
| 204 | + del_directory_content(zPath); | |
| 205 | + }else if( file_isfile(zPath) ){ | |
| 206 | + char *zFilePath; | |
| 207 | + Blob pathname; | |
| 208 | + file_tree_name(zPath, &pathname, 1); | |
| 209 | + zFilePath = blob_str(&pathname); | |
| 210 | + if( !db_exists( | |
| 211 | + "SELECT 1 FROM vfile WHERE pathname=%Q AND NOT deleted", zFilePath) | |
| 212 | + ){ | |
| 213 | + printf("SKIPPED %s\n", zPath); | |
| 214 | + }else{ | |
| 215 | + db_multi_exec("UPDATE vfile SET deleted=1 WHERE pathname=%Q", zPath); | |
| 216 | + printf("DELETED %s\n", zPath); | |
| 217 | + } | |
| 218 | + blob_reset(&pathname); | |
| 219 | + } | |
| 220 | + blob_resize(&path, origSize); | |
| 221 | + } | |
| 222 | + } | |
| 223 | + closedir(d); | |
| 224 | + blob_reset(&path); | |
| 225 | +} | |
| 179 | 226 | |
| 180 | 227 | /* |
| 181 | 228 | ** COMMAND: rm |
| 182 | 229 | ** COMMAND: del |
| 183 | 230 | ** |
| @@ -200,36 +247,36 @@ | ||
| 200 | 247 | fossil_panic("no checkout to remove from"); |
| 201 | 248 | } |
| 202 | 249 | db_begin_transaction(); |
| 203 | 250 | for(i=2; i<g.argc; i++){ |
| 204 | 251 | char *zName; |
| 205 | - char *zPath; | |
| 206 | - Blob pathname; | |
| 207 | 252 | |
| 208 | 253 | zName = mprintf("%/", g.argv[i]); |
| 209 | 254 | if( file_isdir(zName) ){ |
| 210 | - fossil_fatal("cannot remove directories -" | |
| 211 | - " remove individual files instead"); | |
| 212 | - } | |
| 213 | - file_tree_name(zName, &pathname, 1); | |
| 214 | - zPath = blob_str(&pathname); | |
| 215 | - if( !db_exists( | |
| 216 | - "SELECT 1 FROM vfile WHERE pathname=%Q AND NOT deleted", zPath) ){ | |
| 217 | - fossil_fatal("not in the repository: %s", zName); | |
| 218 | - }else{ | |
| 219 | - db_multi_exec("UPDATE vfile SET deleted=1 WHERE pathname=%Q", zPath); | |
| 220 | - printf("DELETED %s\n", zPath); | |
| 221 | - } | |
| 222 | - blob_reset(&pathname); | |
| 255 | + del_directory_content(zName); | |
| 256 | + } else { | |
| 257 | + char *zPath; | |
| 258 | + Blob pathname; | |
| 259 | + file_tree_name(zName, &pathname, 1); | |
| 260 | + zPath = blob_str(&pathname); | |
| 261 | + if( !db_exists( | |
| 262 | + "SELECT 1 FROM vfile WHERE pathname=%Q AND NOT deleted", zPath) ){ | |
| 263 | + fossil_fatal("not in the repository: %s", zName); | |
| 264 | + }else{ | |
| 265 | + db_multi_exec("UPDATE vfile SET deleted=1 WHERE pathname=%Q", zPath); | |
| 266 | + printf("DELETED %s\n", zPath); | |
| 267 | + } | |
| 268 | + blob_reset(&pathname); | |
| 269 | + } | |
| 223 | 270 | free(zName); |
| 224 | 271 | } |
| 225 | 272 | db_multi_exec("DELETE FROM vfile WHERE deleted AND rid=0"); |
| 226 | 273 | db_end_transaction(0); |
| 227 | 274 | } |
| 228 | 275 | |
| 229 | 276 | /* |
| 230 | -** Rename a single file. | |
| 277 | +** Rename a single file. | |
| 231 | 278 | ** |
| 232 | 279 | ** The original name of the file is zOrig. The new filename is zNew. |
| 233 | 280 | */ |
| 234 | 281 | static void mv_one_file(int vid, const char *zOrig, const char *zNew){ |
| 235 | 282 | printf("RENAME %s %s\n", zOrig, zNew); |
| 236 | 283 |
| --- src/add.c | |
| +++ src/add.c | |
| @@ -7,11 +7,11 @@ | |
| 7 | ** |
| 8 | ** This program is distributed in the hope that it will be useful, |
| 9 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 10 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 11 | ** General Public License for more details. |
| 12 | ** |
| 13 | ** You should have received a copy of the GNU General Public |
| 14 | ** License along with this library; if not, write to the |
| 15 | ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
| 16 | ** Boston, MA 02111-1307, USA. |
| 17 | ** |
| @@ -32,18 +32,18 @@ | |
| 32 | /* |
| 33 | ** Set to true if files whose names begin with "." should be |
| 34 | ** included when processing a recursive "add" command. |
| 35 | */ |
| 36 | static int includeDotFiles = 0; |
| 37 | |
| 38 | /* |
| 39 | ** Add a single file |
| 40 | */ |
| 41 | static void add_one_file(const char *zName, int vid, Blob *pOmit){ |
| 42 | Blob pathname; |
| 43 | const char *zPath; |
| 44 | |
| 45 | file_tree_name(zName, &pathname, 1); |
| 46 | zPath = blob_str(&pathname); |
| 47 | if( strcmp(zPath, "manifest")==0 |
| 48 | || strcmp(zPath, "_FOSSIL_")==0 |
| 49 | || strcmp(zPath, "manifest.uuid")==0 |
| @@ -126,11 +126,11 @@ | |
| 126 | /* |
| 127 | ** COMMAND: add |
| 128 | ** |
| 129 | ** Usage: %fossil add FILE... |
| 130 | ** |
| 131 | ** Make arrangements to add one or more files to the current checkout |
| 132 | ** at the next commit. |
| 133 | ** |
| 134 | ** When adding files recursively, filenames that begin with "." are |
| 135 | ** excluded by default. To include such files, add the "--dotfiles" |
| 136 | ** option to the command-line. |
| @@ -174,10 +174,57 @@ | |
| 174 | } |
| 175 | free(zName); |
| 176 | } |
| 177 | db_end_transaction(0); |
| 178 | } |
| 179 | |
| 180 | /* |
| 181 | ** COMMAND: rm |
| 182 | ** COMMAND: del |
| 183 | ** |
| @@ -200,36 +247,36 @@ | |
| 200 | fossil_panic("no checkout to remove from"); |
| 201 | } |
| 202 | db_begin_transaction(); |
| 203 | for(i=2; i<g.argc; i++){ |
| 204 | char *zName; |
| 205 | char *zPath; |
| 206 | Blob pathname; |
| 207 | |
| 208 | zName = mprintf("%/", g.argv[i]); |
| 209 | if( file_isdir(zName) ){ |
| 210 | fossil_fatal("cannot remove directories -" |
| 211 | " remove individual files instead"); |
| 212 | } |
| 213 | file_tree_name(zName, &pathname, 1); |
| 214 | zPath = blob_str(&pathname); |
| 215 | if( !db_exists( |
| 216 | "SELECT 1 FROM vfile WHERE pathname=%Q AND NOT deleted", zPath) ){ |
| 217 | fossil_fatal("not in the repository: %s", zName); |
| 218 | }else{ |
| 219 | db_multi_exec("UPDATE vfile SET deleted=1 WHERE pathname=%Q", zPath); |
| 220 | printf("DELETED %s\n", zPath); |
| 221 | } |
| 222 | blob_reset(&pathname); |
| 223 | free(zName); |
| 224 | } |
| 225 | db_multi_exec("DELETE FROM vfile WHERE deleted AND rid=0"); |
| 226 | db_end_transaction(0); |
| 227 | } |
| 228 | |
| 229 | /* |
| 230 | ** Rename a single file. |
| 231 | ** |
| 232 | ** The original name of the file is zOrig. The new filename is zNew. |
| 233 | */ |
| 234 | static void mv_one_file(int vid, const char *zOrig, const char *zNew){ |
| 235 | printf("RENAME %s %s\n", zOrig, zNew); |
| 236 |
| --- src/add.c | |
| +++ src/add.c | |
| @@ -7,11 +7,11 @@ | |
| 7 | ** |
| 8 | ** This program is distributed in the hope that it will be useful, |
| 9 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 10 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 11 | ** General Public License for more details. |
| 12 | ** |
| 13 | ** You should have received a copy of the GNU General Public |
| 14 | ** License along with this library; if not, write to the |
| 15 | ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
| 16 | ** Boston, MA 02111-1307, USA. |
| 17 | ** |
| @@ -32,18 +32,18 @@ | |
| 32 | /* |
| 33 | ** Set to true if files whose names begin with "." should be |
| 34 | ** included when processing a recursive "add" command. |
| 35 | */ |
| 36 | static int includeDotFiles = 0; |
| 37 | |
| 38 | /* |
| 39 | ** Add a single file |
| 40 | */ |
| 41 | static void add_one_file(const char *zName, int vid, Blob *pOmit){ |
| 42 | Blob pathname; |
| 43 | const char *zPath; |
| 44 | |
| 45 | file_tree_name(zName, &pathname, 1); |
| 46 | zPath = blob_str(&pathname); |
| 47 | if( strcmp(zPath, "manifest")==0 |
| 48 | || strcmp(zPath, "_FOSSIL_")==0 |
| 49 | || strcmp(zPath, "manifest.uuid")==0 |
| @@ -126,11 +126,11 @@ | |
| 126 | /* |
| 127 | ** COMMAND: add |
| 128 | ** |
| 129 | ** Usage: %fossil add FILE... |
| 130 | ** |
| 131 | ** Make arrangements to add one or more files to the current checkout |
| 132 | ** at the next commit. |
| 133 | ** |
| 134 | ** When adding files recursively, filenames that begin with "." are |
| 135 | ** excluded by default. To include such files, add the "--dotfiles" |
| 136 | ** option to the command-line. |
| @@ -174,10 +174,57 @@ | |
| 174 | } |
| 175 | free(zName); |
| 176 | } |
| 177 | db_end_transaction(0); |
| 178 | } |
| 179 | |
| 180 | /* |
| 181 | ** Remove all contents of zDir |
| 182 | */ |
| 183 | void del_directory_content(const char *zDir){ |
| 184 | DIR *d; |
| 185 | int origSize; |
| 186 | struct dirent *pEntry; |
| 187 | Blob path; |
| 188 | |
| 189 | blob_zero(&path); |
| 190 | blob_append(&path, zDir, -1); |
| 191 | origSize = blob_size(&path); |
| 192 | d = opendir(zDir); |
| 193 | if( d ){ |
| 194 | while( (pEntry=readdir(d))!=0 ){ |
| 195 | char *zPath; |
| 196 | if( pEntry->d_name[0]=='.'){ |
| 197 | if( !includeDotFiles ) continue; |
| 198 | if( pEntry->d_name[1]==0 ) continue; |
| 199 | if( pEntry->d_name[1]=='.' && pEntry->d_name[2]==0 ) continue; |
| 200 | } |
| 201 | blob_appendf(&path, "/%s", pEntry->d_name); |
| 202 | zPath = blob_str(&path); |
| 203 | if( file_isdir(zPath)==1 ){ |
| 204 | del_directory_content(zPath); |
| 205 | }else if( file_isfile(zPath) ){ |
| 206 | char *zFilePath; |
| 207 | Blob pathname; |
| 208 | file_tree_name(zPath, &pathname, 1); |
| 209 | zFilePath = blob_str(&pathname); |
| 210 | if( !db_exists( |
| 211 | "SELECT 1 FROM vfile WHERE pathname=%Q AND NOT deleted", zFilePath) |
| 212 | ){ |
| 213 | printf("SKIPPED %s\n", zPath); |
| 214 | }else{ |
| 215 | db_multi_exec("UPDATE vfile SET deleted=1 WHERE pathname=%Q", zPath); |
| 216 | printf("DELETED %s\n", zPath); |
| 217 | } |
| 218 | blob_reset(&pathname); |
| 219 | } |
| 220 | blob_resize(&path, origSize); |
| 221 | } |
| 222 | } |
| 223 | closedir(d); |
| 224 | blob_reset(&path); |
| 225 | } |
| 226 | |
| 227 | /* |
| 228 | ** COMMAND: rm |
| 229 | ** COMMAND: del |
| 230 | ** |
| @@ -200,36 +247,36 @@ | |
| 247 | fossil_panic("no checkout to remove from"); |
| 248 | } |
| 249 | db_begin_transaction(); |
| 250 | for(i=2; i<g.argc; i++){ |
| 251 | char *zName; |
| 252 | |
| 253 | zName = mprintf("%/", g.argv[i]); |
| 254 | if( file_isdir(zName) ){ |
| 255 | del_directory_content(zName); |
| 256 | } else { |
| 257 | char *zPath; |
| 258 | Blob pathname; |
| 259 | file_tree_name(zName, &pathname, 1); |
| 260 | zPath = blob_str(&pathname); |
| 261 | if( !db_exists( |
| 262 | "SELECT 1 FROM vfile WHERE pathname=%Q AND NOT deleted", zPath) ){ |
| 263 | fossil_fatal("not in the repository: %s", zName); |
| 264 | }else{ |
| 265 | db_multi_exec("UPDATE vfile SET deleted=1 WHERE pathname=%Q", zPath); |
| 266 | printf("DELETED %s\n", zPath); |
| 267 | } |
| 268 | blob_reset(&pathname); |
| 269 | } |
| 270 | free(zName); |
| 271 | } |
| 272 | db_multi_exec("DELETE FROM vfile WHERE deleted AND rid=0"); |
| 273 | db_end_transaction(0); |
| 274 | } |
| 275 | |
| 276 | /* |
| 277 | ** Rename a single file. |
| 278 | ** |
| 279 | ** The original name of the file is zOrig. The new filename is zNew. |
| 280 | */ |
| 281 | static void mv_one_file(int vid, const char *zOrig, const char *zNew){ |
| 282 | printf("RENAME %s %s\n", zOrig, zNew); |
| 283 |