Fossil

Diff
Login

Differences From Artifact [4ce4ad4c57]:

To Artifact [bccc41bfa4]:


331
332
333
334
335
336
337

338
339
340
341
342
343
344
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345







+







  int fShowId = P("showid")!=0;
  Stmt qparent;
  int iTableId = timeline_tableid();
  int tmFlags = 0;            /* Viewing mode */
  const char *zStyle;         /* Viewing mode name */
  const char *zMark;          /* Mark this version of the file */
  int selRid = 0;             /* RID of the marked file version */
  int mxfnid;                 /* Maximum filename.fnid value */

  login_check_credentials();
  if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
  fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
  ridCi = zCI ? name_to_rid_www("ci") : 0;
  if( fnid==0 ){
    style_header("No such file");
390
391
392
393
394
395
396
397

398
399
400
401
402
403
404
391
392
393
394
395
396
397

398
399
400
401
402
403
404
405







-
+







    blob_append_sql(&sql,
      /* The clade(fid,fnid) table is the set of all (fid,fnid) pairs
      ** that should participate in the output.  Clade is computed by
      ** walking the graph of mlink edges.
      */
      "WITH RECURSIVE clade(fid,fnid) AS (\n"
      "  SELECT blob.rid, %d FROM blob\n"         /* %d is fnid */
      "   WHERE blob.uuid=(SELECT uuid FROM files_of_checkin(%Q)\n"
      "   WHERE blob.uuid=(SELECT uuid FROM files_of_checkin(%Q)"
                         " WHERE filename=%Q)\n"  /* %Q is the filename */
      "   UNION\n"
      "  SELECT mlink.fid, mlink.fnid\n"
      "    FROM clade, mlink\n"
      "   WHERE clade.fid=mlink.pid\n"
      "     AND ((mlink.pfnid=0 AND mlink.fnid=clade.fnid)\n"
      "          OR mlink.pfnid=clade.fnid)\n"
475
476
477
478
479
480
481
482


483
484
485
486
487
488
489
476
477
478
479
480
481
482

483
484
485
486
487
488
489
490
491







-
+
+







    ** files are deleted (when they have mlink.fid==0).  If the same file
    ** is deleted in multiple places, we want to show each deletion, so
    ** use a "fake fid" which is derived from the parent-fid for grouping.
    ** The same fake-fid must be used on the graph.
    */
    blob_append_sql(&sql,
      "GROUP BY"
      " CASE WHEN mlink.fid>0 THEN mlink.fid ELSE mlink.pid+1000000000 END\n"
      " CASE WHEN mlink.fid>0 THEN mlink.fid ELSE mlink.pid+1000000000 END,"
      " mlink.fnid\n"
    );
  }
  blob_append_sql(&sql, "ORDER BY event.mtime DESC");
  if( (n = atoi(PD("n","0")))>0 ){
    blob_append_sql(&sql, " LIMIT %d", n);
    url_add_parameter(&url, "n", P("n"));
  }
536
537
538
539
540
541
542

543
544
545


546
547
548

549
550
551
552


553
554

555
556
557
558
559
560
561
538
539
540
541
542
543
544
545
546
547

548
549
550
551

552
553
554
555

556
557
558

559
560
561
562
563
564
565
566







+


-
+
+


-
+



-
+
+

-
+







  if( uBg ){
    blob_append(&title, " (color-coded by user)", -1);
  }
  @ <h2>%b(&title)</h2>
  blob_reset(&title);
  pGraph = graph_init();
  @ <table id="timelineTable%d(iTableId)" class="timelineTable">
  mxfnid = db_int(0, "SELECT max(fnid) FROM filename");
  if( ridFrom ){
    db_prepare(&qparent,
      "SELECT DISTINCT pid FROM mlink"
      "SELECT DISTINCT pid*%d+CASE WHEN pfnid>0 THEN pfnid ELSE fnid END"
      "  FROM mlink"
      " WHERE fid=:fid AND mid=:mid AND pid>0 AND fnid=:fnid"
      "   AND pmid IN (SELECT rid FROM ancestor)"
      " ORDER BY isaux /*sort*/"
      " ORDER BY isaux /*sort*/", mxfnid+1
    );
  }else{
    db_prepare(&qparent,
      "SELECT DISTINCT pid FROM mlink"
      "SELECT DISTINCT pid*%d+CASE WHEN pfnid>0 THEN pfnid ELSE fnid END"
      "  FROM mlink"
      " WHERE fid=:fid AND mid=:mid AND pid>0 AND fnid=:fnid"
      " ORDER BY isaux /*sort*/"
      " ORDER BY isaux /*sort*/", mxfnid+1
    );
  }
  while( db_step(&q)==SQLITE_ROW ){
    const char *zDate = db_column_text(&q, 0);
    const char *zCom = db_column_text(&q, 1);
    const char *zUser = db_column_text(&q, 2);
    int fpid = db_column_int(&q, 3);
585
586
587
588
589
590
591
592


593
594
595
596
597
598
599
590
591
592
593
594
595
596

597
598
599
600
601
602
603
604
605







-
+
+







    db_reset(&qparent);
    if( zBr==0 ) zBr = "trunk";
    if( uBg ){
      zBgClr = hash_color(zUser);
    }else if( brBg || zBgClr==0 || zBgClr[0]==0 ){
      zBgClr = strcmp(zBr,"trunk")==0 ? "" : hash_color(zBr);
    }
    gidx = graph_add_row(pGraph, frid>0 ? frid : fpid+1000000000,
    gidx = graph_add_row(pGraph,
                         frid>0 ? frid*(mxfnid+1)+fnid : fpid+1000000000,
                         nParent, 0, aParent, zBr, zBgClr,
                         zUuid, 0);
    if( strncmp(zDate, zPrevDate, 10) ){
      sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate);
      @ <tr><td>
      @   <div class="divider timelineDate">%s(zPrevDate)</div>
      @ </td><td></td><td></td></tr>
637
638
639
640
641
642
643






644
645
646
647
648
649
650
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662







+
+
+
+
+
+







        @ <td class="timelineDetailCell">
      }
    }
    if( tmFlags & TIMELINE_COMPACT ){
      cgi_printf("<span class='clutter' id='detail-%d'>",frid);
    }
    cgi_printf("<span class='timeline%sDetail'>", zStyle);
    if( pfnid ){
      char *zPrevName = db_text(0,"SELECT name FROM filename WHERE fnid=%d",
                                 pfnid);
      @ <b>Renamed</b> %h(zPrevName) &rarr; %h(zFName).
      fossil_free(zPrevName);
    }
    if( tmFlags & (TIMELINE_COMPACT|TIMELINE_VERBOSE) ) cgi_printf("(");
    if( zUuid && (tmFlags & TIMELINE_VERBOSE)==0 ){
      @ file:&nbsp;%z(href("%R/file?name=%T&ci=%!S",zFName,zCkin))\
      @ [%S(zUuid)]</a>
      if( fShowId ){
        int srcId = delta_source_rid(frid);
        if( srcId>0 ){
663
664
665
666
667
668
669
670

671
672

673
674
675
676
677
678
679
680
681
682
683
684
685
675
676
677
678
679
680
681

682


683






684
685
686
687
688
689
690







-
+
-
-
+
-
-
-
-
-
-







    hyperlink_to_user(zUser, zDate, ",");
    @ branch:&nbsp;%z(href("%R/timeline?t=%T",zBr))%h(zBr)</a>,
    if( tmFlags & (TIMELINE_COMPACT|TIMELINE_VERBOSE) ){
      @ size:&nbsp;%d(szFile))
    }else{
      @ size:&nbsp;%d(szFile)
    }
    if( zUuid && ridTo==0 ){
    if( zUuid && ridTo==0 && nParent==0 ){
      if( nParent==0 ){
        @ <b>Added</b>
      @ <b>Added</b>
      }else if( pfnid ){
        char *zPrevName = db_text(0,"SELECT name FROM filename WHERE fnid=%d",
                                  pfnid);
        @ <b>Renamed</b> from
        @ %z(href("%R/finfo?name=%t", zPrevName))%h(zPrevName)</a>
      }
    }
    if( zUuid==0 ){
      char *zNewName;
      zNewName = db_text(0,
        "SELECT name FROM filename WHERE fnid = "
        "   (SELECT fnid FROM mlink"
        "     WHERE mid=%d"