Fossil SCM

Add --limit and --log options to the "annotate" command and corresponding query parameters to the web annotation interface. Part of the investigation of ticket [f0f9aff371f26b4]

drh 2011-05-06 14:36 trunk
Commit bd36723c3d771114390e8791924825e4d57be6a8
1 file changed +48 -5
+48 -5
--- src/diff.c
+++ src/diff.c
@@ -633,10 +633,12 @@
633633
int n; /* Number of bytes (omitting trailing space and \n) */
634634
const char *zSrc; /* Tag showing origin of this line */
635635
} *aOrig;
636636
int nOrig; /* Number of elements in aOrig[] */
637637
int nNoSrc; /* Number of entries where aOrig[].zSrc==NULL */
638
+ int nVers; /* Number of versions analyzed */
639
+ char **azVers; /* Names of versions analyzed */
638640
};
639641
640642
/*
641643
** Initialize the annotation process by specifying the file that is
642644
** to be annotated. The annotator takes control of the input Blob and
@@ -739,11 +741,17 @@
739741
/*
740742
** Compute a complete annotation on a file. The file is identified
741743
** by its filename number (filename.fnid) and the baseline in which
742744
** it was checked in (mlink.mid).
743745
*/
744
-static void annotate_file(Annotator *p, int fnid, int mid, int webLabel){
746
+static void annotate_file(
747
+ Annotator *p, /* The annotator */
748
+ int fnid, /* The name of the file to be annotated */
749
+ int mid, /* The specific version of the file for this step */
750
+ int webLabel, /* Use web-style annotations if true */
751
+ int iLimit /* Limit the number of levels if greater than zero */
752
+){
745753
Blob toAnnotate; /* Text of the final version of the file */
746754
Blob step; /* Text of previous revision */
747755
int rid; /* Artifact ID of the file being annotated */
748756
char *zLabel; /* Label to apply to a line */
749757
Stmt q; /* Query returning all ancestor versions */
@@ -766,12 +774,14 @@
766774
" FROM mlink, blob, event"
767775
" WHERE mlink.fnid=%d"
768776
" AND mlink.mid IN ok"
769777
" AND blob.rid=mlink.mid"
770778
" AND event.objid=mlink.mid"
771
- " ORDER BY event.mtime DESC",
772
- fnid
779
+ " ORDER BY event.mtime DESC"
780
+ " LIMIT %d",
781
+ fnid,
782
+ iLimit>0 ? iLimit : 10000000
773783
);
774784
while( db_step(&q)==SQLITE_ROW ){
775785
int pid = db_column_int(&q, 0);
776786
const char *zUuid = db_column_text(&q, 1);
777787
const char *zDate = db_column_text(&q, 2);
@@ -782,10 +792,13 @@
782792
g.zTop, zUuid, zUuid, zDate, zUser
783793
);
784794
}else{
785795
zLabel = mprintf("%.10s %s %9.9s", zUuid, zDate, zUser);
786796
}
797
+ p->nVers++;
798
+ p->azVers = fossil_realloc(p->azVers, p->nVers*sizeof(p->azVers[0]) );
799
+ p->azVers[p->nVers-1] = zLabel;
787800
content_get(pid, &step);
788801
annotation_step(p, &step, zLabel);
789802
blob_reset(&step);
790803
}
791804
db_finalize(&q);
@@ -801,22 +814,35 @@
801814
*/
802815
void annotation_page(void){
803816
int mid;
804817
int fnid;
805818
int i;
819
+ int iLimit;
806820
Annotator ann;
807821
808822
login_check_credentials();
809823
if( !g.okRead ){ login_needed(); return; }
810824
mid = name_to_rid(PD("checkin","0"));
811825
fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", P("filename"));
812826
if( mid==0 || fnid==0 ){ fossil_redirect_home(); }
827
+ iLimit = atoi(PD("limit","-1"));
813828
if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){
814829
fossil_redirect_home();
815830
}
816831
style_header("File Annotation");
817
- annotate_file(&ann, fnid, mid, g.okHistory);
832
+ annotate_file(&ann, fnid, mid, g.okHistory, iLimit);
833
+ if( P("log") ){
834
+ int i;
835
+ @ <h2>Versions analyzed:</h2>
836
+ @ <ol>
837
+ for(i=0; i<ann.nVers; i++){
838
+ @ <li><tt>%s(ann.azVers[i])</tt></li>
839
+ }
840
+ @ </ol>
841
+ @ <hr>
842
+ @ <h2>Annotation:</h2>
843
+ }
818844
@ <pre>
819845
for(i=0; i<ann.nOrig; i++){
820846
((char*)ann.aOrig[i].z)[ann.aOrig[i].n] = 0;
821847
@ %s(ann.aOrig[i].zSrc): %h(ann.aOrig[i].z)
822848
}
@@ -829,20 +855,31 @@
829855
**
830856
** %fossil annotate FILENAME
831857
**
832858
** Output the text of a file with markings to show when each line of
833859
** the file was last modified.
860
+**
861
+** Options:
862
+** --limit N Only look backwards in time by N versions
863
+** --log List all versions analyzed
834864
*/
835865
void annotate_cmd(void){
836866
int fnid; /* Filename ID */
837867
int fid; /* File instance ID */
838868
int mid; /* Manifest where file was checked in */
839869
Blob treename; /* FILENAME translated to canonical form */
840870
char *zFilename; /* Cannonical filename */
841871
Annotator ann; /* The annotation of the file */
842872
int i; /* Loop counter */
873
+ const char *zLimit; /* The value to the --limit option */
874
+ int iLimit; /* How far back in time to look */
875
+ int showLog; /* True to show the log */
843876
877
+ zLimit = find_option("limit",0,1);
878
+ if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1";
879
+ iLimit = atoi(zLimit);
880
+ showLog = find_option("log",0,0)!=0;
844881
db_must_be_within_tree();
845882
if (g.argc<3) {
846883
usage("FILENAME");
847884
}
848885
file_tree_name(g.argv[2], &treename, 1);
@@ -857,10 +894,16 @@
857894
}
858895
mid = db_int(0, "SELECT mid FROM mlink WHERE fid=%d AND fnid=%d", fid, fnid);
859896
if( mid==0 ){
860897
fossil_panic("unable to find manifest");
861898
}
862
- annotate_file(&ann, fnid, mid, 0);
899
+ annotate_file(&ann, fnid, mid, 0, iLimit);
900
+ if( showLog ){
901
+ for(i=0; i<ann.nVers; i++){
902
+ printf("version %3d: %s\n", i+1, ann.azVers[i]);
903
+ }
904
+ printf("---------------------------------------------------\n");
905
+ }
863906
for(i=0; i<ann.nOrig; i++){
864907
printf("%s: %.*s\n", ann.aOrig[i].zSrc, ann.aOrig[i].n, ann.aOrig[i].z);
865908
}
866909
}
867910
--- src/diff.c
+++ src/diff.c
@@ -633,10 +633,12 @@
633 int n; /* Number of bytes (omitting trailing space and \n) */
634 const char *zSrc; /* Tag showing origin of this line */
635 } *aOrig;
636 int nOrig; /* Number of elements in aOrig[] */
637 int nNoSrc; /* Number of entries where aOrig[].zSrc==NULL */
 
 
638 };
639
640 /*
641 ** Initialize the annotation process by specifying the file that is
642 ** to be annotated. The annotator takes control of the input Blob and
@@ -739,11 +741,17 @@
739 /*
740 ** Compute a complete annotation on a file. The file is identified
741 ** by its filename number (filename.fnid) and the baseline in which
742 ** it was checked in (mlink.mid).
743 */
744 static void annotate_file(Annotator *p, int fnid, int mid, int webLabel){
 
 
 
 
 
 
745 Blob toAnnotate; /* Text of the final version of the file */
746 Blob step; /* Text of previous revision */
747 int rid; /* Artifact ID of the file being annotated */
748 char *zLabel; /* Label to apply to a line */
749 Stmt q; /* Query returning all ancestor versions */
@@ -766,12 +774,14 @@
766 " FROM mlink, blob, event"
767 " WHERE mlink.fnid=%d"
768 " AND mlink.mid IN ok"
769 " AND blob.rid=mlink.mid"
770 " AND event.objid=mlink.mid"
771 " ORDER BY event.mtime DESC",
772 fnid
 
 
773 );
774 while( db_step(&q)==SQLITE_ROW ){
775 int pid = db_column_int(&q, 0);
776 const char *zUuid = db_column_text(&q, 1);
777 const char *zDate = db_column_text(&q, 2);
@@ -782,10 +792,13 @@
782 g.zTop, zUuid, zUuid, zDate, zUser
783 );
784 }else{
785 zLabel = mprintf("%.10s %s %9.9s", zUuid, zDate, zUser);
786 }
 
 
 
787 content_get(pid, &step);
788 annotation_step(p, &step, zLabel);
789 blob_reset(&step);
790 }
791 db_finalize(&q);
@@ -801,22 +814,35 @@
801 */
802 void annotation_page(void){
803 int mid;
804 int fnid;
805 int i;
 
806 Annotator ann;
807
808 login_check_credentials();
809 if( !g.okRead ){ login_needed(); return; }
810 mid = name_to_rid(PD("checkin","0"));
811 fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", P("filename"));
812 if( mid==0 || fnid==0 ){ fossil_redirect_home(); }
 
813 if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){
814 fossil_redirect_home();
815 }
816 style_header("File Annotation");
817 annotate_file(&ann, fnid, mid, g.okHistory);
 
 
 
 
 
 
 
 
 
 
 
818 @ <pre>
819 for(i=0; i<ann.nOrig; i++){
820 ((char*)ann.aOrig[i].z)[ann.aOrig[i].n] = 0;
821 @ %s(ann.aOrig[i].zSrc): %h(ann.aOrig[i].z)
822 }
@@ -829,20 +855,31 @@
829 **
830 ** %fossil annotate FILENAME
831 **
832 ** Output the text of a file with markings to show when each line of
833 ** the file was last modified.
 
 
 
 
834 */
835 void annotate_cmd(void){
836 int fnid; /* Filename ID */
837 int fid; /* File instance ID */
838 int mid; /* Manifest where file was checked in */
839 Blob treename; /* FILENAME translated to canonical form */
840 char *zFilename; /* Cannonical filename */
841 Annotator ann; /* The annotation of the file */
842 int i; /* Loop counter */
 
 
 
843
 
 
 
 
844 db_must_be_within_tree();
845 if (g.argc<3) {
846 usage("FILENAME");
847 }
848 file_tree_name(g.argv[2], &treename, 1);
@@ -857,10 +894,16 @@
857 }
858 mid = db_int(0, "SELECT mid FROM mlink WHERE fid=%d AND fnid=%d", fid, fnid);
859 if( mid==0 ){
860 fossil_panic("unable to find manifest");
861 }
862 annotate_file(&ann, fnid, mid, 0);
 
 
 
 
 
 
863 for(i=0; i<ann.nOrig; i++){
864 printf("%s: %.*s\n", ann.aOrig[i].zSrc, ann.aOrig[i].n, ann.aOrig[i].z);
865 }
866 }
867
--- src/diff.c
+++ src/diff.c
@@ -633,10 +633,12 @@
633 int n; /* Number of bytes (omitting trailing space and \n) */
634 const char *zSrc; /* Tag showing origin of this line */
635 } *aOrig;
636 int nOrig; /* Number of elements in aOrig[] */
637 int nNoSrc; /* Number of entries where aOrig[].zSrc==NULL */
638 int nVers; /* Number of versions analyzed */
639 char **azVers; /* Names of versions analyzed */
640 };
641
642 /*
643 ** Initialize the annotation process by specifying the file that is
644 ** to be annotated. The annotator takes control of the input Blob and
@@ -739,11 +741,17 @@
741 /*
742 ** Compute a complete annotation on a file. The file is identified
743 ** by its filename number (filename.fnid) and the baseline in which
744 ** it was checked in (mlink.mid).
745 */
746 static void annotate_file(
747 Annotator *p, /* The annotator */
748 int fnid, /* The name of the file to be annotated */
749 int mid, /* The specific version of the file for this step */
750 int webLabel, /* Use web-style annotations if true */
751 int iLimit /* Limit the number of levels if greater than zero */
752 ){
753 Blob toAnnotate; /* Text of the final version of the file */
754 Blob step; /* Text of previous revision */
755 int rid; /* Artifact ID of the file being annotated */
756 char *zLabel; /* Label to apply to a line */
757 Stmt q; /* Query returning all ancestor versions */
@@ -766,12 +774,14 @@
774 " FROM mlink, blob, event"
775 " WHERE mlink.fnid=%d"
776 " AND mlink.mid IN ok"
777 " AND blob.rid=mlink.mid"
778 " AND event.objid=mlink.mid"
779 " ORDER BY event.mtime DESC"
780 " LIMIT %d",
781 fnid,
782 iLimit>0 ? iLimit : 10000000
783 );
784 while( db_step(&q)==SQLITE_ROW ){
785 int pid = db_column_int(&q, 0);
786 const char *zUuid = db_column_text(&q, 1);
787 const char *zDate = db_column_text(&q, 2);
@@ -782,10 +792,13 @@
792 g.zTop, zUuid, zUuid, zDate, zUser
793 );
794 }else{
795 zLabel = mprintf("%.10s %s %9.9s", zUuid, zDate, zUser);
796 }
797 p->nVers++;
798 p->azVers = fossil_realloc(p->azVers, p->nVers*sizeof(p->azVers[0]) );
799 p->azVers[p->nVers-1] = zLabel;
800 content_get(pid, &step);
801 annotation_step(p, &step, zLabel);
802 blob_reset(&step);
803 }
804 db_finalize(&q);
@@ -801,22 +814,35 @@
814 */
815 void annotation_page(void){
816 int mid;
817 int fnid;
818 int i;
819 int iLimit;
820 Annotator ann;
821
822 login_check_credentials();
823 if( !g.okRead ){ login_needed(); return; }
824 mid = name_to_rid(PD("checkin","0"));
825 fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", P("filename"));
826 if( mid==0 || fnid==0 ){ fossil_redirect_home(); }
827 iLimit = atoi(PD("limit","-1"));
828 if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){
829 fossil_redirect_home();
830 }
831 style_header("File Annotation");
832 annotate_file(&ann, fnid, mid, g.okHistory, iLimit);
833 if( P("log") ){
834 int i;
835 @ <h2>Versions analyzed:</h2>
836 @ <ol>
837 for(i=0; i<ann.nVers; i++){
838 @ <li><tt>%s(ann.azVers[i])</tt></li>
839 }
840 @ </ol>
841 @ <hr>
842 @ <h2>Annotation:</h2>
843 }
844 @ <pre>
845 for(i=0; i<ann.nOrig; i++){
846 ((char*)ann.aOrig[i].z)[ann.aOrig[i].n] = 0;
847 @ %s(ann.aOrig[i].zSrc): %h(ann.aOrig[i].z)
848 }
@@ -829,20 +855,31 @@
855 **
856 ** %fossil annotate FILENAME
857 **
858 ** Output the text of a file with markings to show when each line of
859 ** the file was last modified.
860 **
861 ** Options:
862 ** --limit N Only look backwards in time by N versions
863 ** --log List all versions analyzed
864 */
865 void annotate_cmd(void){
866 int fnid; /* Filename ID */
867 int fid; /* File instance ID */
868 int mid; /* Manifest where file was checked in */
869 Blob treename; /* FILENAME translated to canonical form */
870 char *zFilename; /* Cannonical filename */
871 Annotator ann; /* The annotation of the file */
872 int i; /* Loop counter */
873 const char *zLimit; /* The value to the --limit option */
874 int iLimit; /* How far back in time to look */
875 int showLog; /* True to show the log */
876
877 zLimit = find_option("limit",0,1);
878 if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1";
879 iLimit = atoi(zLimit);
880 showLog = find_option("log",0,0)!=0;
881 db_must_be_within_tree();
882 if (g.argc<3) {
883 usage("FILENAME");
884 }
885 file_tree_name(g.argv[2], &treename, 1);
@@ -857,10 +894,16 @@
894 }
895 mid = db_int(0, "SELECT mid FROM mlink WHERE fid=%d AND fnid=%d", fid, fnid);
896 if( mid==0 ){
897 fossil_panic("unable to find manifest");
898 }
899 annotate_file(&ann, fnid, mid, 0, iLimit);
900 if( showLog ){
901 for(i=0; i<ann.nVers; i++){
902 printf("version %3d: %s\n", i+1, ann.azVers[i]);
903 }
904 printf("---------------------------------------------------\n");
905 }
906 for(i=0; i<ann.nOrig; i++){
907 printf("%s: %.*s\n", ann.aOrig[i].zSrc, ann.aOrig[i].n, ann.aOrig[i].z);
908 }
909 }
910

Keyboard Shortcuts

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