Fossil SCM
Add the --dirsonly and --allckouts options to the 'clean' command.
Commit
51403ee52e05833df6b26892b840f35f402ece86
Parent
8f1e1ee8fbbe762…
2 files changed
+56
-42
+2
-1
+56
-42
| --- src/checkin.c | ||
| +++ src/checkin.c | ||
| @@ -507,11 +507,19 @@ | ||
| 507 | 507 | ** Files and subdirectories whose names begin with "." are |
| 508 | 508 | ** normally kept. They are handled if the "--dotfiles" option |
| 509 | 509 | ** is used. |
| 510 | 510 | ** |
| 511 | 511 | ** Options: |
| 512 | +** --allckouts Check for empty directories within any checkouts | |
| 513 | +** that may be nested within the current one. This | |
| 514 | +** option should be used with great care because the | |
| 515 | +** empty-dirs setting (and other applicable settings) | |
| 516 | +** belonging to the other repositories, if any, will | |
| 517 | +** not be checked. | |
| 512 | 518 | ** --case-sensitive <BOOL> override case-sensitive setting |
| 519 | +** --dirsonly Only remove empty directories. No files will | |
| 520 | +** be removed. | |
| 513 | 521 | ** --dotfiles Include files beginning with a dot ("."). |
| 514 | 522 | ** --emptydirs Remove any empty directories that are not |
| 515 | 523 | ** explicitly exempted via the empty-dirs setting |
| 516 | 524 | ** or another applicable setting or command line |
| 517 | 525 | ** argument. Matching files, if any, are removed |
| @@ -530,26 +538,27 @@ | ||
| 530 | 538 | ** -v|--verbose Show all files as they are removed. |
| 531 | 539 | ** |
| 532 | 540 | ** See also: addremove, extra, status |
| 533 | 541 | */ |
| 534 | 542 | void clean_cmd(void){ |
| 535 | - int allFileFlag, allDirFlag, dryRunFlag, emptyDirsFlag, verboseFlag; | |
| 543 | + int allFileFlag, allDirFlag, dryRunFlag, verboseFlag; | |
| 544 | + int emptyDirsFlag, dirsOnlyFlag; | |
| 536 | 545 | unsigned scanFlags = 0; |
| 537 | 546 | const char *zIgnoreFlag, *zKeepFlag, *zCleanFlag; |
| 538 | - Blob repo; | |
| 539 | - Stmt q; | |
| 540 | 547 | Glob *pIgnore, *pKeep, *pClean; |
| 541 | 548 | int nRoot; |
| 542 | 549 | |
| 543 | 550 | dryRunFlag = find_option("dry-run","n",0)!=0; |
| 544 | 551 | if( !dryRunFlag ){ |
| 545 | 552 | dryRunFlag = find_option("test",0,0)!=0; /* deprecated */ |
| 546 | 553 | } |
| 547 | 554 | allFileFlag = allDirFlag = find_option("force","f",0)!=0; |
| 548 | 555 | emptyDirsFlag = find_option("emptydirs","d",0)!=0; |
| 556 | + dirsOnlyFlag = find_option("dirsonly",0,0)!=0; | |
| 549 | 557 | if( find_option("dotfiles",0,0)!=0 ) scanFlags |= SCAN_ALL; |
| 550 | 558 | if( find_option("temp",0,0)!=0 ) scanFlags |= SCAN_TEMP; |
| 559 | + if( find_option("allckouts",0,0)!=0 ) scanFlags |= SCAN_NESTED; | |
| 551 | 560 | zIgnoreFlag = find_option("ignore",0,1); |
| 552 | 561 | verboseFlag = find_option("verbose","v",0)!=0; |
| 553 | 562 | zKeepFlag = find_option("keep",0,1); |
| 554 | 563 | zCleanFlag = find_option("clean",0,1); |
| 555 | 564 | capture_case_sensitive_option(); |
| @@ -565,56 +574,61 @@ | ||
| 565 | 574 | } |
| 566 | 575 | verify_all_options(); |
| 567 | 576 | pIgnore = glob_create(zIgnoreFlag); |
| 568 | 577 | pKeep = glob_create(zKeepFlag); |
| 569 | 578 | pClean = glob_create(zCleanFlag); |
| 570 | - locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore, pKeep); | |
| 571 | - db_prepare(&q, | |
| 572 | - "SELECT %Q || x FROM sfile" | |
| 573 | - " WHERE x NOT IN (%s)" | |
| 574 | - " ORDER BY 1", | |
| 575 | - g.zLocalRoot, fossil_all_reserved_names(0) | |
| 576 | - ); | |
| 577 | - if( file_tree_name(g.zRepositoryName, &repo, 0) ){ | |
| 578 | - db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo); | |
| 579 | - } | |
| 580 | - db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)"); | |
| 581 | - nRoot = (int)strlen(g.zLocalRoot); | |
| 582 | - while( db_step(&q)==SQLITE_ROW ){ | |
| 583 | - const char *zName = db_column_text(&q, 0); | |
| 584 | - if( !allFileFlag && !dryRunFlag && !glob_match(pClean, zName+nRoot) ){ | |
| 585 | - Blob ans; | |
| 586 | - char cReply; | |
| 587 | - char *prompt = mprintf("Remove unmanaged file \"%s\" (a=all/y/N)? ", | |
| 588 | - zName+nRoot); | |
| 589 | - blob_zero(&ans); | |
| 590 | - prompt_user(prompt, &ans); | |
| 591 | - cReply = blob_str(&ans)[0]; | |
| 592 | - if( cReply=='a' || cReply=='A' ){ | |
| 593 | - allFileFlag = 1; | |
| 594 | - }else if( cReply!='y' && cReply!='Y' ){ | |
| 595 | - blob_reset(&ans); | |
| 596 | - continue; | |
| 597 | - } | |
| 598 | - blob_reset(&ans); | |
| 599 | - } | |
| 600 | - if ( dryRunFlag || file_delete(zName)==0 ){ | |
| 601 | - if( verboseFlag || dryRunFlag ){ | |
| 602 | - fossil_print("Removed unmanaged file: %s\n", zName+nRoot); | |
| 603 | - } | |
| 604 | - }else if( verboseFlag ){ | |
| 605 | - fossil_print("Could not remove file: %s\n", zName+nRoot); | |
| 606 | - } | |
| 579 | + nRoot = (int)strlen(g.zLocalRoot); | |
| 580 | + if( !dirsOnlyFlag ){ | |
| 581 | + Stmt q; | |
| 582 | + Blob repo; | |
| 583 | + locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore, pKeep); | |
| 584 | + db_prepare(&q, | |
| 585 | + "SELECT %Q || x FROM sfile" | |
| 586 | + " WHERE x NOT IN (%s)" | |
| 587 | + " ORDER BY 1", | |
| 588 | + g.zLocalRoot, fossil_all_reserved_names(0) | |
| 589 | + ); | |
| 590 | + if( file_tree_name(g.zRepositoryName, &repo, 0) ){ | |
| 591 | + db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo); | |
| 592 | + } | |
| 593 | + db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)"); | |
| 594 | + while( db_step(&q)==SQLITE_ROW ){ | |
| 595 | + const char *zName = db_column_text(&q, 0); | |
| 596 | + if( !allFileFlag && !dryRunFlag && !glob_match(pClean, zName+nRoot) ){ | |
| 597 | + Blob ans; | |
| 598 | + char cReply; | |
| 599 | + char *prompt = mprintf("Remove unmanaged file \"%s\" (a=all/y/N)? ", | |
| 600 | + zName+nRoot); | |
| 601 | + blob_zero(&ans); | |
| 602 | + prompt_user(prompt, &ans); | |
| 603 | + cReply = blob_str(&ans)[0]; | |
| 604 | + if( cReply=='a' || cReply=='A' ){ | |
| 605 | + allFileFlag = 1; | |
| 606 | + }else if( cReply!='y' && cReply!='Y' ){ | |
| 607 | + blob_reset(&ans); | |
| 608 | + continue; | |
| 609 | + } | |
| 610 | + blob_reset(&ans); | |
| 611 | + } | |
| 612 | + if ( dryRunFlag || file_delete(zName)==0 ){ | |
| 613 | + if( verboseFlag || dryRunFlag ){ | |
| 614 | + fossil_print("Removed unmanaged file: %s\n", zName+nRoot); | |
| 615 | + } | |
| 616 | + }else if( verboseFlag ){ | |
| 617 | + fossil_print("Could not remove file: %s\n", zName+nRoot); | |
| 618 | + } | |
| 619 | + } | |
| 620 | + db_finalize(&q); | |
| 607 | 621 | } |
| 608 | 622 | if( emptyDirsFlag ){ |
| 609 | 623 | Glob *pEmptyDirs = glob_create(db_get("empty-dirs", 0)); |
| 624 | + Stmt q; | |
| 610 | 625 | Blob root; |
| 611 | 626 | blob_init(&root, g.zLocalRoot, nRoot - 1); |
| 612 | 627 | vfile_dir_scan(&root, blob_size(&root), scanFlags, pIgnore, pKeep, |
| 613 | 628 | pEmptyDirs); |
| 614 | 629 | blob_reset(&root); |
| 615 | - db_finalize(&q); | |
| 616 | 630 | db_prepare(&q, |
| 617 | 631 | "SELECT %Q || x FROM dscan_temp" |
| 618 | 632 | " WHERE x NOT IN (%s) AND y = 0" |
| 619 | 633 | " ORDER BY 1 DESC", |
| 620 | 634 | g.zLocalRoot, fossil_all_reserved_names(0) |
| @@ -643,16 +657,16 @@ | ||
| 643 | 657 | } |
| 644 | 658 | }else if( verboseFlag ){ |
| 645 | 659 | fossil_print("Could not remove directory: %s\n", zName+nRoot); |
| 646 | 660 | } |
| 647 | 661 | } |
| 662 | + db_finalize(&q); | |
| 648 | 663 | glob_free(pEmptyDirs); |
| 649 | 664 | } |
| 650 | 665 | glob_free(pClean); |
| 651 | 666 | glob_free(pKeep); |
| 652 | 667 | glob_free(pIgnore); |
| 653 | - db_finalize(&q); | |
| 654 | 668 | } |
| 655 | 669 | |
| 656 | 670 | /* |
| 657 | 671 | ** Prompt the user for a check-in or stash comment (given in pPrompt), |
| 658 | 672 | ** gather the response, then return the response in pComment. |
| 659 | 673 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -507,11 +507,19 @@ | |
| 507 | ** Files and subdirectories whose names begin with "." are |
| 508 | ** normally kept. They are handled if the "--dotfiles" option |
| 509 | ** is used. |
| 510 | ** |
| 511 | ** Options: |
| 512 | ** --case-sensitive <BOOL> override case-sensitive setting |
| 513 | ** --dotfiles Include files beginning with a dot ("."). |
| 514 | ** --emptydirs Remove any empty directories that are not |
| 515 | ** explicitly exempted via the empty-dirs setting |
| 516 | ** or another applicable setting or command line |
| 517 | ** argument. Matching files, if any, are removed |
| @@ -530,26 +538,27 @@ | |
| 530 | ** -v|--verbose Show all files as they are removed. |
| 531 | ** |
| 532 | ** See also: addremove, extra, status |
| 533 | */ |
| 534 | void clean_cmd(void){ |
| 535 | int allFileFlag, allDirFlag, dryRunFlag, emptyDirsFlag, verboseFlag; |
| 536 | unsigned scanFlags = 0; |
| 537 | const char *zIgnoreFlag, *zKeepFlag, *zCleanFlag; |
| 538 | Blob repo; |
| 539 | Stmt q; |
| 540 | Glob *pIgnore, *pKeep, *pClean; |
| 541 | int nRoot; |
| 542 | |
| 543 | dryRunFlag = find_option("dry-run","n",0)!=0; |
| 544 | if( !dryRunFlag ){ |
| 545 | dryRunFlag = find_option("test",0,0)!=0; /* deprecated */ |
| 546 | } |
| 547 | allFileFlag = allDirFlag = find_option("force","f",0)!=0; |
| 548 | emptyDirsFlag = find_option("emptydirs","d",0)!=0; |
| 549 | if( find_option("dotfiles",0,0)!=0 ) scanFlags |= SCAN_ALL; |
| 550 | if( find_option("temp",0,0)!=0 ) scanFlags |= SCAN_TEMP; |
| 551 | zIgnoreFlag = find_option("ignore",0,1); |
| 552 | verboseFlag = find_option("verbose","v",0)!=0; |
| 553 | zKeepFlag = find_option("keep",0,1); |
| 554 | zCleanFlag = find_option("clean",0,1); |
| 555 | capture_case_sensitive_option(); |
| @@ -565,56 +574,61 @@ | |
| 565 | } |
| 566 | verify_all_options(); |
| 567 | pIgnore = glob_create(zIgnoreFlag); |
| 568 | pKeep = glob_create(zKeepFlag); |
| 569 | pClean = glob_create(zCleanFlag); |
| 570 | locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore, pKeep); |
| 571 | db_prepare(&q, |
| 572 | "SELECT %Q || x FROM sfile" |
| 573 | " WHERE x NOT IN (%s)" |
| 574 | " ORDER BY 1", |
| 575 | g.zLocalRoot, fossil_all_reserved_names(0) |
| 576 | ); |
| 577 | if( file_tree_name(g.zRepositoryName, &repo, 0) ){ |
| 578 | db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo); |
| 579 | } |
| 580 | db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)"); |
| 581 | nRoot = (int)strlen(g.zLocalRoot); |
| 582 | while( db_step(&q)==SQLITE_ROW ){ |
| 583 | const char *zName = db_column_text(&q, 0); |
| 584 | if( !allFileFlag && !dryRunFlag && !glob_match(pClean, zName+nRoot) ){ |
| 585 | Blob ans; |
| 586 | char cReply; |
| 587 | char *prompt = mprintf("Remove unmanaged file \"%s\" (a=all/y/N)? ", |
| 588 | zName+nRoot); |
| 589 | blob_zero(&ans); |
| 590 | prompt_user(prompt, &ans); |
| 591 | cReply = blob_str(&ans)[0]; |
| 592 | if( cReply=='a' || cReply=='A' ){ |
| 593 | allFileFlag = 1; |
| 594 | }else if( cReply!='y' && cReply!='Y' ){ |
| 595 | blob_reset(&ans); |
| 596 | continue; |
| 597 | } |
| 598 | blob_reset(&ans); |
| 599 | } |
| 600 | if ( dryRunFlag || file_delete(zName)==0 ){ |
| 601 | if( verboseFlag || dryRunFlag ){ |
| 602 | fossil_print("Removed unmanaged file: %s\n", zName+nRoot); |
| 603 | } |
| 604 | }else if( verboseFlag ){ |
| 605 | fossil_print("Could not remove file: %s\n", zName+nRoot); |
| 606 | } |
| 607 | } |
| 608 | if( emptyDirsFlag ){ |
| 609 | Glob *pEmptyDirs = glob_create(db_get("empty-dirs", 0)); |
| 610 | Blob root; |
| 611 | blob_init(&root, g.zLocalRoot, nRoot - 1); |
| 612 | vfile_dir_scan(&root, blob_size(&root), scanFlags, pIgnore, pKeep, |
| 613 | pEmptyDirs); |
| 614 | blob_reset(&root); |
| 615 | db_finalize(&q); |
| 616 | db_prepare(&q, |
| 617 | "SELECT %Q || x FROM dscan_temp" |
| 618 | " WHERE x NOT IN (%s) AND y = 0" |
| 619 | " ORDER BY 1 DESC", |
| 620 | g.zLocalRoot, fossil_all_reserved_names(0) |
| @@ -643,16 +657,16 @@ | |
| 643 | } |
| 644 | }else if( verboseFlag ){ |
| 645 | fossil_print("Could not remove directory: %s\n", zName+nRoot); |
| 646 | } |
| 647 | } |
| 648 | glob_free(pEmptyDirs); |
| 649 | } |
| 650 | glob_free(pClean); |
| 651 | glob_free(pKeep); |
| 652 | glob_free(pIgnore); |
| 653 | db_finalize(&q); |
| 654 | } |
| 655 | |
| 656 | /* |
| 657 | ** Prompt the user for a check-in or stash comment (given in pPrompt), |
| 658 | ** gather the response, then return the response in pComment. |
| 659 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -507,11 +507,19 @@ | |
| 507 | ** Files and subdirectories whose names begin with "." are |
| 508 | ** normally kept. They are handled if the "--dotfiles" option |
| 509 | ** is used. |
| 510 | ** |
| 511 | ** Options: |
| 512 | ** --allckouts Check for empty directories within any checkouts |
| 513 | ** that may be nested within the current one. This |
| 514 | ** option should be used with great care because the |
| 515 | ** empty-dirs setting (and other applicable settings) |
| 516 | ** belonging to the other repositories, if any, will |
| 517 | ** not be checked. |
| 518 | ** --case-sensitive <BOOL> override case-sensitive setting |
| 519 | ** --dirsonly Only remove empty directories. No files will |
| 520 | ** be removed. |
| 521 | ** --dotfiles Include files beginning with a dot ("."). |
| 522 | ** --emptydirs Remove any empty directories that are not |
| 523 | ** explicitly exempted via the empty-dirs setting |
| 524 | ** or another applicable setting or command line |
| 525 | ** argument. Matching files, if any, are removed |
| @@ -530,26 +538,27 @@ | |
| 538 | ** -v|--verbose Show all files as they are removed. |
| 539 | ** |
| 540 | ** See also: addremove, extra, status |
| 541 | */ |
| 542 | void clean_cmd(void){ |
| 543 | int allFileFlag, allDirFlag, dryRunFlag, verboseFlag; |
| 544 | int emptyDirsFlag, dirsOnlyFlag; |
| 545 | unsigned scanFlags = 0; |
| 546 | const char *zIgnoreFlag, *zKeepFlag, *zCleanFlag; |
| 547 | Glob *pIgnore, *pKeep, *pClean; |
| 548 | int nRoot; |
| 549 | |
| 550 | dryRunFlag = find_option("dry-run","n",0)!=0; |
| 551 | if( !dryRunFlag ){ |
| 552 | dryRunFlag = find_option("test",0,0)!=0; /* deprecated */ |
| 553 | } |
| 554 | allFileFlag = allDirFlag = find_option("force","f",0)!=0; |
| 555 | emptyDirsFlag = find_option("emptydirs","d",0)!=0; |
| 556 | dirsOnlyFlag = find_option("dirsonly",0,0)!=0; |
| 557 | if( find_option("dotfiles",0,0)!=0 ) scanFlags |= SCAN_ALL; |
| 558 | if( find_option("temp",0,0)!=0 ) scanFlags |= SCAN_TEMP; |
| 559 | if( find_option("allckouts",0,0)!=0 ) scanFlags |= SCAN_NESTED; |
| 560 | zIgnoreFlag = find_option("ignore",0,1); |
| 561 | verboseFlag = find_option("verbose","v",0)!=0; |
| 562 | zKeepFlag = find_option("keep",0,1); |
| 563 | zCleanFlag = find_option("clean",0,1); |
| 564 | capture_case_sensitive_option(); |
| @@ -565,56 +574,61 @@ | |
| 574 | } |
| 575 | verify_all_options(); |
| 576 | pIgnore = glob_create(zIgnoreFlag); |
| 577 | pKeep = glob_create(zKeepFlag); |
| 578 | pClean = glob_create(zCleanFlag); |
| 579 | nRoot = (int)strlen(g.zLocalRoot); |
| 580 | if( !dirsOnlyFlag ){ |
| 581 | Stmt q; |
| 582 | Blob repo; |
| 583 | locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore, pKeep); |
| 584 | db_prepare(&q, |
| 585 | "SELECT %Q || x FROM sfile" |
| 586 | " WHERE x NOT IN (%s)" |
| 587 | " ORDER BY 1", |
| 588 | g.zLocalRoot, fossil_all_reserved_names(0) |
| 589 | ); |
| 590 | if( file_tree_name(g.zRepositoryName, &repo, 0) ){ |
| 591 | db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo); |
| 592 | } |
| 593 | db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)"); |
| 594 | while( db_step(&q)==SQLITE_ROW ){ |
| 595 | const char *zName = db_column_text(&q, 0); |
| 596 | if( !allFileFlag && !dryRunFlag && !glob_match(pClean, zName+nRoot) ){ |
| 597 | Blob ans; |
| 598 | char cReply; |
| 599 | char *prompt = mprintf("Remove unmanaged file \"%s\" (a=all/y/N)? ", |
| 600 | zName+nRoot); |
| 601 | blob_zero(&ans); |
| 602 | prompt_user(prompt, &ans); |
| 603 | cReply = blob_str(&ans)[0]; |
| 604 | if( cReply=='a' || cReply=='A' ){ |
| 605 | allFileFlag = 1; |
| 606 | }else if( cReply!='y' && cReply!='Y' ){ |
| 607 | blob_reset(&ans); |
| 608 | continue; |
| 609 | } |
| 610 | blob_reset(&ans); |
| 611 | } |
| 612 | if ( dryRunFlag || file_delete(zName)==0 ){ |
| 613 | if( verboseFlag || dryRunFlag ){ |
| 614 | fossil_print("Removed unmanaged file: %s\n", zName+nRoot); |
| 615 | } |
| 616 | }else if( verboseFlag ){ |
| 617 | fossil_print("Could not remove file: %s\n", zName+nRoot); |
| 618 | } |
| 619 | } |
| 620 | db_finalize(&q); |
| 621 | } |
| 622 | if( emptyDirsFlag ){ |
| 623 | Glob *pEmptyDirs = glob_create(db_get("empty-dirs", 0)); |
| 624 | Stmt q; |
| 625 | Blob root; |
| 626 | blob_init(&root, g.zLocalRoot, nRoot - 1); |
| 627 | vfile_dir_scan(&root, blob_size(&root), scanFlags, pIgnore, pKeep, |
| 628 | pEmptyDirs); |
| 629 | blob_reset(&root); |
| 630 | db_prepare(&q, |
| 631 | "SELECT %Q || x FROM dscan_temp" |
| 632 | " WHERE x NOT IN (%s) AND y = 0" |
| 633 | " ORDER BY 1 DESC", |
| 634 | g.zLocalRoot, fossil_all_reserved_names(0) |
| @@ -643,16 +657,16 @@ | |
| 657 | } |
| 658 | }else if( verboseFlag ){ |
| 659 | fossil_print("Could not remove directory: %s\n", zName+nRoot); |
| 660 | } |
| 661 | } |
| 662 | db_finalize(&q); |
| 663 | glob_free(pEmptyDirs); |
| 664 | } |
| 665 | glob_free(pClean); |
| 666 | glob_free(pKeep); |
| 667 | glob_free(pIgnore); |
| 668 | } |
| 669 | |
| 670 | /* |
| 671 | ** Prompt the user for a check-in or stash comment (given in pPrompt), |
| 672 | ** gather the response, then return the response in pComment. |
| 673 |
+2
-1
| --- src/vfile.c | ||
| +++ src/vfile.c | ||
| @@ -418,10 +418,11 @@ | ||
| 418 | 418 | /* |
| 419 | 419 | ** Values for the scanFlags parameter to vfile_scan(). |
| 420 | 420 | */ |
| 421 | 421 | #define SCAN_ALL 0x001 /* Includes files that begin with "." */ |
| 422 | 422 | #define SCAN_TEMP 0x002 /* Only Fossil-generated files like *-baseline */ |
| 423 | +#define SCAN_NESTED 0x004 /* Scan for empty dirs in nested checkouts */ | |
| 423 | 424 | #endif /* INTERFACE */ |
| 424 | 425 | |
| 425 | 426 | /* |
| 426 | 427 | ** Load into table SFILE the name of every ordinary file in |
| 427 | 428 | ** the directory pPath. Omit the first nPrefix characters of |
| @@ -593,11 +594,11 @@ | ||
| 593 | 594 | if( glob_match(pIgnore1, &zPath[nPrefix+1]) || |
| 594 | 595 | glob_match(pIgnore2, &zPath[nPrefix+1]) || |
| 595 | 596 | glob_match(pIgnore3, &zPath[nPrefix+1]) ){ |
| 596 | 597 | /* do nothing */ |
| 597 | 598 | }else if( file_wd_isdir(zPath)==1 ){ |
| 598 | - if( !vfile_top_of_checkout(zPath) ){ | |
| 599 | + if( (scanFlags & SCAN_NESTED) || !vfile_top_of_checkout(zPath) ){ | |
| 599 | 600 | Blob dirPattern; |
| 600 | 601 | int count = vfile_dir_scan(pPath, nPrefix, scanFlags, pIgnore1, |
| 601 | 602 | pIgnore2, pIgnore3); |
| 602 | 603 | blob_init(&dirPattern, &zPath[nPrefix+1], -1); |
| 603 | 604 | blob_appendf(&dirPattern, "*"); |
| 604 | 605 |
| --- src/vfile.c | |
| +++ src/vfile.c | |
| @@ -418,10 +418,11 @@ | |
| 418 | /* |
| 419 | ** Values for the scanFlags parameter to vfile_scan(). |
| 420 | */ |
| 421 | #define SCAN_ALL 0x001 /* Includes files that begin with "." */ |
| 422 | #define SCAN_TEMP 0x002 /* Only Fossil-generated files like *-baseline */ |
| 423 | #endif /* INTERFACE */ |
| 424 | |
| 425 | /* |
| 426 | ** Load into table SFILE the name of every ordinary file in |
| 427 | ** the directory pPath. Omit the first nPrefix characters of |
| @@ -593,11 +594,11 @@ | |
| 593 | if( glob_match(pIgnore1, &zPath[nPrefix+1]) || |
| 594 | glob_match(pIgnore2, &zPath[nPrefix+1]) || |
| 595 | glob_match(pIgnore3, &zPath[nPrefix+1]) ){ |
| 596 | /* do nothing */ |
| 597 | }else if( file_wd_isdir(zPath)==1 ){ |
| 598 | if( !vfile_top_of_checkout(zPath) ){ |
| 599 | Blob dirPattern; |
| 600 | int count = vfile_dir_scan(pPath, nPrefix, scanFlags, pIgnore1, |
| 601 | pIgnore2, pIgnore3); |
| 602 | blob_init(&dirPattern, &zPath[nPrefix+1], -1); |
| 603 | blob_appendf(&dirPattern, "*"); |
| 604 |
| --- src/vfile.c | |
| +++ src/vfile.c | |
| @@ -418,10 +418,11 @@ | |
| 418 | /* |
| 419 | ** Values for the scanFlags parameter to vfile_scan(). |
| 420 | */ |
| 421 | #define SCAN_ALL 0x001 /* Includes files that begin with "." */ |
| 422 | #define SCAN_TEMP 0x002 /* Only Fossil-generated files like *-baseline */ |
| 423 | #define SCAN_NESTED 0x004 /* Scan for empty dirs in nested checkouts */ |
| 424 | #endif /* INTERFACE */ |
| 425 | |
| 426 | /* |
| 427 | ** Load into table SFILE the name of every ordinary file in |
| 428 | ** the directory pPath. Omit the first nPrefix characters of |
| @@ -593,11 +594,11 @@ | |
| 594 | if( glob_match(pIgnore1, &zPath[nPrefix+1]) || |
| 595 | glob_match(pIgnore2, &zPath[nPrefix+1]) || |
| 596 | glob_match(pIgnore3, &zPath[nPrefix+1]) ){ |
| 597 | /* do nothing */ |
| 598 | }else if( file_wd_isdir(zPath)==1 ){ |
| 599 | if( (scanFlags & SCAN_NESTED) || !vfile_top_of_checkout(zPath) ){ |
| 600 | Blob dirPattern; |
| 601 | int count = vfile_dir_scan(pPath, nPrefix, scanFlags, pIgnore1, |
| 602 | pIgnore2, pIgnore3); |
| 603 | blob_init(&dirPattern, &zPath[nPrefix+1], -1); |
| 604 | blob_appendf(&dirPattern, "*"); |
| 605 |