Fossil SCM

Implement -x|-X|-e|--exclude options for "fossil clean". Compatible with "git clean -x|-X|-e|--exclude".

jan.nijtmans 2013-05-21 14:45 trunk
Commit 44025538c402793240b3e49f0385a44cb17c1e07
1 file changed +44 -19
+44 -19
--- src/checkin.c
+++ src/checkin.c
@@ -236,11 +236,11 @@
236236
int verboseFlag;
237237
int showAge;
238238
char *zOrderBy = "pathname";
239239
240240
verboseFlag = find_option("verbose","v", 0)!=0;
241
- if(!verboseFlag){
241
+ if( !verboseFlag ){
242242
verboseFlag = find_option("l","l", 0)!=0; /* deprecated */
243243
}
244244
showAge = find_option("age",0,0)!=0;
245245
db_must_be_within_tree();
246246
vid = db_lget_int("checkout", 0);
@@ -381,11 +381,13 @@
381381
** COMMAND: clean
382382
** Usage: %fossil clean ?OPTIONS?
383383
**
384384
** Delete all "extra" files in the source tree. "Extra" files are
385385
** files that are not officially part of the checkout. This operation
386
-** cannot be undone.
386
+** cannot be undone. Normally, only files unknown to fossil are
387
+** removed, but if the -x option is specified, ignored files are
388
+** removed as well.
387389
**
388390
** You will be prompted before removing each eligible file unless the
389391
** --force flag is in use or it matches the --clean option. The
390392
** GLOBPATTERN specified by the "ignore-glob" setting is used if the
391393
** --ignore option is omitted, the same with "clean-glob" and --clean
@@ -399,49 +401,63 @@
399401
** normally kept. They are handled if the "--dotfiles" option
400402
** is used.
401403
**
402404
** Options:
403405
** --case-sensitive <BOOL> override case-sensitive setting
404
-** --dotfiles include files beginning with a dot (".")
405
-** -f|--force Remove files without prompting
406
-** --clean <CSG> never prompt for files matching this
407
-** comma separated list of glob patterns.
408
-** --ignore <CSG> ignore files matching patterns from the
409
-** comma separated list of glob patterns.
410
-** --keep <CSG> keep files matching this comma separated
411
-** list of glob patterns.
412
-** -n|--dry-run If given, display instead of run actions
413
-** --temp Remove only Fossil-generated temporary files
414
-** -v|--verbose Show all files as they are removed
406
+** --dotfiles include files beginning with a dot (".")
407
+** -f|--force Remove files without prompting
408
+** --clean <CSG> never prompt for files matching this
409
+** comma separated list of glob patterns.
410
+** --ignore <CSG> ignore files matching patterns from the
411
+** comma separated list of glob patterns.
412
+** -e|--exclude <CSG> In addition to those found in --ignore or
413
+** "ignore-glob", consider these patterns to
414
+** be in the set of the ignore rules as well.
415
+** --keep <CSG> keep files matching this comma separated
416
+** list of glob patterns, even with -x/-X.
417
+** -n|--dry-run If given, display instead of run actions
418
+** --temp Remove only Fossil-generated temporary files
419
+** -v|--verbose Show all files as they are removed
420
+** -x Don't use "ignore-glob" as default for
421
+** --ignore. For compatibility with git.
422
+** -X Remove only files ignored by fossil. This
423
+** may be useful to rebuild everything from
424
+** scratch, but keep manually created files.
425
+** Compatible with "git clean -X"
415426
**
416427
** See also: addremove, extra, status
417428
*/
418429
void clean_cmd(void){
419430
int allFlag;
420431
unsigned scanFlags = 0;
421
- const char *zIgnoreFlag, *zKeepFlag, *zCleanFlag;
432
+ const char *zIgnoreFlag, *zKeepFlag, *zCleanFlag, *zExcludeFlag;
422433
Blob path, repo;
423434
Stmt q;
424435
int n;
425436
Glob *pIgnore, *pKeep, *pClean;
426
- int dryRunFlag = 0;
437
+ int xflag, capXflag = 0, dryRunFlag;
427438
int verboseFlag;
428439
429440
allFlag = find_option("force","f",0)!=0;
430441
if( find_option("dotfiles",0,0)!=0 ) scanFlags |= SCAN_ALL;
431442
if( find_option("temp",0,0)!=0 ) scanFlags |= SCAN_TEMP;
432443
zIgnoreFlag = find_option("ignore",0,1);
444
+ zExcludeFlag = find_option("exclude","e",1);
433445
verboseFlag = find_option("verbose","v",0)!=0;
434446
dryRunFlag = find_option("dry-run","n",0)!=0;
447
+ xflag = find_option("x","x",0)!=0;
448
+ if ( !xflag ){
449
+ capXflag = find_option("X","X",0)!=0;
450
+ }
435451
if( !dryRunFlag ){
436452
dryRunFlag = find_option("test",0,0)!=0; /* deprecated */
437453
}
438454
zKeepFlag = find_option("keep",0,1);
439455
zCleanFlag = find_option("clean",0,1);
440456
capture_case_sensitive_option();
441457
db_must_be_within_tree();
442
- if( zIgnoreFlag==0 ){
458
+ if( zIgnoreFlag==0 && !xflag){
443459
zIgnoreFlag = db_get("ignore-glob", 0);
444460
}
445461
if( zKeepFlag==0 ){
446462
zKeepFlag = db_get("keep-glob", 0);
447463
}
@@ -451,16 +467,22 @@
451467
verify_all_options();
452468
db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY %s)",
453469
filename_collation());
454470
n = strlen(g.zLocalRoot);
455471
blob_init(&path, g.zLocalRoot, n-1);
472
+ if( zExcludeFlag ){
473
+ if( zIgnoreFlag ){
474
+ zIgnoreFlag = mprintf("%s,%s", zIgnoreFlag, zExcludeFlag);
475
+ }else{
476
+ zIgnoreFlag = zExcludeFlag;
477
+ }
478
+ }
456479
pIgnore = glob_create(zIgnoreFlag);
457480
pKeep = glob_create(zKeepFlag);
458481
pClean = glob_create(zCleanFlag);
459
- vfile_scan2(&path, blob_size(&path), scanFlags, pIgnore, pKeep);
482
+ vfile_scan2(&path, blob_size(&path), scanFlags, capXflag?0:pIgnore, pKeep);
460483
glob_free(pKeep);
461
- glob_free(pIgnore);
462484
db_prepare(&q,
463485
"SELECT %Q || x FROM sfile"
464486
" WHERE x NOT IN (%s)"
465487
" ORDER BY 1",
466488
g.zLocalRoot, fossil_all_reserved_names(0)
@@ -469,11 +491,13 @@
469491
db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo);
470492
}
471493
db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)");
472494
while( db_step(&q)==SQLITE_ROW ){
473495
const char *zName = db_column_text(&q, 0);
474
- if( !allFlag && !dryRunFlag && !glob_match(pClean, zName+n) ){
496
+ if( capXflag ){
497
+ if ( !glob_match(pIgnore, zName+n) ) continue;
498
+ }else if( !allFlag && !dryRunFlag && !glob_match(pClean, zName+n) ){
475499
Blob ans;
476500
char cReply;
477501
char *prompt = mprintf("remove unmanaged file \"%s\" (a=all/y/N)? ",
478502
zName+n);
479503
blob_zero(&ans);
@@ -490,10 +514,11 @@
490514
}
491515
if( !dryRunFlag ){
492516
file_delete(zName);
493517
}
494518
}
519
+ glob_free(pIgnore);
495520
glob_free(pClean);
496521
db_finalize(&q);
497522
}
498523
499524
/*
500525
--- src/checkin.c
+++ src/checkin.c
@@ -236,11 +236,11 @@
236 int verboseFlag;
237 int showAge;
238 char *zOrderBy = "pathname";
239
240 verboseFlag = find_option("verbose","v", 0)!=0;
241 if(!verboseFlag){
242 verboseFlag = find_option("l","l", 0)!=0; /* deprecated */
243 }
244 showAge = find_option("age",0,0)!=0;
245 db_must_be_within_tree();
246 vid = db_lget_int("checkout", 0);
@@ -381,11 +381,13 @@
381 ** COMMAND: clean
382 ** Usage: %fossil clean ?OPTIONS?
383 **
384 ** Delete all "extra" files in the source tree. "Extra" files are
385 ** files that are not officially part of the checkout. This operation
386 ** cannot be undone.
 
 
387 **
388 ** You will be prompted before removing each eligible file unless the
389 ** --force flag is in use or it matches the --clean option. The
390 ** GLOBPATTERN specified by the "ignore-glob" setting is used if the
391 ** --ignore option is omitted, the same with "clean-glob" and --clean
@@ -399,49 +401,63 @@
399 ** normally kept. They are handled if the "--dotfiles" option
400 ** is used.
401 **
402 ** Options:
403 ** --case-sensitive <BOOL> override case-sensitive setting
404 ** --dotfiles include files beginning with a dot (".")
405 ** -f|--force Remove files without prompting
406 ** --clean <CSG> never prompt for files matching this
407 ** comma separated list of glob patterns.
408 ** --ignore <CSG> ignore files matching patterns from the
409 ** comma separated list of glob patterns.
410 ** --keep <CSG> keep files matching this comma separated
411 ** list of glob patterns.
412 ** -n|--dry-run If given, display instead of run actions
413 ** --temp Remove only Fossil-generated temporary files
414 ** -v|--verbose Show all files as they are removed
 
 
 
 
 
 
 
 
 
415 **
416 ** See also: addremove, extra, status
417 */
418 void clean_cmd(void){
419 int allFlag;
420 unsigned scanFlags = 0;
421 const char *zIgnoreFlag, *zKeepFlag, *zCleanFlag;
422 Blob path, repo;
423 Stmt q;
424 int n;
425 Glob *pIgnore, *pKeep, *pClean;
426 int dryRunFlag = 0;
427 int verboseFlag;
428
429 allFlag = find_option("force","f",0)!=0;
430 if( find_option("dotfiles",0,0)!=0 ) scanFlags |= SCAN_ALL;
431 if( find_option("temp",0,0)!=0 ) scanFlags |= SCAN_TEMP;
432 zIgnoreFlag = find_option("ignore",0,1);
 
433 verboseFlag = find_option("verbose","v",0)!=0;
434 dryRunFlag = find_option("dry-run","n",0)!=0;
 
 
 
 
435 if( !dryRunFlag ){
436 dryRunFlag = find_option("test",0,0)!=0; /* deprecated */
437 }
438 zKeepFlag = find_option("keep",0,1);
439 zCleanFlag = find_option("clean",0,1);
440 capture_case_sensitive_option();
441 db_must_be_within_tree();
442 if( zIgnoreFlag==0 ){
443 zIgnoreFlag = db_get("ignore-glob", 0);
444 }
445 if( zKeepFlag==0 ){
446 zKeepFlag = db_get("keep-glob", 0);
447 }
@@ -451,16 +467,22 @@
451 verify_all_options();
452 db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY %s)",
453 filename_collation());
454 n = strlen(g.zLocalRoot);
455 blob_init(&path, g.zLocalRoot, n-1);
 
 
 
 
 
 
 
456 pIgnore = glob_create(zIgnoreFlag);
457 pKeep = glob_create(zKeepFlag);
458 pClean = glob_create(zCleanFlag);
459 vfile_scan2(&path, blob_size(&path), scanFlags, pIgnore, pKeep);
460 glob_free(pKeep);
461 glob_free(pIgnore);
462 db_prepare(&q,
463 "SELECT %Q || x FROM sfile"
464 " WHERE x NOT IN (%s)"
465 " ORDER BY 1",
466 g.zLocalRoot, fossil_all_reserved_names(0)
@@ -469,11 +491,13 @@
469 db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo);
470 }
471 db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)");
472 while( db_step(&q)==SQLITE_ROW ){
473 const char *zName = db_column_text(&q, 0);
474 if( !allFlag && !dryRunFlag && !glob_match(pClean, zName+n) ){
 
 
475 Blob ans;
476 char cReply;
477 char *prompt = mprintf("remove unmanaged file \"%s\" (a=all/y/N)? ",
478 zName+n);
479 blob_zero(&ans);
@@ -490,10 +514,11 @@
490 }
491 if( !dryRunFlag ){
492 file_delete(zName);
493 }
494 }
 
495 glob_free(pClean);
496 db_finalize(&q);
497 }
498
499 /*
500
--- src/checkin.c
+++ src/checkin.c
@@ -236,11 +236,11 @@
236 int verboseFlag;
237 int showAge;
238 char *zOrderBy = "pathname";
239
240 verboseFlag = find_option("verbose","v", 0)!=0;
241 if( !verboseFlag ){
242 verboseFlag = find_option("l","l", 0)!=0; /* deprecated */
243 }
244 showAge = find_option("age",0,0)!=0;
245 db_must_be_within_tree();
246 vid = db_lget_int("checkout", 0);
@@ -381,11 +381,13 @@
381 ** COMMAND: clean
382 ** Usage: %fossil clean ?OPTIONS?
383 **
384 ** Delete all "extra" files in the source tree. "Extra" files are
385 ** files that are not officially part of the checkout. This operation
386 ** cannot be undone. Normally, only files unknown to fossil are
387 ** removed, but if the -x option is specified, ignored files are
388 ** removed as well.
389 **
390 ** You will be prompted before removing each eligible file unless the
391 ** --force flag is in use or it matches the --clean option. The
392 ** GLOBPATTERN specified by the "ignore-glob" setting is used if the
393 ** --ignore option is omitted, the same with "clean-glob" and --clean
@@ -399,49 +401,63 @@
401 ** normally kept. They are handled if the "--dotfiles" option
402 ** is used.
403 **
404 ** Options:
405 ** --case-sensitive <BOOL> override case-sensitive setting
406 ** --dotfiles include files beginning with a dot (".")
407 ** -f|--force Remove files without prompting
408 ** --clean <CSG> never prompt for files matching this
409 ** comma separated list of glob patterns.
410 ** --ignore <CSG> ignore files matching patterns from the
411 ** comma separated list of glob patterns.
412 ** -e|--exclude <CSG> In addition to those found in --ignore or
413 ** "ignore-glob", consider these patterns to
414 ** be in the set of the ignore rules as well.
415 ** --keep <CSG> keep files matching this comma separated
416 ** list of glob patterns, even with -x/-X.
417 ** -n|--dry-run If given, display instead of run actions
418 ** --temp Remove only Fossil-generated temporary files
419 ** -v|--verbose Show all files as they are removed
420 ** -x Don't use "ignore-glob" as default for
421 ** --ignore. For compatibility with git.
422 ** -X Remove only files ignored by fossil. This
423 ** may be useful to rebuild everything from
424 ** scratch, but keep manually created files.
425 ** Compatible with "git clean -X"
426 **
427 ** See also: addremove, extra, status
428 */
429 void clean_cmd(void){
430 int allFlag;
431 unsigned scanFlags = 0;
432 const char *zIgnoreFlag, *zKeepFlag, *zCleanFlag, *zExcludeFlag;
433 Blob path, repo;
434 Stmt q;
435 int n;
436 Glob *pIgnore, *pKeep, *pClean;
437 int xflag, capXflag = 0, dryRunFlag;
438 int verboseFlag;
439
440 allFlag = find_option("force","f",0)!=0;
441 if( find_option("dotfiles",0,0)!=0 ) scanFlags |= SCAN_ALL;
442 if( find_option("temp",0,0)!=0 ) scanFlags |= SCAN_TEMP;
443 zIgnoreFlag = find_option("ignore",0,1);
444 zExcludeFlag = find_option("exclude","e",1);
445 verboseFlag = find_option("verbose","v",0)!=0;
446 dryRunFlag = find_option("dry-run","n",0)!=0;
447 xflag = find_option("x","x",0)!=0;
448 if ( !xflag ){
449 capXflag = find_option("X","X",0)!=0;
450 }
451 if( !dryRunFlag ){
452 dryRunFlag = find_option("test",0,0)!=0; /* deprecated */
453 }
454 zKeepFlag = find_option("keep",0,1);
455 zCleanFlag = find_option("clean",0,1);
456 capture_case_sensitive_option();
457 db_must_be_within_tree();
458 if( zIgnoreFlag==0 && !xflag){
459 zIgnoreFlag = db_get("ignore-glob", 0);
460 }
461 if( zKeepFlag==0 ){
462 zKeepFlag = db_get("keep-glob", 0);
463 }
@@ -451,16 +467,22 @@
467 verify_all_options();
468 db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY %s)",
469 filename_collation());
470 n = strlen(g.zLocalRoot);
471 blob_init(&path, g.zLocalRoot, n-1);
472 if( zExcludeFlag ){
473 if( zIgnoreFlag ){
474 zIgnoreFlag = mprintf("%s,%s", zIgnoreFlag, zExcludeFlag);
475 }else{
476 zIgnoreFlag = zExcludeFlag;
477 }
478 }
479 pIgnore = glob_create(zIgnoreFlag);
480 pKeep = glob_create(zKeepFlag);
481 pClean = glob_create(zCleanFlag);
482 vfile_scan2(&path, blob_size(&path), scanFlags, capXflag?0:pIgnore, pKeep);
483 glob_free(pKeep);
 
484 db_prepare(&q,
485 "SELECT %Q || x FROM sfile"
486 " WHERE x NOT IN (%s)"
487 " ORDER BY 1",
488 g.zLocalRoot, fossil_all_reserved_names(0)
@@ -469,11 +491,13 @@
491 db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo);
492 }
493 db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)");
494 while( db_step(&q)==SQLITE_ROW ){
495 const char *zName = db_column_text(&q, 0);
496 if( capXflag ){
497 if ( !glob_match(pIgnore, zName+n) ) continue;
498 }else if( !allFlag && !dryRunFlag && !glob_match(pClean, zName+n) ){
499 Blob ans;
500 char cReply;
501 char *prompt = mprintf("remove unmanaged file \"%s\" (a=all/y/N)? ",
502 zName+n);
503 blob_zero(&ans);
@@ -490,10 +514,11 @@
514 }
515 if( !dryRunFlag ){
516 file_delete(zName);
517 }
518 }
519 glob_free(pIgnore);
520 glob_free(pClean);
521 db_finalize(&q);
522 }
523
524 /*
525

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button