Fossil SCM
Make "fossil clean -x" less dangerous by respecting the "keep-glob" setting. Fix a few historical merge errors
Commit
a5c85348c60125b6092f1b8802eee7b247377d21
Parent
d7f04ea46fbf65b…
1 file changed
+16
-14
+16
-14
| --- src/checkin.c | ||
| +++ src/checkin.c | ||
| @@ -495,12 +495,12 @@ | ||
| 495 | 495 | ** files specified will be considered for cleaning. |
| 496 | 496 | ** |
| 497 | 497 | ** WARNING: Normally, only the files unknown to Fossil are removed; |
| 498 | 498 | ** however, if the --extreme option is specified, all files that are |
| 499 | 499 | ** not part of the current checkout will be removed as well, without |
| 500 | -** regard for the "ignore-glob" and "keep-glob" settings and their | |
| 501 | -** associated command line options. | |
| 500 | +** regard for the "ignore-glob" setting and the --ignore command line | |
| 501 | +** option. | |
| 502 | 502 | ** |
| 503 | 503 | ** You will be prompted before removing each eligible file unless the |
| 504 | 504 | ** --force flag is in use or it matches the --clean option. The |
| 505 | 505 | ** GLOBPATTERN specified by the "ignore-glob" setting is used if the |
| 506 | 506 | ** --ignore option is omitted, the same with "clean-glob" and --clean |
| @@ -543,12 +543,12 @@ | ||
| 543 | 543 | ** -n|--dry-run If given, display instead of run actions. |
| 544 | 544 | ** --temp Remove only Fossil-generated temporary files. |
| 545 | 545 | ** -v|--verbose Show all files as they are removed. |
| 546 | 546 | ** -x|--extreme Remove all files not part of the current |
| 547 | 547 | ** checkout, without taking into consideration |
| 548 | -** the "ignore-glob" and "keep-glob" settings | |
| 549 | -** and their associated command line options. | |
| 548 | +** the "ignore-glob" setting and the --ignore | |
| 549 | +** command line option. | |
| 550 | 550 | ** Compatibile with "git clean -x". |
| 551 | 551 | ** |
| 552 | 552 | ** See also: addremove, extra, status |
| 553 | 553 | */ |
| 554 | 554 | void clean_cmd(void){ |
| @@ -561,10 +561,13 @@ | ||
| 561 | 561 | |
| 562 | 562 | dryRunFlag = find_option("dry-run","n",0)!=0; |
| 563 | 563 | if( !dryRunFlag ){ |
| 564 | 564 | dryRunFlag = find_option("test",0,0)!=0; /* deprecated */ |
| 565 | 565 | } |
| 566 | + if( !dryRunFlag ){ | |
| 567 | + dryRunFlag = find_option("whatif",0,0)!=0; | |
| 568 | + } | |
| 566 | 569 | extremeFlag = find_option("extreme","x",0)!=0; |
| 567 | 570 | allFileFlag = allDirFlag = find_option("force","f",0)!=0; |
| 568 | 571 | dirsOnlyFlag = find_option("dirsonly",0,0)!=0; |
| 569 | 572 | emptyDirsFlag = find_option("emptydirs","d",0)!=0 || dirsOnlyFlag; |
| 570 | 573 | if( find_option("dotfiles",0,0)!=0 ) scanFlags |= SCAN_ALL; |
| @@ -589,16 +592,15 @@ | ||
| 589 | 592 | if( extremeFlag ){ |
| 590 | 593 | Blob extremeAnswer; |
| 591 | 594 | char *extremePrompt = |
| 592 | 595 | "\n\nWARNING: The --extreme option is enabled and all untracked files\n" |
| 593 | 596 | "that would otherwise be left alone will be deleted (i.e. those\n" |
| 594 | - "matching the \"ignore-glob\" and \"keep-glob\" settings and their\n" | |
| 595 | - "associated command line options). As a precaution, in order to\n" | |
| 596 | - "proceed with this clean operation, the string \"YES\" must be\n" | |
| 597 | - "entered in all upper case; any other response will cancel the\n" | |
| 598 | - "clean operation.\n\nDo you still wish to proceed with the clean " | |
| 599 | - "operation? "; | |
| 597 | + "matching the \"ignore-glob\" setting and the --ignore command line\n" | |
| 598 | + "option). As a precaution, in order to proceed with this clean\n" | |
| 599 | + "operation, the string \"YES\" must be entered in all upper case;\n" | |
| 600 | + "any other response will cancel the\nclean operation.\n\n" | |
| 601 | + "Do you still wish to proceed with the clean operation? "; | |
| 600 | 602 | blob_zero(&extremeAnswer); |
| 601 | 603 | prompt_user(extremePrompt, &extremeAnswer); |
| 602 | 604 | if( fossil_strcmp(blob_str(&extremeAnswer), "YES")!=0 ){ |
| 603 | 605 | fossil_print("Extreme clean operation canceled.\n"); |
| 604 | 606 | blob_reset(&extremeAnswer); |
| @@ -612,11 +614,11 @@ | ||
| 612 | 614 | nRoot = (int)strlen(g.zLocalRoot); |
| 613 | 615 | if( !dirsOnlyFlag ){ |
| 614 | 616 | Stmt q; |
| 615 | 617 | Blob repo; |
| 616 | 618 | locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, |
| 617 | - extremeFlag ? 0 : pIgnore, extremeFlag ? 0 : pKeep); | |
| 619 | + extremeFlag ? 0 : pIgnore, pKeep); | |
| 618 | 620 | db_prepare(&q, |
| 619 | 621 | "SELECT %Q || x FROM sfile" |
| 620 | 622 | " WHERE x NOT IN (%s)" |
| 621 | 623 | " ORDER BY 1", |
| 622 | 624 | g.zLocalRoot, fossil_all_reserved_names(0) |
| @@ -625,11 +627,11 @@ | ||
| 625 | 627 | db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo); |
| 626 | 628 | } |
| 627 | 629 | db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)"); |
| 628 | 630 | while( db_step(&q)==SQLITE_ROW ){ |
| 629 | 631 | const char *zName = db_column_text(&q, 0); |
| 630 | - if( !allFileFlag && !glob_match(pClean, zName+nRoot) ){ | |
| 632 | + if( !allFileFlag && !dryRunFlag && !glob_match(pClean, zName+nRoot) ){ | |
| 631 | 633 | Blob ans; |
| 632 | 634 | char cReply; |
| 633 | 635 | int matchIgnore = glob_match(pIgnore, zName+nRoot); |
| 634 | 636 | int matchKeep = glob_match(pKeep, zName+nRoot); |
| 635 | 637 | char *prompt = mprintf("%sRemove %s file \"%s\" (a=all/y/N)? ", |
| @@ -660,11 +662,11 @@ | ||
| 660 | 662 | Glob *pEmptyDirs = glob_create(db_get("empty-dirs", 0)); |
| 661 | 663 | Stmt q; |
| 662 | 664 | Blob root; |
| 663 | 665 | blob_init(&root, g.zLocalRoot, nRoot - 1); |
| 664 | 666 | vfile_dir_scan(&root, blob_size(&root), scanFlags, |
| 665 | - extremeFlag ? 0 : pIgnore, extremeFlag ? 0 : pKeep, | |
| 667 | + extremeFlag ? 0 : pIgnore, pKeep, | |
| 666 | 668 | extremeFlag ? 0 : pEmptyDirs); |
| 667 | 669 | blob_reset(&root); |
| 668 | 670 | db_prepare(&q, |
| 669 | 671 | "SELECT %Q || x FROM dscan_temp" |
| 670 | 672 | " WHERE x NOT IN (%s) AND y = 0" |
| @@ -671,11 +673,11 @@ | ||
| 671 | 673 | " ORDER BY 1 DESC", |
| 672 | 674 | g.zLocalRoot, fossil_all_reserved_names(0) |
| 673 | 675 | ); |
| 674 | 676 | while( db_step(&q)==SQLITE_ROW ){ |
| 675 | 677 | const char *zName = db_column_text(&q, 0); |
| 676 | - if( !allDirFlag && !glob_match(pClean, zName+nRoot) ){ | |
| 678 | + if( !allDirFlag && !dryRunFlag && !glob_match(pClean, zName+nRoot) ){ | |
| 677 | 679 | Blob ans; |
| 678 | 680 | char cReply; |
| 679 | 681 | int matchIgnore = glob_match(pIgnore, zName+nRoot); |
| 680 | 682 | int matchKeep = glob_match(pKeep, zName+nRoot); |
| 681 | 683 | int matchEmpty = glob_match(pEmptyDirs, zName+nRoot); |
| 682 | 684 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -495,12 +495,12 @@ | |
| 495 | ** files specified will be considered for cleaning. |
| 496 | ** |
| 497 | ** WARNING: Normally, only the files unknown to Fossil are removed; |
| 498 | ** however, if the --extreme option is specified, all files that are |
| 499 | ** not part of the current checkout will be removed as well, without |
| 500 | ** regard for the "ignore-glob" and "keep-glob" settings and their |
| 501 | ** associated command line options. |
| 502 | ** |
| 503 | ** You will be prompted before removing each eligible file unless the |
| 504 | ** --force flag is in use or it matches the --clean option. The |
| 505 | ** GLOBPATTERN specified by the "ignore-glob" setting is used if the |
| 506 | ** --ignore option is omitted, the same with "clean-glob" and --clean |
| @@ -543,12 +543,12 @@ | |
| 543 | ** -n|--dry-run If given, display instead of run actions. |
| 544 | ** --temp Remove only Fossil-generated temporary files. |
| 545 | ** -v|--verbose Show all files as they are removed. |
| 546 | ** -x|--extreme Remove all files not part of the current |
| 547 | ** checkout, without taking into consideration |
| 548 | ** the "ignore-glob" and "keep-glob" settings |
| 549 | ** and their associated command line options. |
| 550 | ** Compatibile with "git clean -x". |
| 551 | ** |
| 552 | ** See also: addremove, extra, status |
| 553 | */ |
| 554 | void clean_cmd(void){ |
| @@ -561,10 +561,13 @@ | |
| 561 | |
| 562 | dryRunFlag = find_option("dry-run","n",0)!=0; |
| 563 | if( !dryRunFlag ){ |
| 564 | dryRunFlag = find_option("test",0,0)!=0; /* deprecated */ |
| 565 | } |
| 566 | extremeFlag = find_option("extreme","x",0)!=0; |
| 567 | allFileFlag = allDirFlag = find_option("force","f",0)!=0; |
| 568 | dirsOnlyFlag = find_option("dirsonly",0,0)!=0; |
| 569 | emptyDirsFlag = find_option("emptydirs","d",0)!=0 || dirsOnlyFlag; |
| 570 | if( find_option("dotfiles",0,0)!=0 ) scanFlags |= SCAN_ALL; |
| @@ -589,16 +592,15 @@ | |
| 589 | if( extremeFlag ){ |
| 590 | Blob extremeAnswer; |
| 591 | char *extremePrompt = |
| 592 | "\n\nWARNING: The --extreme option is enabled and all untracked files\n" |
| 593 | "that would otherwise be left alone will be deleted (i.e. those\n" |
| 594 | "matching the \"ignore-glob\" and \"keep-glob\" settings and their\n" |
| 595 | "associated command line options). As a precaution, in order to\n" |
| 596 | "proceed with this clean operation, the string \"YES\" must be\n" |
| 597 | "entered in all upper case; any other response will cancel the\n" |
| 598 | "clean operation.\n\nDo you still wish to proceed with the clean " |
| 599 | "operation? "; |
| 600 | blob_zero(&extremeAnswer); |
| 601 | prompt_user(extremePrompt, &extremeAnswer); |
| 602 | if( fossil_strcmp(blob_str(&extremeAnswer), "YES")!=0 ){ |
| 603 | fossil_print("Extreme clean operation canceled.\n"); |
| 604 | blob_reset(&extremeAnswer); |
| @@ -612,11 +614,11 @@ | |
| 612 | nRoot = (int)strlen(g.zLocalRoot); |
| 613 | if( !dirsOnlyFlag ){ |
| 614 | Stmt q; |
| 615 | Blob repo; |
| 616 | locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, |
| 617 | extremeFlag ? 0 : pIgnore, extremeFlag ? 0 : pKeep); |
| 618 | db_prepare(&q, |
| 619 | "SELECT %Q || x FROM sfile" |
| 620 | " WHERE x NOT IN (%s)" |
| 621 | " ORDER BY 1", |
| 622 | g.zLocalRoot, fossil_all_reserved_names(0) |
| @@ -625,11 +627,11 @@ | |
| 625 | db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo); |
| 626 | } |
| 627 | db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)"); |
| 628 | while( db_step(&q)==SQLITE_ROW ){ |
| 629 | const char *zName = db_column_text(&q, 0); |
| 630 | if( !allFileFlag && !glob_match(pClean, zName+nRoot) ){ |
| 631 | Blob ans; |
| 632 | char cReply; |
| 633 | int matchIgnore = glob_match(pIgnore, zName+nRoot); |
| 634 | int matchKeep = glob_match(pKeep, zName+nRoot); |
| 635 | char *prompt = mprintf("%sRemove %s file \"%s\" (a=all/y/N)? ", |
| @@ -660,11 +662,11 @@ | |
| 660 | Glob *pEmptyDirs = glob_create(db_get("empty-dirs", 0)); |
| 661 | Stmt q; |
| 662 | Blob root; |
| 663 | blob_init(&root, g.zLocalRoot, nRoot - 1); |
| 664 | vfile_dir_scan(&root, blob_size(&root), scanFlags, |
| 665 | extremeFlag ? 0 : pIgnore, extremeFlag ? 0 : pKeep, |
| 666 | extremeFlag ? 0 : pEmptyDirs); |
| 667 | blob_reset(&root); |
| 668 | db_prepare(&q, |
| 669 | "SELECT %Q || x FROM dscan_temp" |
| 670 | " WHERE x NOT IN (%s) AND y = 0" |
| @@ -671,11 +673,11 @@ | |
| 671 | " ORDER BY 1 DESC", |
| 672 | g.zLocalRoot, fossil_all_reserved_names(0) |
| 673 | ); |
| 674 | while( db_step(&q)==SQLITE_ROW ){ |
| 675 | const char *zName = db_column_text(&q, 0); |
| 676 | if( !allDirFlag && !glob_match(pClean, zName+nRoot) ){ |
| 677 | Blob ans; |
| 678 | char cReply; |
| 679 | int matchIgnore = glob_match(pIgnore, zName+nRoot); |
| 680 | int matchKeep = glob_match(pKeep, zName+nRoot); |
| 681 | int matchEmpty = glob_match(pEmptyDirs, zName+nRoot); |
| 682 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -495,12 +495,12 @@ | |
| 495 | ** files specified will be considered for cleaning. |
| 496 | ** |
| 497 | ** WARNING: Normally, only the files unknown to Fossil are removed; |
| 498 | ** however, if the --extreme option is specified, all files that are |
| 499 | ** not part of the current checkout will be removed as well, without |
| 500 | ** regard for the "ignore-glob" setting and the --ignore command line |
| 501 | ** option. |
| 502 | ** |
| 503 | ** You will be prompted before removing each eligible file unless the |
| 504 | ** --force flag is in use or it matches the --clean option. The |
| 505 | ** GLOBPATTERN specified by the "ignore-glob" setting is used if the |
| 506 | ** --ignore option is omitted, the same with "clean-glob" and --clean |
| @@ -543,12 +543,12 @@ | |
| 543 | ** -n|--dry-run If given, display instead of run actions. |
| 544 | ** --temp Remove only Fossil-generated temporary files. |
| 545 | ** -v|--verbose Show all files as they are removed. |
| 546 | ** -x|--extreme Remove all files not part of the current |
| 547 | ** checkout, without taking into consideration |
| 548 | ** the "ignore-glob" setting and the --ignore |
| 549 | ** command line option. |
| 550 | ** Compatibile with "git clean -x". |
| 551 | ** |
| 552 | ** See also: addremove, extra, status |
| 553 | */ |
| 554 | void clean_cmd(void){ |
| @@ -561,10 +561,13 @@ | |
| 561 | |
| 562 | dryRunFlag = find_option("dry-run","n",0)!=0; |
| 563 | if( !dryRunFlag ){ |
| 564 | dryRunFlag = find_option("test",0,0)!=0; /* deprecated */ |
| 565 | } |
| 566 | if( !dryRunFlag ){ |
| 567 | dryRunFlag = find_option("whatif",0,0)!=0; |
| 568 | } |
| 569 | extremeFlag = find_option("extreme","x",0)!=0; |
| 570 | allFileFlag = allDirFlag = find_option("force","f",0)!=0; |
| 571 | dirsOnlyFlag = find_option("dirsonly",0,0)!=0; |
| 572 | emptyDirsFlag = find_option("emptydirs","d",0)!=0 || dirsOnlyFlag; |
| 573 | if( find_option("dotfiles",0,0)!=0 ) scanFlags |= SCAN_ALL; |
| @@ -589,16 +592,15 @@ | |
| 592 | if( extremeFlag ){ |
| 593 | Blob extremeAnswer; |
| 594 | char *extremePrompt = |
| 595 | "\n\nWARNING: The --extreme option is enabled and all untracked files\n" |
| 596 | "that would otherwise be left alone will be deleted (i.e. those\n" |
| 597 | "matching the \"ignore-glob\" setting and the --ignore command line\n" |
| 598 | "option). As a precaution, in order to proceed with this clean\n" |
| 599 | "operation, the string \"YES\" must be entered in all upper case;\n" |
| 600 | "any other response will cancel the\nclean operation.\n\n" |
| 601 | "Do you still wish to proceed with the clean operation? "; |
| 602 | blob_zero(&extremeAnswer); |
| 603 | prompt_user(extremePrompt, &extremeAnswer); |
| 604 | if( fossil_strcmp(blob_str(&extremeAnswer), "YES")!=0 ){ |
| 605 | fossil_print("Extreme clean operation canceled.\n"); |
| 606 | blob_reset(&extremeAnswer); |
| @@ -612,11 +614,11 @@ | |
| 614 | nRoot = (int)strlen(g.zLocalRoot); |
| 615 | if( !dirsOnlyFlag ){ |
| 616 | Stmt q; |
| 617 | Blob repo; |
| 618 | locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, |
| 619 | extremeFlag ? 0 : pIgnore, pKeep); |
| 620 | db_prepare(&q, |
| 621 | "SELECT %Q || x FROM sfile" |
| 622 | " WHERE x NOT IN (%s)" |
| 623 | " ORDER BY 1", |
| 624 | g.zLocalRoot, fossil_all_reserved_names(0) |
| @@ -625,11 +627,11 @@ | |
| 627 | db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo); |
| 628 | } |
| 629 | db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)"); |
| 630 | while( db_step(&q)==SQLITE_ROW ){ |
| 631 | const char *zName = db_column_text(&q, 0); |
| 632 | if( !allFileFlag && !dryRunFlag && !glob_match(pClean, zName+nRoot) ){ |
| 633 | Blob ans; |
| 634 | char cReply; |
| 635 | int matchIgnore = glob_match(pIgnore, zName+nRoot); |
| 636 | int matchKeep = glob_match(pKeep, zName+nRoot); |
| 637 | char *prompt = mprintf("%sRemove %s file \"%s\" (a=all/y/N)? ", |
| @@ -660,11 +662,11 @@ | |
| 662 | Glob *pEmptyDirs = glob_create(db_get("empty-dirs", 0)); |
| 663 | Stmt q; |
| 664 | Blob root; |
| 665 | blob_init(&root, g.zLocalRoot, nRoot - 1); |
| 666 | vfile_dir_scan(&root, blob_size(&root), scanFlags, |
| 667 | extremeFlag ? 0 : pIgnore, pKeep, |
| 668 | extremeFlag ? 0 : pEmptyDirs); |
| 669 | blob_reset(&root); |
| 670 | db_prepare(&q, |
| 671 | "SELECT %Q || x FROM dscan_temp" |
| 672 | " WHERE x NOT IN (%s) AND y = 0" |
| @@ -671,11 +673,11 @@ | |
| 673 | " ORDER BY 1 DESC", |
| 674 | g.zLocalRoot, fossil_all_reserved_names(0) |
| 675 | ); |
| 676 | while( db_step(&q)==SQLITE_ROW ){ |
| 677 | const char *zName = db_column_text(&q, 0); |
| 678 | if( !allDirFlag && !dryRunFlag && !glob_match(pClean, zName+nRoot) ){ |
| 679 | Blob ans; |
| 680 | char cReply; |
| 681 | int matchIgnore = glob_match(pIgnore, zName+nRoot); |
| 682 | int matchKeep = glob_match(pKeep, zName+nRoot); |
| 683 | int matchEmpty = glob_match(pEmptyDirs, zName+nRoot); |
| 684 |