Fossil SCM

Improvements to /finfo: Show all file rename events. The "rid" for each timeline entry must be a combination of the file-id "fid" and the filename-id "fnid" since either one of those two might change which should result in a new entry on the timeline.

drh 2020-10-19 18:24 trunk
Commit 8c598d7232c227e199612aa305e85d0f9534334077b49d66bbe163ccdff0b0f4
1 file changed +21 -16
+21 -16
--- src/finfo.c
+++ src/finfo.c
@@ -333,10 +333,11 @@
333333
int iTableId = timeline_tableid();
334334
int tmFlags = 0; /* Viewing mode */
335335
const char *zStyle; /* Viewing mode name */
336336
const char *zMark; /* Mark this version of the file */
337337
int selRid = 0; /* RID of the marked file version */
338
+ int mxfnid; /* Maximum filename.fnid value */
338339
339340
login_check_credentials();
340341
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
341342
fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
342343
ridCi = zCI ? name_to_rid_www("ci") : 0;
@@ -392,11 +393,11 @@
392393
** that should participate in the output. Clade is computed by
393394
** walking the graph of mlink edges.
394395
*/
395396
"WITH RECURSIVE clade(fid,fnid) AS (\n"
396397
" SELECT blob.rid, %d FROM blob\n" /* %d is fnid */
397
- " WHERE blob.uuid=(SELECT uuid FROM files_of_checkin(%Q)\n"
398
+ " WHERE blob.uuid=(SELECT uuid FROM files_of_checkin(%Q)"
398399
" WHERE filename=%Q)\n" /* %Q is the filename */
399400
" UNION\n"
400401
" SELECT mlink.fid, mlink.fnid\n"
401402
" FROM clade, mlink\n"
402403
" WHERE clade.fid=mlink.pid\n"
@@ -477,11 +478,12 @@
477478
** use a "fake fid" which is derived from the parent-fid for grouping.
478479
** The same fake-fid must be used on the graph.
479480
*/
480481
blob_append_sql(&sql,
481482
"GROUP BY"
482
- " CASE WHEN mlink.fid>0 THEN mlink.fid ELSE mlink.pid+1000000000 END\n"
483
+ " CASE WHEN mlink.fid>0 THEN mlink.fid ELSE mlink.pid+1000000000 END,"
484
+ " mlink.fnid\n"
483485
);
484486
}
485487
blob_append_sql(&sql, "ORDER BY event.mtime DESC");
486488
if( (n = atoi(PD("n","0")))>0 ){
487489
blob_append_sql(&sql, " LIMIT %d", n);
@@ -538,22 +540,25 @@
538540
}
539541
@ <h2>%b(&title)</h2>
540542
blob_reset(&title);
541543
pGraph = graph_init();
542544
@ <table id="timelineTable%d(iTableId)" class="timelineTable">
545
+ mxfnid = db_int(0, "SELECT max(fnid) FROM filename");
543546
if( ridFrom ){
544547
db_prepare(&qparent,
545
- "SELECT DISTINCT pid FROM mlink"
548
+ "SELECT DISTINCT pid*%d+CASE WHEN pfnid>0 THEN pfnid ELSE fnid END"
549
+ " FROM mlink"
546550
" WHERE fid=:fid AND mid=:mid AND pid>0 AND fnid=:fnid"
547551
" AND pmid IN (SELECT rid FROM ancestor)"
548
- " ORDER BY isaux /*sort*/"
552
+ " ORDER BY isaux /*sort*/", mxfnid+1
549553
);
550554
}else{
551555
db_prepare(&qparent,
552
- "SELECT DISTINCT pid FROM mlink"
556
+ "SELECT DISTINCT pid*%d+CASE WHEN pfnid>0 THEN pfnid ELSE fnid END"
557
+ " FROM mlink"
553558
" WHERE fid=:fid AND mid=:mid AND pid>0 AND fnid=:fnid"
554
- " ORDER BY isaux /*sort*/"
559
+ " ORDER BY isaux /*sort*/", mxfnid+1
555560
);
556561
}
557562
while( db_step(&q)==SQLITE_ROW ){
558563
const char *zDate = db_column_text(&q, 0);
559564
const char *zCom = db_column_text(&q, 1);
@@ -587,11 +592,12 @@
587592
if( uBg ){
588593
zBgClr = hash_color(zUser);
589594
}else if( brBg || zBgClr==0 || zBgClr[0]==0 ){
590595
zBgClr = strcmp(zBr,"trunk")==0 ? "" : hash_color(zBr);
591596
}
592
- gidx = graph_add_row(pGraph, frid>0 ? frid : fpid+1000000000,
597
+ gidx = graph_add_row(pGraph,
598
+ frid>0 ? frid*(mxfnid+1)+fnid : fpid+1000000000,
593599
nParent, 0, aParent, zBr, zBgClr,
594600
zUuid, 0);
595601
if( strncmp(zDate, zPrevDate, 10) ){
596602
sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate);
597603
@ <tr><td>
@@ -639,10 +645,16 @@
639645
}
640646
if( tmFlags & TIMELINE_COMPACT ){
641647
cgi_printf("<span class='clutter' id='detail-%d'>",frid);
642648
}
643649
cgi_printf("<span class='timeline%sDetail'>", zStyle);
650
+ if( pfnid ){
651
+ char *zPrevName = db_text(0,"SELECT name FROM filename WHERE fnid=%d",
652
+ pfnid);
653
+ @ <b>Renamed</b> %h(zPrevName) &rarr; %h(zFName).
654
+ fossil_free(zPrevName);
655
+ }
644656
if( tmFlags & (TIMELINE_COMPACT|TIMELINE_VERBOSE) ) cgi_printf("(");
645657
if( zUuid && (tmFlags & TIMELINE_VERBOSE)==0 ){
646658
@ file:&nbsp;%z(href("%R/file?name=%T&ci=%!S",zFName,zCkin))\
647659
@ [%S(zUuid)]</a>
648660
if( fShowId ){
@@ -665,19 +677,12 @@
665677
if( tmFlags & (TIMELINE_COMPACT|TIMELINE_VERBOSE) ){
666678
@ size:&nbsp;%d(szFile))
667679
}else{
668680
@ size:&nbsp;%d(szFile)
669681
}
670
- if( zUuid && ridTo==0 ){
671
- if( nParent==0 ){
672
- @ <b>Added</b>
673
- }else if( pfnid ){
674
- char *zPrevName = db_text(0,"SELECT name FROM filename WHERE fnid=%d",
675
- pfnid);
676
- @ <b>Renamed</b> from
677
- @ %z(href("%R/finfo?name=%t", zPrevName))%h(zPrevName)</a>
678
- }
682
+ if( zUuid && ridTo==0 && nParent==0 ){
683
+ @ <b>Added</b>
679684
}
680685
if( zUuid==0 ){
681686
char *zNewName;
682687
zNewName = db_text(0,
683688
"SELECT name FROM filename WHERE fnid = "
684689
--- src/finfo.c
+++ src/finfo.c
@@ -333,10 +333,11 @@
333 int iTableId = timeline_tableid();
334 int tmFlags = 0; /* Viewing mode */
335 const char *zStyle; /* Viewing mode name */
336 const char *zMark; /* Mark this version of the file */
337 int selRid = 0; /* RID of the marked file version */
 
338
339 login_check_credentials();
340 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
341 fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
342 ridCi = zCI ? name_to_rid_www("ci") : 0;
@@ -392,11 +393,11 @@
392 ** that should participate in the output. Clade is computed by
393 ** walking the graph of mlink edges.
394 */
395 "WITH RECURSIVE clade(fid,fnid) AS (\n"
396 " SELECT blob.rid, %d FROM blob\n" /* %d is fnid */
397 " WHERE blob.uuid=(SELECT uuid FROM files_of_checkin(%Q)\n"
398 " WHERE filename=%Q)\n" /* %Q is the filename */
399 " UNION\n"
400 " SELECT mlink.fid, mlink.fnid\n"
401 " FROM clade, mlink\n"
402 " WHERE clade.fid=mlink.pid\n"
@@ -477,11 +478,12 @@
477 ** use a "fake fid" which is derived from the parent-fid for grouping.
478 ** The same fake-fid must be used on the graph.
479 */
480 blob_append_sql(&sql,
481 "GROUP BY"
482 " CASE WHEN mlink.fid>0 THEN mlink.fid ELSE mlink.pid+1000000000 END\n"
 
483 );
484 }
485 blob_append_sql(&sql, "ORDER BY event.mtime DESC");
486 if( (n = atoi(PD("n","0")))>0 ){
487 blob_append_sql(&sql, " LIMIT %d", n);
@@ -538,22 +540,25 @@
538 }
539 @ <h2>%b(&title)</h2>
540 blob_reset(&title);
541 pGraph = graph_init();
542 @ <table id="timelineTable%d(iTableId)" class="timelineTable">
 
543 if( ridFrom ){
544 db_prepare(&qparent,
545 "SELECT DISTINCT pid FROM mlink"
 
546 " WHERE fid=:fid AND mid=:mid AND pid>0 AND fnid=:fnid"
547 " AND pmid IN (SELECT rid FROM ancestor)"
548 " ORDER BY isaux /*sort*/"
549 );
550 }else{
551 db_prepare(&qparent,
552 "SELECT DISTINCT pid FROM mlink"
 
553 " WHERE fid=:fid AND mid=:mid AND pid>0 AND fnid=:fnid"
554 " ORDER BY isaux /*sort*/"
555 );
556 }
557 while( db_step(&q)==SQLITE_ROW ){
558 const char *zDate = db_column_text(&q, 0);
559 const char *zCom = db_column_text(&q, 1);
@@ -587,11 +592,12 @@
587 if( uBg ){
588 zBgClr = hash_color(zUser);
589 }else if( brBg || zBgClr==0 || zBgClr[0]==0 ){
590 zBgClr = strcmp(zBr,"trunk")==0 ? "" : hash_color(zBr);
591 }
592 gidx = graph_add_row(pGraph, frid>0 ? frid : fpid+1000000000,
 
593 nParent, 0, aParent, zBr, zBgClr,
594 zUuid, 0);
595 if( strncmp(zDate, zPrevDate, 10) ){
596 sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate);
597 @ <tr><td>
@@ -639,10 +645,16 @@
639 }
640 if( tmFlags & TIMELINE_COMPACT ){
641 cgi_printf("<span class='clutter' id='detail-%d'>",frid);
642 }
643 cgi_printf("<span class='timeline%sDetail'>", zStyle);
 
 
 
 
 
 
644 if( tmFlags & (TIMELINE_COMPACT|TIMELINE_VERBOSE) ) cgi_printf("(");
645 if( zUuid && (tmFlags & TIMELINE_VERBOSE)==0 ){
646 @ file:&nbsp;%z(href("%R/file?name=%T&ci=%!S",zFName,zCkin))\
647 @ [%S(zUuid)]</a>
648 if( fShowId ){
@@ -665,19 +677,12 @@
665 if( tmFlags & (TIMELINE_COMPACT|TIMELINE_VERBOSE) ){
666 @ size:&nbsp;%d(szFile))
667 }else{
668 @ size:&nbsp;%d(szFile)
669 }
670 if( zUuid && ridTo==0 ){
671 if( nParent==0 ){
672 @ <b>Added</b>
673 }else if( pfnid ){
674 char *zPrevName = db_text(0,"SELECT name FROM filename WHERE fnid=%d",
675 pfnid);
676 @ <b>Renamed</b> from
677 @ %z(href("%R/finfo?name=%t", zPrevName))%h(zPrevName)</a>
678 }
679 }
680 if( zUuid==0 ){
681 char *zNewName;
682 zNewName = db_text(0,
683 "SELECT name FROM filename WHERE fnid = "
684
--- src/finfo.c
+++ src/finfo.c
@@ -333,10 +333,11 @@
333 int iTableId = timeline_tableid();
334 int tmFlags = 0; /* Viewing mode */
335 const char *zStyle; /* Viewing mode name */
336 const char *zMark; /* Mark this version of the file */
337 int selRid = 0; /* RID of the marked file version */
338 int mxfnid; /* Maximum filename.fnid value */
339
340 login_check_credentials();
341 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
342 fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
343 ridCi = zCI ? name_to_rid_www("ci") : 0;
@@ -392,11 +393,11 @@
393 ** that should participate in the output. Clade is computed by
394 ** walking the graph of mlink edges.
395 */
396 "WITH RECURSIVE clade(fid,fnid) AS (\n"
397 " SELECT blob.rid, %d FROM blob\n" /* %d is fnid */
398 " WHERE blob.uuid=(SELECT uuid FROM files_of_checkin(%Q)"
399 " WHERE filename=%Q)\n" /* %Q is the filename */
400 " UNION\n"
401 " SELECT mlink.fid, mlink.fnid\n"
402 " FROM clade, mlink\n"
403 " WHERE clade.fid=mlink.pid\n"
@@ -477,11 +478,12 @@
478 ** use a "fake fid" which is derived from the parent-fid for grouping.
479 ** The same fake-fid must be used on the graph.
480 */
481 blob_append_sql(&sql,
482 "GROUP BY"
483 " CASE WHEN mlink.fid>0 THEN mlink.fid ELSE mlink.pid+1000000000 END,"
484 " mlink.fnid\n"
485 );
486 }
487 blob_append_sql(&sql, "ORDER BY event.mtime DESC");
488 if( (n = atoi(PD("n","0")))>0 ){
489 blob_append_sql(&sql, " LIMIT %d", n);
@@ -538,22 +540,25 @@
540 }
541 @ <h2>%b(&title)</h2>
542 blob_reset(&title);
543 pGraph = graph_init();
544 @ <table id="timelineTable%d(iTableId)" class="timelineTable">
545 mxfnid = db_int(0, "SELECT max(fnid) FROM filename");
546 if( ridFrom ){
547 db_prepare(&qparent,
548 "SELECT DISTINCT pid*%d+CASE WHEN pfnid>0 THEN pfnid ELSE fnid END"
549 " FROM mlink"
550 " WHERE fid=:fid AND mid=:mid AND pid>0 AND fnid=:fnid"
551 " AND pmid IN (SELECT rid FROM ancestor)"
552 " ORDER BY isaux /*sort*/", mxfnid+1
553 );
554 }else{
555 db_prepare(&qparent,
556 "SELECT DISTINCT pid*%d+CASE WHEN pfnid>0 THEN pfnid ELSE fnid END"
557 " FROM mlink"
558 " WHERE fid=:fid AND mid=:mid AND pid>0 AND fnid=:fnid"
559 " ORDER BY isaux /*sort*/", mxfnid+1
560 );
561 }
562 while( db_step(&q)==SQLITE_ROW ){
563 const char *zDate = db_column_text(&q, 0);
564 const char *zCom = db_column_text(&q, 1);
@@ -587,11 +592,12 @@
592 if( uBg ){
593 zBgClr = hash_color(zUser);
594 }else if( brBg || zBgClr==0 || zBgClr[0]==0 ){
595 zBgClr = strcmp(zBr,"trunk")==0 ? "" : hash_color(zBr);
596 }
597 gidx = graph_add_row(pGraph,
598 frid>0 ? frid*(mxfnid+1)+fnid : fpid+1000000000,
599 nParent, 0, aParent, zBr, zBgClr,
600 zUuid, 0);
601 if( strncmp(zDate, zPrevDate, 10) ){
602 sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate);
603 @ <tr><td>
@@ -639,10 +645,16 @@
645 }
646 if( tmFlags & TIMELINE_COMPACT ){
647 cgi_printf("<span class='clutter' id='detail-%d'>",frid);
648 }
649 cgi_printf("<span class='timeline%sDetail'>", zStyle);
650 if( pfnid ){
651 char *zPrevName = db_text(0,"SELECT name FROM filename WHERE fnid=%d",
652 pfnid);
653 @ <b>Renamed</b> %h(zPrevName) &rarr; %h(zFName).
654 fossil_free(zPrevName);
655 }
656 if( tmFlags & (TIMELINE_COMPACT|TIMELINE_VERBOSE) ) cgi_printf("(");
657 if( zUuid && (tmFlags & TIMELINE_VERBOSE)==0 ){
658 @ file:&nbsp;%z(href("%R/file?name=%T&ci=%!S",zFName,zCkin))\
659 @ [%S(zUuid)]</a>
660 if( fShowId ){
@@ -665,19 +677,12 @@
677 if( tmFlags & (TIMELINE_COMPACT|TIMELINE_VERBOSE) ){
678 @ size:&nbsp;%d(szFile))
679 }else{
680 @ size:&nbsp;%d(szFile)
681 }
682 if( zUuid && ridTo==0 && nParent==0 ){
683 @ <b>Added</b>
 
 
 
 
 
 
 
684 }
685 if( zUuid==0 ){
686 char *zNewName;
687 zNewName = db_text(0,
688 "SELECT name FROM filename WHERE fnid = "
689

Keyboard Shortcuts

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