Fossil SCM

Add the "fossil tree" command and the --tree option to "fossil ls" and "fossil extras".

drh 2024-04-29 03:04 trunk
Commit dd72a96111edd296ea1fb2c09a637f471a3fa48ec1a7c2d11842bcc668cae8e4
1 file changed +146 -5
+146 -5
--- src/checkin.c
+++ src/checkin.c
@@ -592,26 +592,119 @@
592592
/* The status command ends with warnings about ambiguous leaves (forks). */
593593
if( command==STATUS ){
594594
leaf_ambiguity_warning(vid, vid);
595595
}
596596
}
597
+
598
+/*
599
+** Characters used for drawing a file hierarchy graph.
600
+*/
601
+#if _WIN32
602
+/* ASCII only available on Windows */
603
+#define ENTRY "|-- "
604
+#define LASTE "`-- "
605
+#define CONTU "| "
606
+#define BLANK " "
607
+#else
608
+/* All other platforms support Unicode box-drawing chracters */
609
+#define ENTRY "\342\224\234\342\224\200\342\224\200 "
610
+#define LASTE "\342\224\224\342\224\200\342\224\200 "
611
+#define CONTU "\342\224\202 "
612
+#define BLANK " "
613
+#endif
614
+
615
+
616
+/* zIn is a string that is guaranteed to be followed by \n. Return
617
+** a pointer to the next line after the \n. The returned value might
618
+** point to the \000 string terminator.
619
+*/
620
+static const char *next_line(const char *zIn){
621
+ const char *z = strchr(zIn, '\n');
622
+ assert( z!=0 );
623
+ return z+1;
624
+}
625
+
626
+/* zIn is a non-empty list of filenames in sorted order and separated
627
+** by \n. There might be a cluster of lines that have the same n-character
628
+** prefix. Return a pointer to the start of the last line of that
629
+** cluster. The return value might be zIn if the first line of zIn is
630
+** unique in its first n character.
631
+*/
632
+static const char *last_line(const char *zIn, int n){
633
+ const char *zLast = zIn;
634
+ const char *z;
635
+ while( 1 ){
636
+ z = next_line(zLast);
637
+ if( z[0]==0 || (n>0 && strncmp(zIn, z, n)!=0) ) break;
638
+ zLast = z;
639
+ }
640
+ return zLast;
641
+}
642
+
643
+/*
644
+** Print a section of a filelist hierarchy graph. This is a helper
645
+** routine for print_filelist_as_tree() below.
646
+*/
647
+static const char *print_filelist_section(
648
+ const char *zIn, /* List of filenames, separated by \n */
649
+ const char *zLast, /* Last filename in the list to print */
650
+ const char *zPrefix, /* Prefix so put before each output line */
651
+ int nDir /* Ignore this many characters of directory name */
652
+){
653
+ while( zIn<=zLast ){
654
+ int i;
655
+ for(i=nDir; zIn[i]!='\n' && zIn[i]!='/'; i++){}
656
+ if( zIn[i]=='/' ){
657
+ char *zSubPrefix;
658
+ const char *zSubLast = last_line(zIn, i+1);
659
+ zSubPrefix = mprintf("%s%s", zPrefix, zSubLast==zLast ? BLANK : CONTU);
660
+ fossil_print("%s%s%.*s\n", zPrefix, zSubLast==zLast ? LASTE : ENTRY,
661
+ i-nDir, &zIn[nDir]);
662
+ zIn = print_filelist_section(zIn, zSubLast, zSubPrefix, i+1);
663
+ fossil_free(zSubPrefix);
664
+ }else{
665
+ fossil_print("%s%s%.*s\n", zPrefix, zIn==zLast ? LASTE : ENTRY,
666
+ i-nDir, &zIn[nDir]);
667
+ zIn = next_line(zIn);
668
+ }
669
+ }
670
+ return zIn;
671
+}
672
+
673
+/*
674
+** Input blob pList is a list of filenames, one filename per line,
675
+** in sorted order and with / directory separators. Output this list
676
+** as a tree in a manner similar to the "tree" command on Linux.
677
+*/
678
+static void print_filelist_as_tree(Blob *pList){
679
+ char *zAll;
680
+ const char *zLast;
681
+ fossil_print("%s\n", g.zLocalRoot);
682
+ zAll = blob_str(pList);
683
+ if( zAll[0] ){
684
+ zLast = last_line(zAll, 0);
685
+ print_filelist_section(zAll, zLast, "", 0);
686
+ }
687
+}
597688
598689
/*
599690
** Take care of -r version of ls command
600691
*/
601692
static void ls_cmd_rev(
602693
const char *zRev, /* Revision string given */
603694
int verboseFlag, /* Verbose flag given */
604695
int showAge, /* Age flag given */
605
- int timeOrder /* Order by time flag given */
696
+ int timeOrder, /* Order by time flag given */
697
+ int treeFmt /* Show output in the tree format */
606698
){
607699
Stmt q;
608700
char *zOrderBy = "pathname COLLATE nocase";
609701
char *zName;
610702
Blob where;
611703
int rid;
612704
int i;
705
+ Blob out;
613706
614707
/* Handle given file names */
615708
blob_zero(&where);
616709
for(i=2; i<g.argc; i++){
617710
Blob fname;
@@ -649,24 +742,31 @@
649742
" FROM fileage, blob\n"
650743
" WHERE blob.rid=fileage.fid %s\n"
651744
" ORDER BY %s;", blob_sql_text(&where), zOrderBy /*safe-for-%s*/
652745
);
653746
blob_reset(&where);
747
+ if( treeFmt ) blob_init(&out, 0, 0);
654748
655749
while( db_step(&q)==SQLITE_ROW ){
656750
const char *zTime = db_column_text(&q,0);
657751
const char *zFile = db_column_text(&q,1);
658752
int size = db_column_int(&q,2);
659
- if( verboseFlag ){
753
+ if( treeFmt ){
754
+ blob_appendf(&out, "%s\n", zFile);
755
+ }else if( verboseFlag ){
660756
fossil_print("%s %7d %s\n", zTime, size, zFile);
661757
}else if( showAge ){
662758
fossil_print("%s %s\n", zTime, zFile);
663759
}else{
664760
fossil_print("%s\n", zFile);
665761
}
666762
}
667763
db_finalize(&q);
764
+ if( treeFmt ){
765
+ print_filelist_as_tree(&out);
766
+ blob_reset(&out);
767
+ }
668768
}
669769
670770
/*
671771
** COMMAND: ls
672772
**
@@ -694,22 +794,24 @@
694794
**
695795
** Options:
696796
** --age Show when each file was committed
697797
** -v|--verbose Provide extra information about each file
698798
** -t Sort output in time order
799
+** --tree Tree format
699800
** -r VERSION The specific check-in to list
700801
** -R|--repository REPO Extract info from repository REPO
701802
** --hash With -v, verify file status using hashing
702803
** rather than relying on file sizes and mtimes
703804
**
704
-** See also: [[changes]], [[extras]], [[status]]
805
+** See also: [[changes]], [[extras]], [[status]], [[tree]]
705806
*/
706807
void ls_cmd(void){
707808
int vid;
708809
Stmt q;
709810
int verboseFlag;
710811
int showAge;
812
+ int treeFmt;
711813
int timeOrder;
712814
char *zOrderBy = "pathname";
713815
Blob where;
714816
int i;
715817
int useHash = 0;
@@ -724,15 +826,19 @@
724826
zRev = find_option("r","r",1);
725827
timeOrder = find_option("t","t",0)!=0;
726828
if( verboseFlag ){
727829
useHash = find_option("hash",0,0)!=0;
728830
}
831
+ treeFmt = find_option("tree",0,0)!=0;
832
+ if( treeFmt ){
833
+ if( zRev==0 ) zRev = "current";
834
+ }
729835
730836
if( zRev!=0 ){
731837
db_find_and_open_repository(0, 0);
732838
verify_all_options();
733
- ls_cmd_rev(zRev,verboseFlag,showAge,timeOrder);
839
+ ls_cmd_rev(zRev,verboseFlag,showAge,timeOrder,treeFmt);
734840
return;
735841
}else if( find_option("R",0,1)!=0 ){
736842
fossil_fatal("the -r is required in addition to -R");
737843
}
738844
@@ -828,10 +934,35 @@
828934
}
829935
free(zFullName);
830936
}
831937
db_finalize(&q);
832938
}
939
+
940
+/*
941
+** COMMAND: tree
942
+**
943
+** Usage: %fossil tree ?OPTIONS? ?PATHS ...?
944
+**
945
+** List all files in the current check-out in after the fashion of the
946
+** "tree" command. If PATHS is included, only the named files
947
+** (or their children if directories) are shown.
948
+**
949
+** Options:
950
+** -r VERSION The specific check-in to list
951
+** -R|--repository REPO Extract info from repository REPO
952
+**
953
+** See also: [[ls]]
954
+*/
955
+void tree_cmd(void){
956
+ const char *zRev;
957
+
958
+ zRev = find_option("r","r",1);
959
+ if( zRev==0 ) zRev = "current";
960
+ db_find_and_open_repository(0, 0);
961
+ verify_all_options();
962
+ ls_cmd_rev(zRev,0,0,0,1);
963
+}
833964
834965
/*
835966
** COMMAND: extras
836967
**
837968
** Usage: %fossil extras ?OPTIONS? ?PATH1 ...?
@@ -856,19 +987,21 @@
856987
** --dotfiles Include files beginning with a dot (".")
857988
** --header Identify the repository if there are extras
858989
** --ignore CSG Ignore files matching patterns from the argument
859990
** --rel-paths Display pathnames relative to the current working
860991
** directory
992
+** --tree Show output in the tree format
861993
**
862994
** See also: [[changes]], [[clean]], [[status]]
863995
*/
864996
void extras_cmd(void){
865997
Blob report = BLOB_INITIALIZER;
866998
const char *zIgnoreFlag = find_option("ignore",0,1);
867999
unsigned scanFlags = find_option("dotfiles",0,0)!=0 ? SCAN_ALL : 0;
8681000
unsigned flags = C_EXTRA;
8691001
int showHdr = find_option("header",0,0)!=0;
1002
+ int treeFmt = find_option("tree",0,0)!=0;
8701003
Glob *pIgnore;
8711004
8721005
if( find_option("temp",0,0)!=0 ) scanFlags |= SCAN_TEMP;
8731006
db_must_be_within_tree();
8741007
@@ -875,10 +1008,14 @@
8751008
if( determine_cwd_relative_option() ){
8761009
flags |= C_RELPATH;
8771010
}
8781011
8791012
if( db_get_boolean("dotfiles", 0) ) scanFlags |= SCAN_ALL;
1013
+
1014
+ if( treeFmt ){
1015
+ flags &= ~C_RELPATH;
1016
+ }
8801017
8811018
/* We should be done with options.. */
8821019
verify_all_options();
8831020
8841021
if( zIgnoreFlag==0 ){
@@ -893,11 +1030,15 @@
8931030
if( blob_size(&report) ){
8941031
if( showHdr ){
8951032
fossil_print("Extras for %s at %s:\n", db_get("project-name","<unnamed>"),
8961033
g.zLocalRoot);
8971034
}
898
- blob_write_to_file(&report, "-");
1035
+ if( treeFmt ){
1036
+ print_filelist_as_tree(&report);
1037
+ }else{
1038
+ blob_write_to_file(&report, "-");
1039
+ }
8991040
}
9001041
blob_reset(&report);
9011042
}
9021043
9031044
/*
9041045
--- src/checkin.c
+++ src/checkin.c
@@ -592,26 +592,119 @@
592 /* The status command ends with warnings about ambiguous leaves (forks). */
593 if( command==STATUS ){
594 leaf_ambiguity_warning(vid, vid);
595 }
596 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
597
598 /*
599 ** Take care of -r version of ls command
600 */
601 static void ls_cmd_rev(
602 const char *zRev, /* Revision string given */
603 int verboseFlag, /* Verbose flag given */
604 int showAge, /* Age flag given */
605 int timeOrder /* Order by time flag given */
 
606 ){
607 Stmt q;
608 char *zOrderBy = "pathname COLLATE nocase";
609 char *zName;
610 Blob where;
611 int rid;
612 int i;
 
613
614 /* Handle given file names */
615 blob_zero(&where);
616 for(i=2; i<g.argc; i++){
617 Blob fname;
@@ -649,24 +742,31 @@
649 " FROM fileage, blob\n"
650 " WHERE blob.rid=fileage.fid %s\n"
651 " ORDER BY %s;", blob_sql_text(&where), zOrderBy /*safe-for-%s*/
652 );
653 blob_reset(&where);
 
654
655 while( db_step(&q)==SQLITE_ROW ){
656 const char *zTime = db_column_text(&q,0);
657 const char *zFile = db_column_text(&q,1);
658 int size = db_column_int(&q,2);
659 if( verboseFlag ){
 
 
660 fossil_print("%s %7d %s\n", zTime, size, zFile);
661 }else if( showAge ){
662 fossil_print("%s %s\n", zTime, zFile);
663 }else{
664 fossil_print("%s\n", zFile);
665 }
666 }
667 db_finalize(&q);
 
 
 
 
668 }
669
670 /*
671 ** COMMAND: ls
672 **
@@ -694,22 +794,24 @@
694 **
695 ** Options:
696 ** --age Show when each file was committed
697 ** -v|--verbose Provide extra information about each file
698 ** -t Sort output in time order
 
699 ** -r VERSION The specific check-in to list
700 ** -R|--repository REPO Extract info from repository REPO
701 ** --hash With -v, verify file status using hashing
702 ** rather than relying on file sizes and mtimes
703 **
704 ** See also: [[changes]], [[extras]], [[status]]
705 */
706 void ls_cmd(void){
707 int vid;
708 Stmt q;
709 int verboseFlag;
710 int showAge;
 
711 int timeOrder;
712 char *zOrderBy = "pathname";
713 Blob where;
714 int i;
715 int useHash = 0;
@@ -724,15 +826,19 @@
724 zRev = find_option("r","r",1);
725 timeOrder = find_option("t","t",0)!=0;
726 if( verboseFlag ){
727 useHash = find_option("hash",0,0)!=0;
728 }
 
 
 
 
729
730 if( zRev!=0 ){
731 db_find_and_open_repository(0, 0);
732 verify_all_options();
733 ls_cmd_rev(zRev,verboseFlag,showAge,timeOrder);
734 return;
735 }else if( find_option("R",0,1)!=0 ){
736 fossil_fatal("the -r is required in addition to -R");
737 }
738
@@ -828,10 +934,35 @@
828 }
829 free(zFullName);
830 }
831 db_finalize(&q);
832 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
833
834 /*
835 ** COMMAND: extras
836 **
837 ** Usage: %fossil extras ?OPTIONS? ?PATH1 ...?
@@ -856,19 +987,21 @@
856 ** --dotfiles Include files beginning with a dot (".")
857 ** --header Identify the repository if there are extras
858 ** --ignore CSG Ignore files matching patterns from the argument
859 ** --rel-paths Display pathnames relative to the current working
860 ** directory
 
861 **
862 ** See also: [[changes]], [[clean]], [[status]]
863 */
864 void extras_cmd(void){
865 Blob report = BLOB_INITIALIZER;
866 const char *zIgnoreFlag = find_option("ignore",0,1);
867 unsigned scanFlags = find_option("dotfiles",0,0)!=0 ? SCAN_ALL : 0;
868 unsigned flags = C_EXTRA;
869 int showHdr = find_option("header",0,0)!=0;
 
870 Glob *pIgnore;
871
872 if( find_option("temp",0,0)!=0 ) scanFlags |= SCAN_TEMP;
873 db_must_be_within_tree();
874
@@ -875,10 +1008,14 @@
875 if( determine_cwd_relative_option() ){
876 flags |= C_RELPATH;
877 }
878
879 if( db_get_boolean("dotfiles", 0) ) scanFlags |= SCAN_ALL;
 
 
 
 
880
881 /* We should be done with options.. */
882 verify_all_options();
883
884 if( zIgnoreFlag==0 ){
@@ -893,11 +1030,15 @@
893 if( blob_size(&report) ){
894 if( showHdr ){
895 fossil_print("Extras for %s at %s:\n", db_get("project-name","<unnamed>"),
896 g.zLocalRoot);
897 }
898 blob_write_to_file(&report, "-");
 
 
 
 
899 }
900 blob_reset(&report);
901 }
902
903 /*
904
--- src/checkin.c
+++ src/checkin.c
@@ -592,26 +592,119 @@
592 /* The status command ends with warnings about ambiguous leaves (forks). */
593 if( command==STATUS ){
594 leaf_ambiguity_warning(vid, vid);
595 }
596 }
597
598 /*
599 ** Characters used for drawing a file hierarchy graph.
600 */
601 #if _WIN32
602 /* ASCII only available on Windows */
603 #define ENTRY "|-- "
604 #define LASTE "`-- "
605 #define CONTU "| "
606 #define BLANK " "
607 #else
608 /* All other platforms support Unicode box-drawing chracters */
609 #define ENTRY "\342\224\234\342\224\200\342\224\200 "
610 #define LASTE "\342\224\224\342\224\200\342\224\200 "
611 #define CONTU "\342\224\202 "
612 #define BLANK " "
613 #endif
614
615
616 /* zIn is a string that is guaranteed to be followed by \n. Return
617 ** a pointer to the next line after the \n. The returned value might
618 ** point to the \000 string terminator.
619 */
620 static const char *next_line(const char *zIn){
621 const char *z = strchr(zIn, '\n');
622 assert( z!=0 );
623 return z+1;
624 }
625
626 /* zIn is a non-empty list of filenames in sorted order and separated
627 ** by \n. There might be a cluster of lines that have the same n-character
628 ** prefix. Return a pointer to the start of the last line of that
629 ** cluster. The return value might be zIn if the first line of zIn is
630 ** unique in its first n character.
631 */
632 static const char *last_line(const char *zIn, int n){
633 const char *zLast = zIn;
634 const char *z;
635 while( 1 ){
636 z = next_line(zLast);
637 if( z[0]==0 || (n>0 && strncmp(zIn, z, n)!=0) ) break;
638 zLast = z;
639 }
640 return zLast;
641 }
642
643 /*
644 ** Print a section of a filelist hierarchy graph. This is a helper
645 ** routine for print_filelist_as_tree() below.
646 */
647 static const char *print_filelist_section(
648 const char *zIn, /* List of filenames, separated by \n */
649 const char *zLast, /* Last filename in the list to print */
650 const char *zPrefix, /* Prefix so put before each output line */
651 int nDir /* Ignore this many characters of directory name */
652 ){
653 while( zIn<=zLast ){
654 int i;
655 for(i=nDir; zIn[i]!='\n' && zIn[i]!='/'; i++){}
656 if( zIn[i]=='/' ){
657 char *zSubPrefix;
658 const char *zSubLast = last_line(zIn, i+1);
659 zSubPrefix = mprintf("%s%s", zPrefix, zSubLast==zLast ? BLANK : CONTU);
660 fossil_print("%s%s%.*s\n", zPrefix, zSubLast==zLast ? LASTE : ENTRY,
661 i-nDir, &zIn[nDir]);
662 zIn = print_filelist_section(zIn, zSubLast, zSubPrefix, i+1);
663 fossil_free(zSubPrefix);
664 }else{
665 fossil_print("%s%s%.*s\n", zPrefix, zIn==zLast ? LASTE : ENTRY,
666 i-nDir, &zIn[nDir]);
667 zIn = next_line(zIn);
668 }
669 }
670 return zIn;
671 }
672
673 /*
674 ** Input blob pList is a list of filenames, one filename per line,
675 ** in sorted order and with / directory separators. Output this list
676 ** as a tree in a manner similar to the "tree" command on Linux.
677 */
678 static void print_filelist_as_tree(Blob *pList){
679 char *zAll;
680 const char *zLast;
681 fossil_print("%s\n", g.zLocalRoot);
682 zAll = blob_str(pList);
683 if( zAll[0] ){
684 zLast = last_line(zAll, 0);
685 print_filelist_section(zAll, zLast, "", 0);
686 }
687 }
688
689 /*
690 ** Take care of -r version of ls command
691 */
692 static void ls_cmd_rev(
693 const char *zRev, /* Revision string given */
694 int verboseFlag, /* Verbose flag given */
695 int showAge, /* Age flag given */
696 int timeOrder, /* Order by time flag given */
697 int treeFmt /* Show output in the tree format */
698 ){
699 Stmt q;
700 char *zOrderBy = "pathname COLLATE nocase";
701 char *zName;
702 Blob where;
703 int rid;
704 int i;
705 Blob out;
706
707 /* Handle given file names */
708 blob_zero(&where);
709 for(i=2; i<g.argc; i++){
710 Blob fname;
@@ -649,24 +742,31 @@
742 " FROM fileage, blob\n"
743 " WHERE blob.rid=fileage.fid %s\n"
744 " ORDER BY %s;", blob_sql_text(&where), zOrderBy /*safe-for-%s*/
745 );
746 blob_reset(&where);
747 if( treeFmt ) blob_init(&out, 0, 0);
748
749 while( db_step(&q)==SQLITE_ROW ){
750 const char *zTime = db_column_text(&q,0);
751 const char *zFile = db_column_text(&q,1);
752 int size = db_column_int(&q,2);
753 if( treeFmt ){
754 blob_appendf(&out, "%s\n", zFile);
755 }else if( verboseFlag ){
756 fossil_print("%s %7d %s\n", zTime, size, zFile);
757 }else if( showAge ){
758 fossil_print("%s %s\n", zTime, zFile);
759 }else{
760 fossil_print("%s\n", zFile);
761 }
762 }
763 db_finalize(&q);
764 if( treeFmt ){
765 print_filelist_as_tree(&out);
766 blob_reset(&out);
767 }
768 }
769
770 /*
771 ** COMMAND: ls
772 **
@@ -694,22 +794,24 @@
794 **
795 ** Options:
796 ** --age Show when each file was committed
797 ** -v|--verbose Provide extra information about each file
798 ** -t Sort output in time order
799 ** --tree Tree format
800 ** -r VERSION The specific check-in to list
801 ** -R|--repository REPO Extract info from repository REPO
802 ** --hash With -v, verify file status using hashing
803 ** rather than relying on file sizes and mtimes
804 **
805 ** See also: [[changes]], [[extras]], [[status]], [[tree]]
806 */
807 void ls_cmd(void){
808 int vid;
809 Stmt q;
810 int verboseFlag;
811 int showAge;
812 int treeFmt;
813 int timeOrder;
814 char *zOrderBy = "pathname";
815 Blob where;
816 int i;
817 int useHash = 0;
@@ -724,15 +826,19 @@
826 zRev = find_option("r","r",1);
827 timeOrder = find_option("t","t",0)!=0;
828 if( verboseFlag ){
829 useHash = find_option("hash",0,0)!=0;
830 }
831 treeFmt = find_option("tree",0,0)!=0;
832 if( treeFmt ){
833 if( zRev==0 ) zRev = "current";
834 }
835
836 if( zRev!=0 ){
837 db_find_and_open_repository(0, 0);
838 verify_all_options();
839 ls_cmd_rev(zRev,verboseFlag,showAge,timeOrder,treeFmt);
840 return;
841 }else if( find_option("R",0,1)!=0 ){
842 fossil_fatal("the -r is required in addition to -R");
843 }
844
@@ -828,10 +934,35 @@
934 }
935 free(zFullName);
936 }
937 db_finalize(&q);
938 }
939
940 /*
941 ** COMMAND: tree
942 **
943 ** Usage: %fossil tree ?OPTIONS? ?PATHS ...?
944 **
945 ** List all files in the current check-out in after the fashion of the
946 ** "tree" command. If PATHS is included, only the named files
947 ** (or their children if directories) are shown.
948 **
949 ** Options:
950 ** -r VERSION The specific check-in to list
951 ** -R|--repository REPO Extract info from repository REPO
952 **
953 ** See also: [[ls]]
954 */
955 void tree_cmd(void){
956 const char *zRev;
957
958 zRev = find_option("r","r",1);
959 if( zRev==0 ) zRev = "current";
960 db_find_and_open_repository(0, 0);
961 verify_all_options();
962 ls_cmd_rev(zRev,0,0,0,1);
963 }
964
965 /*
966 ** COMMAND: extras
967 **
968 ** Usage: %fossil extras ?OPTIONS? ?PATH1 ...?
@@ -856,19 +987,21 @@
987 ** --dotfiles Include files beginning with a dot (".")
988 ** --header Identify the repository if there are extras
989 ** --ignore CSG Ignore files matching patterns from the argument
990 ** --rel-paths Display pathnames relative to the current working
991 ** directory
992 ** --tree Show output in the tree format
993 **
994 ** See also: [[changes]], [[clean]], [[status]]
995 */
996 void extras_cmd(void){
997 Blob report = BLOB_INITIALIZER;
998 const char *zIgnoreFlag = find_option("ignore",0,1);
999 unsigned scanFlags = find_option("dotfiles",0,0)!=0 ? SCAN_ALL : 0;
1000 unsigned flags = C_EXTRA;
1001 int showHdr = find_option("header",0,0)!=0;
1002 int treeFmt = find_option("tree",0,0)!=0;
1003 Glob *pIgnore;
1004
1005 if( find_option("temp",0,0)!=0 ) scanFlags |= SCAN_TEMP;
1006 db_must_be_within_tree();
1007
@@ -875,10 +1008,14 @@
1008 if( determine_cwd_relative_option() ){
1009 flags |= C_RELPATH;
1010 }
1011
1012 if( db_get_boolean("dotfiles", 0) ) scanFlags |= SCAN_ALL;
1013
1014 if( treeFmt ){
1015 flags &= ~C_RELPATH;
1016 }
1017
1018 /* We should be done with options.. */
1019 verify_all_options();
1020
1021 if( zIgnoreFlag==0 ){
@@ -893,11 +1030,15 @@
1030 if( blob_size(&report) ){
1031 if( showHdr ){
1032 fossil_print("Extras for %s at %s:\n", db_get("project-name","<unnamed>"),
1033 g.zLocalRoot);
1034 }
1035 if( treeFmt ){
1036 print_filelist_as_tree(&report);
1037 }else{
1038 blob_write_to_file(&report, "-");
1039 }
1040 }
1041 blob_reset(&report);
1042 }
1043
1044 /*
1045

Keyboard Shortcuts

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