Fossil SCM

Merge the latest trunk changes into windows-i18n branch.

drh 2011-05-06 16:55 windows-i18n merge
Commit 59ddd3c8ae134f41fd775c7ba7946452bffd2e65
+22 -8
--- src/branch.c
+++ src/branch.c
@@ -276,18 +276,32 @@
276276
@ reopened)</li>
277277
@ </ol>
278278
style_sidebox_end();
279279
280280
cnt = 0;
281
- db_prepare(&q,
282
- "SELECT DISTINCT value FROM tagxref"
283
- " WHERE tagid=%d AND value NOT NULL"
284
- " AND rid IN leaf"
285
- " AND %s %z"
286
- " ORDER BY value /*sort*/",
287
- TAG_BRANCH, showClosed ? "" : "NOT", leaf_is_closed_sql("tagxref.rid")
288
- );
281
+ if( showClosed ){
282
+ db_prepare(&q,
283
+ "SELECT value FROM tagxref"
284
+ " WHERE tagid=%d AND value NOT NULL "
285
+ "EXCEPT "
286
+ "SELECT value FROM tagxref"
287
+ " WHERE tagid=%d"
288
+ " AND rid IN leaf"
289
+ " AND NOT %z"
290
+ " ORDER BY value /*sort*/",
291
+ TAG_BRANCH, TAG_BRANCH, leaf_is_closed_sql("tagxref.rid")
292
+ );
293
+ }else{
294
+ db_prepare(&q,
295
+ "SELECT DISTINCT value FROM tagxref"
296
+ " WHERE tagid=%d AND value NOT NULL"
297
+ " AND rid IN leaf"
298
+ " AND NOT %z"
299
+ " ORDER BY value /*sort*/",
300
+ TAG_BRANCH, leaf_is_closed_sql("tagxref.rid")
301
+ );
302
+ }
289303
while( db_step(&q)==SQLITE_ROW ){
290304
const char *zBr = db_column_text(&q, 0);
291305
if( cnt==0 ){
292306
if( showClosed ){
293307
@ <h2>Closed Branches:</h2>
294308
--- src/branch.c
+++ src/branch.c
@@ -276,18 +276,32 @@
276 @ reopened)</li>
277 @ </ol>
278 style_sidebox_end();
279
280 cnt = 0;
281 db_prepare(&q,
282 "SELECT DISTINCT value FROM tagxref"
283 " WHERE tagid=%d AND value NOT NULL"
284 " AND rid IN leaf"
285 " AND %s %z"
286 " ORDER BY value /*sort*/",
287 TAG_BRANCH, showClosed ? "" : "NOT", leaf_is_closed_sql("tagxref.rid")
288 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
289 while( db_step(&q)==SQLITE_ROW ){
290 const char *zBr = db_column_text(&q, 0);
291 if( cnt==0 ){
292 if( showClosed ){
293 @ <h2>Closed Branches:</h2>
294
--- src/branch.c
+++ src/branch.c
@@ -276,18 +276,32 @@
276 @ reopened)</li>
277 @ </ol>
278 style_sidebox_end();
279
280 cnt = 0;
281 if( showClosed ){
282 db_prepare(&q,
283 "SELECT value FROM tagxref"
284 " WHERE tagid=%d AND value NOT NULL "
285 "EXCEPT "
286 "SELECT value FROM tagxref"
287 " WHERE tagid=%d"
288 " AND rid IN leaf"
289 " AND NOT %z"
290 " ORDER BY value /*sort*/",
291 TAG_BRANCH, TAG_BRANCH, leaf_is_closed_sql("tagxref.rid")
292 );
293 }else{
294 db_prepare(&q,
295 "SELECT DISTINCT value FROM tagxref"
296 " WHERE tagid=%d AND value NOT NULL"
297 " AND rid IN leaf"
298 " AND NOT %z"
299 " ORDER BY value /*sort*/",
300 TAG_BRANCH, leaf_is_closed_sql("tagxref.rid")
301 );
302 }
303 while( db_step(&q)==SQLITE_ROW ){
304 const char *zBr = db_column_text(&q, 0);
305 if( cnt==0 ){
306 if( showClosed ){
307 @ <h2>Closed Branches:</h2>
308
+22 -8
--- src/branch.c
+++ src/branch.c
@@ -276,18 +276,32 @@
276276
@ reopened)</li>
277277
@ </ol>
278278
style_sidebox_end();
279279
280280
cnt = 0;
281
- db_prepare(&q,
282
- "SELECT DISTINCT value FROM tagxref"
283
- " WHERE tagid=%d AND value NOT NULL"
284
- " AND rid IN leaf"
285
- " AND %s %z"
286
- " ORDER BY value /*sort*/",
287
- TAG_BRANCH, showClosed ? "" : "NOT", leaf_is_closed_sql("tagxref.rid")
288
- );
281
+ if( showClosed ){
282
+ db_prepare(&q,
283
+ "SELECT value FROM tagxref"
284
+ " WHERE tagid=%d AND value NOT NULL "
285
+ "EXCEPT "
286
+ "SELECT value FROM tagxref"
287
+ " WHERE tagid=%d"
288
+ " AND rid IN leaf"
289
+ " AND NOT %z"
290
+ " ORDER BY value /*sort*/",
291
+ TAG_BRANCH, TAG_BRANCH, leaf_is_closed_sql("tagxref.rid")
292
+ );
293
+ }else{
294
+ db_prepare(&q,
295
+ "SELECT DISTINCT value FROM tagxref"
296
+ " WHERE tagid=%d AND value NOT NULL"
297
+ " AND rid IN leaf"
298
+ " AND NOT %z"
299
+ " ORDER BY value /*sort*/",
300
+ TAG_BRANCH, leaf_is_closed_sql("tagxref.rid")
301
+ );
302
+ }
289303
while( db_step(&q)==SQLITE_ROW ){
290304
const char *zBr = db_column_text(&q, 0);
291305
if( cnt==0 ){
292306
if( showClosed ){
293307
@ <h2>Closed Branches:</h2>
294308
--- src/branch.c
+++ src/branch.c
@@ -276,18 +276,32 @@
276 @ reopened)</li>
277 @ </ol>
278 style_sidebox_end();
279
280 cnt = 0;
281 db_prepare(&q,
282 "SELECT DISTINCT value FROM tagxref"
283 " WHERE tagid=%d AND value NOT NULL"
284 " AND rid IN leaf"
285 " AND %s %z"
286 " ORDER BY value /*sort*/",
287 TAG_BRANCH, showClosed ? "" : "NOT", leaf_is_closed_sql("tagxref.rid")
288 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
289 while( db_step(&q)==SQLITE_ROW ){
290 const char *zBr = db_column_text(&q, 0);
291 if( cnt==0 ){
292 if( showClosed ){
293 @ <h2>Closed Branches:</h2>
294
--- src/branch.c
+++ src/branch.c
@@ -276,18 +276,32 @@
276 @ reopened)</li>
277 @ </ol>
278 style_sidebox_end();
279
280 cnt = 0;
281 if( showClosed ){
282 db_prepare(&q,
283 "SELECT value FROM tagxref"
284 " WHERE tagid=%d AND value NOT NULL "
285 "EXCEPT "
286 "SELECT value FROM tagxref"
287 " WHERE tagid=%d"
288 " AND rid IN leaf"
289 " AND NOT %z"
290 " ORDER BY value /*sort*/",
291 TAG_BRANCH, TAG_BRANCH, leaf_is_closed_sql("tagxref.rid")
292 );
293 }else{
294 db_prepare(&q,
295 "SELECT DISTINCT value FROM tagxref"
296 " WHERE tagid=%d AND value NOT NULL"
297 " AND rid IN leaf"
298 " AND NOT %z"
299 " ORDER BY value /*sort*/",
300 TAG_BRANCH, leaf_is_closed_sql("tagxref.rid")
301 );
302 }
303 while( db_step(&q)==SQLITE_ROW ){
304 const char *zBr = db_column_text(&q, 0);
305 if( cnt==0 ){
306 if( showClosed ){
307 @ <h2>Closed Branches:</h2>
308
+63 -9
--- src/diff.c
+++ src/diff.c
@@ -626,17 +626,21 @@
626626
** of the following structure.
627627
*/
628628
typedef struct Annotator Annotator;
629629
struct Annotator {
630630
DContext c; /* The diff-engine context */
631
- struct { /* Lines of the original files... */
631
+ struct AnnLine { /* Lines of the original files... */
632632
const char *z; /* The text of the line */
633
- int n; /* Number of bytes (omitting trailing space and \n) */
633
+ short int n; /* Number of bytes (omitting trailing space and \n) */
634
+ short int iLevel; /* Level at which tag was set */
634635
const char *zSrc; /* Tag showing origin of this line */
635636
} *aOrig;
636637
int nOrig; /* Number of elements in aOrig[] */
637638
int nNoSrc; /* Number of entries where aOrig[].zSrc==NULL */
639
+ int iLevel; /* Current level */
640
+ int nVers; /* Number of versions analyzed */
641
+ char **azVers; /* Names of versions analyzed */
638642
};
639643
640644
/*
641645
** Initialize the annotation process by specifying the file that is
642646
** to be annotated. The annotator takes control of the input Blob and
@@ -668,10 +672,12 @@
668672
** pParent. Memory to hold zPName is leaked.
669673
*/
670674
static int annotation_step(Annotator *p, Blob *pParent, char *zPName){
671675
int i, j;
672676
int lnTo;
677
+ int iPrevLevel;
678
+ int iThisLevel;
673679
674680
/* Prepare the parent file to be diffed */
675681
p->c.aFrom = break_into_lines(blob_str(pParent), blob_size(pParent),
676682
&p->c.nFrom, 1);
677683
if( p->c.aFrom==0 ){
@@ -683,13 +689,20 @@
683689
diff_all(&p->c);
684690
685691
/* Where new lines are inserted on this difference, record the
686692
** zPName as the source of the new line.
687693
*/
694
+ iPrevLevel = p->iLevel;
695
+ p->iLevel++;
696
+ iThisLevel = p->iLevel;
688697
for(i=lnTo=0; i<p->c.nEdit; i+=3){
689
- for(j=0; j<p->c.aEdit[i]; j++, lnTo++){
690
- p->aOrig[lnTo].zSrc = zPName;
698
+ struct AnnLine *x = &p->aOrig[lnTo];
699
+ for(j=0; j<p->c.aEdit[i]; j++, lnTo++, x++){
700
+ if( x->zSrc==0 || x->iLevel==iPrevLevel ){
701
+ x->zSrc = zPName;
702
+ x->iLevel = iThisLevel;
703
+ }
691704
}
692705
lnTo += p->c.aEdit[i+2];
693706
}
694707
695708
/* Clear out the diff results */
@@ -739,11 +752,17 @@
739752
/*
740753
** Compute a complete annotation on a file. The file is identified
741754
** by its filename number (filename.fnid) and the baseline in which
742755
** it was checked in (mlink.mid).
743756
*/
744
-static void annotate_file(Annotator *p, int fnid, int mid, int webLabel){
757
+static void annotate_file(
758
+ Annotator *p, /* The annotator */
759
+ int fnid, /* The name of the file to be annotated */
760
+ int mid, /* The specific version of the file for this step */
761
+ int webLabel, /* Use web-style annotations if true */
762
+ int iLimit /* Limit the number of levels if greater than zero */
763
+){
745764
Blob toAnnotate; /* Text of the final version of the file */
746765
Blob step; /* Text of previous revision */
747766
int rid; /* Artifact ID of the file being annotated */
748767
char *zLabel; /* Label to apply to a line */
749768
Stmt q; /* Query returning all ancestor versions */
@@ -766,12 +785,14 @@
766785
" FROM mlink, blob, event"
767786
" WHERE mlink.fnid=%d"
768787
" AND mlink.mid IN ok"
769788
" AND blob.rid=mlink.mid"
770789
" AND event.objid=mlink.mid"
771
- " ORDER BY event.mtime DESC",
772
- fnid
790
+ " ORDER BY event.mtime DESC"
791
+ " LIMIT %d",
792
+ fnid,
793
+ iLimit>0 ? iLimit : 10000000
773794
);
774795
while( db_step(&q)==SQLITE_ROW ){
775796
int pid = db_column_int(&q, 0);
776797
const char *zUuid = db_column_text(&q, 1);
777798
const char *zDate = db_column_text(&q, 2);
@@ -782,10 +803,13 @@
782803
g.zTop, zUuid, zUuid, zDate, zUser
783804
);
784805
}else{
785806
zLabel = mprintf("%.10s %s %9.9s", zUuid, zDate, zUser);
786807
}
808
+ p->nVers++;
809
+ p->azVers = fossil_realloc(p->azVers, p->nVers*sizeof(p->azVers[0]) );
810
+ p->azVers[p->nVers-1] = zLabel;
787811
content_get(pid, &step);
788812
annotation_step(p, &step, zLabel);
789813
blob_reset(&step);
790814
}
791815
db_finalize(&q);
@@ -801,22 +825,35 @@
801825
*/
802826
void annotation_page(void){
803827
int mid;
804828
int fnid;
805829
int i;
830
+ int iLimit;
806831
Annotator ann;
807832
808833
login_check_credentials();
809834
if( !g.okRead ){ login_needed(); return; }
810835
mid = name_to_rid(PD("checkin","0"));
811836
fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", P("filename"));
812837
if( mid==0 || fnid==0 ){ fossil_redirect_home(); }
838
+ iLimit = atoi(PD("limit","-1"));
813839
if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){
814840
fossil_redirect_home();
815841
}
816842
style_header("File Annotation");
817
- annotate_file(&ann, fnid, mid, g.okHistory);
843
+ annotate_file(&ann, fnid, mid, g.okHistory, iLimit);
844
+ if( P("log") ){
845
+ int i;
846
+ @ <h2>Versions analyzed:</h2>
847
+ @ <ol>
848
+ for(i=0; i<ann.nVers; i++){
849
+ @ <li><tt>%s(ann.azVers[i])</tt></li>
850
+ }
851
+ @ </ol>
852
+ @ <hr>
853
+ @ <h2>Annotation:</h2>
854
+ }
818855
@ <pre>
819856
for(i=0; i<ann.nOrig; i++){
820857
((char*)ann.aOrig[i].z)[ann.aOrig[i].n] = 0;
821858
@ %s(ann.aOrig[i].zSrc): %h(ann.aOrig[i].z)
822859
}
@@ -829,20 +866,31 @@
829866
**
830867
** %fossil annotate FILENAME
831868
**
832869
** Output the text of a file with markings to show when each line of
833870
** the file was last modified.
871
+**
872
+** Options:
873
+** --limit N Only look backwards in time by N versions
874
+** --log List all versions analyzed
834875
*/
835876
void annotate_cmd(void){
836877
int fnid; /* Filename ID */
837878
int fid; /* File instance ID */
838879
int mid; /* Manifest where file was checked in */
839880
Blob treename; /* FILENAME translated to canonical form */
840881
char *zFilename; /* Cannonical filename */
841882
Annotator ann; /* The annotation of the file */
842883
int i; /* Loop counter */
884
+ const char *zLimit; /* The value to the --limit option */
885
+ int iLimit; /* How far back in time to look */
886
+ int showLog; /* True to show the log */
843887
888
+ zLimit = find_option("limit",0,1);
889
+ if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1";
890
+ iLimit = atoi(zLimit);
891
+ showLog = find_option("log",0,0)!=0;
844892
db_must_be_within_tree();
845893
if (g.argc<3) {
846894
usage("FILENAME");
847895
}
848896
file_tree_name(g.argv[2], &treename, 1);
@@ -857,11 +905,17 @@
857905
}
858906
mid = db_int(0, "SELECT mid FROM mlink WHERE fid=%d AND fnid=%d", fid, fnid);
859907
if( mid==0 ){
860908
fossil_panic("unable to find manifest");
861909
}
862
- annotate_file(&ann, fnid, mid, 0);
910
+ annotate_file(&ann, fnid, mid, 0, iLimit);
911
+ if( showLog ){
912
+ for(i=0; i<ann.nVers; i++){
913
+ printf("version %3d: %s\n", i+1, ann.azVers[i]);
914
+ }
915
+ printf("---------------------------------------------------\n");
916
+ }
863917
for(i=0; i<ann.nOrig; i++){
864918
fossil_print("%s: %.*s\n",
865919
ann.aOrig[i].zSrc, ann.aOrig[i].n, ann.aOrig[i].z);
866920
}
867921
}
868922
--- src/diff.c
+++ src/diff.c
@@ -626,17 +626,21 @@
626 ** of the following structure.
627 */
628 typedef struct Annotator Annotator;
629 struct Annotator {
630 DContext c; /* The diff-engine context */
631 struct { /* Lines of the original files... */
632 const char *z; /* The text of the line */
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
@@ -668,10 +672,12 @@
668 ** pParent. Memory to hold zPName is leaked.
669 */
670 static int annotation_step(Annotator *p, Blob *pParent, char *zPName){
671 int i, j;
672 int lnTo;
 
 
673
674 /* Prepare the parent file to be diffed */
675 p->c.aFrom = break_into_lines(blob_str(pParent), blob_size(pParent),
676 &p->c.nFrom, 1);
677 if( p->c.aFrom==0 ){
@@ -683,13 +689,20 @@
683 diff_all(&p->c);
684
685 /* Where new lines are inserted on this difference, record the
686 ** zPName as the source of the new line.
687 */
 
 
 
688 for(i=lnTo=0; i<p->c.nEdit; i+=3){
689 for(j=0; j<p->c.aEdit[i]; j++, lnTo++){
690 p->aOrig[lnTo].zSrc = zPName;
 
 
 
 
691 }
692 lnTo += p->c.aEdit[i+2];
693 }
694
695 /* Clear out the diff results */
@@ -739,11 +752,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 +785,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 +803,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 +825,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 +866,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,11 +905,17 @@
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 fossil_print("%s: %.*s\n",
865 ann.aOrig[i].zSrc, ann.aOrig[i].n, ann.aOrig[i].z);
866 }
867 }
868
--- src/diff.c
+++ src/diff.c
@@ -626,17 +626,21 @@
626 ** of the following structure.
627 */
628 typedef struct Annotator Annotator;
629 struct Annotator {
630 DContext c; /* The diff-engine context */
631 struct AnnLine { /* Lines of the original files... */
632 const char *z; /* The text of the line */
633 short int n; /* Number of bytes (omitting trailing space and \n) */
634 short int iLevel; /* Level at which tag was set */
635 const char *zSrc; /* Tag showing origin of this line */
636 } *aOrig;
637 int nOrig; /* Number of elements in aOrig[] */
638 int nNoSrc; /* Number of entries where aOrig[].zSrc==NULL */
639 int iLevel; /* Current level */
640 int nVers; /* Number of versions analyzed */
641 char **azVers; /* Names of versions analyzed */
642 };
643
644 /*
645 ** Initialize the annotation process by specifying the file that is
646 ** to be annotated. The annotator takes control of the input Blob and
@@ -668,10 +672,12 @@
672 ** pParent. Memory to hold zPName is leaked.
673 */
674 static int annotation_step(Annotator *p, Blob *pParent, char *zPName){
675 int i, j;
676 int lnTo;
677 int iPrevLevel;
678 int iThisLevel;
679
680 /* Prepare the parent file to be diffed */
681 p->c.aFrom = break_into_lines(blob_str(pParent), blob_size(pParent),
682 &p->c.nFrom, 1);
683 if( p->c.aFrom==0 ){
@@ -683,13 +689,20 @@
689 diff_all(&p->c);
690
691 /* Where new lines are inserted on this difference, record the
692 ** zPName as the source of the new line.
693 */
694 iPrevLevel = p->iLevel;
695 p->iLevel++;
696 iThisLevel = p->iLevel;
697 for(i=lnTo=0; i<p->c.nEdit; i+=3){
698 struct AnnLine *x = &p->aOrig[lnTo];
699 for(j=0; j<p->c.aEdit[i]; j++, lnTo++, x++){
700 if( x->zSrc==0 || x->iLevel==iPrevLevel ){
701 x->zSrc = zPName;
702 x->iLevel = iThisLevel;
703 }
704 }
705 lnTo += p->c.aEdit[i+2];
706 }
707
708 /* Clear out the diff results */
@@ -739,11 +752,17 @@
752 /*
753 ** Compute a complete annotation on a file. The file is identified
754 ** by its filename number (filename.fnid) and the baseline in which
755 ** it was checked in (mlink.mid).
756 */
757 static void annotate_file(
758 Annotator *p, /* The annotator */
759 int fnid, /* The name of the file to be annotated */
760 int mid, /* The specific version of the file for this step */
761 int webLabel, /* Use web-style annotations if true */
762 int iLimit /* Limit the number of levels if greater than zero */
763 ){
764 Blob toAnnotate; /* Text of the final version of the file */
765 Blob step; /* Text of previous revision */
766 int rid; /* Artifact ID of the file being annotated */
767 char *zLabel; /* Label to apply to a line */
768 Stmt q; /* Query returning all ancestor versions */
@@ -766,12 +785,14 @@
785 " FROM mlink, blob, event"
786 " WHERE mlink.fnid=%d"
787 " AND mlink.mid IN ok"
788 " AND blob.rid=mlink.mid"
789 " AND event.objid=mlink.mid"
790 " ORDER BY event.mtime DESC"
791 " LIMIT %d",
792 fnid,
793 iLimit>0 ? iLimit : 10000000
794 );
795 while( db_step(&q)==SQLITE_ROW ){
796 int pid = db_column_int(&q, 0);
797 const char *zUuid = db_column_text(&q, 1);
798 const char *zDate = db_column_text(&q, 2);
@@ -782,10 +803,13 @@
803 g.zTop, zUuid, zUuid, zDate, zUser
804 );
805 }else{
806 zLabel = mprintf("%.10s %s %9.9s", zUuid, zDate, zUser);
807 }
808 p->nVers++;
809 p->azVers = fossil_realloc(p->azVers, p->nVers*sizeof(p->azVers[0]) );
810 p->azVers[p->nVers-1] = zLabel;
811 content_get(pid, &step);
812 annotation_step(p, &step, zLabel);
813 blob_reset(&step);
814 }
815 db_finalize(&q);
@@ -801,22 +825,35 @@
825 */
826 void annotation_page(void){
827 int mid;
828 int fnid;
829 int i;
830 int iLimit;
831 Annotator ann;
832
833 login_check_credentials();
834 if( !g.okRead ){ login_needed(); return; }
835 mid = name_to_rid(PD("checkin","0"));
836 fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", P("filename"));
837 if( mid==0 || fnid==0 ){ fossil_redirect_home(); }
838 iLimit = atoi(PD("limit","-1"));
839 if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){
840 fossil_redirect_home();
841 }
842 style_header("File Annotation");
843 annotate_file(&ann, fnid, mid, g.okHistory, iLimit);
844 if( P("log") ){
845 int i;
846 @ <h2>Versions analyzed:</h2>
847 @ <ol>
848 for(i=0; i<ann.nVers; i++){
849 @ <li><tt>%s(ann.azVers[i])</tt></li>
850 }
851 @ </ol>
852 @ <hr>
853 @ <h2>Annotation:</h2>
854 }
855 @ <pre>
856 for(i=0; i<ann.nOrig; i++){
857 ((char*)ann.aOrig[i].z)[ann.aOrig[i].n] = 0;
858 @ %s(ann.aOrig[i].zSrc): %h(ann.aOrig[i].z)
859 }
@@ -829,20 +866,31 @@
866 **
867 ** %fossil annotate FILENAME
868 **
869 ** Output the text of a file with markings to show when each line of
870 ** the file was last modified.
871 **
872 ** Options:
873 ** --limit N Only look backwards in time by N versions
874 ** --log List all versions analyzed
875 */
876 void annotate_cmd(void){
877 int fnid; /* Filename ID */
878 int fid; /* File instance ID */
879 int mid; /* Manifest where file was checked in */
880 Blob treename; /* FILENAME translated to canonical form */
881 char *zFilename; /* Cannonical filename */
882 Annotator ann; /* The annotation of the file */
883 int i; /* Loop counter */
884 const char *zLimit; /* The value to the --limit option */
885 int iLimit; /* How far back in time to look */
886 int showLog; /* True to show the log */
887
888 zLimit = find_option("limit",0,1);
889 if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1";
890 iLimit = atoi(zLimit);
891 showLog = find_option("log",0,0)!=0;
892 db_must_be_within_tree();
893 if (g.argc<3) {
894 usage("FILENAME");
895 }
896 file_tree_name(g.argv[2], &treename, 1);
@@ -857,11 +905,17 @@
905 }
906 mid = db_int(0, "SELECT mid FROM mlink WHERE fid=%d AND fnid=%d", fid, fnid);
907 if( mid==0 ){
908 fossil_panic("unable to find manifest");
909 }
910 annotate_file(&ann, fnid, mid, 0, iLimit);
911 if( showLog ){
912 for(i=0; i<ann.nVers; i++){
913 printf("version %3d: %s\n", i+1, ann.azVers[i]);
914 }
915 printf("---------------------------------------------------\n");
916 }
917 for(i=0; i<ann.nOrig; i++){
918 fossil_print("%s: %.*s\n",
919 ann.aOrig[i].zSrc, ann.aOrig[i].n, ann.aOrig[i].z);
920 }
921 }
922
+63 -9
--- src/diff.c
+++ src/diff.c
@@ -626,17 +626,21 @@
626626
** of the following structure.
627627
*/
628628
typedef struct Annotator Annotator;
629629
struct Annotator {
630630
DContext c; /* The diff-engine context */
631
- struct { /* Lines of the original files... */
631
+ struct AnnLine { /* Lines of the original files... */
632632
const char *z; /* The text of the line */
633
- int n; /* Number of bytes (omitting trailing space and \n) */
633
+ short int n; /* Number of bytes (omitting trailing space and \n) */
634
+ short int iLevel; /* Level at which tag was set */
634635
const char *zSrc; /* Tag showing origin of this line */
635636
} *aOrig;
636637
int nOrig; /* Number of elements in aOrig[] */
637638
int nNoSrc; /* Number of entries where aOrig[].zSrc==NULL */
639
+ int iLevel; /* Current level */
640
+ int nVers; /* Number of versions analyzed */
641
+ char **azVers; /* Names of versions analyzed */
638642
};
639643
640644
/*
641645
** Initialize the annotation process by specifying the file that is
642646
** to be annotated. The annotator takes control of the input Blob and
@@ -668,10 +672,12 @@
668672
** pParent. Memory to hold zPName is leaked.
669673
*/
670674
static int annotation_step(Annotator *p, Blob *pParent, char *zPName){
671675
int i, j;
672676
int lnTo;
677
+ int iPrevLevel;
678
+ int iThisLevel;
673679
674680
/* Prepare the parent file to be diffed */
675681
p->c.aFrom = break_into_lines(blob_str(pParent), blob_size(pParent),
676682
&p->c.nFrom, 1);
677683
if( p->c.aFrom==0 ){
@@ -683,13 +689,20 @@
683689
diff_all(&p->c);
684690
685691
/* Where new lines are inserted on this difference, record the
686692
** zPName as the source of the new line.
687693
*/
694
+ iPrevLevel = p->iLevel;
695
+ p->iLevel++;
696
+ iThisLevel = p->iLevel;
688697
for(i=lnTo=0; i<p->c.nEdit; i+=3){
689
- for(j=0; j<p->c.aEdit[i]; j++, lnTo++){
690
- p->aOrig[lnTo].zSrc = zPName;
698
+ struct AnnLine *x = &p->aOrig[lnTo];
699
+ for(j=0; j<p->c.aEdit[i]; j++, lnTo++, x++){
700
+ if( x->zSrc==0 || x->iLevel==iPrevLevel ){
701
+ x->zSrc = zPName;
702
+ x->iLevel = iThisLevel;
703
+ }
691704
}
692705
lnTo += p->c.aEdit[i+2];
693706
}
694707
695708
/* Clear out the diff results */
@@ -739,11 +752,17 @@
739752
/*
740753
** Compute a complete annotation on a file. The file is identified
741754
** by its filename number (filename.fnid) and the baseline in which
742755
** it was checked in (mlink.mid).
743756
*/
744
-static void annotate_file(Annotator *p, int fnid, int mid, int webLabel){
757
+static void annotate_file(
758
+ Annotator *p, /* The annotator */
759
+ int fnid, /* The name of the file to be annotated */
760
+ int mid, /* The specific version of the file for this step */
761
+ int webLabel, /* Use web-style annotations if true */
762
+ int iLimit /* Limit the number of levels if greater than zero */
763
+){
745764
Blob toAnnotate; /* Text of the final version of the file */
746765
Blob step; /* Text of previous revision */
747766
int rid; /* Artifact ID of the file being annotated */
748767
char *zLabel; /* Label to apply to a line */
749768
Stmt q; /* Query returning all ancestor versions */
@@ -766,12 +785,14 @@
766785
" FROM mlink, blob, event"
767786
" WHERE mlink.fnid=%d"
768787
" AND mlink.mid IN ok"
769788
" AND blob.rid=mlink.mid"
770789
" AND event.objid=mlink.mid"
771
- " ORDER BY event.mtime DESC",
772
- fnid
790
+ " ORDER BY event.mtime DESC"
791
+ " LIMIT %d",
792
+ fnid,
793
+ iLimit>0 ? iLimit : 10000000
773794
);
774795
while( db_step(&q)==SQLITE_ROW ){
775796
int pid = db_column_int(&q, 0);
776797
const char *zUuid = db_column_text(&q, 1);
777798
const char *zDate = db_column_text(&q, 2);
@@ -782,10 +803,13 @@
782803
g.zTop, zUuid, zUuid, zDate, zUser
783804
);
784805
}else{
785806
zLabel = mprintf("%.10s %s %9.9s", zUuid, zDate, zUser);
786807
}
808
+ p->nVers++;
809
+ p->azVers = fossil_realloc(p->azVers, p->nVers*sizeof(p->azVers[0]) );
810
+ p->azVers[p->nVers-1] = zLabel;
787811
content_get(pid, &step);
788812
annotation_step(p, &step, zLabel);
789813
blob_reset(&step);
790814
}
791815
db_finalize(&q);
@@ -801,22 +825,35 @@
801825
*/
802826
void annotation_page(void){
803827
int mid;
804828
int fnid;
805829
int i;
830
+ int iLimit;
806831
Annotator ann;
807832
808833
login_check_credentials();
809834
if( !g.okRead ){ login_needed(); return; }
810835
mid = name_to_rid(PD("checkin","0"));
811836
fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", P("filename"));
812837
if( mid==0 || fnid==0 ){ fossil_redirect_home(); }
838
+ iLimit = atoi(PD("limit","-1"));
813839
if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){
814840
fossil_redirect_home();
815841
}
816842
style_header("File Annotation");
817
- annotate_file(&ann, fnid, mid, g.okHistory);
843
+ annotate_file(&ann, fnid, mid, g.okHistory, iLimit);
844
+ if( P("log") ){
845
+ int i;
846
+ @ <h2>Versions analyzed:</h2>
847
+ @ <ol>
848
+ for(i=0; i<ann.nVers; i++){
849
+ @ <li><tt>%s(ann.azVers[i])</tt></li>
850
+ }
851
+ @ </ol>
852
+ @ <hr>
853
+ @ <h2>Annotation:</h2>
854
+ }
818855
@ <pre>
819856
for(i=0; i<ann.nOrig; i++){
820857
((char*)ann.aOrig[i].z)[ann.aOrig[i].n] = 0;
821858
@ %s(ann.aOrig[i].zSrc): %h(ann.aOrig[i].z)
822859
}
@@ -829,20 +866,31 @@
829866
**
830867
** %fossil annotate FILENAME
831868
**
832869
** Output the text of a file with markings to show when each line of
833870
** the file was last modified.
871
+**
872
+** Options:
873
+** --limit N Only look backwards in time by N versions
874
+** --log List all versions analyzed
834875
*/
835876
void annotate_cmd(void){
836877
int fnid; /* Filename ID */
837878
int fid; /* File instance ID */
838879
int mid; /* Manifest where file was checked in */
839880
Blob treename; /* FILENAME translated to canonical form */
840881
char *zFilename; /* Cannonical filename */
841882
Annotator ann; /* The annotation of the file */
842883
int i; /* Loop counter */
884
+ const char *zLimit; /* The value to the --limit option */
885
+ int iLimit; /* How far back in time to look */
886
+ int showLog; /* True to show the log */
843887
888
+ zLimit = find_option("limit",0,1);
889
+ if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1";
890
+ iLimit = atoi(zLimit);
891
+ showLog = find_option("log",0,0)!=0;
844892
db_must_be_within_tree();
845893
if (g.argc<3) {
846894
usage("FILENAME");
847895
}
848896
file_tree_name(g.argv[2], &treename, 1);
@@ -857,11 +905,17 @@
857905
}
858906
mid = db_int(0, "SELECT mid FROM mlink WHERE fid=%d AND fnid=%d", fid, fnid);
859907
if( mid==0 ){
860908
fossil_panic("unable to find manifest");
861909
}
862
- annotate_file(&ann, fnid, mid, 0);
910
+ annotate_file(&ann, fnid, mid, 0, iLimit);
911
+ if( showLog ){
912
+ for(i=0; i<ann.nVers; i++){
913
+ printf("version %3d: %s\n", i+1, ann.azVers[i]);
914
+ }
915
+ printf("---------------------------------------------------\n");
916
+ }
863917
for(i=0; i<ann.nOrig; i++){
864918
fossil_print("%s: %.*s\n",
865919
ann.aOrig[i].zSrc, ann.aOrig[i].n, ann.aOrig[i].z);
866920
}
867921
}
868922
--- src/diff.c
+++ src/diff.c
@@ -626,17 +626,21 @@
626 ** of the following structure.
627 */
628 typedef struct Annotator Annotator;
629 struct Annotator {
630 DContext c; /* The diff-engine context */
631 struct { /* Lines of the original files... */
632 const char *z; /* The text of the line */
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
@@ -668,10 +672,12 @@
668 ** pParent. Memory to hold zPName is leaked.
669 */
670 static int annotation_step(Annotator *p, Blob *pParent, char *zPName){
671 int i, j;
672 int lnTo;
 
 
673
674 /* Prepare the parent file to be diffed */
675 p->c.aFrom = break_into_lines(blob_str(pParent), blob_size(pParent),
676 &p->c.nFrom, 1);
677 if( p->c.aFrom==0 ){
@@ -683,13 +689,20 @@
683 diff_all(&p->c);
684
685 /* Where new lines are inserted on this difference, record the
686 ** zPName as the source of the new line.
687 */
 
 
 
688 for(i=lnTo=0; i<p->c.nEdit; i+=3){
689 for(j=0; j<p->c.aEdit[i]; j++, lnTo++){
690 p->aOrig[lnTo].zSrc = zPName;
 
 
 
 
691 }
692 lnTo += p->c.aEdit[i+2];
693 }
694
695 /* Clear out the diff results */
@@ -739,11 +752,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 +785,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 +803,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 +825,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 +866,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,11 +905,17 @@
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 fossil_print("%s: %.*s\n",
865 ann.aOrig[i].zSrc, ann.aOrig[i].n, ann.aOrig[i].z);
866 }
867 }
868
--- src/diff.c
+++ src/diff.c
@@ -626,17 +626,21 @@
626 ** of the following structure.
627 */
628 typedef struct Annotator Annotator;
629 struct Annotator {
630 DContext c; /* The diff-engine context */
631 struct AnnLine { /* Lines of the original files... */
632 const char *z; /* The text of the line */
633 short int n; /* Number of bytes (omitting trailing space and \n) */
634 short int iLevel; /* Level at which tag was set */
635 const char *zSrc; /* Tag showing origin of this line */
636 } *aOrig;
637 int nOrig; /* Number of elements in aOrig[] */
638 int nNoSrc; /* Number of entries where aOrig[].zSrc==NULL */
639 int iLevel; /* Current level */
640 int nVers; /* Number of versions analyzed */
641 char **azVers; /* Names of versions analyzed */
642 };
643
644 /*
645 ** Initialize the annotation process by specifying the file that is
646 ** to be annotated. The annotator takes control of the input Blob and
@@ -668,10 +672,12 @@
672 ** pParent. Memory to hold zPName is leaked.
673 */
674 static int annotation_step(Annotator *p, Blob *pParent, char *zPName){
675 int i, j;
676 int lnTo;
677 int iPrevLevel;
678 int iThisLevel;
679
680 /* Prepare the parent file to be diffed */
681 p->c.aFrom = break_into_lines(blob_str(pParent), blob_size(pParent),
682 &p->c.nFrom, 1);
683 if( p->c.aFrom==0 ){
@@ -683,13 +689,20 @@
689 diff_all(&p->c);
690
691 /* Where new lines are inserted on this difference, record the
692 ** zPName as the source of the new line.
693 */
694 iPrevLevel = p->iLevel;
695 p->iLevel++;
696 iThisLevel = p->iLevel;
697 for(i=lnTo=0; i<p->c.nEdit; i+=3){
698 struct AnnLine *x = &p->aOrig[lnTo];
699 for(j=0; j<p->c.aEdit[i]; j++, lnTo++, x++){
700 if( x->zSrc==0 || x->iLevel==iPrevLevel ){
701 x->zSrc = zPName;
702 x->iLevel = iThisLevel;
703 }
704 }
705 lnTo += p->c.aEdit[i+2];
706 }
707
708 /* Clear out the diff results */
@@ -739,11 +752,17 @@
752 /*
753 ** Compute a complete annotation on a file. The file is identified
754 ** by its filename number (filename.fnid) and the baseline in which
755 ** it was checked in (mlink.mid).
756 */
757 static void annotate_file(
758 Annotator *p, /* The annotator */
759 int fnid, /* The name of the file to be annotated */
760 int mid, /* The specific version of the file for this step */
761 int webLabel, /* Use web-style annotations if true */
762 int iLimit /* Limit the number of levels if greater than zero */
763 ){
764 Blob toAnnotate; /* Text of the final version of the file */
765 Blob step; /* Text of previous revision */
766 int rid; /* Artifact ID of the file being annotated */
767 char *zLabel; /* Label to apply to a line */
768 Stmt q; /* Query returning all ancestor versions */
@@ -766,12 +785,14 @@
785 " FROM mlink, blob, event"
786 " WHERE mlink.fnid=%d"
787 " AND mlink.mid IN ok"
788 " AND blob.rid=mlink.mid"
789 " AND event.objid=mlink.mid"
790 " ORDER BY event.mtime DESC"
791 " LIMIT %d",
792 fnid,
793 iLimit>0 ? iLimit : 10000000
794 );
795 while( db_step(&q)==SQLITE_ROW ){
796 int pid = db_column_int(&q, 0);
797 const char *zUuid = db_column_text(&q, 1);
798 const char *zDate = db_column_text(&q, 2);
@@ -782,10 +803,13 @@
803 g.zTop, zUuid, zUuid, zDate, zUser
804 );
805 }else{
806 zLabel = mprintf("%.10s %s %9.9s", zUuid, zDate, zUser);
807 }
808 p->nVers++;
809 p->azVers = fossil_realloc(p->azVers, p->nVers*sizeof(p->azVers[0]) );
810 p->azVers[p->nVers-1] = zLabel;
811 content_get(pid, &step);
812 annotation_step(p, &step, zLabel);
813 blob_reset(&step);
814 }
815 db_finalize(&q);
@@ -801,22 +825,35 @@
825 */
826 void annotation_page(void){
827 int mid;
828 int fnid;
829 int i;
830 int iLimit;
831 Annotator ann;
832
833 login_check_credentials();
834 if( !g.okRead ){ login_needed(); return; }
835 mid = name_to_rid(PD("checkin","0"));
836 fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", P("filename"));
837 if( mid==0 || fnid==0 ){ fossil_redirect_home(); }
838 iLimit = atoi(PD("limit","-1"));
839 if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){
840 fossil_redirect_home();
841 }
842 style_header("File Annotation");
843 annotate_file(&ann, fnid, mid, g.okHistory, iLimit);
844 if( P("log") ){
845 int i;
846 @ <h2>Versions analyzed:</h2>
847 @ <ol>
848 for(i=0; i<ann.nVers; i++){
849 @ <li><tt>%s(ann.azVers[i])</tt></li>
850 }
851 @ </ol>
852 @ <hr>
853 @ <h2>Annotation:</h2>
854 }
855 @ <pre>
856 for(i=0; i<ann.nOrig; i++){
857 ((char*)ann.aOrig[i].z)[ann.aOrig[i].n] = 0;
858 @ %s(ann.aOrig[i].zSrc): %h(ann.aOrig[i].z)
859 }
@@ -829,20 +866,31 @@
866 **
867 ** %fossil annotate FILENAME
868 **
869 ** Output the text of a file with markings to show when each line of
870 ** the file was last modified.
871 **
872 ** Options:
873 ** --limit N Only look backwards in time by N versions
874 ** --log List all versions analyzed
875 */
876 void annotate_cmd(void){
877 int fnid; /* Filename ID */
878 int fid; /* File instance ID */
879 int mid; /* Manifest where file was checked in */
880 Blob treename; /* FILENAME translated to canonical form */
881 char *zFilename; /* Cannonical filename */
882 Annotator ann; /* The annotation of the file */
883 int i; /* Loop counter */
884 const char *zLimit; /* The value to the --limit option */
885 int iLimit; /* How far back in time to look */
886 int showLog; /* True to show the log */
887
888 zLimit = find_option("limit",0,1);
889 if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1";
890 iLimit = atoi(zLimit);
891 showLog = find_option("log",0,0)!=0;
892 db_must_be_within_tree();
893 if (g.argc<3) {
894 usage("FILENAME");
895 }
896 file_tree_name(g.argv[2], &treename, 1);
@@ -857,11 +905,17 @@
905 }
906 mid = db_int(0, "SELECT mid FROM mlink WHERE fid=%d AND fnid=%d", fid, fnid);
907 if( mid==0 ){
908 fossil_panic("unable to find manifest");
909 }
910 annotate_file(&ann, fnid, mid, 0, iLimit);
911 if( showLog ){
912 for(i=0; i<ann.nVers; i++){
913 printf("version %3d: %s\n", i+1, ann.azVers[i]);
914 }
915 printf("---------------------------------------------------\n");
916 }
917 for(i=0; i<ann.nOrig; i++){
918 fossil_print("%s: %.*s\n",
919 ann.aOrig[i].zSrc, ann.aOrig[i].n, ann.aOrig[i].z);
920 }
921 }
922
+7 -2
--- src/info.c
+++ src/info.c
@@ -949,16 +949,20 @@
949949
*/
950950
void diff_page(void){
951951
int v1, v2;
952952
int isPatch;
953953
Blob c1, c2, diff, *pOut;
954
+ char *zV1;
955
+ char *zV2;
954956
955957
login_check_credentials();
956958
if( !g.okRead ){ login_needed(); return; }
957959
v1 = name_to_rid_www("v1");
958960
v2 = name_to_rid_www("v2");
959961
if( v1==0 || v2==0 ) fossil_redirect_home();
962
+ zV1 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v1);
963
+ zV2 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v2);
960964
isPatch = P("patch")!=0;
961965
if( isPatch ){
962966
pOut = cgi_output_blob();
963967
cgi_set_content_type("text/plain");
964968
}else{
@@ -972,15 +976,16 @@
972976
blob_reset(&c2);
973977
if( !isPatch ){
974978
style_header("Diff");
975979
style_submenu_element("Patch", "Patch", "%s/fdiff?v1=%T&v2=%T&patch",
976980
g.zTop, P("v1"), P("v2"));
977
- @ <h2>Differences From:</h2>
981
+ @ <h2>Differences From
982
+ @ Artifact <a href="%s(g.zTop)/artifact/%S(zV1)">[%S(zV1)]</a>:</h2>
978983
@ <blockquote><p>
979984
object_description(v1, 1, 0);
980985
@ </p></blockquote>
981
- @ <h2>To:</h2>
986
+ @ <h2>To Artifact <a href="%s(g.zTop)/artifact/%S(zV2)">[%S(zV2)]</a>:</h2>
982987
@ <blockquote><p>
983988
object_description(v2, 1, 0);
984989
@ </p></blockquote>
985990
@ <hr />
986991
@ <blockquote><pre>
987992
--- src/info.c
+++ src/info.c
@@ -949,16 +949,20 @@
949 */
950 void diff_page(void){
951 int v1, v2;
952 int isPatch;
953 Blob c1, c2, diff, *pOut;
 
 
954
955 login_check_credentials();
956 if( !g.okRead ){ login_needed(); return; }
957 v1 = name_to_rid_www("v1");
958 v2 = name_to_rid_www("v2");
959 if( v1==0 || v2==0 ) fossil_redirect_home();
 
 
960 isPatch = P("patch")!=0;
961 if( isPatch ){
962 pOut = cgi_output_blob();
963 cgi_set_content_type("text/plain");
964 }else{
@@ -972,15 +976,16 @@
972 blob_reset(&c2);
973 if( !isPatch ){
974 style_header("Diff");
975 style_submenu_element("Patch", "Patch", "%s/fdiff?v1=%T&v2=%T&patch",
976 g.zTop, P("v1"), P("v2"));
977 @ <h2>Differences From:</h2>
 
978 @ <blockquote><p>
979 object_description(v1, 1, 0);
980 @ </p></blockquote>
981 @ <h2>To:</h2>
982 @ <blockquote><p>
983 object_description(v2, 1, 0);
984 @ </p></blockquote>
985 @ <hr />
986 @ <blockquote><pre>
987
--- src/info.c
+++ src/info.c
@@ -949,16 +949,20 @@
949 */
950 void diff_page(void){
951 int v1, v2;
952 int isPatch;
953 Blob c1, c2, diff, *pOut;
954 char *zV1;
955 char *zV2;
956
957 login_check_credentials();
958 if( !g.okRead ){ login_needed(); return; }
959 v1 = name_to_rid_www("v1");
960 v2 = name_to_rid_www("v2");
961 if( v1==0 || v2==0 ) fossil_redirect_home();
962 zV1 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v1);
963 zV2 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v2);
964 isPatch = P("patch")!=0;
965 if( isPatch ){
966 pOut = cgi_output_blob();
967 cgi_set_content_type("text/plain");
968 }else{
@@ -972,15 +976,16 @@
976 blob_reset(&c2);
977 if( !isPatch ){
978 style_header("Diff");
979 style_submenu_element("Patch", "Patch", "%s/fdiff?v1=%T&v2=%T&patch",
980 g.zTop, P("v1"), P("v2"));
981 @ <h2>Differences From
982 @ Artifact <a href="%s(g.zTop)/artifact/%S(zV1)">[%S(zV1)]</a>:</h2>
983 @ <blockquote><p>
984 object_description(v1, 1, 0);
985 @ </p></blockquote>
986 @ <h2>To Artifact <a href="%s(g.zTop)/artifact/%S(zV2)">[%S(zV2)]</a>:</h2>
987 @ <blockquote><p>
988 object_description(v2, 1, 0);
989 @ </p></blockquote>
990 @ <hr />
991 @ <blockquote><pre>
992
+7 -2
--- src/info.c
+++ src/info.c
@@ -949,16 +949,20 @@
949949
*/
950950
void diff_page(void){
951951
int v1, v2;
952952
int isPatch;
953953
Blob c1, c2, diff, *pOut;
954
+ char *zV1;
955
+ char *zV2;
954956
955957
login_check_credentials();
956958
if( !g.okRead ){ login_needed(); return; }
957959
v1 = name_to_rid_www("v1");
958960
v2 = name_to_rid_www("v2");
959961
if( v1==0 || v2==0 ) fossil_redirect_home();
962
+ zV1 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v1);
963
+ zV2 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v2);
960964
isPatch = P("patch")!=0;
961965
if( isPatch ){
962966
pOut = cgi_output_blob();
963967
cgi_set_content_type("text/plain");
964968
}else{
@@ -972,15 +976,16 @@
972976
blob_reset(&c2);
973977
if( !isPatch ){
974978
style_header("Diff");
975979
style_submenu_element("Patch", "Patch", "%s/fdiff?v1=%T&v2=%T&patch",
976980
g.zTop, P("v1"), P("v2"));
977
- @ <h2>Differences From:</h2>
981
+ @ <h2>Differences From
982
+ @ Artifact <a href="%s(g.zTop)/artifact/%S(zV1)">[%S(zV1)]</a>:</h2>
978983
@ <blockquote><p>
979984
object_description(v1, 1, 0);
980985
@ </p></blockquote>
981
- @ <h2>To:</h2>
986
+ @ <h2>To Artifact <a href="%s(g.zTop)/artifact/%S(zV2)">[%S(zV2)]</a>:</h2>
982987
@ <blockquote><p>
983988
object_description(v2, 1, 0);
984989
@ </p></blockquote>
985990
@ <hr />
986991
@ <blockquote><pre>
987992
--- src/info.c
+++ src/info.c
@@ -949,16 +949,20 @@
949 */
950 void diff_page(void){
951 int v1, v2;
952 int isPatch;
953 Blob c1, c2, diff, *pOut;
 
 
954
955 login_check_credentials();
956 if( !g.okRead ){ login_needed(); return; }
957 v1 = name_to_rid_www("v1");
958 v2 = name_to_rid_www("v2");
959 if( v1==0 || v2==0 ) fossil_redirect_home();
 
 
960 isPatch = P("patch")!=0;
961 if( isPatch ){
962 pOut = cgi_output_blob();
963 cgi_set_content_type("text/plain");
964 }else{
@@ -972,15 +976,16 @@
972 blob_reset(&c2);
973 if( !isPatch ){
974 style_header("Diff");
975 style_submenu_element("Patch", "Patch", "%s/fdiff?v1=%T&v2=%T&patch",
976 g.zTop, P("v1"), P("v2"));
977 @ <h2>Differences From:</h2>
 
978 @ <blockquote><p>
979 object_description(v1, 1, 0);
980 @ </p></blockquote>
981 @ <h2>To:</h2>
982 @ <blockquote><p>
983 object_description(v2, 1, 0);
984 @ </p></blockquote>
985 @ <hr />
986 @ <blockquote><pre>
987
--- src/info.c
+++ src/info.c
@@ -949,16 +949,20 @@
949 */
950 void diff_page(void){
951 int v1, v2;
952 int isPatch;
953 Blob c1, c2, diff, *pOut;
954 char *zV1;
955 char *zV2;
956
957 login_check_credentials();
958 if( !g.okRead ){ login_needed(); return; }
959 v1 = name_to_rid_www("v1");
960 v2 = name_to_rid_www("v2");
961 if( v1==0 || v2==0 ) fossil_redirect_home();
962 zV1 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v1);
963 zV2 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v2);
964 isPatch = P("patch")!=0;
965 if( isPatch ){
966 pOut = cgi_output_blob();
967 cgi_set_content_type("text/plain");
968 }else{
@@ -972,15 +976,16 @@
976 blob_reset(&c2);
977 if( !isPatch ){
978 style_header("Diff");
979 style_submenu_element("Patch", "Patch", "%s/fdiff?v1=%T&v2=%T&patch",
980 g.zTop, P("v1"), P("v2"));
981 @ <h2>Differences From
982 @ Artifact <a href="%s(g.zTop)/artifact/%S(zV1)">[%S(zV1)]</a>:</h2>
983 @ <blockquote><p>
984 object_description(v1, 1, 0);
985 @ </p></blockquote>
986 @ <h2>To Artifact <a href="%s(g.zTop)/artifact/%S(zV2)">[%S(zV2)]</a>:</h2>
987 @ <blockquote><p>
988 object_description(v2, 1, 0);
989 @ </p></blockquote>
990 @ <hr />
991 @ <blockquote><pre>
992
+2 -2
--- src/vfile.c
+++ src/vfile.c
@@ -301,15 +301,15 @@
301301
*/
302302
int vfile_top_of_checkout(const char *zPath){
303303
char *zFile;
304304
int fileFound = 0;
305305
306
- zFile = mprintf("%s/_FOSSIL_");
306
+ zFile = mprintf("%s/_FOSSIL_", zPath);
307307
fileFound = file_size(zFile)>=1024;
308308
fossil_free(zFile);
309309
if( !fileFound ){
310
- zFile = mprintf("%s/.fos");
310
+ zFile = mprintf("%s/.fos", zPath);
311311
fileFound = file_size(zFile)>=1024;
312312
fossil_free(zFile);
313313
}
314314
return fileFound;
315315
}
316316
--- src/vfile.c
+++ src/vfile.c
@@ -301,15 +301,15 @@
301 */
302 int vfile_top_of_checkout(const char *zPath){
303 char *zFile;
304 int fileFound = 0;
305
306 zFile = mprintf("%s/_FOSSIL_");
307 fileFound = file_size(zFile)>=1024;
308 fossil_free(zFile);
309 if( !fileFound ){
310 zFile = mprintf("%s/.fos");
311 fileFound = file_size(zFile)>=1024;
312 fossil_free(zFile);
313 }
314 return fileFound;
315 }
316
--- src/vfile.c
+++ src/vfile.c
@@ -301,15 +301,15 @@
301 */
302 int vfile_top_of_checkout(const char *zPath){
303 char *zFile;
304 int fileFound = 0;
305
306 zFile = mprintf("%s/_FOSSIL_", zPath);
307 fileFound = file_size(zFile)>=1024;
308 fossil_free(zFile);
309 if( !fileFound ){
310 zFile = mprintf("%s/.fos", zPath);
311 fileFound = file_size(zFile)>=1024;
312 fossil_free(zFile);
313 }
314 return fileFound;
315 }
316
+2 -2
--- src/vfile.c
+++ src/vfile.c
@@ -301,15 +301,15 @@
301301
*/
302302
int vfile_top_of_checkout(const char *zPath){
303303
char *zFile;
304304
int fileFound = 0;
305305
306
- zFile = mprintf("%s/_FOSSIL_");
306
+ zFile = mprintf("%s/_FOSSIL_", zPath);
307307
fileFound = file_size(zFile)>=1024;
308308
fossil_free(zFile);
309309
if( !fileFound ){
310
- zFile = mprintf("%s/.fos");
310
+ zFile = mprintf("%s/.fos", zPath);
311311
fileFound = file_size(zFile)>=1024;
312312
fossil_free(zFile);
313313
}
314314
return fileFound;
315315
}
316316
--- src/vfile.c
+++ src/vfile.c
@@ -301,15 +301,15 @@
301 */
302 int vfile_top_of_checkout(const char *zPath){
303 char *zFile;
304 int fileFound = 0;
305
306 zFile = mprintf("%s/_FOSSIL_");
307 fileFound = file_size(zFile)>=1024;
308 fossil_free(zFile);
309 if( !fileFound ){
310 zFile = mprintf("%s/.fos");
311 fileFound = file_size(zFile)>=1024;
312 fossil_free(zFile);
313 }
314 return fileFound;
315 }
316
--- src/vfile.c
+++ src/vfile.c
@@ -301,15 +301,15 @@
301 */
302 int vfile_top_of_checkout(const char *zPath){
303 char *zFile;
304 int fileFound = 0;
305
306 zFile = mprintf("%s/_FOSSIL_", zPath);
307 fileFound = file_size(zFile)>=1024;
308 fossil_free(zFile);
309 if( !fileFound ){
310 zFile = mprintf("%s/.fos", zPath);
311 fileFound = file_size(zFile)>=1024;
312 fossil_free(zFile);
313 }
314 return fileFound;
315 }
316

Keyboard Shortcuts

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