Fossil SCM
merged in trunk [fda7c2c63d] for side-by-side diffs.
Commit
571f3aca5bdb5275805c7dc1b1d544fc46de0648
Parent
8da8432630de964…
22 files changed
+1
-1
+1
-1
-2
+184
+1
-3
+114
-23
+1
-1
+1
-1
+38
+18
-4
+3
-19
+3
-19
+1
-1
+205
-1
+59
+28
-12
+28
-12
-2
-2
+19
-8
+1
-3
+1
-4
~
src/cgi.c
~
src/cgi.c
~
src/checkin.c
~
src/diff.c
~
src/http_transport.c
~
src/info.c
~
src/json_artifact.c
+
src/json_artifact.c
~
src/manifest.c
~
src/merge.c
~
src/report.c
~
src/report.c
~
src/schema.c
~
src/skins.c
~
src/style.c
~
src/timeline.c
~
src/timeline.c
~
src/tkt.c
~
src/tkt.c
~
src/update.c
~
src/wikiformat.c
~
src/xfer.c
+1
-1
| --- src/cgi.c | ||
| +++ src/cgi.c | ||
| @@ -135,11 +135,11 @@ | ||
| 135 | 135 | } |
| 136 | 136 | |
| 137 | 137 | /* |
| 138 | 138 | ** Return a pointer to the HTTP reply text. |
| 139 | 139 | */ |
| 140 | -char *cgi_extract_content(int *pnAmt){ | |
| 140 | +char *cgi_extract_content(void){ | |
| 141 | 141 | cgi_combine_header_and_body(); |
| 142 | 142 | return blob_buffer(&cgiContent[0]); |
| 143 | 143 | } |
| 144 | 144 | |
| 145 | 145 | /* |
| 146 | 146 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -135,11 +135,11 @@ | |
| 135 | } |
| 136 | |
| 137 | /* |
| 138 | ** Return a pointer to the HTTP reply text. |
| 139 | */ |
| 140 | char *cgi_extract_content(int *pnAmt){ |
| 141 | cgi_combine_header_and_body(); |
| 142 | return blob_buffer(&cgiContent[0]); |
| 143 | } |
| 144 | |
| 145 | /* |
| 146 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -135,11 +135,11 @@ | |
| 135 | } |
| 136 | |
| 137 | /* |
| 138 | ** Return a pointer to the HTTP reply text. |
| 139 | */ |
| 140 | char *cgi_extract_content(void){ |
| 141 | cgi_combine_header_and_body(); |
| 142 | return blob_buffer(&cgiContent[0]); |
| 143 | } |
| 144 | |
| 145 | /* |
| 146 |
+1
-1
| --- src/cgi.c | ||
| +++ src/cgi.c | ||
| @@ -135,11 +135,11 @@ | ||
| 135 | 135 | } |
| 136 | 136 | |
| 137 | 137 | /* |
| 138 | 138 | ** Return a pointer to the HTTP reply text. |
| 139 | 139 | */ |
| 140 | -char *cgi_extract_content(int *pnAmt){ | |
| 140 | +char *cgi_extract_content(void){ | |
| 141 | 141 | cgi_combine_header_and_body(); |
| 142 | 142 | return blob_buffer(&cgiContent[0]); |
| 143 | 143 | } |
| 144 | 144 | |
| 145 | 145 | /* |
| 146 | 146 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -135,11 +135,11 @@ | |
| 135 | } |
| 136 | |
| 137 | /* |
| 138 | ** Return a pointer to the HTTP reply text. |
| 139 | */ |
| 140 | char *cgi_extract_content(int *pnAmt){ |
| 141 | cgi_combine_header_and_body(); |
| 142 | return blob_buffer(&cgiContent[0]); |
| 143 | } |
| 144 | |
| 145 | /* |
| 146 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -135,11 +135,11 @@ | |
| 135 | } |
| 136 | |
| 137 | /* |
| 138 | ** Return a pointer to the HTTP reply text. |
| 139 | */ |
| 140 | char *cgi_extract_content(void){ |
| 141 | cgi_combine_header_and_body(); |
| 142 | return blob_buffer(&cgiContent[0]); |
| 143 | } |
| 144 | |
| 145 | /* |
| 146 |
-2
| --- src/checkin.c | ||
| +++ src/checkin.c | ||
| @@ -282,18 +282,16 @@ | ||
| 282 | 282 | Stmt q; |
| 283 | 283 | int n; |
| 284 | 284 | const char *zIgnoreFlag = find_option("ignore",0,1); |
| 285 | 285 | int allFlag = find_option("dotfiles",0,0)!=0; |
| 286 | 286 | int cwdRelative = 0; |
| 287 | - int outputManifest; | |
| 288 | 287 | Glob *pIgnore; |
| 289 | 288 | Blob rewrittenPathname; |
| 290 | 289 | const char *zPathname, *zDisplayName; |
| 291 | 290 | |
| 292 | 291 | db_must_be_within_tree(); |
| 293 | 292 | cwdRelative = determine_cwd_relative_option(); |
| 294 | - outputManifest = db_get_boolean("manifest",0); | |
| 295 | 293 | db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)"); |
| 296 | 294 | n = strlen(g.zLocalRoot); |
| 297 | 295 | blob_init(&path, g.zLocalRoot, n-1); |
| 298 | 296 | if( zIgnoreFlag==0 ){ |
| 299 | 297 | zIgnoreFlag = db_get("ignore-glob", 0); |
| 300 | 298 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -282,18 +282,16 @@ | |
| 282 | Stmt q; |
| 283 | int n; |
| 284 | const char *zIgnoreFlag = find_option("ignore",0,1); |
| 285 | int allFlag = find_option("dotfiles",0,0)!=0; |
| 286 | int cwdRelative = 0; |
| 287 | int outputManifest; |
| 288 | Glob *pIgnore; |
| 289 | Blob rewrittenPathname; |
| 290 | const char *zPathname, *zDisplayName; |
| 291 | |
| 292 | db_must_be_within_tree(); |
| 293 | cwdRelative = determine_cwd_relative_option(); |
| 294 | outputManifest = db_get_boolean("manifest",0); |
| 295 | db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)"); |
| 296 | n = strlen(g.zLocalRoot); |
| 297 | blob_init(&path, g.zLocalRoot, n-1); |
| 298 | if( zIgnoreFlag==0 ){ |
| 299 | zIgnoreFlag = db_get("ignore-glob", 0); |
| 300 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -282,18 +282,16 @@ | |
| 282 | Stmt q; |
| 283 | int n; |
| 284 | const char *zIgnoreFlag = find_option("ignore",0,1); |
| 285 | int allFlag = find_option("dotfiles",0,0)!=0; |
| 286 | int cwdRelative = 0; |
| 287 | Glob *pIgnore; |
| 288 | Blob rewrittenPathname; |
| 289 | const char *zPathname, *zDisplayName; |
| 290 | |
| 291 | db_must_be_within_tree(); |
| 292 | cwdRelative = determine_cwd_relative_option(); |
| 293 | db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)"); |
| 294 | n = strlen(g.zLocalRoot); |
| 295 | blob_init(&path, g.zLocalRoot, n-1); |
| 296 | if( zIgnoreFlag==0 ){ |
| 297 | zIgnoreFlag = db_get("ignore-glob", 0); |
| 298 |
+184
| --- src/diff.c | ||
| +++ src/diff.c | ||
| @@ -578,10 +578,194 @@ | ||
| 578 | 578 | free(c.aFrom); |
| 579 | 579 | free(c.aTo); |
| 580 | 580 | return c.aEdit; |
| 581 | 581 | } |
| 582 | 582 | } |
| 583 | + | |
| 584 | +/* | |
| 585 | +** Copy a line with a limit. Used for side-by-side diffs to enforce a maximum | |
| 586 | +** line length limit. | |
| 587 | +*/ | |
| 588 | +static char *copylimline(char *out, DLine *dl, int lim){ | |
| 589 | + int len; | |
| 590 | + len = dl->h & LENGTH_MASK; | |
| 591 | + if( lim && len > lim ){ | |
| 592 | + memcpy(out, dl->z, lim-3); | |
| 593 | + strcpy(&out[lim-3], "..."); | |
| 594 | + }else{ | |
| 595 | + memcpy(out, dl->z, len); | |
| 596 | + out[len] = '\0'; | |
| 597 | + } | |
| 598 | + return out; | |
| 599 | +} | |
| 600 | + | |
| 601 | +/* | |
| 602 | +** Output table body of a side-by-side diff. Prior to the call, the caller | |
| 603 | +** should have output: | |
| 604 | +** <table class="sbsdiff"> | |
| 605 | +** <tr><th colspan="2" class="diffhdr">Old title</th><th/> | |
| 606 | +** <th colspan="2" class="diffhdr">New title</th></tr> | |
| 607 | +** | |
| 608 | +** And after the call, it should output: | |
| 609 | +** </table> | |
| 610 | +** | |
| 611 | +** Some good reference diffs in the fossil repository for testing: | |
| 612 | +** /vdiff?from=080d27a&to=4b0f813&detail=1 | |
| 613 | +** /vdiff?from=636804745b&to=c1d78e0556&detail=1 | |
| 614 | +** /vdiff?from=c0b6c28d29&to=25169506b7&detail=1 | |
| 615 | +** /vdiff?from=e3d022dffa&to=48bcfbd47b&detail=1 | |
| 616 | +*/ | |
| 617 | +int html_sbsdiff( | |
| 618 | + Blob *pA_Blob, /* FROM file */ | |
| 619 | + Blob *pB_Blob, /* TO file */ | |
| 620 | + int nContext, /* Amount of context to unified diff */ | |
| 621 | + int ignoreEolWs /* Ignore whitespace at the end of lines */ | |
| 622 | +){ | |
| 623 | + DContext c; | |
| 624 | + int i; | |
| 625 | + int iFrom, iTo; | |
| 626 | + char *linebuf; | |
| 627 | + int collim=0; /* Currently not settable; allows a column limit for diffs */ | |
| 628 | + int allowExp=0; /* Currently not settable; (dis)allow expansion of rows */ | |
| 629 | + | |
| 630 | + /* Prepare the input files */ | |
| 631 | + memset(&c, 0, sizeof(c)); | |
| 632 | + c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob), | |
| 633 | + &c.nFrom, ignoreEolWs); | |
| 634 | + c.aTo = break_into_lines(blob_str(pB_Blob), blob_size(pB_Blob), | |
| 635 | + &c.nTo, ignoreEolWs); | |
| 636 | + if( c.aFrom==0 || c.aTo==0 ){ | |
| 637 | + free(c.aFrom); | |
| 638 | + free(c.aTo); | |
| 639 | + /* Note: This would be generated within a table. */ | |
| 640 | + @ <p class="generalError" style="white-space: nowrap">cannot compute | |
| 641 | + @ difference between binary files</p> | |
| 642 | + return 0; | |
| 643 | + } | |
| 644 | + | |
| 645 | + collim = collim < 4 ? 0 : collim; | |
| 646 | + | |
| 647 | + /* Compute the difference */ | |
| 648 | + diff_all(&c); | |
| 649 | + | |
| 650 | + linebuf = fossil_malloc(LENGTH_MASK+1); | |
| 651 | + if( !linebuf ){ | |
| 652 | + free(c.aFrom); | |
| 653 | + free(c.aTo); | |
| 654 | + free(c.aEdit); | |
| 655 | + return 0; | |
| 656 | + } | |
| 657 | + | |
| 658 | + iFrom=iTo=0; | |
| 659 | + i=0; | |
| 660 | + while( i<c.nEdit ){ | |
| 661 | + int j; | |
| 662 | + /* Copied lines */ | |
| 663 | + for( j=0; j<c.aEdit[i]; j++){ | |
| 664 | + /* Hide lines which are copied and are further away from block boundaries | |
| 665 | + ** than nConext lines. For each block with hidden lines, show a row | |
| 666 | + ** notifying the user about the hidden rows. | |
| 667 | + */ | |
| 668 | + if( j<nContext || j>c.aEdit[i]-nContext-1 ){ | |
| 669 | + @ <tr> | |
| 670 | + }else if( j==nContext && j<c.aEdit[i]-nContext-1 ){ | |
| 671 | + @ <tr> | |
| 672 | + @ <td class="meta" colspan="5" style="white-space: nowrap;"> | |
| 673 | + @ %d(c.aEdit[i]-2*nContext) hidden lines</td> | |
| 674 | + @ </tr> | |
| 675 | + if( !allowExp ) | |
| 676 | + continue; | |
| 677 | + @ <tr style="display:none;"> | |
| 678 | + }else{ | |
| 679 | + if( !allowExp ) | |
| 680 | + continue; | |
| 681 | + @ <tr style="display:none;"> | |
| 682 | + } | |
| 683 | + | |
| 684 | + copylimline(linebuf, &c.aFrom[iFrom+j], collim); | |
| 685 | + @ <td class="lineno">%d(iFrom+j+1)</td> | |
| 686 | + @ <td class="srcline">%h(linebuf)</td> | |
| 687 | + | |
| 688 | + @ <td> </td> | |
| 689 | + | |
| 690 | + copylimline(linebuf, &c.aTo[iTo+j], collim); | |
| 691 | + @ <td class="lineno">%d(iTo+j+1)</td> | |
| 692 | + @ <td class="srcline">%h(linebuf)</td> | |
| 693 | + | |
| 694 | + @ </tr> | |
| 695 | + } | |
| 696 | + iFrom+=c.aEdit[i]; | |
| 697 | + iTo+=c.aEdit[i]; | |
| 698 | + | |
| 699 | + if( c.aEdit[i+1]!=0 && c.aEdit[i+2]!=0 ){ | |
| 700 | + int lim; | |
| 701 | + lim = c.aEdit[i+1] > c.aEdit[i+2] ? c.aEdit[i+1] : c.aEdit[i+2]; | |
| 702 | + | |
| 703 | + /* Assume changed lines */ | |
| 704 | + for( j=0; j<lim; j++ ){ | |
| 705 | + @ <tr> | |
| 706 | + | |
| 707 | + if( j<c.aEdit[i+1] ){ | |
| 708 | + copylimline(linebuf, &c.aFrom[iFrom+j], collim); | |
| 709 | + @ <td class="changed lineno">%d(iFrom+j+1)</td> | |
| 710 | + @ <td class="changed srcline">%h(linebuf)</td> | |
| 711 | + }else{ | |
| 712 | + @ <td colspan="2" class="changedvoid"/> | |
| 713 | + } | |
| 714 | + | |
| 715 | + @ <td class="changed">|</td> | |
| 716 | + | |
| 717 | + if( j<c.aEdit[i+2] ){ | |
| 718 | + copylimline(linebuf, &c.aTo[iTo+j], collim); | |
| 719 | + @ <td class="changed lineno">%d(iTo+j+1)</td> | |
| 720 | + @ <td class="changed srcline">%h(linebuf)</td> | |
| 721 | + }else{ | |
| 722 | + @ <td colspan="2" class="changedvoid"/> | |
| 723 | + } | |
| 724 | + | |
| 725 | + @ </tr> | |
| 726 | + } | |
| 727 | + iFrom+=c.aEdit[i+1]; | |
| 728 | + iTo+=c.aEdit[i+2]; | |
| 729 | + }else{ | |
| 730 | + | |
| 731 | + /* Process deleted lines */ | |
| 732 | + for( j=0; j<c.aEdit[i+1]; j++ ){ | |
| 733 | + @ <tr> | |
| 734 | + | |
| 735 | + copylimline(linebuf, &c.aFrom[iFrom+j], collim); | |
| 736 | + @ <td class="removed lineno">%d(iFrom+j+1)</td> | |
| 737 | + @ <td class="removed srcline">%h(linebuf)</td> | |
| 738 | + @ <td><</td> | |
| 739 | + @ <td colspan="2" class="removedvoid"/> | |
| 740 | + @ </tr> | |
| 741 | + } | |
| 742 | + iFrom+=c.aEdit[i+1]; | |
| 743 | + | |
| 744 | + /* Process inserted lines */ | |
| 745 | + for( j=0; j<c.aEdit[i+2]; j++ ){ | |
| 746 | + @ <tr> | |
| 747 | + @ <td colspan="2" class="addedvoid"/> | |
| 748 | + @ <td>></td> | |
| 749 | + copylimline(linebuf, &c.aTo[iTo+j], collim); | |
| 750 | + @ <td class="added lineno">%d(iTo+j+1)</td> | |
| 751 | + @ <td class="added srcline">%h(linebuf)</td> | |
| 752 | + @ </tr> | |
| 753 | + } | |
| 754 | + iTo+=c.aEdit[i+2]; | |
| 755 | + } | |
| 756 | + | |
| 757 | + i+=3; | |
| 758 | + } | |
| 759 | + | |
| 760 | + free(linebuf); | |
| 761 | + free(c.aFrom); | |
| 762 | + free(c.aTo); | |
| 763 | + free(c.aEdit); | |
| 764 | + return 1; | |
| 765 | +} | |
| 766 | + | |
| 583 | 767 | |
| 584 | 768 | /* |
| 585 | 769 | ** COMMAND: test-rawdiff |
| 586 | 770 | */ |
| 587 | 771 | void test_rawdiff_cmd(void){ |
| 588 | 772 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -578,10 +578,194 @@ | |
| 578 | free(c.aFrom); |
| 579 | free(c.aTo); |
| 580 | return c.aEdit; |
| 581 | } |
| 582 | } |
| 583 | |
| 584 | /* |
| 585 | ** COMMAND: test-rawdiff |
| 586 | */ |
| 587 | void test_rawdiff_cmd(void){ |
| 588 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -578,10 +578,194 @@ | |
| 578 | free(c.aFrom); |
| 579 | free(c.aTo); |
| 580 | return c.aEdit; |
| 581 | } |
| 582 | } |
| 583 | |
| 584 | /* |
| 585 | ** Copy a line with a limit. Used for side-by-side diffs to enforce a maximum |
| 586 | ** line length limit. |
| 587 | */ |
| 588 | static char *copylimline(char *out, DLine *dl, int lim){ |
| 589 | int len; |
| 590 | len = dl->h & LENGTH_MASK; |
| 591 | if( lim && len > lim ){ |
| 592 | memcpy(out, dl->z, lim-3); |
| 593 | strcpy(&out[lim-3], "..."); |
| 594 | }else{ |
| 595 | memcpy(out, dl->z, len); |
| 596 | out[len] = '\0'; |
| 597 | } |
| 598 | return out; |
| 599 | } |
| 600 | |
| 601 | /* |
| 602 | ** Output table body of a side-by-side diff. Prior to the call, the caller |
| 603 | ** should have output: |
| 604 | ** <table class="sbsdiff"> |
| 605 | ** <tr><th colspan="2" class="diffhdr">Old title</th><th/> |
| 606 | ** <th colspan="2" class="diffhdr">New title</th></tr> |
| 607 | ** |
| 608 | ** And after the call, it should output: |
| 609 | ** </table> |
| 610 | ** |
| 611 | ** Some good reference diffs in the fossil repository for testing: |
| 612 | ** /vdiff?from=080d27a&to=4b0f813&detail=1 |
| 613 | ** /vdiff?from=636804745b&to=c1d78e0556&detail=1 |
| 614 | ** /vdiff?from=c0b6c28d29&to=25169506b7&detail=1 |
| 615 | ** /vdiff?from=e3d022dffa&to=48bcfbd47b&detail=1 |
| 616 | */ |
| 617 | int html_sbsdiff( |
| 618 | Blob *pA_Blob, /* FROM file */ |
| 619 | Blob *pB_Blob, /* TO file */ |
| 620 | int nContext, /* Amount of context to unified diff */ |
| 621 | int ignoreEolWs /* Ignore whitespace at the end of lines */ |
| 622 | ){ |
| 623 | DContext c; |
| 624 | int i; |
| 625 | int iFrom, iTo; |
| 626 | char *linebuf; |
| 627 | int collim=0; /* Currently not settable; allows a column limit for diffs */ |
| 628 | int allowExp=0; /* Currently not settable; (dis)allow expansion of rows */ |
| 629 | |
| 630 | /* Prepare the input files */ |
| 631 | memset(&c, 0, sizeof(c)); |
| 632 | c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob), |
| 633 | &c.nFrom, ignoreEolWs); |
| 634 | c.aTo = break_into_lines(blob_str(pB_Blob), blob_size(pB_Blob), |
| 635 | &c.nTo, ignoreEolWs); |
| 636 | if( c.aFrom==0 || c.aTo==0 ){ |
| 637 | free(c.aFrom); |
| 638 | free(c.aTo); |
| 639 | /* Note: This would be generated within a table. */ |
| 640 | @ <p class="generalError" style="white-space: nowrap">cannot compute |
| 641 | @ difference between binary files</p> |
| 642 | return 0; |
| 643 | } |
| 644 | |
| 645 | collim = collim < 4 ? 0 : collim; |
| 646 | |
| 647 | /* Compute the difference */ |
| 648 | diff_all(&c); |
| 649 | |
| 650 | linebuf = fossil_malloc(LENGTH_MASK+1); |
| 651 | if( !linebuf ){ |
| 652 | free(c.aFrom); |
| 653 | free(c.aTo); |
| 654 | free(c.aEdit); |
| 655 | return 0; |
| 656 | } |
| 657 | |
| 658 | iFrom=iTo=0; |
| 659 | i=0; |
| 660 | while( i<c.nEdit ){ |
| 661 | int j; |
| 662 | /* Copied lines */ |
| 663 | for( j=0; j<c.aEdit[i]; j++){ |
| 664 | /* Hide lines which are copied and are further away from block boundaries |
| 665 | ** than nConext lines. For each block with hidden lines, show a row |
| 666 | ** notifying the user about the hidden rows. |
| 667 | */ |
| 668 | if( j<nContext || j>c.aEdit[i]-nContext-1 ){ |
| 669 | @ <tr> |
| 670 | }else if( j==nContext && j<c.aEdit[i]-nContext-1 ){ |
| 671 | @ <tr> |
| 672 | @ <td class="meta" colspan="5" style="white-space: nowrap;"> |
| 673 | @ %d(c.aEdit[i]-2*nContext) hidden lines</td> |
| 674 | @ </tr> |
| 675 | if( !allowExp ) |
| 676 | continue; |
| 677 | @ <tr style="display:none;"> |
| 678 | }else{ |
| 679 | if( !allowExp ) |
| 680 | continue; |
| 681 | @ <tr style="display:none;"> |
| 682 | } |
| 683 | |
| 684 | copylimline(linebuf, &c.aFrom[iFrom+j], collim); |
| 685 | @ <td class="lineno">%d(iFrom+j+1)</td> |
| 686 | @ <td class="srcline">%h(linebuf)</td> |
| 687 | |
| 688 | @ <td> </td> |
| 689 | |
| 690 | copylimline(linebuf, &c.aTo[iTo+j], collim); |
| 691 | @ <td class="lineno">%d(iTo+j+1)</td> |
| 692 | @ <td class="srcline">%h(linebuf)</td> |
| 693 | |
| 694 | @ </tr> |
| 695 | } |
| 696 | iFrom+=c.aEdit[i]; |
| 697 | iTo+=c.aEdit[i]; |
| 698 | |
| 699 | if( c.aEdit[i+1]!=0 && c.aEdit[i+2]!=0 ){ |
| 700 | int lim; |
| 701 | lim = c.aEdit[i+1] > c.aEdit[i+2] ? c.aEdit[i+1] : c.aEdit[i+2]; |
| 702 | |
| 703 | /* Assume changed lines */ |
| 704 | for( j=0; j<lim; j++ ){ |
| 705 | @ <tr> |
| 706 | |
| 707 | if( j<c.aEdit[i+1] ){ |
| 708 | copylimline(linebuf, &c.aFrom[iFrom+j], collim); |
| 709 | @ <td class="changed lineno">%d(iFrom+j+1)</td> |
| 710 | @ <td class="changed srcline">%h(linebuf)</td> |
| 711 | }else{ |
| 712 | @ <td colspan="2" class="changedvoid"/> |
| 713 | } |
| 714 | |
| 715 | @ <td class="changed">|</td> |
| 716 | |
| 717 | if( j<c.aEdit[i+2] ){ |
| 718 | copylimline(linebuf, &c.aTo[iTo+j], collim); |
| 719 | @ <td class="changed lineno">%d(iTo+j+1)</td> |
| 720 | @ <td class="changed srcline">%h(linebuf)</td> |
| 721 | }else{ |
| 722 | @ <td colspan="2" class="changedvoid"/> |
| 723 | } |
| 724 | |
| 725 | @ </tr> |
| 726 | } |
| 727 | iFrom+=c.aEdit[i+1]; |
| 728 | iTo+=c.aEdit[i+2]; |
| 729 | }else{ |
| 730 | |
| 731 | /* Process deleted lines */ |
| 732 | for( j=0; j<c.aEdit[i+1]; j++ ){ |
| 733 | @ <tr> |
| 734 | |
| 735 | copylimline(linebuf, &c.aFrom[iFrom+j], collim); |
| 736 | @ <td class="removed lineno">%d(iFrom+j+1)</td> |
| 737 | @ <td class="removed srcline">%h(linebuf)</td> |
| 738 | @ <td><</td> |
| 739 | @ <td colspan="2" class="removedvoid"/> |
| 740 | @ </tr> |
| 741 | } |
| 742 | iFrom+=c.aEdit[i+1]; |
| 743 | |
| 744 | /* Process inserted lines */ |
| 745 | for( j=0; j<c.aEdit[i+2]; j++ ){ |
| 746 | @ <tr> |
| 747 | @ <td colspan="2" class="addedvoid"/> |
| 748 | @ <td>></td> |
| 749 | copylimline(linebuf, &c.aTo[iTo+j], collim); |
| 750 | @ <td class="added lineno">%d(iTo+j+1)</td> |
| 751 | @ <td class="added srcline">%h(linebuf)</td> |
| 752 | @ </tr> |
| 753 | } |
| 754 | iTo+=c.aEdit[i+2]; |
| 755 | } |
| 756 | |
| 757 | i+=3; |
| 758 | } |
| 759 | |
| 760 | free(linebuf); |
| 761 | free(c.aFrom); |
| 762 | free(c.aTo); |
| 763 | free(c.aEdit); |
| 764 | return 1; |
| 765 | } |
| 766 | |
| 767 | |
| 768 | /* |
| 769 | ** COMMAND: test-rawdiff |
| 770 | */ |
| 771 | void test_rawdiff_cmd(void){ |
| 772 |
+1
-3
| --- src/http_transport.c | ||
| +++ src/http_transport.c | ||
| @@ -265,14 +265,12 @@ | ||
| 265 | 265 | void transport_send(Blob *toSend){ |
| 266 | 266 | char *z = blob_buffer(toSend); |
| 267 | 267 | int n = blob_size(toSend); |
| 268 | 268 | transport.nSent += n; |
| 269 | 269 | if( g.urlIsSsh ){ |
| 270 | - int sent; | |
| 271 | - sent = fwrite(z, 1, n, sshOut); | |
| 270 | + fwrite(z, 1, n, sshOut); | |
| 272 | 271 | fflush(sshOut); |
| 273 | - /* printf("sent %d of %d bytes\n", sent, n); fflush(stdout); */ | |
| 274 | 272 | }else if( g.urlIsHttps ){ |
| 275 | 273 | #ifdef FOSSIL_ENABLE_SSL |
| 276 | 274 | int sent; |
| 277 | 275 | while( n>0 ){ |
| 278 | 276 | sent = ssl_send(0, z, n); |
| 279 | 277 |
| --- src/http_transport.c | |
| +++ src/http_transport.c | |
| @@ -265,14 +265,12 @@ | |
| 265 | void transport_send(Blob *toSend){ |
| 266 | char *z = blob_buffer(toSend); |
| 267 | int n = blob_size(toSend); |
| 268 | transport.nSent += n; |
| 269 | if( g.urlIsSsh ){ |
| 270 | int sent; |
| 271 | sent = fwrite(z, 1, n, sshOut); |
| 272 | fflush(sshOut); |
| 273 | /* printf("sent %d of %d bytes\n", sent, n); fflush(stdout); */ |
| 274 | }else if( g.urlIsHttps ){ |
| 275 | #ifdef FOSSIL_ENABLE_SSL |
| 276 | int sent; |
| 277 | while( n>0 ){ |
| 278 | sent = ssl_send(0, z, n); |
| 279 |
| --- src/http_transport.c | |
| +++ src/http_transport.c | |
| @@ -265,14 +265,12 @@ | |
| 265 | void transport_send(Blob *toSend){ |
| 266 | char *z = blob_buffer(toSend); |
| 267 | int n = blob_size(toSend); |
| 268 | transport.nSent += n; |
| 269 | if( g.urlIsSsh ){ |
| 270 | fwrite(z, 1, n, sshOut); |
| 271 | fflush(sshOut); |
| 272 | }else if( g.urlIsHttps ){ |
| 273 | #ifdef FOSSIL_ENABLE_SSL |
| 274 | int sent; |
| 275 | while( n>0 ){ |
| 276 | sent = ssl_send(0, z, n); |
| 277 |
+114
-23
| --- src/info.c | ||
| +++ src/info.c | ||
| @@ -276,10 +276,40 @@ | ||
| 276 | 276 | @ %h(blob_str(&out)) |
| 277 | 277 | blob_reset(&from); |
| 278 | 278 | blob_reset(&to); |
| 279 | 279 | blob_reset(&out); |
| 280 | 280 | } |
| 281 | + | |
| 282 | + | |
| 283 | +/* | |
| 284 | +** Write the difference between two RIDs to the output | |
| 285 | +*/ | |
| 286 | +static void generate_sbsdiff(const char *zFrom, const char *zTo){ | |
| 287 | + int fromid; | |
| 288 | + int toid; | |
| 289 | + Blob from, to; | |
| 290 | + if( zFrom ){ | |
| 291 | + fromid = uuid_to_rid(zFrom, 0); | |
| 292 | + content_get(fromid, &from); | |
| 293 | + }else{ | |
| 294 | + blob_zero(&from); | |
| 295 | + } | |
| 296 | + if( zTo ){ | |
| 297 | + toid = uuid_to_rid(zTo, 0); | |
| 298 | + content_get(toid, &to); | |
| 299 | + }else{ | |
| 300 | + blob_zero(&to); | |
| 301 | + } | |
| 302 | + @ <table class="sbsdiff"> | |
| 303 | + @ <tr><th colspan="2" class="diffhdr">Old (%S(zFrom))</th><th/> | |
| 304 | + @ <th colspan="2" class="diffhdr">New (%S(zTo))</th></tr> | |
| 305 | + html_sbsdiff(&from, &to, 5, 1); | |
| 306 | + @ </table> | |
| 307 | + blob_reset(&from); | |
| 308 | + blob_reset(&to); | |
| 309 | +} | |
| 310 | + | |
| 281 | 311 | |
| 282 | 312 | /* |
| 283 | 313 | ** Write a line of web-page output that shows changes that have occurred |
| 284 | 314 | ** to a file between two check-ins. |
| 285 | 315 | */ |
| @@ -287,10 +317,11 @@ | ||
| 287 | 317 | const char *zName, /* Name of the file that has changed */ |
| 288 | 318 | const char *zOld, /* blob.uuid before change. NULL for added files */ |
| 289 | 319 | const char *zNew, /* blob.uuid after change. NULL for deletes */ |
| 290 | 320 | const char *zOldName, /* Prior name. NULL if no name change. */ |
| 291 | 321 | int showDiff, /* Show edit diffs if true */ |
| 322 | + int sideBySide, /* Show diffs side-by-side */ | |
| 292 | 323 | int mperm /* executable or symlink permission for zNew */ |
| 293 | 324 | ){ |
| 294 | 325 | if( !g.perm.History ){ |
| 295 | 326 | if( zNew==0 ){ |
| 296 | 327 | @ <p>Deleted %h(zName)</p> |
| @@ -329,13 +360,17 @@ | ||
| 329 | 360 | }else{ |
| 330 | 361 | @ <p>Added <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> |
| 331 | 362 | @ version <a href="%s(g.zTop)/artifact/%s(zNew)">[%S(zNew)]</a> |
| 332 | 363 | } |
| 333 | 364 | if( showDiff ){ |
| 334 | - @ <blockquote><pre> | |
| 335 | - append_diff(zOld, zNew); | |
| 336 | - @ </pre></blockquote> | |
| 365 | + if( sideBySide ){ | |
| 366 | + generate_sbsdiff(zOld, zNew); | |
| 367 | + }else{ | |
| 368 | + @ <blockquote><pre> | |
| 369 | + append_diff(zOld, zNew); | |
| 370 | + @ </pre></blockquote> | |
| 371 | + } | |
| 337 | 372 | }else if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){ |
| 338 | 373 | @ |
| 339 | 374 | @ <a href="%s(g.zTop)/fdiff?v1=%S(zOld)&v2=%S(zNew)">[diff]</a> |
| 340 | 375 | } |
| 341 | 376 | @ </p> |
| @@ -361,10 +396,11 @@ | ||
| 361 | 396 | void ci_page(void){ |
| 362 | 397 | Stmt q; |
| 363 | 398 | int rid; |
| 364 | 399 | int isLeaf; |
| 365 | 400 | int showDiff; |
| 401 | + int sideBySide; | |
| 366 | 402 | const char *zName; /* Name of the checkin to be displayed */ |
| 367 | 403 | const char *zUuid; /* UUID of zName */ |
| 368 | 404 | const char *zParent; /* UUID of the parent checkin (if any) */ |
| 369 | 405 | |
| 370 | 406 | login_check_credentials(); |
| @@ -390,10 +426,11 @@ | ||
| 390 | 426 | " FROM blob, event" |
| 391 | 427 | " WHERE blob.rid=%d" |
| 392 | 428 | " AND event.objid=%d", |
| 393 | 429 | rid, rid |
| 394 | 430 | ); |
| 431 | + sideBySide = atoi(PD("sbs","1")); | |
| 395 | 432 | if( db_step(&q)==SQLITE_ROW ){ |
| 396 | 433 | const char *zUuid = db_column_text(&q, 0); |
| 397 | 434 | char *zTitle = mprintf("Check-in [%.10s]", zUuid); |
| 398 | 435 | char *zEUser, *zEComment; |
| 399 | 436 | const char *zUser; |
| @@ -467,11 +504,11 @@ | ||
| 467 | 504 | } |
| 468 | 505 | if( !isLeaf ){ |
| 469 | 506 | @ | <a href="%s(g.zTop)/timeline?d=%S(zUuid)">descendants</a> |
| 470 | 507 | } |
| 471 | 508 | if( zParent && !isLeaf ){ |
| 472 | - @ | <a href="%s(g.zTop)/timeline?d=%S(zUuid)&p=%S(zUuid)">both</a> | |
| 509 | + @ | <a href="%s(g.zTop)/timeline?dp=%S(zUuid)">both</a> | |
| 473 | 510 | } |
| 474 | 511 | db_prepare(&q, "SELECT substr(tag.tagname,5) FROM tagxref, tag " |
| 475 | 512 | " WHERE rid=%d AND tagtype>0 " |
| 476 | 513 | " AND tag.tagid=tagxref.tagid " |
| 477 | 514 | " AND +tag.tagname GLOB 'sym-*'", rid); |
| @@ -511,18 +548,42 @@ | ||
| 511 | 548 | showDiff = g.zPath[0]!='c'; |
| 512 | 549 | if( db_get_boolean("show-version-diffs", 0)==0 ){ |
| 513 | 550 | showDiff = !showDiff; |
| 514 | 551 | if( showDiff ){ |
| 515 | 552 | @ <a href="%s(g.zTop)/vinfo/%T(zName)">[hide diffs]</a> |
| 553 | + @ | |
| 554 | + if( sideBySide ){ | |
| 555 | + @ <a href="%s(g.zTop)/ci/%T(zName)?sbs=0"> | |
| 556 | + @ [unified diffs]</a> | |
| 557 | + }else{ | |
| 558 | + @ <a href="%s(g.zTop)/ci/%T(zName)?sbs=1"> | |
| 559 | + @ [side-by-side diffs]</a> | |
| 560 | + } | |
| 516 | 561 | }else{ |
| 517 | - @ <a href="%s(g.zTop)/ci/%T(zName)">[show diffs]</a> | |
| 562 | + @ <a href="%s(g.zTop)/ci/%T(zName)?sbs=0"> | |
| 563 | + @ [show unified diffs]</a> | |
| 564 | + @ | |
| 565 | + @ <a href="%s(g.zTop)/ci/%T(zName)?sbs=1"> | |
| 566 | + @ [show side-by-side diffs]</a> | |
| 518 | 567 | } |
| 519 | 568 | }else{ |
| 520 | 569 | if( showDiff ){ |
| 521 | 570 | @ <a href="%s(g.zTop)/ci/%T(zName)">[hide diffs]</a> |
| 571 | + @ | |
| 572 | + if( sideBySide ){ | |
| 573 | + @ <a href="%s(g.zTop)/info/%T(zName)?sbs=0"> | |
| 574 | + @ [unified diffs]</a> | |
| 575 | + }else{ | |
| 576 | + @ <a href="%s(g.zTop)/info/%T(zName)?sbs=1"> | |
| 577 | + @ [side-by-side diffs]</a> | |
| 578 | + } | |
| 522 | 579 | }else{ |
| 523 | - @ <a href="%s(g.zTop)/vinfo/%T(zName)">[show diffs]</a> | |
| 580 | + @ <a href="%s(g.zTop)/vinfo/%T(zName)?sbs=0"> | |
| 581 | + @ [show unified diffs]</a> | |
| 582 | + @ | |
| 583 | + @ <a href="%s(g.zTop)/vinfo/%T(zName)?sbs=1"> | |
| 584 | + @ [show side-by-side diffs]</a> | |
| 524 | 585 | } |
| 525 | 586 | } |
| 526 | 587 | @ |
| 527 | 588 | @ <a href="%s(g.zTop)/vpatch?from=%S(zParent)&to=%S(zUuid)">[patch]</a><br/> |
| 528 | 589 | db_prepare(&q, |
| @@ -540,11 +601,12 @@ | ||
| 540 | 601 | const char *zName = db_column_text(&q,0); |
| 541 | 602 | int mperm = db_column_int(&q, 1); |
| 542 | 603 | const char *zOld = db_column_text(&q,2); |
| 543 | 604 | const char *zNew = db_column_text(&q,3); |
| 544 | 605 | const char *zOldName = db_column_text(&q, 4); |
| 545 | - append_file_change_line(zName, zOld, zNew, zOldName, showDiff, mperm); | |
| 606 | + append_file_change_line(zName, zOld, zNew, zOldName, showDiff, | |
| 607 | + sideBySide, mperm); | |
| 546 | 608 | } |
| 547 | 609 | db_finalize(&q); |
| 548 | 610 | } |
| 549 | 611 | style_footer(); |
| 550 | 612 | } |
| @@ -690,17 +752,18 @@ | ||
| 690 | 752 | } |
| 691 | 753 | |
| 692 | 754 | |
| 693 | 755 | /* |
| 694 | 756 | ** WEBPAGE: vdiff |
| 695 | -** URL: /vdiff?from=UUID&to=UUID&detail=BOOLEAN | |
| 757 | +** URL: /vdiff?from=UUID&to=UUID&detail=BOOLEAN;sbs=BOOLEAN | |
| 696 | 758 | ** |
| 697 | 759 | ** Show all differences between two checkins. |
| 698 | 760 | */ |
| 699 | 761 | void vdiff_page(void){ |
| 700 | 762 | int ridFrom, ridTo; |
| 701 | 763 | int showDetail = 0; |
| 764 | + int sideBySide = 0; | |
| 702 | 765 | Manifest *pFrom, *pTo; |
| 703 | 766 | ManifestFile *pFileFrom, *pFileTo; |
| 704 | 767 | |
| 705 | 768 | login_check_credentials(); |
| 706 | 769 | if( !g.perm.Read ){ login_needed(); return; } |
| @@ -709,10 +772,20 @@ | ||
| 709 | 772 | pFrom = vdiff_parse_manifest("from", &ridFrom); |
| 710 | 773 | if( pFrom==0 ) return; |
| 711 | 774 | pTo = vdiff_parse_manifest("to", &ridTo); |
| 712 | 775 | if( pTo==0 ) return; |
| 713 | 776 | showDetail = atoi(PD("detail","0")); |
| 777 | + sideBySide = atoi(PD("sbs","1")); | |
| 778 | + if( !sideBySide ){ | |
| 779 | + style_submenu_element("Side-by-side Diff", "sbsdiff", | |
| 780 | + "%s/vdiff?from=%T&to=%T&detail=%d&sbs=1", | |
| 781 | + g.zTop, P("from"), P("to"), showDetail); | |
| 782 | + }else{ | |
| 783 | + style_submenu_element("Unified Diff", "udiff", | |
| 784 | + "%s/vdiff?from=%T&to=%T&detail=%d&sbs=0", | |
| 785 | + g.zTop, P("from"), P("to"), showDetail); | |
| 786 | + } | |
| 714 | 787 | style_header("Check-in Differences"); |
| 715 | 788 | @ <h2>Difference From:</h2><blockquote> |
| 716 | 789 | checkin_description(ridFrom); |
| 717 | 790 | @ </blockquote><h2>To:</h2><blockquote> |
| 718 | 791 | checkin_description(ridTo); |
| @@ -731,25 +804,25 @@ | ||
| 731 | 804 | }else{ |
| 732 | 805 | cmp = fossil_strcmp(pFileFrom->zName, pFileTo->zName); |
| 733 | 806 | } |
| 734 | 807 | if( cmp<0 ){ |
| 735 | 808 | append_file_change_line(pFileFrom->zName, |
| 736 | - pFileFrom->zUuid, 0, 0, 0, 0); | |
| 809 | + pFileFrom->zUuid, 0, 0, 0, 0, 0); | |
| 737 | 810 | pFileFrom = manifest_file_next(pFrom, 0); |
| 738 | 811 | }else if( cmp>0 ){ |
| 739 | 812 | append_file_change_line(pFileTo->zName, |
| 740 | - 0, pFileTo->zUuid, 0, 0, | |
| 813 | + 0, pFileTo->zUuid, 0, 0, 0, | |
| 741 | 814 | manifest_file_mperm(pFileTo)); |
| 742 | 815 | pFileTo = manifest_file_next(pTo, 0); |
| 743 | 816 | }else if( fossil_strcmp(pFileFrom->zUuid, pFileTo->zUuid)==0 ){ |
| 744 | 817 | /* No changes */ |
| 745 | 818 | pFileFrom = manifest_file_next(pFrom, 0); |
| 746 | 819 | pFileTo = manifest_file_next(pTo, 0); |
| 747 | 820 | }else{ |
| 748 | 821 | append_file_change_line(pFileFrom->zName, |
| 749 | 822 | pFileFrom->zUuid, |
| 750 | - pFileTo->zUuid, 0, showDetail, | |
| 823 | + pFileTo->zUuid, 0, showDetail, sideBySide, | |
| 751 | 824 | manifest_file_mperm(pFileTo)); |
| 752 | 825 | pFileFrom = manifest_file_next(pFrom, 0); |
| 753 | 826 | pFileTo = manifest_file_next(pTo, 0); |
| 754 | 827 | } |
| 755 | 828 | } |
| @@ -983,28 +1056,30 @@ | ||
| 983 | 1056 | } |
| 984 | 1057 | |
| 985 | 1058 | |
| 986 | 1059 | /* |
| 987 | 1060 | ** WEBPAGE: fdiff |
| 988 | -** URL: fdiff?v1=UUID&v2=UUID&patch | |
| 1061 | +** URL: fdiff?v1=UUID&v2=UUID&patch&sbs=BOOLEAN | |
| 989 | 1062 | ** |
| 990 | -** Two arguments, v1 and v2, identify the files to be diffed. Show the | |
| 991 | -** difference between the two artifacts. Generate plaintext if "patch" | |
| 992 | -** is present. | |
| 1063 | +** Two arguments, v1 and v2, identify the files to be diffed. Show the | |
| 1064 | +** difference between the two artifacts. Show diff side by side unless sbs | |
| 1065 | +** is 0. Generate plaintext if "patch" is present. | |
| 993 | 1066 | */ |
| 994 | 1067 | void diff_page(void){ |
| 995 | 1068 | int v1, v2; |
| 996 | 1069 | int isPatch; |
| 1070 | + int sideBySide; | |
| 997 | 1071 | Blob c1, c2, diff, *pOut; |
| 998 | 1072 | char *zV1; |
| 999 | 1073 | char *zV2; |
| 1000 | 1074 | |
| 1001 | 1075 | login_check_credentials(); |
| 1002 | 1076 | if( !g.perm.Read ){ login_needed(); return; } |
| 1003 | 1077 | v1 = name_to_rid_www("v1"); |
| 1004 | 1078 | v2 = name_to_rid_www("v2"); |
| 1005 | 1079 | if( v1==0 || v2==0 ) fossil_redirect_home(); |
| 1080 | + sideBySide = atoi(PD("sbs","1")); | |
| 1006 | 1081 | zV1 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v1); |
| 1007 | 1082 | zV2 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v2); |
| 1008 | 1083 | isPatch = P("patch")!=0; |
| 1009 | 1084 | if( isPatch ){ |
| 1010 | 1085 | pOut = cgi_output_blob(); |
| @@ -1011,28 +1086,44 @@ | ||
| 1011 | 1086 | cgi_set_content_type("text/plain"); |
| 1012 | 1087 | }else{ |
| 1013 | 1088 | blob_zero(&diff); |
| 1014 | 1089 | pOut = &diff; |
| 1015 | 1090 | } |
| 1016 | - content_get(v1, &c1); | |
| 1017 | - content_get(v2, &c2); | |
| 1018 | - text_diff(&c1, &c2, pOut, 4, 1); | |
| 1019 | - blob_reset(&c1); | |
| 1020 | - blob_reset(&c2); | |
| 1091 | + if( !sideBySide || isPatch ){ | |
| 1092 | + content_get(v1, &c1); | |
| 1093 | + content_get(v2, &c2); | |
| 1094 | + text_diff(&c1, &c2, pOut, 4, 1); | |
| 1095 | + blob_reset(&c1); | |
| 1096 | + blob_reset(&c2); | |
| 1097 | + } | |
| 1021 | 1098 | if( !isPatch ){ |
| 1022 | 1099 | style_header("Diff"); |
| 1023 | 1100 | style_submenu_element("Patch", "Patch", "%s/fdiff?v1=%T&v2=%T&patch", |
| 1024 | 1101 | g.zTop, P("v1"), P("v2")); |
| 1102 | + if( !sideBySide ){ | |
| 1103 | + style_submenu_element("Side-by-side Diff", "sbsdiff", | |
| 1104 | + "%s/fdiff?v1=%T&v2=%T&sbs=1", | |
| 1105 | + g.zTop, P("v1"), P("v2")); | |
| 1106 | + }else{ | |
| 1107 | + style_submenu_element("Unified Diff", "udiff", | |
| 1108 | + "%s/fdiff?v1=%T&v2=%T&sbs=0", | |
| 1109 | + g.zTop, P("v1"), P("v2")); | |
| 1110 | + } | |
| 1111 | + | |
| 1025 | 1112 | @ <h2>Differences From |
| 1026 | 1113 | @ Artifact <a href="%s(g.zTop)/artifact/%S(zV1)">[%S(zV1)]</a>:</h2> |
| 1027 | 1114 | object_description(v1, 0, 0); |
| 1028 | 1115 | @ <h2>To Artifact <a href="%s(g.zTop)/artifact/%S(zV2)">[%S(zV2)]</a>:</h2> |
| 1029 | 1116 | object_description(v2, 0, 0); |
| 1030 | 1117 | @ <hr /> |
| 1031 | - @ <blockquote><pre> | |
| 1032 | - @ %h(blob_str(&diff)) | |
| 1033 | - @ </pre></blockquote> | |
| 1118 | + if( sideBySide ){ | |
| 1119 | + generate_sbsdiff(zV1, zV2); | |
| 1120 | + }else{ | |
| 1121 | + @ <blockquote><pre> | |
| 1122 | + @ %h(blob_str(&diff)) | |
| 1123 | + @ </pre></blockquote> | |
| 1124 | + } | |
| 1034 | 1125 | blob_reset(&diff); |
| 1035 | 1126 | style_footer(); |
| 1036 | 1127 | } |
| 1037 | 1128 | } |
| 1038 | 1129 | |
| 1039 | 1130 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -276,10 +276,40 @@ | |
| 276 | @ %h(blob_str(&out)) |
| 277 | blob_reset(&from); |
| 278 | blob_reset(&to); |
| 279 | blob_reset(&out); |
| 280 | } |
| 281 | |
| 282 | /* |
| 283 | ** Write a line of web-page output that shows changes that have occurred |
| 284 | ** to a file between two check-ins. |
| 285 | */ |
| @@ -287,10 +317,11 @@ | |
| 287 | const char *zName, /* Name of the file that has changed */ |
| 288 | const char *zOld, /* blob.uuid before change. NULL for added files */ |
| 289 | const char *zNew, /* blob.uuid after change. NULL for deletes */ |
| 290 | const char *zOldName, /* Prior name. NULL if no name change. */ |
| 291 | int showDiff, /* Show edit diffs if true */ |
| 292 | int mperm /* executable or symlink permission for zNew */ |
| 293 | ){ |
| 294 | if( !g.perm.History ){ |
| 295 | if( zNew==0 ){ |
| 296 | @ <p>Deleted %h(zName)</p> |
| @@ -329,13 +360,17 @@ | |
| 329 | }else{ |
| 330 | @ <p>Added <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> |
| 331 | @ version <a href="%s(g.zTop)/artifact/%s(zNew)">[%S(zNew)]</a> |
| 332 | } |
| 333 | if( showDiff ){ |
| 334 | @ <blockquote><pre> |
| 335 | append_diff(zOld, zNew); |
| 336 | @ </pre></blockquote> |
| 337 | }else if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){ |
| 338 | @ |
| 339 | @ <a href="%s(g.zTop)/fdiff?v1=%S(zOld)&v2=%S(zNew)">[diff]</a> |
| 340 | } |
| 341 | @ </p> |
| @@ -361,10 +396,11 @@ | |
| 361 | void ci_page(void){ |
| 362 | Stmt q; |
| 363 | int rid; |
| 364 | int isLeaf; |
| 365 | int showDiff; |
| 366 | const char *zName; /* Name of the checkin to be displayed */ |
| 367 | const char *zUuid; /* UUID of zName */ |
| 368 | const char *zParent; /* UUID of the parent checkin (if any) */ |
| 369 | |
| 370 | login_check_credentials(); |
| @@ -390,10 +426,11 @@ | |
| 390 | " FROM blob, event" |
| 391 | " WHERE blob.rid=%d" |
| 392 | " AND event.objid=%d", |
| 393 | rid, rid |
| 394 | ); |
| 395 | if( db_step(&q)==SQLITE_ROW ){ |
| 396 | const char *zUuid = db_column_text(&q, 0); |
| 397 | char *zTitle = mprintf("Check-in [%.10s]", zUuid); |
| 398 | char *zEUser, *zEComment; |
| 399 | const char *zUser; |
| @@ -467,11 +504,11 @@ | |
| 467 | } |
| 468 | if( !isLeaf ){ |
| 469 | @ | <a href="%s(g.zTop)/timeline?d=%S(zUuid)">descendants</a> |
| 470 | } |
| 471 | if( zParent && !isLeaf ){ |
| 472 | @ | <a href="%s(g.zTop)/timeline?d=%S(zUuid)&p=%S(zUuid)">both</a> |
| 473 | } |
| 474 | db_prepare(&q, "SELECT substr(tag.tagname,5) FROM tagxref, tag " |
| 475 | " WHERE rid=%d AND tagtype>0 " |
| 476 | " AND tag.tagid=tagxref.tagid " |
| 477 | " AND +tag.tagname GLOB 'sym-*'", rid); |
| @@ -511,18 +548,42 @@ | |
| 511 | showDiff = g.zPath[0]!='c'; |
| 512 | if( db_get_boolean("show-version-diffs", 0)==0 ){ |
| 513 | showDiff = !showDiff; |
| 514 | if( showDiff ){ |
| 515 | @ <a href="%s(g.zTop)/vinfo/%T(zName)">[hide diffs]</a> |
| 516 | }else{ |
| 517 | @ <a href="%s(g.zTop)/ci/%T(zName)">[show diffs]</a> |
| 518 | } |
| 519 | }else{ |
| 520 | if( showDiff ){ |
| 521 | @ <a href="%s(g.zTop)/ci/%T(zName)">[hide diffs]</a> |
| 522 | }else{ |
| 523 | @ <a href="%s(g.zTop)/vinfo/%T(zName)">[show diffs]</a> |
| 524 | } |
| 525 | } |
| 526 | @ |
| 527 | @ <a href="%s(g.zTop)/vpatch?from=%S(zParent)&to=%S(zUuid)">[patch]</a><br/> |
| 528 | db_prepare(&q, |
| @@ -540,11 +601,12 @@ | |
| 540 | const char *zName = db_column_text(&q,0); |
| 541 | int mperm = db_column_int(&q, 1); |
| 542 | const char *zOld = db_column_text(&q,2); |
| 543 | const char *zNew = db_column_text(&q,3); |
| 544 | const char *zOldName = db_column_text(&q, 4); |
| 545 | append_file_change_line(zName, zOld, zNew, zOldName, showDiff, mperm); |
| 546 | } |
| 547 | db_finalize(&q); |
| 548 | } |
| 549 | style_footer(); |
| 550 | } |
| @@ -690,17 +752,18 @@ | |
| 690 | } |
| 691 | |
| 692 | |
| 693 | /* |
| 694 | ** WEBPAGE: vdiff |
| 695 | ** URL: /vdiff?from=UUID&to=UUID&detail=BOOLEAN |
| 696 | ** |
| 697 | ** Show all differences between two checkins. |
| 698 | */ |
| 699 | void vdiff_page(void){ |
| 700 | int ridFrom, ridTo; |
| 701 | int showDetail = 0; |
| 702 | Manifest *pFrom, *pTo; |
| 703 | ManifestFile *pFileFrom, *pFileTo; |
| 704 | |
| 705 | login_check_credentials(); |
| 706 | if( !g.perm.Read ){ login_needed(); return; } |
| @@ -709,10 +772,20 @@ | |
| 709 | pFrom = vdiff_parse_manifest("from", &ridFrom); |
| 710 | if( pFrom==0 ) return; |
| 711 | pTo = vdiff_parse_manifest("to", &ridTo); |
| 712 | if( pTo==0 ) return; |
| 713 | showDetail = atoi(PD("detail","0")); |
| 714 | style_header("Check-in Differences"); |
| 715 | @ <h2>Difference From:</h2><blockquote> |
| 716 | checkin_description(ridFrom); |
| 717 | @ </blockquote><h2>To:</h2><blockquote> |
| 718 | checkin_description(ridTo); |
| @@ -731,25 +804,25 @@ | |
| 731 | }else{ |
| 732 | cmp = fossil_strcmp(pFileFrom->zName, pFileTo->zName); |
| 733 | } |
| 734 | if( cmp<0 ){ |
| 735 | append_file_change_line(pFileFrom->zName, |
| 736 | pFileFrom->zUuid, 0, 0, 0, 0); |
| 737 | pFileFrom = manifest_file_next(pFrom, 0); |
| 738 | }else if( cmp>0 ){ |
| 739 | append_file_change_line(pFileTo->zName, |
| 740 | 0, pFileTo->zUuid, 0, 0, |
| 741 | manifest_file_mperm(pFileTo)); |
| 742 | pFileTo = manifest_file_next(pTo, 0); |
| 743 | }else if( fossil_strcmp(pFileFrom->zUuid, pFileTo->zUuid)==0 ){ |
| 744 | /* No changes */ |
| 745 | pFileFrom = manifest_file_next(pFrom, 0); |
| 746 | pFileTo = manifest_file_next(pTo, 0); |
| 747 | }else{ |
| 748 | append_file_change_line(pFileFrom->zName, |
| 749 | pFileFrom->zUuid, |
| 750 | pFileTo->zUuid, 0, showDetail, |
| 751 | manifest_file_mperm(pFileTo)); |
| 752 | pFileFrom = manifest_file_next(pFrom, 0); |
| 753 | pFileTo = manifest_file_next(pTo, 0); |
| 754 | } |
| 755 | } |
| @@ -983,28 +1056,30 @@ | |
| 983 | } |
| 984 | |
| 985 | |
| 986 | /* |
| 987 | ** WEBPAGE: fdiff |
| 988 | ** URL: fdiff?v1=UUID&v2=UUID&patch |
| 989 | ** |
| 990 | ** Two arguments, v1 and v2, identify the files to be diffed. Show the |
| 991 | ** difference between the two artifacts. Generate plaintext if "patch" |
| 992 | ** is present. |
| 993 | */ |
| 994 | void diff_page(void){ |
| 995 | int v1, v2; |
| 996 | int isPatch; |
| 997 | Blob c1, c2, diff, *pOut; |
| 998 | char *zV1; |
| 999 | char *zV2; |
| 1000 | |
| 1001 | login_check_credentials(); |
| 1002 | if( !g.perm.Read ){ login_needed(); return; } |
| 1003 | v1 = name_to_rid_www("v1"); |
| 1004 | v2 = name_to_rid_www("v2"); |
| 1005 | if( v1==0 || v2==0 ) fossil_redirect_home(); |
| 1006 | zV1 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v1); |
| 1007 | zV2 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v2); |
| 1008 | isPatch = P("patch")!=0; |
| 1009 | if( isPatch ){ |
| 1010 | pOut = cgi_output_blob(); |
| @@ -1011,28 +1086,44 @@ | |
| 1011 | cgi_set_content_type("text/plain"); |
| 1012 | }else{ |
| 1013 | blob_zero(&diff); |
| 1014 | pOut = &diff; |
| 1015 | } |
| 1016 | content_get(v1, &c1); |
| 1017 | content_get(v2, &c2); |
| 1018 | text_diff(&c1, &c2, pOut, 4, 1); |
| 1019 | blob_reset(&c1); |
| 1020 | blob_reset(&c2); |
| 1021 | if( !isPatch ){ |
| 1022 | style_header("Diff"); |
| 1023 | style_submenu_element("Patch", "Patch", "%s/fdiff?v1=%T&v2=%T&patch", |
| 1024 | g.zTop, P("v1"), P("v2")); |
| 1025 | @ <h2>Differences From |
| 1026 | @ Artifact <a href="%s(g.zTop)/artifact/%S(zV1)">[%S(zV1)]</a>:</h2> |
| 1027 | object_description(v1, 0, 0); |
| 1028 | @ <h2>To Artifact <a href="%s(g.zTop)/artifact/%S(zV2)">[%S(zV2)]</a>:</h2> |
| 1029 | object_description(v2, 0, 0); |
| 1030 | @ <hr /> |
| 1031 | @ <blockquote><pre> |
| 1032 | @ %h(blob_str(&diff)) |
| 1033 | @ </pre></blockquote> |
| 1034 | blob_reset(&diff); |
| 1035 | style_footer(); |
| 1036 | } |
| 1037 | } |
| 1038 | |
| 1039 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -276,10 +276,40 @@ | |
| 276 | @ %h(blob_str(&out)) |
| 277 | blob_reset(&from); |
| 278 | blob_reset(&to); |
| 279 | blob_reset(&out); |
| 280 | } |
| 281 | |
| 282 | |
| 283 | /* |
| 284 | ** Write the difference between two RIDs to the output |
| 285 | */ |
| 286 | static void generate_sbsdiff(const char *zFrom, const char *zTo){ |
| 287 | int fromid; |
| 288 | int toid; |
| 289 | Blob from, to; |
| 290 | if( zFrom ){ |
| 291 | fromid = uuid_to_rid(zFrom, 0); |
| 292 | content_get(fromid, &from); |
| 293 | }else{ |
| 294 | blob_zero(&from); |
| 295 | } |
| 296 | if( zTo ){ |
| 297 | toid = uuid_to_rid(zTo, 0); |
| 298 | content_get(toid, &to); |
| 299 | }else{ |
| 300 | blob_zero(&to); |
| 301 | } |
| 302 | @ <table class="sbsdiff"> |
| 303 | @ <tr><th colspan="2" class="diffhdr">Old (%S(zFrom))</th><th/> |
| 304 | @ <th colspan="2" class="diffhdr">New (%S(zTo))</th></tr> |
| 305 | html_sbsdiff(&from, &to, 5, 1); |
| 306 | @ </table> |
| 307 | blob_reset(&from); |
| 308 | blob_reset(&to); |
| 309 | } |
| 310 | |
| 311 | |
| 312 | /* |
| 313 | ** Write a line of web-page output that shows changes that have occurred |
| 314 | ** to a file between two check-ins. |
| 315 | */ |
| @@ -287,10 +317,11 @@ | |
| 317 | const char *zName, /* Name of the file that has changed */ |
| 318 | const char *zOld, /* blob.uuid before change. NULL for added files */ |
| 319 | const char *zNew, /* blob.uuid after change. NULL for deletes */ |
| 320 | const char *zOldName, /* Prior name. NULL if no name change. */ |
| 321 | int showDiff, /* Show edit diffs if true */ |
| 322 | int sideBySide, /* Show diffs side-by-side */ |
| 323 | int mperm /* executable or symlink permission for zNew */ |
| 324 | ){ |
| 325 | if( !g.perm.History ){ |
| 326 | if( zNew==0 ){ |
| 327 | @ <p>Deleted %h(zName)</p> |
| @@ -329,13 +360,17 @@ | |
| 360 | }else{ |
| 361 | @ <p>Added <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> |
| 362 | @ version <a href="%s(g.zTop)/artifact/%s(zNew)">[%S(zNew)]</a> |
| 363 | } |
| 364 | if( showDiff ){ |
| 365 | if( sideBySide ){ |
| 366 | generate_sbsdiff(zOld, zNew); |
| 367 | }else{ |
| 368 | @ <blockquote><pre> |
| 369 | append_diff(zOld, zNew); |
| 370 | @ </pre></blockquote> |
| 371 | } |
| 372 | }else if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){ |
| 373 | @ |
| 374 | @ <a href="%s(g.zTop)/fdiff?v1=%S(zOld)&v2=%S(zNew)">[diff]</a> |
| 375 | } |
| 376 | @ </p> |
| @@ -361,10 +396,11 @@ | |
| 396 | void ci_page(void){ |
| 397 | Stmt q; |
| 398 | int rid; |
| 399 | int isLeaf; |
| 400 | int showDiff; |
| 401 | int sideBySide; |
| 402 | const char *zName; /* Name of the checkin to be displayed */ |
| 403 | const char *zUuid; /* UUID of zName */ |
| 404 | const char *zParent; /* UUID of the parent checkin (if any) */ |
| 405 | |
| 406 | login_check_credentials(); |
| @@ -390,10 +426,11 @@ | |
| 426 | " FROM blob, event" |
| 427 | " WHERE blob.rid=%d" |
| 428 | " AND event.objid=%d", |
| 429 | rid, rid |
| 430 | ); |
| 431 | sideBySide = atoi(PD("sbs","1")); |
| 432 | if( db_step(&q)==SQLITE_ROW ){ |
| 433 | const char *zUuid = db_column_text(&q, 0); |
| 434 | char *zTitle = mprintf("Check-in [%.10s]", zUuid); |
| 435 | char *zEUser, *zEComment; |
| 436 | const char *zUser; |
| @@ -467,11 +504,11 @@ | |
| 504 | } |
| 505 | if( !isLeaf ){ |
| 506 | @ | <a href="%s(g.zTop)/timeline?d=%S(zUuid)">descendants</a> |
| 507 | } |
| 508 | if( zParent && !isLeaf ){ |
| 509 | @ | <a href="%s(g.zTop)/timeline?dp=%S(zUuid)">both</a> |
| 510 | } |
| 511 | db_prepare(&q, "SELECT substr(tag.tagname,5) FROM tagxref, tag " |
| 512 | " WHERE rid=%d AND tagtype>0 " |
| 513 | " AND tag.tagid=tagxref.tagid " |
| 514 | " AND +tag.tagname GLOB 'sym-*'", rid); |
| @@ -511,18 +548,42 @@ | |
| 548 | showDiff = g.zPath[0]!='c'; |
| 549 | if( db_get_boolean("show-version-diffs", 0)==0 ){ |
| 550 | showDiff = !showDiff; |
| 551 | if( showDiff ){ |
| 552 | @ <a href="%s(g.zTop)/vinfo/%T(zName)">[hide diffs]</a> |
| 553 | @ |
| 554 | if( sideBySide ){ |
| 555 | @ <a href="%s(g.zTop)/ci/%T(zName)?sbs=0"> |
| 556 | @ [unified diffs]</a> |
| 557 | }else{ |
| 558 | @ <a href="%s(g.zTop)/ci/%T(zName)?sbs=1"> |
| 559 | @ [side-by-side diffs]</a> |
| 560 | } |
| 561 | }else{ |
| 562 | @ <a href="%s(g.zTop)/ci/%T(zName)?sbs=0"> |
| 563 | @ [show unified diffs]</a> |
| 564 | @ |
| 565 | @ <a href="%s(g.zTop)/ci/%T(zName)?sbs=1"> |
| 566 | @ [show side-by-side diffs]</a> |
| 567 | } |
| 568 | }else{ |
| 569 | if( showDiff ){ |
| 570 | @ <a href="%s(g.zTop)/ci/%T(zName)">[hide diffs]</a> |
| 571 | @ |
| 572 | if( sideBySide ){ |
| 573 | @ <a href="%s(g.zTop)/info/%T(zName)?sbs=0"> |
| 574 | @ [unified diffs]</a> |
| 575 | }else{ |
| 576 | @ <a href="%s(g.zTop)/info/%T(zName)?sbs=1"> |
| 577 | @ [side-by-side diffs]</a> |
| 578 | } |
| 579 | }else{ |
| 580 | @ <a href="%s(g.zTop)/vinfo/%T(zName)?sbs=0"> |
| 581 | @ [show unified diffs]</a> |
| 582 | @ |
| 583 | @ <a href="%s(g.zTop)/vinfo/%T(zName)?sbs=1"> |
| 584 | @ [show side-by-side diffs]</a> |
| 585 | } |
| 586 | } |
| 587 | @ |
| 588 | @ <a href="%s(g.zTop)/vpatch?from=%S(zParent)&to=%S(zUuid)">[patch]</a><br/> |
| 589 | db_prepare(&q, |
| @@ -540,11 +601,12 @@ | |
| 601 | const char *zName = db_column_text(&q,0); |
| 602 | int mperm = db_column_int(&q, 1); |
| 603 | const char *zOld = db_column_text(&q,2); |
| 604 | const char *zNew = db_column_text(&q,3); |
| 605 | const char *zOldName = db_column_text(&q, 4); |
| 606 | append_file_change_line(zName, zOld, zNew, zOldName, showDiff, |
| 607 | sideBySide, mperm); |
| 608 | } |
| 609 | db_finalize(&q); |
| 610 | } |
| 611 | style_footer(); |
| 612 | } |
| @@ -690,17 +752,18 @@ | |
| 752 | } |
| 753 | |
| 754 | |
| 755 | /* |
| 756 | ** WEBPAGE: vdiff |
| 757 | ** URL: /vdiff?from=UUID&to=UUID&detail=BOOLEAN;sbs=BOOLEAN |
| 758 | ** |
| 759 | ** Show all differences between two checkins. |
| 760 | */ |
| 761 | void vdiff_page(void){ |
| 762 | int ridFrom, ridTo; |
| 763 | int showDetail = 0; |
| 764 | int sideBySide = 0; |
| 765 | Manifest *pFrom, *pTo; |
| 766 | ManifestFile *pFileFrom, *pFileTo; |
| 767 | |
| 768 | login_check_credentials(); |
| 769 | if( !g.perm.Read ){ login_needed(); return; } |
| @@ -709,10 +772,20 @@ | |
| 772 | pFrom = vdiff_parse_manifest("from", &ridFrom); |
| 773 | if( pFrom==0 ) return; |
| 774 | pTo = vdiff_parse_manifest("to", &ridTo); |
| 775 | if( pTo==0 ) return; |
| 776 | showDetail = atoi(PD("detail","0")); |
| 777 | sideBySide = atoi(PD("sbs","1")); |
| 778 | if( !sideBySide ){ |
| 779 | style_submenu_element("Side-by-side Diff", "sbsdiff", |
| 780 | "%s/vdiff?from=%T&to=%T&detail=%d&sbs=1", |
| 781 | g.zTop, P("from"), P("to"), showDetail); |
| 782 | }else{ |
| 783 | style_submenu_element("Unified Diff", "udiff", |
| 784 | "%s/vdiff?from=%T&to=%T&detail=%d&sbs=0", |
| 785 | g.zTop, P("from"), P("to"), showDetail); |
| 786 | } |
| 787 | style_header("Check-in Differences"); |
| 788 | @ <h2>Difference From:</h2><blockquote> |
| 789 | checkin_description(ridFrom); |
| 790 | @ </blockquote><h2>To:</h2><blockquote> |
| 791 | checkin_description(ridTo); |
| @@ -731,25 +804,25 @@ | |
| 804 | }else{ |
| 805 | cmp = fossil_strcmp(pFileFrom->zName, pFileTo->zName); |
| 806 | } |
| 807 | if( cmp<0 ){ |
| 808 | append_file_change_line(pFileFrom->zName, |
| 809 | pFileFrom->zUuid, 0, 0, 0, 0, 0); |
| 810 | pFileFrom = manifest_file_next(pFrom, 0); |
| 811 | }else if( cmp>0 ){ |
| 812 | append_file_change_line(pFileTo->zName, |
| 813 | 0, pFileTo->zUuid, 0, 0, 0, |
| 814 | manifest_file_mperm(pFileTo)); |
| 815 | pFileTo = manifest_file_next(pTo, 0); |
| 816 | }else if( fossil_strcmp(pFileFrom->zUuid, pFileTo->zUuid)==0 ){ |
| 817 | /* No changes */ |
| 818 | pFileFrom = manifest_file_next(pFrom, 0); |
| 819 | pFileTo = manifest_file_next(pTo, 0); |
| 820 | }else{ |
| 821 | append_file_change_line(pFileFrom->zName, |
| 822 | pFileFrom->zUuid, |
| 823 | pFileTo->zUuid, 0, showDetail, sideBySide, |
| 824 | manifest_file_mperm(pFileTo)); |
| 825 | pFileFrom = manifest_file_next(pFrom, 0); |
| 826 | pFileTo = manifest_file_next(pTo, 0); |
| 827 | } |
| 828 | } |
| @@ -983,28 +1056,30 @@ | |
| 1056 | } |
| 1057 | |
| 1058 | |
| 1059 | /* |
| 1060 | ** WEBPAGE: fdiff |
| 1061 | ** URL: fdiff?v1=UUID&v2=UUID&patch&sbs=BOOLEAN |
| 1062 | ** |
| 1063 | ** Two arguments, v1 and v2, identify the files to be diffed. Show the |
| 1064 | ** difference between the two artifacts. Show diff side by side unless sbs |
| 1065 | ** is 0. Generate plaintext if "patch" is present. |
| 1066 | */ |
| 1067 | void diff_page(void){ |
| 1068 | int v1, v2; |
| 1069 | int isPatch; |
| 1070 | int sideBySide; |
| 1071 | Blob c1, c2, diff, *pOut; |
| 1072 | char *zV1; |
| 1073 | char *zV2; |
| 1074 | |
| 1075 | login_check_credentials(); |
| 1076 | if( !g.perm.Read ){ login_needed(); return; } |
| 1077 | v1 = name_to_rid_www("v1"); |
| 1078 | v2 = name_to_rid_www("v2"); |
| 1079 | if( v1==0 || v2==0 ) fossil_redirect_home(); |
| 1080 | sideBySide = atoi(PD("sbs","1")); |
| 1081 | zV1 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v1); |
| 1082 | zV2 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v2); |
| 1083 | isPatch = P("patch")!=0; |
| 1084 | if( isPatch ){ |
| 1085 | pOut = cgi_output_blob(); |
| @@ -1011,28 +1086,44 @@ | |
| 1086 | cgi_set_content_type("text/plain"); |
| 1087 | }else{ |
| 1088 | blob_zero(&diff); |
| 1089 | pOut = &diff; |
| 1090 | } |
| 1091 | if( !sideBySide || isPatch ){ |
| 1092 | content_get(v1, &c1); |
| 1093 | content_get(v2, &c2); |
| 1094 | text_diff(&c1, &c2, pOut, 4, 1); |
| 1095 | blob_reset(&c1); |
| 1096 | blob_reset(&c2); |
| 1097 | } |
| 1098 | if( !isPatch ){ |
| 1099 | style_header("Diff"); |
| 1100 | style_submenu_element("Patch", "Patch", "%s/fdiff?v1=%T&v2=%T&patch", |
| 1101 | g.zTop, P("v1"), P("v2")); |
| 1102 | if( !sideBySide ){ |
| 1103 | style_submenu_element("Side-by-side Diff", "sbsdiff", |
| 1104 | "%s/fdiff?v1=%T&v2=%T&sbs=1", |
| 1105 | g.zTop, P("v1"), P("v2")); |
| 1106 | }else{ |
| 1107 | style_submenu_element("Unified Diff", "udiff", |
| 1108 | "%s/fdiff?v1=%T&v2=%T&sbs=0", |
| 1109 | g.zTop, P("v1"), P("v2")); |
| 1110 | } |
| 1111 | |
| 1112 | @ <h2>Differences From |
| 1113 | @ Artifact <a href="%s(g.zTop)/artifact/%S(zV1)">[%S(zV1)]</a>:</h2> |
| 1114 | object_description(v1, 0, 0); |
| 1115 | @ <h2>To Artifact <a href="%s(g.zTop)/artifact/%S(zV2)">[%S(zV2)]</a>:</h2> |
| 1116 | object_description(v2, 0, 0); |
| 1117 | @ <hr /> |
| 1118 | if( sideBySide ){ |
| 1119 | generate_sbsdiff(zV1, zV2); |
| 1120 | }else{ |
| 1121 | @ <blockquote><pre> |
| 1122 | @ %h(blob_str(&diff)) |
| 1123 | @ </pre></blockquote> |
| 1124 | } |
| 1125 | blob_reset(&diff); |
| 1126 | style_footer(); |
| 1127 | } |
| 1128 | } |
| 1129 | |
| 1130 |
+1
-1
| --- src/json_artifact.c | ||
| +++ src/json_artifact.c | ||
| @@ -55,11 +55,11 @@ | ||
| 55 | 55 | ** which must refer to a Checkin. |
| 56 | 56 | ** |
| 57 | 57 | ** Returned value is NULL or an Object owned by the caller. |
| 58 | 58 | */ |
| 59 | 59 | cson_value * json_artifact_for_ci( int rid, char showFiles ){ |
| 60 | - char const * zParent = NULL; | |
| 60 | + char * zParent = NULL; | |
| 61 | 61 | cson_value * v = NULL; |
| 62 | 62 | Stmt q; |
| 63 | 63 | static cson_value * eventTypeLabel = NULL; |
| 64 | 64 | if(!eventTypeLabel){ |
| 65 | 65 | eventTypeLabel = json_new_string("checkin"); |
| 66 | 66 |
| --- src/json_artifact.c | |
| +++ src/json_artifact.c | |
| @@ -55,11 +55,11 @@ | |
| 55 | ** which must refer to a Checkin. |
| 56 | ** |
| 57 | ** Returned value is NULL or an Object owned by the caller. |
| 58 | */ |
| 59 | cson_value * json_artifact_for_ci( int rid, char showFiles ){ |
| 60 | char const * zParent = NULL; |
| 61 | cson_value * v = NULL; |
| 62 | Stmt q; |
| 63 | static cson_value * eventTypeLabel = NULL; |
| 64 | if(!eventTypeLabel){ |
| 65 | eventTypeLabel = json_new_string("checkin"); |
| 66 |
| --- src/json_artifact.c | |
| +++ src/json_artifact.c | |
| @@ -55,11 +55,11 @@ | |
| 55 | ** which must refer to a Checkin. |
| 56 | ** |
| 57 | ** Returned value is NULL or an Object owned by the caller. |
| 58 | */ |
| 59 | cson_value * json_artifact_for_ci( int rid, char showFiles ){ |
| 60 | char * zParent = NULL; |
| 61 | cson_value * v = NULL; |
| 62 | Stmt q; |
| 63 | static cson_value * eventTypeLabel = NULL; |
| 64 | if(!eventTypeLabel){ |
| 65 | eventTypeLabel = json_new_string("checkin"); |
| 66 |
+1
-1
| --- src/json_artifact.c | ||
| +++ src/json_artifact.c | ||
| @@ -55,11 +55,11 @@ | ||
| 55 | 55 | ** which must refer to a Checkin. |
| 56 | 56 | ** |
| 57 | 57 | ** Returned value is NULL or an Object owned by the caller. |
| 58 | 58 | */ |
| 59 | 59 | cson_value * json_artifact_for_ci( int rid, char showFiles ){ |
| 60 | - char const * zParent = NULL; | |
| 60 | + char * zParent = NULL; | |
| 61 | 61 | cson_value * v = NULL; |
| 62 | 62 | Stmt q; |
| 63 | 63 | static cson_value * eventTypeLabel = NULL; |
| 64 | 64 | if(!eventTypeLabel){ |
| 65 | 65 | eventTypeLabel = json_new_string("checkin"); |
| 66 | 66 |
| --- src/json_artifact.c | |
| +++ src/json_artifact.c | |
| @@ -55,11 +55,11 @@ | |
| 55 | ** which must refer to a Checkin. |
| 56 | ** |
| 57 | ** Returned value is NULL or an Object owned by the caller. |
| 58 | */ |
| 59 | cson_value * json_artifact_for_ci( int rid, char showFiles ){ |
| 60 | char const * zParent = NULL; |
| 61 | cson_value * v = NULL; |
| 62 | Stmt q; |
| 63 | static cson_value * eventTypeLabel = NULL; |
| 64 | if(!eventTypeLabel){ |
| 65 | eventTypeLabel = json_new_string("checkin"); |
| 66 |
| --- src/json_artifact.c | |
| +++ src/json_artifact.c | |
| @@ -55,11 +55,11 @@ | |
| 55 | ** which must refer to a Checkin. |
| 56 | ** |
| 57 | ** Returned value is NULL or an Object owned by the caller. |
| 58 | */ |
| 59 | cson_value * json_artifact_for_ci( int rid, char showFiles ){ |
| 60 | char * zParent = NULL; |
| 61 | cson_value * v = NULL; |
| 62 | Stmt q; |
| 63 | static cson_value * eventTypeLabel = NULL; |
| 64 | if(!eventTypeLabel){ |
| 65 | eventTypeLabel = json_new_string("checkin"); |
| 66 |
+38
| --- src/manifest.c | ||
| +++ src/manifest.c | ||
| @@ -1819,10 +1819,48 @@ | ||
| 1819 | 1819 | "VALUES('t',%.17g,%d,%Q,%Q)", |
| 1820 | 1820 | p->rDate, rid, p->zUser, zComment |
| 1821 | 1821 | ); |
| 1822 | 1822 | free(zComment); |
| 1823 | 1823 | } |
| 1824 | + } | |
| 1825 | + if( p->type==CFTYPE_CONTROL ){ | |
| 1826 | + Blob comment; | |
| 1827 | + int i; | |
| 1828 | + const char *zName; | |
| 1829 | + const char *zValue; | |
| 1830 | + const char *zUuid; | |
| 1831 | + blob_zero(&comment); | |
| 1832 | + for(i=0; i<p->nTag; i++){ | |
| 1833 | + zUuid = p->aTag[i].zUuid; | |
| 1834 | + if( i==0 || fossil_strcmp(zUuid, p->aTag[i-1].zUuid)!=0 ){ | |
| 1835 | + if( i>0 ) blob_append(&comment, " ", 1); | |
| 1836 | + blob_appendf(&comment, "Tag changes on [/timeline?dp=%S&n=4 | %S]:", | |
| 1837 | + zUuid, zUuid); | |
| 1838 | + } | |
| 1839 | + zName = p->aTag[i].zName; | |
| 1840 | + zValue = p->aTag[i].zValue; | |
| 1841 | + if( zName[0]=='-' ){ | |
| 1842 | + blob_appendf(&comment, " Cancel"); | |
| 1843 | + }else if( zName[0]=='+' ){ | |
| 1844 | + blob_appendf(&comment, " Add"); | |
| 1845 | + }else{ | |
| 1846 | + blob_appendf(&comment, " Add propagating"); | |
| 1847 | + } | |
| 1848 | + if( memcmp(&zName[1], "sym-",4)==0 ){ | |
| 1849 | + blob_appendf(&comment, " symbolic tag \"%h\".", &zName[5]); | |
| 1850 | + }else if( fossil_strcmp(&zName[1], "comment")!=0 && zValue && zValue[0] ){ | |
| 1851 | + blob_appendf(&comment, " %h=%h.", &zName[1], zValue); | |
| 1852 | + }else{ | |
| 1853 | + blob_appendf(&comment, " %h.", &zName[1]); | |
| 1854 | + } | |
| 1855 | + } | |
| 1856 | + db_multi_exec( | |
| 1857 | + "REPLACE INTO event(type,mtime,objid,user,comment)" | |
| 1858 | + "VALUES('g',%.17g,%d,%Q,%Q)", | |
| 1859 | + p->rDate, rid, p->zUser, blob_str(&comment) | |
| 1860 | + ); | |
| 1861 | + blob_reset(&comment); | |
| 1824 | 1862 | } |
| 1825 | 1863 | db_end_transaction(0); |
| 1826 | 1864 | if( p->type==CFTYPE_MANIFEST ){ |
| 1827 | 1865 | manifest_cache_insert(p); |
| 1828 | 1866 | }else{ |
| 1829 | 1867 |
| --- src/manifest.c | |
| +++ src/manifest.c | |
| @@ -1819,10 +1819,48 @@ | |
| 1819 | "VALUES('t',%.17g,%d,%Q,%Q)", |
| 1820 | p->rDate, rid, p->zUser, zComment |
| 1821 | ); |
| 1822 | free(zComment); |
| 1823 | } |
| 1824 | } |
| 1825 | db_end_transaction(0); |
| 1826 | if( p->type==CFTYPE_MANIFEST ){ |
| 1827 | manifest_cache_insert(p); |
| 1828 | }else{ |
| 1829 |
| --- src/manifest.c | |
| +++ src/manifest.c | |
| @@ -1819,10 +1819,48 @@ | |
| 1819 | "VALUES('t',%.17g,%d,%Q,%Q)", |
| 1820 | p->rDate, rid, p->zUser, zComment |
| 1821 | ); |
| 1822 | free(zComment); |
| 1823 | } |
| 1824 | } |
| 1825 | if( p->type==CFTYPE_CONTROL ){ |
| 1826 | Blob comment; |
| 1827 | int i; |
| 1828 | const char *zName; |
| 1829 | const char *zValue; |
| 1830 | const char *zUuid; |
| 1831 | blob_zero(&comment); |
| 1832 | for(i=0; i<p->nTag; i++){ |
| 1833 | zUuid = p->aTag[i].zUuid; |
| 1834 | if( i==0 || fossil_strcmp(zUuid, p->aTag[i-1].zUuid)!=0 ){ |
| 1835 | if( i>0 ) blob_append(&comment, " ", 1); |
| 1836 | blob_appendf(&comment, "Tag changes on [/timeline?dp=%S&n=4 | %S]:", |
| 1837 | zUuid, zUuid); |
| 1838 | } |
| 1839 | zName = p->aTag[i].zName; |
| 1840 | zValue = p->aTag[i].zValue; |
| 1841 | if( zName[0]=='-' ){ |
| 1842 | blob_appendf(&comment, " Cancel"); |
| 1843 | }else if( zName[0]=='+' ){ |
| 1844 | blob_appendf(&comment, " Add"); |
| 1845 | }else{ |
| 1846 | blob_appendf(&comment, " Add propagating"); |
| 1847 | } |
| 1848 | if( memcmp(&zName[1], "sym-",4)==0 ){ |
| 1849 | blob_appendf(&comment, " symbolic tag \"%h\".", &zName[5]); |
| 1850 | }else if( fossil_strcmp(&zName[1], "comment")!=0 && zValue && zValue[0] ){ |
| 1851 | blob_appendf(&comment, " %h=%h.", &zName[1], zValue); |
| 1852 | }else{ |
| 1853 | blob_appendf(&comment, " %h.", &zName[1]); |
| 1854 | } |
| 1855 | } |
| 1856 | db_multi_exec( |
| 1857 | "REPLACE INTO event(type,mtime,objid,user,comment)" |
| 1858 | "VALUES('g',%.17g,%d,%Q,%Q)", |
| 1859 | p->rDate, rid, p->zUser, blob_str(&comment) |
| 1860 | ); |
| 1861 | blob_reset(&comment); |
| 1862 | } |
| 1863 | db_end_transaction(0); |
| 1864 | if( p->type==CFTYPE_MANIFEST ){ |
| 1865 | manifest_cache_insert(p); |
| 1866 | }else{ |
| 1867 |
+18
-4
| --- src/merge.c | ||
| +++ src/merge.c | ||
| @@ -73,10 +73,11 @@ | ||
| 73 | 73 | int debugFlag; /* True if --debug is present */ |
| 74 | 74 | int nChng; /* Number of file name changes */ |
| 75 | 75 | int *aChng; /* An array of file name changes */ |
| 76 | 76 | int i; /* Loop counter */ |
| 77 | 77 | int nConflict = 0; /* Number of conflicts seen */ |
| 78 | + int nOverwrite = 0; /* Number of unmanaged files overwritten */ | |
| 78 | 79 | int caseSensitive; /* True for case-sensitive filenames */ |
| 79 | 80 | Stmt q; |
| 80 | 81 | |
| 81 | 82 | |
| 82 | 83 | /* Notation: |
| @@ -319,19 +320,27 @@ | ||
| 319 | 320 | while( db_step(&q)==SQLITE_ROW ){ |
| 320 | 321 | int idm = db_column_int(&q, 0); |
| 321 | 322 | int rowid = db_column_int(&q, 1); |
| 322 | 323 | int idv; |
| 323 | 324 | const char *zName; |
| 325 | + char *zFullName; | |
| 324 | 326 | db_multi_exec( |
| 325 | 327 | "INSERT INTO vfile(vid,chnged,deleted,rid,mrid,isexe,islink,pathname)" |
| 326 | 328 | " SELECT %d,3,0,rid,mrid,isexe,islink,pathname FROM vfile WHERE id=%d", |
| 327 | 329 | vid, idm |
| 328 | 330 | ); |
| 329 | 331 | idv = db_last_insert_rowid(); |
| 330 | 332 | db_multi_exec("UPDATE fv SET idv=%d WHERE rowid=%d", idv, rowid); |
| 331 | 333 | zName = db_column_text(&q, 2); |
| 332 | - fossil_print("ADDED %s\n", zName); | |
| 334 | + zFullName = mprintf("%s%s", g.zLocalRoot, zName); | |
| 335 | + if( file_wd_isfile_or_link(zFullName) ){ | |
| 336 | + fossil_print("ADDED %s (overwrites an unmanaged file)\n", zName); | |
| 337 | + nOverwrite++; | |
| 338 | + }else{ | |
| 339 | + fossil_print("ADDED %s\n", zName); | |
| 340 | + } | |
| 341 | + fossil_free(zFullName); | |
| 333 | 342 | if( !nochangeFlag ){ |
| 334 | 343 | undo_save(zName); |
| 335 | 344 | vfile_to_disk(0, idm, 0, 0); |
| 336 | 345 | } |
| 337 | 346 | } |
| @@ -495,13 +504,18 @@ | ||
| 495 | 504 | db_finalize(&q); |
| 496 | 505 | |
| 497 | 506 | |
| 498 | 507 | /* Report on conflicts |
| 499 | 508 | */ |
| 500 | - if( nConflict && !nochangeFlag ){ | |
| 501 | - fossil_warning( | |
| 502 | - "WARNING: merge conflicts - see messages above for details.\n"); | |
| 509 | + if( !nochangeFlag ){ | |
| 510 | + if( nConflict ){ | |
| 511 | + fossil_print("WARNING: %d merge conflicts", nConflict); | |
| 512 | + } | |
| 513 | + if( nOverwrite ){ | |
| 514 | + fossil_warning("WARNING: %d unmanaged files where overwritten", | |
| 515 | + nOverwrite); | |
| 516 | + } | |
| 503 | 517 | } |
| 504 | 518 | |
| 505 | 519 | /* |
| 506 | 520 | ** Clean up the mid and pid VFILE entries. Then commit the changes. |
| 507 | 521 | */ |
| 508 | 522 |
| --- src/merge.c | |
| +++ src/merge.c | |
| @@ -73,10 +73,11 @@ | |
| 73 | int debugFlag; /* True if --debug is present */ |
| 74 | int nChng; /* Number of file name changes */ |
| 75 | int *aChng; /* An array of file name changes */ |
| 76 | int i; /* Loop counter */ |
| 77 | int nConflict = 0; /* Number of conflicts seen */ |
| 78 | int caseSensitive; /* True for case-sensitive filenames */ |
| 79 | Stmt q; |
| 80 | |
| 81 | |
| 82 | /* Notation: |
| @@ -319,19 +320,27 @@ | |
| 319 | while( db_step(&q)==SQLITE_ROW ){ |
| 320 | int idm = db_column_int(&q, 0); |
| 321 | int rowid = db_column_int(&q, 1); |
| 322 | int idv; |
| 323 | const char *zName; |
| 324 | db_multi_exec( |
| 325 | "INSERT INTO vfile(vid,chnged,deleted,rid,mrid,isexe,islink,pathname)" |
| 326 | " SELECT %d,3,0,rid,mrid,isexe,islink,pathname FROM vfile WHERE id=%d", |
| 327 | vid, idm |
| 328 | ); |
| 329 | idv = db_last_insert_rowid(); |
| 330 | db_multi_exec("UPDATE fv SET idv=%d WHERE rowid=%d", idv, rowid); |
| 331 | zName = db_column_text(&q, 2); |
| 332 | fossil_print("ADDED %s\n", zName); |
| 333 | if( !nochangeFlag ){ |
| 334 | undo_save(zName); |
| 335 | vfile_to_disk(0, idm, 0, 0); |
| 336 | } |
| 337 | } |
| @@ -495,13 +504,18 @@ | |
| 495 | db_finalize(&q); |
| 496 | |
| 497 | |
| 498 | /* Report on conflicts |
| 499 | */ |
| 500 | if( nConflict && !nochangeFlag ){ |
| 501 | fossil_warning( |
| 502 | "WARNING: merge conflicts - see messages above for details.\n"); |
| 503 | } |
| 504 | |
| 505 | /* |
| 506 | ** Clean up the mid and pid VFILE entries. Then commit the changes. |
| 507 | */ |
| 508 |
| --- src/merge.c | |
| +++ src/merge.c | |
| @@ -73,10 +73,11 @@ | |
| 73 | int debugFlag; /* True if --debug is present */ |
| 74 | int nChng; /* Number of file name changes */ |
| 75 | int *aChng; /* An array of file name changes */ |
| 76 | int i; /* Loop counter */ |
| 77 | int nConflict = 0; /* Number of conflicts seen */ |
| 78 | int nOverwrite = 0; /* Number of unmanaged files overwritten */ |
| 79 | int caseSensitive; /* True for case-sensitive filenames */ |
| 80 | Stmt q; |
| 81 | |
| 82 | |
| 83 | /* Notation: |
| @@ -319,19 +320,27 @@ | |
| 320 | while( db_step(&q)==SQLITE_ROW ){ |
| 321 | int idm = db_column_int(&q, 0); |
| 322 | int rowid = db_column_int(&q, 1); |
| 323 | int idv; |
| 324 | const char *zName; |
| 325 | char *zFullName; |
| 326 | db_multi_exec( |
| 327 | "INSERT INTO vfile(vid,chnged,deleted,rid,mrid,isexe,islink,pathname)" |
| 328 | " SELECT %d,3,0,rid,mrid,isexe,islink,pathname FROM vfile WHERE id=%d", |
| 329 | vid, idm |
| 330 | ); |
| 331 | idv = db_last_insert_rowid(); |
| 332 | db_multi_exec("UPDATE fv SET idv=%d WHERE rowid=%d", idv, rowid); |
| 333 | zName = db_column_text(&q, 2); |
| 334 | zFullName = mprintf("%s%s", g.zLocalRoot, zName); |
| 335 | if( file_wd_isfile_or_link(zFullName) ){ |
| 336 | fossil_print("ADDED %s (overwrites an unmanaged file)\n", zName); |
| 337 | nOverwrite++; |
| 338 | }else{ |
| 339 | fossil_print("ADDED %s\n", zName); |
| 340 | } |
| 341 | fossil_free(zFullName); |
| 342 | if( !nochangeFlag ){ |
| 343 | undo_save(zName); |
| 344 | vfile_to_disk(0, idm, 0, 0); |
| 345 | } |
| 346 | } |
| @@ -495,13 +504,18 @@ | |
| 504 | db_finalize(&q); |
| 505 | |
| 506 | |
| 507 | /* Report on conflicts |
| 508 | */ |
| 509 | if( !nochangeFlag ){ |
| 510 | if( nConflict ){ |
| 511 | fossil_print("WARNING: %d merge conflicts", nConflict); |
| 512 | } |
| 513 | if( nOverwrite ){ |
| 514 | fossil_warning("WARNING: %d unmanaged files where overwritten", |
| 515 | nOverwrite); |
| 516 | } |
| 517 | } |
| 518 | |
| 519 | /* |
| 520 | ** Clean up the mid and pid VFILE entries. Then commit the changes. |
| 521 | */ |
| 522 |
+3
-19
| --- src/report.c | ||
| +++ src/report.c | ||
| @@ -631,17 +631,11 @@ | ||
| 631 | 631 | char **azName /* Names of the columns */ |
| 632 | 632 | ){ |
| 633 | 633 | struct GenerateHTML *pState = (struct GenerateHTML*)pUser; |
| 634 | 634 | int i; |
| 635 | 635 | const char *zTid; /* Ticket UUID. (value of column named '#') */ |
| 636 | - int rn; /* Report number */ | |
| 637 | 636 | char *zBg = 0; /* Use this background color */ |
| 638 | - char zPage[30]; /* Text version of the ticket number */ | |
| 639 | - | |
| 640 | - /* Get the report number | |
| 641 | - */ | |
| 642 | - rn = pState->rn; | |
| 643 | 637 | |
| 644 | 638 | /* Do initialization |
| 645 | 639 | */ |
| 646 | 640 | if( pState->nCount==0 ){ |
| 647 | 641 | /* Turn off the authorizer. It is no longer doing anything since the |
| @@ -720,11 +714,10 @@ | ||
| 720 | 714 | */ |
| 721 | 715 | zBg = pState->iBg>=0 ? azArg[pState->iBg] : 0; |
| 722 | 716 | if( zBg==0 ) zBg = "white"; |
| 723 | 717 | @ <tr style="background-color:%h(zBg)"> |
| 724 | 718 | zTid = 0; |
| 725 | - zPage[0] = 0; | |
| 726 | 719 | for(i=0; i<nArg; i++){ |
| 727 | 720 | char *zData; |
| 728 | 721 | if( i==pState->iBg ) continue; |
| 729 | 722 | zData = azArg[i]; |
| 730 | 723 | if( zData==0 ) zData = ""; |
| @@ -1109,41 +1102,32 @@ | ||
| 1109 | 1102 | const char *zFilter, |
| 1110 | 1103 | tTktShowEncoding enc |
| 1111 | 1104 | ){ |
| 1112 | 1105 | Stmt q; |
| 1113 | 1106 | char *zSql; |
| 1114 | - const char *zTitle; | |
| 1115 | - const char *zOwner; | |
| 1116 | - const char *zClrKey; | |
| 1117 | 1107 | char *zErr1 = 0; |
| 1118 | 1108 | char *zErr2 = 0; |
| 1119 | 1109 | int count = 0; |
| 1120 | 1110 | int rn; |
| 1121 | 1111 | |
| 1122 | 1112 | if (!zRep || !strcmp(zRep,zFullTicketRptRn) || !strcmp(zRep,zFullTicketRptTitle) ){ |
| 1123 | - zTitle = zFullTicketRptTitle; | |
| 1124 | 1113 | zSql = "SELECT * FROM ticket"; |
| 1125 | - zOwner = g.zLogin; | |
| 1126 | - zClrKey = ""; | |
| 1127 | 1114 | }else{ |
| 1128 | 1115 | rn = atoi(zRep); |
| 1129 | 1116 | if( rn ){ |
| 1130 | 1117 | db_prepare(&q, |
| 1131 | - "SELECT title, sqlcode, owner, cols FROM reportfmt WHERE rn=%d", rn); | |
| 1118 | + "SELECT sqlcode FROM reportfmt WHERE rn=%d", rn); | |
| 1132 | 1119 | }else{ |
| 1133 | 1120 | db_prepare(&q, |
| 1134 | - "SELECT title, sqlcode, owner, cols FROM reportfmt WHERE title='%s'", zRep); | |
| 1121 | + "SELECT sqlcode FROM reportfmt WHERE title='%s'", zRep); | |
| 1135 | 1122 | } |
| 1136 | 1123 | if( db_step(&q)!=SQLITE_ROW ){ |
| 1137 | 1124 | db_finalize(&q); |
| 1138 | 1125 | rpt_list_reports(); |
| 1139 | 1126 | fossil_fatal("unknown report format(%s)!",zRep); |
| 1140 | 1127 | } |
| 1141 | - zTitle = db_column_malloc(&q, 0); | |
| 1142 | - zSql = db_column_malloc(&q, 1); | |
| 1143 | - zOwner = db_column_malloc(&q, 2); | |
| 1144 | - zClrKey = db_column_malloc(&q, 3); | |
| 1128 | + zSql = db_column_malloc(&q, 0); | |
| 1145 | 1129 | db_finalize(&q); |
| 1146 | 1130 | } |
| 1147 | 1131 | if( zFilter ){ |
| 1148 | 1132 | zSql = mprintf("SELECT * FROM (%s) WHERE %s",zSql,zFilter); |
| 1149 | 1133 | } |
| 1150 | 1134 |
| --- src/report.c | |
| +++ src/report.c | |
| @@ -631,17 +631,11 @@ | |
| 631 | char **azName /* Names of the columns */ |
| 632 | ){ |
| 633 | struct GenerateHTML *pState = (struct GenerateHTML*)pUser; |
| 634 | int i; |
| 635 | const char *zTid; /* Ticket UUID. (value of column named '#') */ |
| 636 | int rn; /* Report number */ |
| 637 | char *zBg = 0; /* Use this background color */ |
| 638 | char zPage[30]; /* Text version of the ticket number */ |
| 639 | |
| 640 | /* Get the report number |
| 641 | */ |
| 642 | rn = pState->rn; |
| 643 | |
| 644 | /* Do initialization |
| 645 | */ |
| 646 | if( pState->nCount==0 ){ |
| 647 | /* Turn off the authorizer. It is no longer doing anything since the |
| @@ -720,11 +714,10 @@ | |
| 720 | */ |
| 721 | zBg = pState->iBg>=0 ? azArg[pState->iBg] : 0; |
| 722 | if( zBg==0 ) zBg = "white"; |
| 723 | @ <tr style="background-color:%h(zBg)"> |
| 724 | zTid = 0; |
| 725 | zPage[0] = 0; |
| 726 | for(i=0; i<nArg; i++){ |
| 727 | char *zData; |
| 728 | if( i==pState->iBg ) continue; |
| 729 | zData = azArg[i]; |
| 730 | if( zData==0 ) zData = ""; |
| @@ -1109,41 +1102,32 @@ | |
| 1109 | const char *zFilter, |
| 1110 | tTktShowEncoding enc |
| 1111 | ){ |
| 1112 | Stmt q; |
| 1113 | char *zSql; |
| 1114 | const char *zTitle; |
| 1115 | const char *zOwner; |
| 1116 | const char *zClrKey; |
| 1117 | char *zErr1 = 0; |
| 1118 | char *zErr2 = 0; |
| 1119 | int count = 0; |
| 1120 | int rn; |
| 1121 | |
| 1122 | if (!zRep || !strcmp(zRep,zFullTicketRptRn) || !strcmp(zRep,zFullTicketRptTitle) ){ |
| 1123 | zTitle = zFullTicketRptTitle; |
| 1124 | zSql = "SELECT * FROM ticket"; |
| 1125 | zOwner = g.zLogin; |
| 1126 | zClrKey = ""; |
| 1127 | }else{ |
| 1128 | rn = atoi(zRep); |
| 1129 | if( rn ){ |
| 1130 | db_prepare(&q, |
| 1131 | "SELECT title, sqlcode, owner, cols FROM reportfmt WHERE rn=%d", rn); |
| 1132 | }else{ |
| 1133 | db_prepare(&q, |
| 1134 | "SELECT title, sqlcode, owner, cols FROM reportfmt WHERE title='%s'", zRep); |
| 1135 | } |
| 1136 | if( db_step(&q)!=SQLITE_ROW ){ |
| 1137 | db_finalize(&q); |
| 1138 | rpt_list_reports(); |
| 1139 | fossil_fatal("unknown report format(%s)!",zRep); |
| 1140 | } |
| 1141 | zTitle = db_column_malloc(&q, 0); |
| 1142 | zSql = db_column_malloc(&q, 1); |
| 1143 | zOwner = db_column_malloc(&q, 2); |
| 1144 | zClrKey = db_column_malloc(&q, 3); |
| 1145 | db_finalize(&q); |
| 1146 | } |
| 1147 | if( zFilter ){ |
| 1148 | zSql = mprintf("SELECT * FROM (%s) WHERE %s",zSql,zFilter); |
| 1149 | } |
| 1150 |
| --- src/report.c | |
| +++ src/report.c | |
| @@ -631,17 +631,11 @@ | |
| 631 | char **azName /* Names of the columns */ |
| 632 | ){ |
| 633 | struct GenerateHTML *pState = (struct GenerateHTML*)pUser; |
| 634 | int i; |
| 635 | const char *zTid; /* Ticket UUID. (value of column named '#') */ |
| 636 | char *zBg = 0; /* Use this background color */ |
| 637 | |
| 638 | /* Do initialization |
| 639 | */ |
| 640 | if( pState->nCount==0 ){ |
| 641 | /* Turn off the authorizer. It is no longer doing anything since the |
| @@ -720,11 +714,10 @@ | |
| 714 | */ |
| 715 | zBg = pState->iBg>=0 ? azArg[pState->iBg] : 0; |
| 716 | if( zBg==0 ) zBg = "white"; |
| 717 | @ <tr style="background-color:%h(zBg)"> |
| 718 | zTid = 0; |
| 719 | for(i=0; i<nArg; i++){ |
| 720 | char *zData; |
| 721 | if( i==pState->iBg ) continue; |
| 722 | zData = azArg[i]; |
| 723 | if( zData==0 ) zData = ""; |
| @@ -1109,41 +1102,32 @@ | |
| 1102 | const char *zFilter, |
| 1103 | tTktShowEncoding enc |
| 1104 | ){ |
| 1105 | Stmt q; |
| 1106 | char *zSql; |
| 1107 | char *zErr1 = 0; |
| 1108 | char *zErr2 = 0; |
| 1109 | int count = 0; |
| 1110 | int rn; |
| 1111 | |
| 1112 | if (!zRep || !strcmp(zRep,zFullTicketRptRn) || !strcmp(zRep,zFullTicketRptTitle) ){ |
| 1113 | zSql = "SELECT * FROM ticket"; |
| 1114 | }else{ |
| 1115 | rn = atoi(zRep); |
| 1116 | if( rn ){ |
| 1117 | db_prepare(&q, |
| 1118 | "SELECT sqlcode FROM reportfmt WHERE rn=%d", rn); |
| 1119 | }else{ |
| 1120 | db_prepare(&q, |
| 1121 | "SELECT sqlcode FROM reportfmt WHERE title='%s'", zRep); |
| 1122 | } |
| 1123 | if( db_step(&q)!=SQLITE_ROW ){ |
| 1124 | db_finalize(&q); |
| 1125 | rpt_list_reports(); |
| 1126 | fossil_fatal("unknown report format(%s)!",zRep); |
| 1127 | } |
| 1128 | zSql = db_column_malloc(&q, 0); |
| 1129 | db_finalize(&q); |
| 1130 | } |
| 1131 | if( zFilter ){ |
| 1132 | zSql = mprintf("SELECT * FROM (%s) WHERE %s",zSql,zFilter); |
| 1133 | } |
| 1134 |
+3
-19
| --- src/report.c | ||
| +++ src/report.c | ||
| @@ -631,17 +631,11 @@ | ||
| 631 | 631 | char **azName /* Names of the columns */ |
| 632 | 632 | ){ |
| 633 | 633 | struct GenerateHTML *pState = (struct GenerateHTML*)pUser; |
| 634 | 634 | int i; |
| 635 | 635 | const char *zTid; /* Ticket UUID. (value of column named '#') */ |
| 636 | - int rn; /* Report number */ | |
| 637 | 636 | char *zBg = 0; /* Use this background color */ |
| 638 | - char zPage[30]; /* Text version of the ticket number */ | |
| 639 | - | |
| 640 | - /* Get the report number | |
| 641 | - */ | |
| 642 | - rn = pState->rn; | |
| 643 | 637 | |
| 644 | 638 | /* Do initialization |
| 645 | 639 | */ |
| 646 | 640 | if( pState->nCount==0 ){ |
| 647 | 641 | /* Turn off the authorizer. It is no longer doing anything since the |
| @@ -720,11 +714,10 @@ | ||
| 720 | 714 | */ |
| 721 | 715 | zBg = pState->iBg>=0 ? azArg[pState->iBg] : 0; |
| 722 | 716 | if( zBg==0 ) zBg = "white"; |
| 723 | 717 | @ <tr style="background-color:%h(zBg)"> |
| 724 | 718 | zTid = 0; |
| 725 | - zPage[0] = 0; | |
| 726 | 719 | for(i=0; i<nArg; i++){ |
| 727 | 720 | char *zData; |
| 728 | 721 | if( i==pState->iBg ) continue; |
| 729 | 722 | zData = azArg[i]; |
| 730 | 723 | if( zData==0 ) zData = ""; |
| @@ -1109,41 +1102,32 @@ | ||
| 1109 | 1102 | const char *zFilter, |
| 1110 | 1103 | tTktShowEncoding enc |
| 1111 | 1104 | ){ |
| 1112 | 1105 | Stmt q; |
| 1113 | 1106 | char *zSql; |
| 1114 | - const char *zTitle; | |
| 1115 | - const char *zOwner; | |
| 1116 | - const char *zClrKey; | |
| 1117 | 1107 | char *zErr1 = 0; |
| 1118 | 1108 | char *zErr2 = 0; |
| 1119 | 1109 | int count = 0; |
| 1120 | 1110 | int rn; |
| 1121 | 1111 | |
| 1122 | 1112 | if (!zRep || !strcmp(zRep,zFullTicketRptRn) || !strcmp(zRep,zFullTicketRptTitle) ){ |
| 1123 | - zTitle = zFullTicketRptTitle; | |
| 1124 | 1113 | zSql = "SELECT * FROM ticket"; |
| 1125 | - zOwner = g.zLogin; | |
| 1126 | - zClrKey = ""; | |
| 1127 | 1114 | }else{ |
| 1128 | 1115 | rn = atoi(zRep); |
| 1129 | 1116 | if( rn ){ |
| 1130 | 1117 | db_prepare(&q, |
| 1131 | - "SELECT title, sqlcode, owner, cols FROM reportfmt WHERE rn=%d", rn); | |
| 1118 | + "SELECT sqlcode FROM reportfmt WHERE rn=%d", rn); | |
| 1132 | 1119 | }else{ |
| 1133 | 1120 | db_prepare(&q, |
| 1134 | - "SELECT title, sqlcode, owner, cols FROM reportfmt WHERE title='%s'", zRep); | |
| 1121 | + "SELECT sqlcode FROM reportfmt WHERE title='%s'", zRep); | |
| 1135 | 1122 | } |
| 1136 | 1123 | if( db_step(&q)!=SQLITE_ROW ){ |
| 1137 | 1124 | db_finalize(&q); |
| 1138 | 1125 | rpt_list_reports(); |
| 1139 | 1126 | fossil_fatal("unknown report format(%s)!",zRep); |
| 1140 | 1127 | } |
| 1141 | - zTitle = db_column_malloc(&q, 0); | |
| 1142 | - zSql = db_column_malloc(&q, 1); | |
| 1143 | - zOwner = db_column_malloc(&q, 2); | |
| 1144 | - zClrKey = db_column_malloc(&q, 3); | |
| 1128 | + zSql = db_column_malloc(&q, 0); | |
| 1145 | 1129 | db_finalize(&q); |
| 1146 | 1130 | } |
| 1147 | 1131 | if( zFilter ){ |
| 1148 | 1132 | zSql = mprintf("SELECT * FROM (%s) WHERE %s",zSql,zFilter); |
| 1149 | 1133 | } |
| 1150 | 1134 |
| --- src/report.c | |
| +++ src/report.c | |
| @@ -631,17 +631,11 @@ | |
| 631 | char **azName /* Names of the columns */ |
| 632 | ){ |
| 633 | struct GenerateHTML *pState = (struct GenerateHTML*)pUser; |
| 634 | int i; |
| 635 | const char *zTid; /* Ticket UUID. (value of column named '#') */ |
| 636 | int rn; /* Report number */ |
| 637 | char *zBg = 0; /* Use this background color */ |
| 638 | char zPage[30]; /* Text version of the ticket number */ |
| 639 | |
| 640 | /* Get the report number |
| 641 | */ |
| 642 | rn = pState->rn; |
| 643 | |
| 644 | /* Do initialization |
| 645 | */ |
| 646 | if( pState->nCount==0 ){ |
| 647 | /* Turn off the authorizer. It is no longer doing anything since the |
| @@ -720,11 +714,10 @@ | |
| 720 | */ |
| 721 | zBg = pState->iBg>=0 ? azArg[pState->iBg] : 0; |
| 722 | if( zBg==0 ) zBg = "white"; |
| 723 | @ <tr style="background-color:%h(zBg)"> |
| 724 | zTid = 0; |
| 725 | zPage[0] = 0; |
| 726 | for(i=0; i<nArg; i++){ |
| 727 | char *zData; |
| 728 | if( i==pState->iBg ) continue; |
| 729 | zData = azArg[i]; |
| 730 | if( zData==0 ) zData = ""; |
| @@ -1109,41 +1102,32 @@ | |
| 1109 | const char *zFilter, |
| 1110 | tTktShowEncoding enc |
| 1111 | ){ |
| 1112 | Stmt q; |
| 1113 | char *zSql; |
| 1114 | const char *zTitle; |
| 1115 | const char *zOwner; |
| 1116 | const char *zClrKey; |
| 1117 | char *zErr1 = 0; |
| 1118 | char *zErr2 = 0; |
| 1119 | int count = 0; |
| 1120 | int rn; |
| 1121 | |
| 1122 | if (!zRep || !strcmp(zRep,zFullTicketRptRn) || !strcmp(zRep,zFullTicketRptTitle) ){ |
| 1123 | zTitle = zFullTicketRptTitle; |
| 1124 | zSql = "SELECT * FROM ticket"; |
| 1125 | zOwner = g.zLogin; |
| 1126 | zClrKey = ""; |
| 1127 | }else{ |
| 1128 | rn = atoi(zRep); |
| 1129 | if( rn ){ |
| 1130 | db_prepare(&q, |
| 1131 | "SELECT title, sqlcode, owner, cols FROM reportfmt WHERE rn=%d", rn); |
| 1132 | }else{ |
| 1133 | db_prepare(&q, |
| 1134 | "SELECT title, sqlcode, owner, cols FROM reportfmt WHERE title='%s'", zRep); |
| 1135 | } |
| 1136 | if( db_step(&q)!=SQLITE_ROW ){ |
| 1137 | db_finalize(&q); |
| 1138 | rpt_list_reports(); |
| 1139 | fossil_fatal("unknown report format(%s)!",zRep); |
| 1140 | } |
| 1141 | zTitle = db_column_malloc(&q, 0); |
| 1142 | zSql = db_column_malloc(&q, 1); |
| 1143 | zOwner = db_column_malloc(&q, 2); |
| 1144 | zClrKey = db_column_malloc(&q, 3); |
| 1145 | db_finalize(&q); |
| 1146 | } |
| 1147 | if( zFilter ){ |
| 1148 | zSql = mprintf("SELECT * FROM (%s) WHERE %s",zSql,zFilter); |
| 1149 | } |
| 1150 |
| --- src/report.c | |
| +++ src/report.c | |
| @@ -631,17 +631,11 @@ | |
| 631 | char **azName /* Names of the columns */ |
| 632 | ){ |
| 633 | struct GenerateHTML *pState = (struct GenerateHTML*)pUser; |
| 634 | int i; |
| 635 | const char *zTid; /* Ticket UUID. (value of column named '#') */ |
| 636 | char *zBg = 0; /* Use this background color */ |
| 637 | |
| 638 | /* Do initialization |
| 639 | */ |
| 640 | if( pState->nCount==0 ){ |
| 641 | /* Turn off the authorizer. It is no longer doing anything since the |
| @@ -720,11 +714,10 @@ | |
| 714 | */ |
| 715 | zBg = pState->iBg>=0 ? azArg[pState->iBg] : 0; |
| 716 | if( zBg==0 ) zBg = "white"; |
| 717 | @ <tr style="background-color:%h(zBg)"> |
| 718 | zTid = 0; |
| 719 | for(i=0; i<nArg; i++){ |
| 720 | char *zData; |
| 721 | if( i==pState->iBg ) continue; |
| 722 | zData = azArg[i]; |
| 723 | if( zData==0 ) zData = ""; |
| @@ -1109,41 +1102,32 @@ | |
| 1102 | const char *zFilter, |
| 1103 | tTktShowEncoding enc |
| 1104 | ){ |
| 1105 | Stmt q; |
| 1106 | char *zSql; |
| 1107 | char *zErr1 = 0; |
| 1108 | char *zErr2 = 0; |
| 1109 | int count = 0; |
| 1110 | int rn; |
| 1111 | |
| 1112 | if (!zRep || !strcmp(zRep,zFullTicketRptRn) || !strcmp(zRep,zFullTicketRptTitle) ){ |
| 1113 | zSql = "SELECT * FROM ticket"; |
| 1114 | }else{ |
| 1115 | rn = atoi(zRep); |
| 1116 | if( rn ){ |
| 1117 | db_prepare(&q, |
| 1118 | "SELECT sqlcode FROM reportfmt WHERE rn=%d", rn); |
| 1119 | }else{ |
| 1120 | db_prepare(&q, |
| 1121 | "SELECT sqlcode FROM reportfmt WHERE title='%s'", zRep); |
| 1122 | } |
| 1123 | if( db_step(&q)!=SQLITE_ROW ){ |
| 1124 | db_finalize(&q); |
| 1125 | rpt_list_reports(); |
| 1126 | fossil_fatal("unknown report format(%s)!",zRep); |
| 1127 | } |
| 1128 | zSql = db_column_malloc(&q, 0); |
| 1129 | db_finalize(&q); |
| 1130 | } |
| 1131 | if( zFilter ){ |
| 1132 | zSql = mprintf("SELECT * FROM (%s) WHERE %s",zSql,zFilter); |
| 1133 | } |
| 1134 |
+1
-1
| --- src/schema.c | ||
| +++ src/schema.c | ||
| @@ -251,11 +251,11 @@ | ||
| 251 | 251 | @ CREATE TABLE leaf(rid INTEGER PRIMARY KEY); |
| 252 | 252 | @ |
| 253 | 253 | @ -- Events used to generate a timeline |
| 254 | 254 | @ -- |
| 255 | 255 | @ CREATE TABLE event( |
| 256 | -@ type TEXT, -- Type of event: 'ci', 'w', 'e', 't' | |
| 256 | +@ type TEXT, -- Type of event: 'ci', 'w', 'e', 't', 'g' | |
| 257 | 257 | @ mtime DATETIME, -- Time of occurrence. Julian day. |
| 258 | 258 | @ objid INTEGER PRIMARY KEY, -- Associated record ID |
| 259 | 259 | @ tagid INTEGER, -- Associated ticket or wiki name tag |
| 260 | 260 | @ uid INTEGER REFERENCES user, -- User who caused the event |
| 261 | 261 | @ bgcolor TEXT, -- Color set by 'bgcolor' property |
| 262 | 262 |
| --- src/schema.c | |
| +++ src/schema.c | |
| @@ -251,11 +251,11 @@ | |
| 251 | @ CREATE TABLE leaf(rid INTEGER PRIMARY KEY); |
| 252 | @ |
| 253 | @ -- Events used to generate a timeline |
| 254 | @ -- |
| 255 | @ CREATE TABLE event( |
| 256 | @ type TEXT, -- Type of event: 'ci', 'w', 'e', 't' |
| 257 | @ mtime DATETIME, -- Time of occurrence. Julian day. |
| 258 | @ objid INTEGER PRIMARY KEY, -- Associated record ID |
| 259 | @ tagid INTEGER, -- Associated ticket or wiki name tag |
| 260 | @ uid INTEGER REFERENCES user, -- User who caused the event |
| 261 | @ bgcolor TEXT, -- Color set by 'bgcolor' property |
| 262 |
| --- src/schema.c | |
| +++ src/schema.c | |
| @@ -251,11 +251,11 @@ | |
| 251 | @ CREATE TABLE leaf(rid INTEGER PRIMARY KEY); |
| 252 | @ |
| 253 | @ -- Events used to generate a timeline |
| 254 | @ -- |
| 255 | @ CREATE TABLE event( |
| 256 | @ type TEXT, -- Type of event: 'ci', 'w', 'e', 't', 'g' |
| 257 | @ mtime DATETIME, -- Time of occurrence. Julian day. |
| 258 | @ objid INTEGER PRIMARY KEY, -- Associated record ID |
| 259 | @ tagid INTEGER, -- Associated ticket or wiki name tag |
| 260 | @ uid INTEGER REFERENCES user, -- User who caused the event |
| 261 | @ bgcolor TEXT, -- Color set by 'bgcolor' property |
| 262 |
+205
-1
| --- src/skins.c | ||
| +++ src/skins.c | ||
| @@ -152,10 +152,55 @@ | ||
| 152 | 152 | @ /* The label/value pairs on (for example) the vinfo page */ |
| 153 | 153 | @ table.label-value th { |
| 154 | 154 | @ vertical-align: top; |
| 155 | 155 | @ text-align: right; |
| 156 | 156 | @ padding: 0.2ex 2ex; |
| 157 | +@ } | |
| 158 | +@ | |
| 159 | +@ /* Side-by-side diff */ | |
| 160 | +@ table.sbsdiff { | |
| 161 | +@ background-color: white; | |
| 162 | +@ font-family: fixed, Dejavu Sans Mono, Monaco, Lucida Console, monospace; | |
| 163 | +@ font-size: 8pt; | |
| 164 | +@ border-collapse:collapse; | |
| 165 | +@ white-space: pre; | |
| 166 | +@ width: 98%; | |
| 167 | +@ border: 1px #000 dashed; | |
| 168 | +@ } | |
| 169 | +@ | |
| 170 | +@ table.sbsdiff th.diffhdr { | |
| 171 | +@ border-bottom: dotted; | |
| 172 | +@ border-width: 1px; | |
| 173 | +@ } | |
| 174 | +@ | |
| 175 | +@ table.sbsdiff tr td { | |
| 176 | +@ white-space: pre; | |
| 177 | +@ padding-left: 3px; | |
| 178 | +@ padding-right: 3px; | |
| 179 | +@ margin: 0px; | |
| 180 | +@ } | |
| 181 | +@ | |
| 182 | +@ table.sbsdiff tr td.lineno { | |
| 183 | +@ text-align: right; | |
| 184 | +@ } | |
| 185 | +@ | |
| 186 | +@ table.sbsdiff tr td.meta { | |
| 187 | +@ color: white; | |
| 188 | +@ background-color: rgb(20, 20, 20); | |
| 189 | +@ text-align: center; | |
| 190 | +@ } | |
| 191 | +@ | |
| 192 | +@ table.sbsdiff tr td.added { | |
| 193 | +@ background-color: rgb(230, 230, 230); | |
| 194 | +@ } | |
| 195 | +@ | |
| 196 | +@ table.sbsdiff tr td.removed { | |
| 197 | +@ background-color: rgb(200, 200, 200); | |
| 198 | +@ } | |
| 199 | +@ | |
| 200 | +@ table.sbsdiff tr td.changed { | |
| 201 | +@ background-color: rgb(220, 220, 220); | |
| 157 | 202 | @ }'); |
| 158 | 203 | @ REPLACE INTO config(name,mtime,value) VALUES('header',now(),'<html> |
| 159 | 204 | @ <head> |
| 160 | 205 | @ <title>$<project_name>: $<title></title> |
| 161 | 206 | @ <link rel="alternate" type="application/rss+xml" title="RSS Feed" |
| @@ -356,11 +401,54 @@ | ||
| 356 | 401 | @ table.label-value th { |
| 357 | 402 | @ vertical-align: top; |
| 358 | 403 | @ text-align: right; |
| 359 | 404 | @ padding: 0.2ex 2ex; |
| 360 | 405 | @ } |
| 361 | -@ '); | |
| 406 | +@ | |
| 407 | +@ /* Side-by-side diff */ | |
| 408 | +@ table.sbsdiff { | |
| 409 | +@ background-color: #ffffc5; | |
| 410 | +@ font-family: fixed, Dejavu Sans Mono, Monaco, Lucida Console, monospace; | |
| 411 | +@ font-size: 8pt; | |
| 412 | +@ border-collapse:collapse; | |
| 413 | +@ white-space: pre; | |
| 414 | +@ width: 98%; | |
| 415 | +@ border: 1px #000 dashed; | |
| 416 | +@ } | |
| 417 | +@ | |
| 418 | +@ table.sbsdiff th.diffhdr { | |
| 419 | +@ border-bottom: dotted; | |
| 420 | +@ border-width: 1px; | |
| 421 | +@ } | |
| 422 | +@ | |
| 423 | +@ table.sbsdiff tr td { | |
| 424 | +@ white-space: pre; | |
| 425 | +@ padding-left: 3px; | |
| 426 | +@ padding-right: 3px; | |
| 427 | +@ margin: 0px; | |
| 428 | +@ } | |
| 429 | +@ | |
| 430 | +@ table.sbsdiff tr td.lineno { | |
| 431 | +@ text-align: right; | |
| 432 | +@ } | |
| 433 | +@ | |
| 434 | +@ table.sbsdiff tr td.meta { | |
| 435 | +@ background-color: #a09048; | |
| 436 | +@ text-align: center; | |
| 437 | +@ } | |
| 438 | +@ | |
| 439 | +@ table.sbsdiff tr td.added { | |
| 440 | +@ background-color: rgb(210, 210, 100); | |
| 441 | +@ } | |
| 442 | +@ | |
| 443 | +@ table.sbsdiff tr td.removed { | |
| 444 | +@ background-color: rgb(190, 200, 110); | |
| 445 | +@ } | |
| 446 | +@ | |
| 447 | +@ table.sbsdiff tr td.changed { | |
| 448 | +@ background-color: rgb(200, 210, 120); | |
| 449 | +@ }'); | |
| 362 | 450 | @ REPLACE INTO config(name,mtime,value) VALUES('header',now(),'<html> |
| 363 | 451 | @ <head> |
| 364 | 452 | @ <title>$<project_name>: $<title></title> |
| 365 | 453 | @ <link rel="alternate" type="application/rss+xml" title="RSS Feed" |
| 366 | 454 | @ href="$home/timeline.rss"> |
| @@ -590,10 +678,56 @@ | ||
| 590 | 678 | @ /* The label/value pairs on (for example) the ci page */ |
| 591 | 679 | @ table.label-value th { |
| 592 | 680 | @ vertical-align: top; |
| 593 | 681 | @ text-align: right; |
| 594 | 682 | @ padding: 0.2ex 2ex; |
| 683 | +@ } | |
| 684 | +@ | |
| 685 | +@ /* Side-by-side diff */ | |
| 686 | +@ table.sbsdiff { | |
| 687 | +@ background-color: white; | |
| 688 | +@ font-family: fixed, Dejavu Sans Mono, Monaco, Lucida Console, monospace; | |
| 689 | +@ font-size: 6pt; | |
| 690 | +@ border-collapse:collapse; | |
| 691 | +@ white-space: pre; | |
| 692 | +@ width: 98%; | |
| 693 | +@ border: 1px #000 dashed; | |
| 694 | +@ } | |
| 695 | +@ | |
| 696 | +@ table.sbsdiff th.diffhdr { | |
| 697 | +@ border-bottom: dotted; | |
| 698 | +@ border-width: 1px; | |
| 699 | +@ } | |
| 700 | +@ | |
| 701 | +@ table.sbsdiff tr td { | |
| 702 | +@ white-space: pre; | |
| 703 | +@ padding-left: 3px; | |
| 704 | +@ padding-right: 3px; | |
| 705 | +@ margin: 0px; | |
| 706 | +@ } | |
| 707 | +@ | |
| 708 | +@ table.sbsdiff tr td.lineno { | |
| 709 | +@ text-align: right; | |
| 710 | +@ } | |
| 711 | +@ | |
| 712 | +@ table.sbsdiff tr td.meta { | |
| 713 | +@ color: white; | |
| 714 | +@ background-color: black; | |
| 715 | +@ text-align: center; | |
| 716 | +@ } | |
| 717 | +@ | |
| 718 | +@ table.sbsdiff tr td.added { | |
| 719 | +@ background-color: white; | |
| 720 | +@ } | |
| 721 | +@ | |
| 722 | +@ table.sbsdiff tr td.removed { | |
| 723 | +@ background-color: white; | |
| 724 | +@ text-decoration: line-through; | |
| 725 | +@ } | |
| 726 | +@ | |
| 727 | +@ table.sbsdiff tr td.changed { | |
| 728 | +@ background-color: white; | |
| 595 | 729 | @ }'); |
| 596 | 730 | @ REPLACE INTO config(name,mtime,value) VALUES('header',now(),'<html> |
| 597 | 731 | @ <head> |
| 598 | 732 | @ <title>$<project_name>: $<title></title> |
| 599 | 733 | @ <link rel="alternate" type="application/rss+xml" title="RSS Feed" |
| @@ -885,10 +1019,77 @@ | ||
| 885 | 1019 | @ padding: 3px 5px; |
| 886 | 1020 | @ } |
| 887 | 1021 | @ |
| 888 | 1022 | @ textarea { |
| 889 | 1023 | @ font-size: 1em; |
| 1024 | +@ } | |
| 1025 | +@ | |
| 1026 | +@ /* Side-by-side diff */ | |
| 1027 | +@ table.sbsdiff { | |
| 1028 | +@ background-color: white; | |
| 1029 | +@ font-family: Dejavu Sans Mono, Monaco, Lucida Console, monospace; | |
| 1030 | +@ font-size: 6pt; | |
| 1031 | +@ border-collapse:collapse; | |
| 1032 | +@ width: 98%; | |
| 1033 | +@ border: 1px #000 dashed; | |
| 1034 | +@ margin-left: auto; | |
| 1035 | +@ margin-right: auto; | |
| 1036 | +@ } | |
| 1037 | +@ | |
| 1038 | +@ table.sbsdiff th.diffhdr { | |
| 1039 | +@ border-bottom: dotted; | |
| 1040 | +@ border-width: 1px; | |
| 1041 | +@ } | |
| 1042 | +@ | |
| 1043 | +@ table.sbsdiff tr td { | |
| 1044 | +@ padding-left: 3px; | |
| 1045 | +@ padding-right: 3px; | |
| 1046 | +@ margin: 0px; | |
| 1047 | +@ vertical-align: top; | |
| 1048 | +@ white-space: pre-wrap; | |
| 1049 | +@ } | |
| 1050 | +@ | |
| 1051 | +@ table.sbsdiff tr td.lineno { | |
| 1052 | +@ text-align: right; | |
| 1053 | +@ /* border-bottom: 1px solid rgb(220, 220, 220); */ | |
| 1054 | +@ } | |
| 1055 | +@ | |
| 1056 | +@ table.sbsdiff tr td.srcline { | |
| 1057 | +@ /* max-width: 400px; */ | |
| 1058 | +@ /* Note: May partially hide long lines without whitespaces */ | |
| 1059 | +@ /* overflow: hidden; */ | |
| 1060 | +@ /* border-bottom: 1px solid rgb(220, 220, 220); */ | |
| 1061 | +@ } | |
| 1062 | +@ | |
| 1063 | +@ table.sbsdiff tr td.meta { | |
| 1064 | +@ background-color: rgb(170, 160, 255); | |
| 1065 | +@ padding-top: 0.25em; | |
| 1066 | +@ padding-bottom: 0.25em; | |
| 1067 | +@ text-align: center; | |
| 1068 | +@ -moz-border-radius: 5px; | |
| 1069 | +@ -moz-border-radius: 5px; | |
| 1070 | +@ -webkit-border-radius: 5px; | |
| 1071 | +@ -webkit-border-radius: 5px; | |
| 1072 | +@ -border-radius: 5px; | |
| 1073 | +@ -border-radius: 5px; | |
| 1074 | +@ border-radius: 5px; | |
| 1075 | +@ border-radius: 5px; | |
| 1076 | +@ } | |
| 1077 | +@ | |
| 1078 | +@ table.sbsdiff tr td.added { | |
| 1079 | +@ background-color: rgb(180, 250, 180); | |
| 1080 | +@ /* border-bottom: 1px solid rgb(160, 230, 160); */ | |
| 1081 | +@ } | |
| 1082 | +@ | |
| 1083 | +@ table.sbsdiff tr td.removed { | |
| 1084 | +@ background-color: rgb(250, 130, 130); | |
| 1085 | +@ /* border-bottom: 1px solid rgb(230, 110, 110); */ | |
| 1086 | +@ } | |
| 1087 | +@ | |
| 1088 | +@ table.sbsdiff tr td.changed { | |
| 1089 | +@ background-color: rgb(210, 210, 200); | |
| 1090 | +@ /* border-bottom: 1px solid rgb(190, 190, 180); */ | |
| 890 | 1091 | @ }'); |
| 891 | 1092 | @ REPLACE INTO config(name,mtime,value) VALUES('header',now(),'<html> |
| 892 | 1093 | @ <head> |
| 893 | 1094 | @ <title>$<project_name>: $<title></title> |
| 894 | 1095 | @ <link rel="alternate" type="application/rss+xml" title="RSS Feed" |
| @@ -1100,10 +1301,13 @@ | ||
| 1100 | 1301 | db_multi_exec("%s", zCurrent); |
| 1101 | 1302 | } |
| 1102 | 1303 | } |
| 1103 | 1304 | |
| 1104 | 1305 | style_header("Skins"); |
| 1306 | + if( zErr ){ | |
| 1307 | + @ <p><font color="red">%h(zErr)</font></p> | |
| 1308 | + } | |
| 1105 | 1309 | @ <p>A "skin" is a combination of |
| 1106 | 1310 | @ <a href="setup_editcss">CSS</a>, |
| 1107 | 1311 | @ <a href="setup_header">Header</a>, |
| 1108 | 1312 | @ <a href="setup_footer">Footer</a>, and |
| 1109 | 1313 | @ <a href="setup_logo">Logo</a> that determines the look and feel |
| 1110 | 1314 |
| --- src/skins.c | |
| +++ src/skins.c | |
| @@ -152,10 +152,55 @@ | |
| 152 | @ /* The label/value pairs on (for example) the vinfo page */ |
| 153 | @ table.label-value th { |
| 154 | @ vertical-align: top; |
| 155 | @ text-align: right; |
| 156 | @ padding: 0.2ex 2ex; |
| 157 | @ }'); |
| 158 | @ REPLACE INTO config(name,mtime,value) VALUES('header',now(),'<html> |
| 159 | @ <head> |
| 160 | @ <title>$<project_name>: $<title></title> |
| 161 | @ <link rel="alternate" type="application/rss+xml" title="RSS Feed" |
| @@ -356,11 +401,54 @@ | |
| 356 | @ table.label-value th { |
| 357 | @ vertical-align: top; |
| 358 | @ text-align: right; |
| 359 | @ padding: 0.2ex 2ex; |
| 360 | @ } |
| 361 | @ '); |
| 362 | @ REPLACE INTO config(name,mtime,value) VALUES('header',now(),'<html> |
| 363 | @ <head> |
| 364 | @ <title>$<project_name>: $<title></title> |
| 365 | @ <link rel="alternate" type="application/rss+xml" title="RSS Feed" |
| 366 | @ href="$home/timeline.rss"> |
| @@ -590,10 +678,56 @@ | |
| 590 | @ /* The label/value pairs on (for example) the ci page */ |
| 591 | @ table.label-value th { |
| 592 | @ vertical-align: top; |
| 593 | @ text-align: right; |
| 594 | @ padding: 0.2ex 2ex; |
| 595 | @ }'); |
| 596 | @ REPLACE INTO config(name,mtime,value) VALUES('header',now(),'<html> |
| 597 | @ <head> |
| 598 | @ <title>$<project_name>: $<title></title> |
| 599 | @ <link rel="alternate" type="application/rss+xml" title="RSS Feed" |
| @@ -885,10 +1019,77 @@ | |
| 885 | @ padding: 3px 5px; |
| 886 | @ } |
| 887 | @ |
| 888 | @ textarea { |
| 889 | @ font-size: 1em; |
| 890 | @ }'); |
| 891 | @ REPLACE INTO config(name,mtime,value) VALUES('header',now(),'<html> |
| 892 | @ <head> |
| 893 | @ <title>$<project_name>: $<title></title> |
| 894 | @ <link rel="alternate" type="application/rss+xml" title="RSS Feed" |
| @@ -1100,10 +1301,13 @@ | |
| 1100 | db_multi_exec("%s", zCurrent); |
| 1101 | } |
| 1102 | } |
| 1103 | |
| 1104 | style_header("Skins"); |
| 1105 | @ <p>A "skin" is a combination of |
| 1106 | @ <a href="setup_editcss">CSS</a>, |
| 1107 | @ <a href="setup_header">Header</a>, |
| 1108 | @ <a href="setup_footer">Footer</a>, and |
| 1109 | @ <a href="setup_logo">Logo</a> that determines the look and feel |
| 1110 |
| --- src/skins.c | |
| +++ src/skins.c | |
| @@ -152,10 +152,55 @@ | |
| 152 | @ /* The label/value pairs on (for example) the vinfo page */ |
| 153 | @ table.label-value th { |
| 154 | @ vertical-align: top; |
| 155 | @ text-align: right; |
| 156 | @ padding: 0.2ex 2ex; |
| 157 | @ } |
| 158 | @ |
| 159 | @ /* Side-by-side diff */ |
| 160 | @ table.sbsdiff { |
| 161 | @ background-color: white; |
| 162 | @ font-family: fixed, Dejavu Sans Mono, Monaco, Lucida Console, monospace; |
| 163 | @ font-size: 8pt; |
| 164 | @ border-collapse:collapse; |
| 165 | @ white-space: pre; |
| 166 | @ width: 98%; |
| 167 | @ border: 1px #000 dashed; |
| 168 | @ } |
| 169 | @ |
| 170 | @ table.sbsdiff th.diffhdr { |
| 171 | @ border-bottom: dotted; |
| 172 | @ border-width: 1px; |
| 173 | @ } |
| 174 | @ |
| 175 | @ table.sbsdiff tr td { |
| 176 | @ white-space: pre; |
| 177 | @ padding-left: 3px; |
| 178 | @ padding-right: 3px; |
| 179 | @ margin: 0px; |
| 180 | @ } |
| 181 | @ |
| 182 | @ table.sbsdiff tr td.lineno { |
| 183 | @ text-align: right; |
| 184 | @ } |
| 185 | @ |
| 186 | @ table.sbsdiff tr td.meta { |
| 187 | @ color: white; |
| 188 | @ background-color: rgb(20, 20, 20); |
| 189 | @ text-align: center; |
| 190 | @ } |
| 191 | @ |
| 192 | @ table.sbsdiff tr td.added { |
| 193 | @ background-color: rgb(230, 230, 230); |
| 194 | @ } |
| 195 | @ |
| 196 | @ table.sbsdiff tr td.removed { |
| 197 | @ background-color: rgb(200, 200, 200); |
| 198 | @ } |
| 199 | @ |
| 200 | @ table.sbsdiff tr td.changed { |
| 201 | @ background-color: rgb(220, 220, 220); |
| 202 | @ }'); |
| 203 | @ REPLACE INTO config(name,mtime,value) VALUES('header',now(),'<html> |
| 204 | @ <head> |
| 205 | @ <title>$<project_name>: $<title></title> |
| 206 | @ <link rel="alternate" type="application/rss+xml" title="RSS Feed" |
| @@ -356,11 +401,54 @@ | |
| 401 | @ table.label-value th { |
| 402 | @ vertical-align: top; |
| 403 | @ text-align: right; |
| 404 | @ padding: 0.2ex 2ex; |
| 405 | @ } |
| 406 | @ |
| 407 | @ /* Side-by-side diff */ |
| 408 | @ table.sbsdiff { |
| 409 | @ background-color: #ffffc5; |
| 410 | @ font-family: fixed, Dejavu Sans Mono, Monaco, Lucida Console, monospace; |
| 411 | @ font-size: 8pt; |
| 412 | @ border-collapse:collapse; |
| 413 | @ white-space: pre; |
| 414 | @ width: 98%; |
| 415 | @ border: 1px #000 dashed; |
| 416 | @ } |
| 417 | @ |
| 418 | @ table.sbsdiff th.diffhdr { |
| 419 | @ border-bottom: dotted; |
| 420 | @ border-width: 1px; |
| 421 | @ } |
| 422 | @ |
| 423 | @ table.sbsdiff tr td { |
| 424 | @ white-space: pre; |
| 425 | @ padding-left: 3px; |
| 426 | @ padding-right: 3px; |
| 427 | @ margin: 0px; |
| 428 | @ } |
| 429 | @ |
| 430 | @ table.sbsdiff tr td.lineno { |
| 431 | @ text-align: right; |
| 432 | @ } |
| 433 | @ |
| 434 | @ table.sbsdiff tr td.meta { |
| 435 | @ background-color: #a09048; |
| 436 | @ text-align: center; |
| 437 | @ } |
| 438 | @ |
| 439 | @ table.sbsdiff tr td.added { |
| 440 | @ background-color: rgb(210, 210, 100); |
| 441 | @ } |
| 442 | @ |
| 443 | @ table.sbsdiff tr td.removed { |
| 444 | @ background-color: rgb(190, 200, 110); |
| 445 | @ } |
| 446 | @ |
| 447 | @ table.sbsdiff tr td.changed { |
| 448 | @ background-color: rgb(200, 210, 120); |
| 449 | @ }'); |
| 450 | @ REPLACE INTO config(name,mtime,value) VALUES('header',now(),'<html> |
| 451 | @ <head> |
| 452 | @ <title>$<project_name>: $<title></title> |
| 453 | @ <link rel="alternate" type="application/rss+xml" title="RSS Feed" |
| 454 | @ href="$home/timeline.rss"> |
| @@ -590,10 +678,56 @@ | |
| 678 | @ /* The label/value pairs on (for example) the ci page */ |
| 679 | @ table.label-value th { |
| 680 | @ vertical-align: top; |
| 681 | @ text-align: right; |
| 682 | @ padding: 0.2ex 2ex; |
| 683 | @ } |
| 684 | @ |
| 685 | @ /* Side-by-side diff */ |
| 686 | @ table.sbsdiff { |
| 687 | @ background-color: white; |
| 688 | @ font-family: fixed, Dejavu Sans Mono, Monaco, Lucida Console, monospace; |
| 689 | @ font-size: 6pt; |
| 690 | @ border-collapse:collapse; |
| 691 | @ white-space: pre; |
| 692 | @ width: 98%; |
| 693 | @ border: 1px #000 dashed; |
| 694 | @ } |
| 695 | @ |
| 696 | @ table.sbsdiff th.diffhdr { |
| 697 | @ border-bottom: dotted; |
| 698 | @ border-width: 1px; |
| 699 | @ } |
| 700 | @ |
| 701 | @ table.sbsdiff tr td { |
| 702 | @ white-space: pre; |
| 703 | @ padding-left: 3px; |
| 704 | @ padding-right: 3px; |
| 705 | @ margin: 0px; |
| 706 | @ } |
| 707 | @ |
| 708 | @ table.sbsdiff tr td.lineno { |
| 709 | @ text-align: right; |
| 710 | @ } |
| 711 | @ |
| 712 | @ table.sbsdiff tr td.meta { |
| 713 | @ color: white; |
| 714 | @ background-color: black; |
| 715 | @ text-align: center; |
| 716 | @ } |
| 717 | @ |
| 718 | @ table.sbsdiff tr td.added { |
| 719 | @ background-color: white; |
| 720 | @ } |
| 721 | @ |
| 722 | @ table.sbsdiff tr td.removed { |
| 723 | @ background-color: white; |
| 724 | @ text-decoration: line-through; |
| 725 | @ } |
| 726 | @ |
| 727 | @ table.sbsdiff tr td.changed { |
| 728 | @ background-color: white; |
| 729 | @ }'); |
| 730 | @ REPLACE INTO config(name,mtime,value) VALUES('header',now(),'<html> |
| 731 | @ <head> |
| 732 | @ <title>$<project_name>: $<title></title> |
| 733 | @ <link rel="alternate" type="application/rss+xml" title="RSS Feed" |
| @@ -885,10 +1019,77 @@ | |
| 1019 | @ padding: 3px 5px; |
| 1020 | @ } |
| 1021 | @ |
| 1022 | @ textarea { |
| 1023 | @ font-size: 1em; |
| 1024 | @ } |
| 1025 | @ |
| 1026 | @ /* Side-by-side diff */ |
| 1027 | @ table.sbsdiff { |
| 1028 | @ background-color: white; |
| 1029 | @ font-family: Dejavu Sans Mono, Monaco, Lucida Console, monospace; |
| 1030 | @ font-size: 6pt; |
| 1031 | @ border-collapse:collapse; |
| 1032 | @ width: 98%; |
| 1033 | @ border: 1px #000 dashed; |
| 1034 | @ margin-left: auto; |
| 1035 | @ margin-right: auto; |
| 1036 | @ } |
| 1037 | @ |
| 1038 | @ table.sbsdiff th.diffhdr { |
| 1039 | @ border-bottom: dotted; |
| 1040 | @ border-width: 1px; |
| 1041 | @ } |
| 1042 | @ |
| 1043 | @ table.sbsdiff tr td { |
| 1044 | @ padding-left: 3px; |
| 1045 | @ padding-right: 3px; |
| 1046 | @ margin: 0px; |
| 1047 | @ vertical-align: top; |
| 1048 | @ white-space: pre-wrap; |
| 1049 | @ } |
| 1050 | @ |
| 1051 | @ table.sbsdiff tr td.lineno { |
| 1052 | @ text-align: right; |
| 1053 | @ /* border-bottom: 1px solid rgb(220, 220, 220); */ |
| 1054 | @ } |
| 1055 | @ |
| 1056 | @ table.sbsdiff tr td.srcline { |
| 1057 | @ /* max-width: 400px; */ |
| 1058 | @ /* Note: May partially hide long lines without whitespaces */ |
| 1059 | @ /* overflow: hidden; */ |
| 1060 | @ /* border-bottom: 1px solid rgb(220, 220, 220); */ |
| 1061 | @ } |
| 1062 | @ |
| 1063 | @ table.sbsdiff tr td.meta { |
| 1064 | @ background-color: rgb(170, 160, 255); |
| 1065 | @ padding-top: 0.25em; |
| 1066 | @ padding-bottom: 0.25em; |
| 1067 | @ text-align: center; |
| 1068 | @ -moz-border-radius: 5px; |
| 1069 | @ -moz-border-radius: 5px; |
| 1070 | @ -webkit-border-radius: 5px; |
| 1071 | @ -webkit-border-radius: 5px; |
| 1072 | @ -border-radius: 5px; |
| 1073 | @ -border-radius: 5px; |
| 1074 | @ border-radius: 5px; |
| 1075 | @ border-radius: 5px; |
| 1076 | @ } |
| 1077 | @ |
| 1078 | @ table.sbsdiff tr td.added { |
| 1079 | @ background-color: rgb(180, 250, 180); |
| 1080 | @ /* border-bottom: 1px solid rgb(160, 230, 160); */ |
| 1081 | @ } |
| 1082 | @ |
| 1083 | @ table.sbsdiff tr td.removed { |
| 1084 | @ background-color: rgb(250, 130, 130); |
| 1085 | @ /* border-bottom: 1px solid rgb(230, 110, 110); */ |
| 1086 | @ } |
| 1087 | @ |
| 1088 | @ table.sbsdiff tr td.changed { |
| 1089 | @ background-color: rgb(210, 210, 200); |
| 1090 | @ /* border-bottom: 1px solid rgb(190, 190, 180); */ |
| 1091 | @ }'); |
| 1092 | @ REPLACE INTO config(name,mtime,value) VALUES('header',now(),'<html> |
| 1093 | @ <head> |
| 1094 | @ <title>$<project_name>: $<title></title> |
| 1095 | @ <link rel="alternate" type="application/rss+xml" title="RSS Feed" |
| @@ -1100,10 +1301,13 @@ | |
| 1301 | db_multi_exec("%s", zCurrent); |
| 1302 | } |
| 1303 | } |
| 1304 | |
| 1305 | style_header("Skins"); |
| 1306 | if( zErr ){ |
| 1307 | @ <p><font color="red">%h(zErr)</font></p> |
| 1308 | } |
| 1309 | @ <p>A "skin" is a combination of |
| 1310 | @ <a href="setup_editcss">CSS</a>, |
| 1311 | @ <a href="setup_header">Header</a>, |
| 1312 | @ <a href="setup_footer">Footer</a>, and |
| 1313 | @ <a href="setup_logo">Logo</a> that determines the look and feel |
| 1314 |
+59
| --- src/style.c | ||
| +++ src/style.c | ||
| @@ -396,10 +396,69 @@ | ||
| 396 | 396 | @ table.label-value th { |
| 397 | 397 | @ vertical-align: top; |
| 398 | 398 | @ text-align: right; |
| 399 | 399 | @ padding: 0.2ex 2ex; |
| 400 | 400 | @ } |
| 401 | +@ | |
| 402 | +@ /* Side-by-side diff */ | |
| 403 | +@ table.sbsdiff { | |
| 404 | +@ background-color: white; | |
| 405 | +@ font-family: fixed, Dejavu Sans Mono, Monaco, Lucida Console, monospace; | |
| 406 | +@ font-size: 8pt; | |
| 407 | +@ border-collapse:collapse; | |
| 408 | +@ white-space: pre; | |
| 409 | +@ width: 98%; | |
| 410 | +@ border: 1px #000 dashed; | |
| 411 | +@ margin-left: auto; | |
| 412 | +@ margin-right: auto; | |
| 413 | +@ } | |
| 414 | +@ | |
| 415 | +@ table.sbsdiff th.diffhdr { | |
| 416 | +@ border-bottom: dotted; | |
| 417 | +@ border-width: 1px; | |
| 418 | +@ } | |
| 419 | +@ | |
| 420 | +@ table.sbsdiff tr td { | |
| 421 | +@ white-space: pre; | |
| 422 | +@ padding-left: 3px; | |
| 423 | +@ padding-right: 3px; | |
| 424 | +@ margin: 0px; | |
| 425 | +@ vertical-align: top; | |
| 426 | +@ } | |
| 427 | +@ | |
| 428 | +@ table.sbsdiff tr td.lineno { | |
| 429 | +@ text-align: right; | |
| 430 | +@ } | |
| 431 | +@ | |
| 432 | +@ table.sbsdiff tr td.srcline { | |
| 433 | +@ } | |
| 434 | +@ | |
| 435 | +@ table.sbsdiff tr td.meta { | |
| 436 | +@ background-color: rgb(170, 160, 255); | |
| 437 | +@ text-align: center; | |
| 438 | +@ } | |
| 439 | +@ | |
| 440 | +@ table.sbsdiff tr td.added { | |
| 441 | +@ background-color: rgb(180, 250, 180); | |
| 442 | +@ } | |
| 443 | +@ table.sbsdiff tr td.addedvoid { | |
| 444 | +@ background-color: rgb(190, 190, 180); | |
| 445 | +@ } | |
| 446 | +@ | |
| 447 | +@ table.sbsdiff tr td.removed { | |
| 448 | +@ background-color: rgb(250, 130, 130); | |
| 449 | +@ } | |
| 450 | +@ table.sbsdiff tr td.removedvoid { | |
| 451 | +@ background-color: rgb(190, 190, 180); | |
| 452 | +@ } | |
| 453 | +@ | |
| 454 | +@ table.sbsdiff tr td.changed { | |
| 455 | +@ background-color: rgb(210, 210, 200); | |
| 456 | +@ } | |
| 457 | +@ table.sbsdiff tr td.changedvoid { | |
| 458 | +@ background-color: rgb(190, 190, 180); | |
| 459 | +@ } | |
| 401 | 460 | @ |
| 402 | 461 | ; |
| 403 | 462 | |
| 404 | 463 | |
| 405 | 464 | /* The following table contains bits of default CSS that must |
| 406 | 465 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -396,10 +396,69 @@ | |
| 396 | @ table.label-value th { |
| 397 | @ vertical-align: top; |
| 398 | @ text-align: right; |
| 399 | @ padding: 0.2ex 2ex; |
| 400 | @ } |
| 401 | @ |
| 402 | ; |
| 403 | |
| 404 | |
| 405 | /* The following table contains bits of default CSS that must |
| 406 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -396,10 +396,69 @@ | |
| 396 | @ table.label-value th { |
| 397 | @ vertical-align: top; |
| 398 | @ text-align: right; |
| 399 | @ padding: 0.2ex 2ex; |
| 400 | @ } |
| 401 | @ |
| 402 | @ /* Side-by-side diff */ |
| 403 | @ table.sbsdiff { |
| 404 | @ background-color: white; |
| 405 | @ font-family: fixed, Dejavu Sans Mono, Monaco, Lucida Console, monospace; |
| 406 | @ font-size: 8pt; |
| 407 | @ border-collapse:collapse; |
| 408 | @ white-space: pre; |
| 409 | @ width: 98%; |
| 410 | @ border: 1px #000 dashed; |
| 411 | @ margin-left: auto; |
| 412 | @ margin-right: auto; |
| 413 | @ } |
| 414 | @ |
| 415 | @ table.sbsdiff th.diffhdr { |
| 416 | @ border-bottom: dotted; |
| 417 | @ border-width: 1px; |
| 418 | @ } |
| 419 | @ |
| 420 | @ table.sbsdiff tr td { |
| 421 | @ white-space: pre; |
| 422 | @ padding-left: 3px; |
| 423 | @ padding-right: 3px; |
| 424 | @ margin: 0px; |
| 425 | @ vertical-align: top; |
| 426 | @ } |
| 427 | @ |
| 428 | @ table.sbsdiff tr td.lineno { |
| 429 | @ text-align: right; |
| 430 | @ } |
| 431 | @ |
| 432 | @ table.sbsdiff tr td.srcline { |
| 433 | @ } |
| 434 | @ |
| 435 | @ table.sbsdiff tr td.meta { |
| 436 | @ background-color: rgb(170, 160, 255); |
| 437 | @ text-align: center; |
| 438 | @ } |
| 439 | @ |
| 440 | @ table.sbsdiff tr td.added { |
| 441 | @ background-color: rgb(180, 250, 180); |
| 442 | @ } |
| 443 | @ table.sbsdiff tr td.addedvoid { |
| 444 | @ background-color: rgb(190, 190, 180); |
| 445 | @ } |
| 446 | @ |
| 447 | @ table.sbsdiff tr td.removed { |
| 448 | @ background-color: rgb(250, 130, 130); |
| 449 | @ } |
| 450 | @ table.sbsdiff tr td.removedvoid { |
| 451 | @ background-color: rgb(190, 190, 180); |
| 452 | @ } |
| 453 | @ |
| 454 | @ table.sbsdiff tr td.changed { |
| 455 | @ background-color: rgb(210, 210, 200); |
| 456 | @ } |
| 457 | @ table.sbsdiff tr td.changedvoid { |
| 458 | @ background-color: rgb(190, 190, 180); |
| 459 | @ } |
| 460 | @ |
| 461 | ; |
| 462 | |
| 463 | |
| 464 | /* The following table contains bits of default CSS that must |
| 465 |
+28
-12
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -180,11 +180,11 @@ | ||
| 180 | 180 | ** 2. Date/Time |
| 181 | 181 | ** 3. Comment string |
| 182 | 182 | ** 4. User |
| 183 | 183 | ** 5. True if is a leaf |
| 184 | 184 | ** 6. background color |
| 185 | -** 7. type ("ci", "w", "t", "e", "div") | |
| 185 | +** 7. type ("ci", "w", "t", "e", "g", "div") | |
| 186 | 186 | ** 8. list of symbolic tags. |
| 187 | 187 | ** 9. tagid for ticket or wiki or event |
| 188 | 188 | ** 10. Short comment to user for repeated tickets and wiki |
| 189 | 189 | */ |
| 190 | 190 | void www_print_timeline( |
| @@ -317,10 +317,13 @@ | ||
| 317 | 317 | @</td> |
| 318 | 318 | if( zBgClr && zBgClr[0] ){ |
| 319 | 319 | @ <td class="timelineTableCell" style="background-color: %h(zBgClr);"> |
| 320 | 320 | }else{ |
| 321 | 321 | @ <td class="timelineTableCell"> |
| 322 | + } | |
| 323 | + if( pGraph && zType[0]!='c' ){ | |
| 324 | + @ • | |
| 322 | 325 | } |
| 323 | 326 | if( zType[0]=='c' ){ |
| 324 | 327 | hyperlink_to_uuid(zUuid); |
| 325 | 328 | if( isLeaf ){ |
| 326 | 329 | if( db_exists("SELECT 1 FROM tagxref" |
| @@ -841,23 +844,24 @@ | ||
| 841 | 844 | ** |
| 842 | 845 | ** a=TIMESTAMP after this date |
| 843 | 846 | ** b=TIMESTAMP before this date. |
| 844 | 847 | ** c=TIMESTAMP "circa" this date. |
| 845 | 848 | ** n=COUNT number of events in output |
| 846 | -** p=RID artifact RID and up to COUNT parents and ancestors | |
| 847 | -** d=RID artifact RID and up to COUNT descendants | |
| 849 | +** p=UUID artifact and up to COUNT parents and ancestors | |
| 850 | +** d=UUID artifact and up to COUNT descendants | |
| 851 | +** dp=UUUID The same as d=UUID&p=UUID | |
| 848 | 852 | ** t=TAGID show only check-ins with the given tagid |
| 849 | 853 | ** r=TAGID show check-ins related to tagid |
| 850 | 854 | ** u=USER only if belonging to this user |
| 851 | 855 | ** y=TYPE 'ci', 'w', 't', 'e' |
| 852 | 856 | ** s=TEXT string search (comment and brief) |
| 853 | 857 | ** ng Suppress the graph if present |
| 854 | 858 | ** nd Suppress "divider" lines |
| 855 | 859 | ** fc Show details of files changed |
| 856 | -** f=RID Show family (immediate parents and children) of RID | |
| 857 | -** from=RID Path from... | |
| 858 | -** to=RID ... to this | |
| 860 | +** f=UUID Show family (immediate parents and children) of UUID | |
| 861 | +** from=UUID Path from... | |
| 862 | +** to=UUID ... to this | |
| 859 | 863 | ** nomerge ... avoid merge links on the path |
| 860 | 864 | ** brbg Background color from branch name |
| 861 | 865 | ** ubg Background color from user |
| 862 | 866 | ** |
| 863 | 867 | ** p= and d= can appear individually or together. If either p= or d= |
| @@ -893,15 +897,23 @@ | ||
| 893 | 897 | int from_rid = name_to_typed_rid(P("from"),"ci"); /* from= for paths */ |
| 894 | 898 | int to_rid = name_to_typed_rid(P("to"),"ci"); /* to= for path timelines */ |
| 895 | 899 | int noMerge = P("nomerge")!=0; /* Do not follow merge links */ |
| 896 | 900 | int me_rid = name_to_typed_rid(P("me"),"ci"); /* me= for common ancestory */ |
| 897 | 901 | int you_rid = name_to_typed_rid(P("you"),"ci");/* you= for common ancst */ |
| 902 | + int pd_rid; | |
| 898 | 903 | |
| 899 | 904 | /* To view the timeline, must have permission to read project data. |
| 900 | 905 | */ |
| 906 | + pd_rid = name_to_typed_rid(P("dp"),"ci"); | |
| 907 | + if( pd_rid ){ | |
| 908 | + p_rid = d_rid = pd_rid; | |
| 909 | + } | |
| 901 | 910 | login_check_credentials(); |
| 902 | - if( !g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki ){ login_needed(); return; } | |
| 911 | + if( !g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki ){ | |
| 912 | + login_needed(); | |
| 913 | + return; | |
| 914 | + } | |
| 903 | 915 | if( zTagName && g.perm.Read ){ |
| 904 | 916 | tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", zTagName); |
| 905 | 917 | zThisTag = zTagName; |
| 906 | 918 | }else if( zBrName && g.perm.Read ){ |
| 907 | 919 | tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",zBrName); |
| @@ -989,14 +1001,12 @@ | ||
| 989 | 1001 | blob_appendf(&sql, " AND event.objid IN ok"); |
| 990 | 1002 | nd = 0; |
| 991 | 1003 | if( d_rid ){ |
| 992 | 1004 | compute_descendants(d_rid, nEntry+1); |
| 993 | 1005 | nd = db_int(0, "SELECT count(*)-1 FROM ok"); |
| 994 | - if( nd>=0 ){ | |
| 995 | - db_multi_exec("%s", blob_str(&sql)); | |
| 996 | - blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s"); | |
| 997 | - } | |
| 1006 | + if( nd>=0 ) db_multi_exec("%s", blob_str(&sql)); | |
| 1007 | + if( nd>0 ) blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s"); | |
| 998 | 1008 | if( useDividers ) timeline_add_dividers(0, d_rid); |
| 999 | 1009 | db_multi_exec("DELETE FROM ok"); |
| 1000 | 1010 | } |
| 1001 | 1011 | if( p_rid ){ |
| 1002 | 1012 | compute_ancestors(p_rid, nEntry+1); |
| @@ -1076,19 +1086,20 @@ | ||
| 1076 | 1086 | } |
| 1077 | 1087 | if( (zType[0]=='w' && !g.perm.RdWiki) |
| 1078 | 1088 | || (zType[0]=='t' && !g.perm.RdTkt) |
| 1079 | 1089 | || (zType[0]=='e' && !g.perm.RdWiki) |
| 1080 | 1090 | || (zType[0]=='c' && !g.perm.Read) |
| 1091 | + || (zType[0]=='g' && !g.perm.Read) | |
| 1081 | 1092 | ){ |
| 1082 | 1093 | zType = "all"; |
| 1083 | 1094 | } |
| 1084 | 1095 | if( zType[0]=='a' ){ |
| 1085 | 1096 | if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){ |
| 1086 | 1097 | char cSep = '('; |
| 1087 | 1098 | blob_appendf(&sql, " AND event.type IN "); |
| 1088 | 1099 | if( g.perm.Read ){ |
| 1089 | - blob_appendf(&sql, "%c'ci'", cSep); | |
| 1100 | + blob_appendf(&sql, "%c'ci','g'", cSep); | |
| 1090 | 1101 | cSep = ','; |
| 1091 | 1102 | } |
| 1092 | 1103 | if( g.perm.RdWiki ){ |
| 1093 | 1104 | blob_appendf(&sql, "%c'w','e'", cSep); |
| 1094 | 1105 | cSep = ','; |
| @@ -1108,10 +1119,12 @@ | ||
| 1108 | 1119 | zEType = "wiki edit"; |
| 1109 | 1120 | }else if( zType[0]=='t' ){ |
| 1110 | 1121 | zEType = "ticket change"; |
| 1111 | 1122 | }else if( zType[0]=='e' ){ |
| 1112 | 1123 | zEType = "event"; |
| 1124 | + }else if( zType[0]=='g' ){ | |
| 1125 | + zEType = "tag"; | |
| 1113 | 1126 | } |
| 1114 | 1127 | } |
| 1115 | 1128 | if( zUser ){ |
| 1116 | 1129 | blob_appendf(&sql, " AND (event.user=%Q OR event.euser=%Q)", |
| 1117 | 1130 | zUser, zUser); |
| @@ -1227,10 +1240,13 @@ | ||
| 1227 | 1240 | timeline_submenu(&url, "Tickets Only", "y", "t", 0); |
| 1228 | 1241 | } |
| 1229 | 1242 | if( zType[0]!='e' && g.perm.RdWiki ){ |
| 1230 | 1243 | timeline_submenu(&url, "Events Only", "y", "e", 0); |
| 1231 | 1244 | } |
| 1245 | + if( zType[0]!='g' && g.perm.Read ){ | |
| 1246 | + timeline_submenu(&url, "Tags Only", "y", "g", 0); | |
| 1247 | + } | |
| 1232 | 1248 | } |
| 1233 | 1249 | if( nEntry>20 ){ |
| 1234 | 1250 | timeline_submenu(&url, "20 Entries", "n", "20", 0); |
| 1235 | 1251 | } |
| 1236 | 1252 | if( nEntry<200 ){ |
| 1237 | 1253 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -180,11 +180,11 @@ | |
| 180 | ** 2. Date/Time |
| 181 | ** 3. Comment string |
| 182 | ** 4. User |
| 183 | ** 5. True if is a leaf |
| 184 | ** 6. background color |
| 185 | ** 7. type ("ci", "w", "t", "e", "div") |
| 186 | ** 8. list of symbolic tags. |
| 187 | ** 9. tagid for ticket or wiki or event |
| 188 | ** 10. Short comment to user for repeated tickets and wiki |
| 189 | */ |
| 190 | void www_print_timeline( |
| @@ -317,10 +317,13 @@ | |
| 317 | @</td> |
| 318 | if( zBgClr && zBgClr[0] ){ |
| 319 | @ <td class="timelineTableCell" style="background-color: %h(zBgClr);"> |
| 320 | }else{ |
| 321 | @ <td class="timelineTableCell"> |
| 322 | } |
| 323 | if( zType[0]=='c' ){ |
| 324 | hyperlink_to_uuid(zUuid); |
| 325 | if( isLeaf ){ |
| 326 | if( db_exists("SELECT 1 FROM tagxref" |
| @@ -841,23 +844,24 @@ | |
| 841 | ** |
| 842 | ** a=TIMESTAMP after this date |
| 843 | ** b=TIMESTAMP before this date. |
| 844 | ** c=TIMESTAMP "circa" this date. |
| 845 | ** n=COUNT number of events in output |
| 846 | ** p=RID artifact RID and up to COUNT parents and ancestors |
| 847 | ** d=RID artifact RID and up to COUNT descendants |
| 848 | ** t=TAGID show only check-ins with the given tagid |
| 849 | ** r=TAGID show check-ins related to tagid |
| 850 | ** u=USER only if belonging to this user |
| 851 | ** y=TYPE 'ci', 'w', 't', 'e' |
| 852 | ** s=TEXT string search (comment and brief) |
| 853 | ** ng Suppress the graph if present |
| 854 | ** nd Suppress "divider" lines |
| 855 | ** fc Show details of files changed |
| 856 | ** f=RID Show family (immediate parents and children) of RID |
| 857 | ** from=RID Path from... |
| 858 | ** to=RID ... to this |
| 859 | ** nomerge ... avoid merge links on the path |
| 860 | ** brbg Background color from branch name |
| 861 | ** ubg Background color from user |
| 862 | ** |
| 863 | ** p= and d= can appear individually or together. If either p= or d= |
| @@ -893,15 +897,23 @@ | |
| 893 | int from_rid = name_to_typed_rid(P("from"),"ci"); /* from= for paths */ |
| 894 | int to_rid = name_to_typed_rid(P("to"),"ci"); /* to= for path timelines */ |
| 895 | int noMerge = P("nomerge")!=0; /* Do not follow merge links */ |
| 896 | int me_rid = name_to_typed_rid(P("me"),"ci"); /* me= for common ancestory */ |
| 897 | int you_rid = name_to_typed_rid(P("you"),"ci");/* you= for common ancst */ |
| 898 | |
| 899 | /* To view the timeline, must have permission to read project data. |
| 900 | */ |
| 901 | login_check_credentials(); |
| 902 | if( !g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki ){ login_needed(); return; } |
| 903 | if( zTagName && g.perm.Read ){ |
| 904 | tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", zTagName); |
| 905 | zThisTag = zTagName; |
| 906 | }else if( zBrName && g.perm.Read ){ |
| 907 | tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",zBrName); |
| @@ -989,14 +1001,12 @@ | |
| 989 | blob_appendf(&sql, " AND event.objid IN ok"); |
| 990 | nd = 0; |
| 991 | if( d_rid ){ |
| 992 | compute_descendants(d_rid, nEntry+1); |
| 993 | nd = db_int(0, "SELECT count(*)-1 FROM ok"); |
| 994 | if( nd>=0 ){ |
| 995 | db_multi_exec("%s", blob_str(&sql)); |
| 996 | blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s"); |
| 997 | } |
| 998 | if( useDividers ) timeline_add_dividers(0, d_rid); |
| 999 | db_multi_exec("DELETE FROM ok"); |
| 1000 | } |
| 1001 | if( p_rid ){ |
| 1002 | compute_ancestors(p_rid, nEntry+1); |
| @@ -1076,19 +1086,20 @@ | |
| 1076 | } |
| 1077 | if( (zType[0]=='w' && !g.perm.RdWiki) |
| 1078 | || (zType[0]=='t' && !g.perm.RdTkt) |
| 1079 | || (zType[0]=='e' && !g.perm.RdWiki) |
| 1080 | || (zType[0]=='c' && !g.perm.Read) |
| 1081 | ){ |
| 1082 | zType = "all"; |
| 1083 | } |
| 1084 | if( zType[0]=='a' ){ |
| 1085 | if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){ |
| 1086 | char cSep = '('; |
| 1087 | blob_appendf(&sql, " AND event.type IN "); |
| 1088 | if( g.perm.Read ){ |
| 1089 | blob_appendf(&sql, "%c'ci'", cSep); |
| 1090 | cSep = ','; |
| 1091 | } |
| 1092 | if( g.perm.RdWiki ){ |
| 1093 | blob_appendf(&sql, "%c'w','e'", cSep); |
| 1094 | cSep = ','; |
| @@ -1108,10 +1119,12 @@ | |
| 1108 | zEType = "wiki edit"; |
| 1109 | }else if( zType[0]=='t' ){ |
| 1110 | zEType = "ticket change"; |
| 1111 | }else if( zType[0]=='e' ){ |
| 1112 | zEType = "event"; |
| 1113 | } |
| 1114 | } |
| 1115 | if( zUser ){ |
| 1116 | blob_appendf(&sql, " AND (event.user=%Q OR event.euser=%Q)", |
| 1117 | zUser, zUser); |
| @@ -1227,10 +1240,13 @@ | |
| 1227 | timeline_submenu(&url, "Tickets Only", "y", "t", 0); |
| 1228 | } |
| 1229 | if( zType[0]!='e' && g.perm.RdWiki ){ |
| 1230 | timeline_submenu(&url, "Events Only", "y", "e", 0); |
| 1231 | } |
| 1232 | } |
| 1233 | if( nEntry>20 ){ |
| 1234 | timeline_submenu(&url, "20 Entries", "n", "20", 0); |
| 1235 | } |
| 1236 | if( nEntry<200 ){ |
| 1237 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -180,11 +180,11 @@ | |
| 180 | ** 2. Date/Time |
| 181 | ** 3. Comment string |
| 182 | ** 4. User |
| 183 | ** 5. True if is a leaf |
| 184 | ** 6. background color |
| 185 | ** 7. type ("ci", "w", "t", "e", "g", "div") |
| 186 | ** 8. list of symbolic tags. |
| 187 | ** 9. tagid for ticket or wiki or event |
| 188 | ** 10. Short comment to user for repeated tickets and wiki |
| 189 | */ |
| 190 | void www_print_timeline( |
| @@ -317,10 +317,13 @@ | |
| 317 | @</td> |
| 318 | if( zBgClr && zBgClr[0] ){ |
| 319 | @ <td class="timelineTableCell" style="background-color: %h(zBgClr);"> |
| 320 | }else{ |
| 321 | @ <td class="timelineTableCell"> |
| 322 | } |
| 323 | if( pGraph && zType[0]!='c' ){ |
| 324 | @ • |
| 325 | } |
| 326 | if( zType[0]=='c' ){ |
| 327 | hyperlink_to_uuid(zUuid); |
| 328 | if( isLeaf ){ |
| 329 | if( db_exists("SELECT 1 FROM tagxref" |
| @@ -841,23 +844,24 @@ | |
| 844 | ** |
| 845 | ** a=TIMESTAMP after this date |
| 846 | ** b=TIMESTAMP before this date. |
| 847 | ** c=TIMESTAMP "circa" this date. |
| 848 | ** n=COUNT number of events in output |
| 849 | ** p=UUID artifact and up to COUNT parents and ancestors |
| 850 | ** d=UUID artifact and up to COUNT descendants |
| 851 | ** dp=UUUID The same as d=UUID&p=UUID |
| 852 | ** t=TAGID show only check-ins with the given tagid |
| 853 | ** r=TAGID show check-ins related to tagid |
| 854 | ** u=USER only if belonging to this user |
| 855 | ** y=TYPE 'ci', 'w', 't', 'e' |
| 856 | ** s=TEXT string search (comment and brief) |
| 857 | ** ng Suppress the graph if present |
| 858 | ** nd Suppress "divider" lines |
| 859 | ** fc Show details of files changed |
| 860 | ** f=UUID Show family (immediate parents and children) of UUID |
| 861 | ** from=UUID Path from... |
| 862 | ** to=UUID ... to this |
| 863 | ** nomerge ... avoid merge links on the path |
| 864 | ** brbg Background color from branch name |
| 865 | ** ubg Background color from user |
| 866 | ** |
| 867 | ** p= and d= can appear individually or together. If either p= or d= |
| @@ -893,15 +897,23 @@ | |
| 897 | int from_rid = name_to_typed_rid(P("from"),"ci"); /* from= for paths */ |
| 898 | int to_rid = name_to_typed_rid(P("to"),"ci"); /* to= for path timelines */ |
| 899 | int noMerge = P("nomerge")!=0; /* Do not follow merge links */ |
| 900 | int me_rid = name_to_typed_rid(P("me"),"ci"); /* me= for common ancestory */ |
| 901 | int you_rid = name_to_typed_rid(P("you"),"ci");/* you= for common ancst */ |
| 902 | int pd_rid; |
| 903 | |
| 904 | /* To view the timeline, must have permission to read project data. |
| 905 | */ |
| 906 | pd_rid = name_to_typed_rid(P("dp"),"ci"); |
| 907 | if( pd_rid ){ |
| 908 | p_rid = d_rid = pd_rid; |
| 909 | } |
| 910 | login_check_credentials(); |
| 911 | if( !g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki ){ |
| 912 | login_needed(); |
| 913 | return; |
| 914 | } |
| 915 | if( zTagName && g.perm.Read ){ |
| 916 | tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", zTagName); |
| 917 | zThisTag = zTagName; |
| 918 | }else if( zBrName && g.perm.Read ){ |
| 919 | tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",zBrName); |
| @@ -989,14 +1001,12 @@ | |
| 1001 | blob_appendf(&sql, " AND event.objid IN ok"); |
| 1002 | nd = 0; |
| 1003 | if( d_rid ){ |
| 1004 | compute_descendants(d_rid, nEntry+1); |
| 1005 | nd = db_int(0, "SELECT count(*)-1 FROM ok"); |
| 1006 | if( nd>=0 ) db_multi_exec("%s", blob_str(&sql)); |
| 1007 | if( nd>0 ) blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s"); |
| 1008 | if( useDividers ) timeline_add_dividers(0, d_rid); |
| 1009 | db_multi_exec("DELETE FROM ok"); |
| 1010 | } |
| 1011 | if( p_rid ){ |
| 1012 | compute_ancestors(p_rid, nEntry+1); |
| @@ -1076,19 +1086,20 @@ | |
| 1086 | } |
| 1087 | if( (zType[0]=='w' && !g.perm.RdWiki) |
| 1088 | || (zType[0]=='t' && !g.perm.RdTkt) |
| 1089 | || (zType[0]=='e' && !g.perm.RdWiki) |
| 1090 | || (zType[0]=='c' && !g.perm.Read) |
| 1091 | || (zType[0]=='g' && !g.perm.Read) |
| 1092 | ){ |
| 1093 | zType = "all"; |
| 1094 | } |
| 1095 | if( zType[0]=='a' ){ |
| 1096 | if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){ |
| 1097 | char cSep = '('; |
| 1098 | blob_appendf(&sql, " AND event.type IN "); |
| 1099 | if( g.perm.Read ){ |
| 1100 | blob_appendf(&sql, "%c'ci','g'", cSep); |
| 1101 | cSep = ','; |
| 1102 | } |
| 1103 | if( g.perm.RdWiki ){ |
| 1104 | blob_appendf(&sql, "%c'w','e'", cSep); |
| 1105 | cSep = ','; |
| @@ -1108,10 +1119,12 @@ | |
| 1119 | zEType = "wiki edit"; |
| 1120 | }else if( zType[0]=='t' ){ |
| 1121 | zEType = "ticket change"; |
| 1122 | }else if( zType[0]=='e' ){ |
| 1123 | zEType = "event"; |
| 1124 | }else if( zType[0]=='g' ){ |
| 1125 | zEType = "tag"; |
| 1126 | } |
| 1127 | } |
| 1128 | if( zUser ){ |
| 1129 | blob_appendf(&sql, " AND (event.user=%Q OR event.euser=%Q)", |
| 1130 | zUser, zUser); |
| @@ -1227,10 +1240,13 @@ | |
| 1240 | timeline_submenu(&url, "Tickets Only", "y", "t", 0); |
| 1241 | } |
| 1242 | if( zType[0]!='e' && g.perm.RdWiki ){ |
| 1243 | timeline_submenu(&url, "Events Only", "y", "e", 0); |
| 1244 | } |
| 1245 | if( zType[0]!='g' && g.perm.Read ){ |
| 1246 | timeline_submenu(&url, "Tags Only", "y", "g", 0); |
| 1247 | } |
| 1248 | } |
| 1249 | if( nEntry>20 ){ |
| 1250 | timeline_submenu(&url, "20 Entries", "n", "20", 0); |
| 1251 | } |
| 1252 | if( nEntry<200 ){ |
| 1253 |
+28
-12
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -180,11 +180,11 @@ | ||
| 180 | 180 | ** 2. Date/Time |
| 181 | 181 | ** 3. Comment string |
| 182 | 182 | ** 4. User |
| 183 | 183 | ** 5. True if is a leaf |
| 184 | 184 | ** 6. background color |
| 185 | -** 7. type ("ci", "w", "t", "e", "div") | |
| 185 | +** 7. type ("ci", "w", "t", "e", "g", "div") | |
| 186 | 186 | ** 8. list of symbolic tags. |
| 187 | 187 | ** 9. tagid for ticket or wiki or event |
| 188 | 188 | ** 10. Short comment to user for repeated tickets and wiki |
| 189 | 189 | */ |
| 190 | 190 | void www_print_timeline( |
| @@ -317,10 +317,13 @@ | ||
| 317 | 317 | @</td> |
| 318 | 318 | if( zBgClr && zBgClr[0] ){ |
| 319 | 319 | @ <td class="timelineTableCell" style="background-color: %h(zBgClr);"> |
| 320 | 320 | }else{ |
| 321 | 321 | @ <td class="timelineTableCell"> |
| 322 | + } | |
| 323 | + if( pGraph && zType[0]!='c' ){ | |
| 324 | + @ • | |
| 322 | 325 | } |
| 323 | 326 | if( zType[0]=='c' ){ |
| 324 | 327 | hyperlink_to_uuid(zUuid); |
| 325 | 328 | if( isLeaf ){ |
| 326 | 329 | if( db_exists("SELECT 1 FROM tagxref" |
| @@ -841,23 +844,24 @@ | ||
| 841 | 844 | ** |
| 842 | 845 | ** a=TIMESTAMP after this date |
| 843 | 846 | ** b=TIMESTAMP before this date. |
| 844 | 847 | ** c=TIMESTAMP "circa" this date. |
| 845 | 848 | ** n=COUNT number of events in output |
| 846 | -** p=RID artifact RID and up to COUNT parents and ancestors | |
| 847 | -** d=RID artifact RID and up to COUNT descendants | |
| 849 | +** p=UUID artifact and up to COUNT parents and ancestors | |
| 850 | +** d=UUID artifact and up to COUNT descendants | |
| 851 | +** dp=UUUID The same as d=UUID&p=UUID | |
| 848 | 852 | ** t=TAGID show only check-ins with the given tagid |
| 849 | 853 | ** r=TAGID show check-ins related to tagid |
| 850 | 854 | ** u=USER only if belonging to this user |
| 851 | 855 | ** y=TYPE 'ci', 'w', 't', 'e' |
| 852 | 856 | ** s=TEXT string search (comment and brief) |
| 853 | 857 | ** ng Suppress the graph if present |
| 854 | 858 | ** nd Suppress "divider" lines |
| 855 | 859 | ** fc Show details of files changed |
| 856 | -** f=RID Show family (immediate parents and children) of RID | |
| 857 | -** from=RID Path from... | |
| 858 | -** to=RID ... to this | |
| 860 | +** f=UUID Show family (immediate parents and children) of UUID | |
| 861 | +** from=UUID Path from... | |
| 862 | +** to=UUID ... to this | |
| 859 | 863 | ** nomerge ... avoid merge links on the path |
| 860 | 864 | ** brbg Background color from branch name |
| 861 | 865 | ** ubg Background color from user |
| 862 | 866 | ** |
| 863 | 867 | ** p= and d= can appear individually or together. If either p= or d= |
| @@ -893,15 +897,23 @@ | ||
| 893 | 897 | int from_rid = name_to_typed_rid(P("from"),"ci"); /* from= for paths */ |
| 894 | 898 | int to_rid = name_to_typed_rid(P("to"),"ci"); /* to= for path timelines */ |
| 895 | 899 | int noMerge = P("nomerge")!=0; /* Do not follow merge links */ |
| 896 | 900 | int me_rid = name_to_typed_rid(P("me"),"ci"); /* me= for common ancestory */ |
| 897 | 901 | int you_rid = name_to_typed_rid(P("you"),"ci");/* you= for common ancst */ |
| 902 | + int pd_rid; | |
| 898 | 903 | |
| 899 | 904 | /* To view the timeline, must have permission to read project data. |
| 900 | 905 | */ |
| 906 | + pd_rid = name_to_typed_rid(P("dp"),"ci"); | |
| 907 | + if( pd_rid ){ | |
| 908 | + p_rid = d_rid = pd_rid; | |
| 909 | + } | |
| 901 | 910 | login_check_credentials(); |
| 902 | - if( !g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki ){ login_needed(); return; } | |
| 911 | + if( !g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki ){ | |
| 912 | + login_needed(); | |
| 913 | + return; | |
| 914 | + } | |
| 903 | 915 | if( zTagName && g.perm.Read ){ |
| 904 | 916 | tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", zTagName); |
| 905 | 917 | zThisTag = zTagName; |
| 906 | 918 | }else if( zBrName && g.perm.Read ){ |
| 907 | 919 | tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",zBrName); |
| @@ -989,14 +1001,12 @@ | ||
| 989 | 1001 | blob_appendf(&sql, " AND event.objid IN ok"); |
| 990 | 1002 | nd = 0; |
| 991 | 1003 | if( d_rid ){ |
| 992 | 1004 | compute_descendants(d_rid, nEntry+1); |
| 993 | 1005 | nd = db_int(0, "SELECT count(*)-1 FROM ok"); |
| 994 | - if( nd>=0 ){ | |
| 995 | - db_multi_exec("%s", blob_str(&sql)); | |
| 996 | - blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s"); | |
| 997 | - } | |
| 1006 | + if( nd>=0 ) db_multi_exec("%s", blob_str(&sql)); | |
| 1007 | + if( nd>0 ) blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s"); | |
| 998 | 1008 | if( useDividers ) timeline_add_dividers(0, d_rid); |
| 999 | 1009 | db_multi_exec("DELETE FROM ok"); |
| 1000 | 1010 | } |
| 1001 | 1011 | if( p_rid ){ |
| 1002 | 1012 | compute_ancestors(p_rid, nEntry+1); |
| @@ -1076,19 +1086,20 @@ | ||
| 1076 | 1086 | } |
| 1077 | 1087 | if( (zType[0]=='w' && !g.perm.RdWiki) |
| 1078 | 1088 | || (zType[0]=='t' && !g.perm.RdTkt) |
| 1079 | 1089 | || (zType[0]=='e' && !g.perm.RdWiki) |
| 1080 | 1090 | || (zType[0]=='c' && !g.perm.Read) |
| 1091 | + || (zType[0]=='g' && !g.perm.Read) | |
| 1081 | 1092 | ){ |
| 1082 | 1093 | zType = "all"; |
| 1083 | 1094 | } |
| 1084 | 1095 | if( zType[0]=='a' ){ |
| 1085 | 1096 | if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){ |
| 1086 | 1097 | char cSep = '('; |
| 1087 | 1098 | blob_appendf(&sql, " AND event.type IN "); |
| 1088 | 1099 | if( g.perm.Read ){ |
| 1089 | - blob_appendf(&sql, "%c'ci'", cSep); | |
| 1100 | + blob_appendf(&sql, "%c'ci','g'", cSep); | |
| 1090 | 1101 | cSep = ','; |
| 1091 | 1102 | } |
| 1092 | 1103 | if( g.perm.RdWiki ){ |
| 1093 | 1104 | blob_appendf(&sql, "%c'w','e'", cSep); |
| 1094 | 1105 | cSep = ','; |
| @@ -1108,10 +1119,12 @@ | ||
| 1108 | 1119 | zEType = "wiki edit"; |
| 1109 | 1120 | }else if( zType[0]=='t' ){ |
| 1110 | 1121 | zEType = "ticket change"; |
| 1111 | 1122 | }else if( zType[0]=='e' ){ |
| 1112 | 1123 | zEType = "event"; |
| 1124 | + }else if( zType[0]=='g' ){ | |
| 1125 | + zEType = "tag"; | |
| 1113 | 1126 | } |
| 1114 | 1127 | } |
| 1115 | 1128 | if( zUser ){ |
| 1116 | 1129 | blob_appendf(&sql, " AND (event.user=%Q OR event.euser=%Q)", |
| 1117 | 1130 | zUser, zUser); |
| @@ -1227,10 +1240,13 @@ | ||
| 1227 | 1240 | timeline_submenu(&url, "Tickets Only", "y", "t", 0); |
| 1228 | 1241 | } |
| 1229 | 1242 | if( zType[0]!='e' && g.perm.RdWiki ){ |
| 1230 | 1243 | timeline_submenu(&url, "Events Only", "y", "e", 0); |
| 1231 | 1244 | } |
| 1245 | + if( zType[0]!='g' && g.perm.Read ){ | |
| 1246 | + timeline_submenu(&url, "Tags Only", "y", "g", 0); | |
| 1247 | + } | |
| 1232 | 1248 | } |
| 1233 | 1249 | if( nEntry>20 ){ |
| 1234 | 1250 | timeline_submenu(&url, "20 Entries", "n", "20", 0); |
| 1235 | 1251 | } |
| 1236 | 1252 | if( nEntry<200 ){ |
| 1237 | 1253 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -180,11 +180,11 @@ | |
| 180 | ** 2. Date/Time |
| 181 | ** 3. Comment string |
| 182 | ** 4. User |
| 183 | ** 5. True if is a leaf |
| 184 | ** 6. background color |
| 185 | ** 7. type ("ci", "w", "t", "e", "div") |
| 186 | ** 8. list of symbolic tags. |
| 187 | ** 9. tagid for ticket or wiki or event |
| 188 | ** 10. Short comment to user for repeated tickets and wiki |
| 189 | */ |
| 190 | void www_print_timeline( |
| @@ -317,10 +317,13 @@ | |
| 317 | @</td> |
| 318 | if( zBgClr && zBgClr[0] ){ |
| 319 | @ <td class="timelineTableCell" style="background-color: %h(zBgClr);"> |
| 320 | }else{ |
| 321 | @ <td class="timelineTableCell"> |
| 322 | } |
| 323 | if( zType[0]=='c' ){ |
| 324 | hyperlink_to_uuid(zUuid); |
| 325 | if( isLeaf ){ |
| 326 | if( db_exists("SELECT 1 FROM tagxref" |
| @@ -841,23 +844,24 @@ | |
| 841 | ** |
| 842 | ** a=TIMESTAMP after this date |
| 843 | ** b=TIMESTAMP before this date. |
| 844 | ** c=TIMESTAMP "circa" this date. |
| 845 | ** n=COUNT number of events in output |
| 846 | ** p=RID artifact RID and up to COUNT parents and ancestors |
| 847 | ** d=RID artifact RID and up to COUNT descendants |
| 848 | ** t=TAGID show only check-ins with the given tagid |
| 849 | ** r=TAGID show check-ins related to tagid |
| 850 | ** u=USER only if belonging to this user |
| 851 | ** y=TYPE 'ci', 'w', 't', 'e' |
| 852 | ** s=TEXT string search (comment and brief) |
| 853 | ** ng Suppress the graph if present |
| 854 | ** nd Suppress "divider" lines |
| 855 | ** fc Show details of files changed |
| 856 | ** f=RID Show family (immediate parents and children) of RID |
| 857 | ** from=RID Path from... |
| 858 | ** to=RID ... to this |
| 859 | ** nomerge ... avoid merge links on the path |
| 860 | ** brbg Background color from branch name |
| 861 | ** ubg Background color from user |
| 862 | ** |
| 863 | ** p= and d= can appear individually or together. If either p= or d= |
| @@ -893,15 +897,23 @@ | |
| 893 | int from_rid = name_to_typed_rid(P("from"),"ci"); /* from= for paths */ |
| 894 | int to_rid = name_to_typed_rid(P("to"),"ci"); /* to= for path timelines */ |
| 895 | int noMerge = P("nomerge")!=0; /* Do not follow merge links */ |
| 896 | int me_rid = name_to_typed_rid(P("me"),"ci"); /* me= for common ancestory */ |
| 897 | int you_rid = name_to_typed_rid(P("you"),"ci");/* you= for common ancst */ |
| 898 | |
| 899 | /* To view the timeline, must have permission to read project data. |
| 900 | */ |
| 901 | login_check_credentials(); |
| 902 | if( !g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki ){ login_needed(); return; } |
| 903 | if( zTagName && g.perm.Read ){ |
| 904 | tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", zTagName); |
| 905 | zThisTag = zTagName; |
| 906 | }else if( zBrName && g.perm.Read ){ |
| 907 | tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",zBrName); |
| @@ -989,14 +1001,12 @@ | |
| 989 | blob_appendf(&sql, " AND event.objid IN ok"); |
| 990 | nd = 0; |
| 991 | if( d_rid ){ |
| 992 | compute_descendants(d_rid, nEntry+1); |
| 993 | nd = db_int(0, "SELECT count(*)-1 FROM ok"); |
| 994 | if( nd>=0 ){ |
| 995 | db_multi_exec("%s", blob_str(&sql)); |
| 996 | blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s"); |
| 997 | } |
| 998 | if( useDividers ) timeline_add_dividers(0, d_rid); |
| 999 | db_multi_exec("DELETE FROM ok"); |
| 1000 | } |
| 1001 | if( p_rid ){ |
| 1002 | compute_ancestors(p_rid, nEntry+1); |
| @@ -1076,19 +1086,20 @@ | |
| 1076 | } |
| 1077 | if( (zType[0]=='w' && !g.perm.RdWiki) |
| 1078 | || (zType[0]=='t' && !g.perm.RdTkt) |
| 1079 | || (zType[0]=='e' && !g.perm.RdWiki) |
| 1080 | || (zType[0]=='c' && !g.perm.Read) |
| 1081 | ){ |
| 1082 | zType = "all"; |
| 1083 | } |
| 1084 | if( zType[0]=='a' ){ |
| 1085 | if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){ |
| 1086 | char cSep = '('; |
| 1087 | blob_appendf(&sql, " AND event.type IN "); |
| 1088 | if( g.perm.Read ){ |
| 1089 | blob_appendf(&sql, "%c'ci'", cSep); |
| 1090 | cSep = ','; |
| 1091 | } |
| 1092 | if( g.perm.RdWiki ){ |
| 1093 | blob_appendf(&sql, "%c'w','e'", cSep); |
| 1094 | cSep = ','; |
| @@ -1108,10 +1119,12 @@ | |
| 1108 | zEType = "wiki edit"; |
| 1109 | }else if( zType[0]=='t' ){ |
| 1110 | zEType = "ticket change"; |
| 1111 | }else if( zType[0]=='e' ){ |
| 1112 | zEType = "event"; |
| 1113 | } |
| 1114 | } |
| 1115 | if( zUser ){ |
| 1116 | blob_appendf(&sql, " AND (event.user=%Q OR event.euser=%Q)", |
| 1117 | zUser, zUser); |
| @@ -1227,10 +1240,13 @@ | |
| 1227 | timeline_submenu(&url, "Tickets Only", "y", "t", 0); |
| 1228 | } |
| 1229 | if( zType[0]!='e' && g.perm.RdWiki ){ |
| 1230 | timeline_submenu(&url, "Events Only", "y", "e", 0); |
| 1231 | } |
| 1232 | } |
| 1233 | if( nEntry>20 ){ |
| 1234 | timeline_submenu(&url, "20 Entries", "n", "20", 0); |
| 1235 | } |
| 1236 | if( nEntry<200 ){ |
| 1237 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -180,11 +180,11 @@ | |
| 180 | ** 2. Date/Time |
| 181 | ** 3. Comment string |
| 182 | ** 4. User |
| 183 | ** 5. True if is a leaf |
| 184 | ** 6. background color |
| 185 | ** 7. type ("ci", "w", "t", "e", "g", "div") |
| 186 | ** 8. list of symbolic tags. |
| 187 | ** 9. tagid for ticket or wiki or event |
| 188 | ** 10. Short comment to user for repeated tickets and wiki |
| 189 | */ |
| 190 | void www_print_timeline( |
| @@ -317,10 +317,13 @@ | |
| 317 | @</td> |
| 318 | if( zBgClr && zBgClr[0] ){ |
| 319 | @ <td class="timelineTableCell" style="background-color: %h(zBgClr);"> |
| 320 | }else{ |
| 321 | @ <td class="timelineTableCell"> |
| 322 | } |
| 323 | if( pGraph && zType[0]!='c' ){ |
| 324 | @ • |
| 325 | } |
| 326 | if( zType[0]=='c' ){ |
| 327 | hyperlink_to_uuid(zUuid); |
| 328 | if( isLeaf ){ |
| 329 | if( db_exists("SELECT 1 FROM tagxref" |
| @@ -841,23 +844,24 @@ | |
| 844 | ** |
| 845 | ** a=TIMESTAMP after this date |
| 846 | ** b=TIMESTAMP before this date. |
| 847 | ** c=TIMESTAMP "circa" this date. |
| 848 | ** n=COUNT number of events in output |
| 849 | ** p=UUID artifact and up to COUNT parents and ancestors |
| 850 | ** d=UUID artifact and up to COUNT descendants |
| 851 | ** dp=UUUID The same as d=UUID&p=UUID |
| 852 | ** t=TAGID show only check-ins with the given tagid |
| 853 | ** r=TAGID show check-ins related to tagid |
| 854 | ** u=USER only if belonging to this user |
| 855 | ** y=TYPE 'ci', 'w', 't', 'e' |
| 856 | ** s=TEXT string search (comment and brief) |
| 857 | ** ng Suppress the graph if present |
| 858 | ** nd Suppress "divider" lines |
| 859 | ** fc Show details of files changed |
| 860 | ** f=UUID Show family (immediate parents and children) of UUID |
| 861 | ** from=UUID Path from... |
| 862 | ** to=UUID ... to this |
| 863 | ** nomerge ... avoid merge links on the path |
| 864 | ** brbg Background color from branch name |
| 865 | ** ubg Background color from user |
| 866 | ** |
| 867 | ** p= and d= can appear individually or together. If either p= or d= |
| @@ -893,15 +897,23 @@ | |
| 897 | int from_rid = name_to_typed_rid(P("from"),"ci"); /* from= for paths */ |
| 898 | int to_rid = name_to_typed_rid(P("to"),"ci"); /* to= for path timelines */ |
| 899 | int noMerge = P("nomerge")!=0; /* Do not follow merge links */ |
| 900 | int me_rid = name_to_typed_rid(P("me"),"ci"); /* me= for common ancestory */ |
| 901 | int you_rid = name_to_typed_rid(P("you"),"ci");/* you= for common ancst */ |
| 902 | int pd_rid; |
| 903 | |
| 904 | /* To view the timeline, must have permission to read project data. |
| 905 | */ |
| 906 | pd_rid = name_to_typed_rid(P("dp"),"ci"); |
| 907 | if( pd_rid ){ |
| 908 | p_rid = d_rid = pd_rid; |
| 909 | } |
| 910 | login_check_credentials(); |
| 911 | if( !g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki ){ |
| 912 | login_needed(); |
| 913 | return; |
| 914 | } |
| 915 | if( zTagName && g.perm.Read ){ |
| 916 | tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", zTagName); |
| 917 | zThisTag = zTagName; |
| 918 | }else if( zBrName && g.perm.Read ){ |
| 919 | tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",zBrName); |
| @@ -989,14 +1001,12 @@ | |
| 1001 | blob_appendf(&sql, " AND event.objid IN ok"); |
| 1002 | nd = 0; |
| 1003 | if( d_rid ){ |
| 1004 | compute_descendants(d_rid, nEntry+1); |
| 1005 | nd = db_int(0, "SELECT count(*)-1 FROM ok"); |
| 1006 | if( nd>=0 ) db_multi_exec("%s", blob_str(&sql)); |
| 1007 | if( nd>0 ) blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s"); |
| 1008 | if( useDividers ) timeline_add_dividers(0, d_rid); |
| 1009 | db_multi_exec("DELETE FROM ok"); |
| 1010 | } |
| 1011 | if( p_rid ){ |
| 1012 | compute_ancestors(p_rid, nEntry+1); |
| @@ -1076,19 +1086,20 @@ | |
| 1086 | } |
| 1087 | if( (zType[0]=='w' && !g.perm.RdWiki) |
| 1088 | || (zType[0]=='t' && !g.perm.RdTkt) |
| 1089 | || (zType[0]=='e' && !g.perm.RdWiki) |
| 1090 | || (zType[0]=='c' && !g.perm.Read) |
| 1091 | || (zType[0]=='g' && !g.perm.Read) |
| 1092 | ){ |
| 1093 | zType = "all"; |
| 1094 | } |
| 1095 | if( zType[0]=='a' ){ |
| 1096 | if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){ |
| 1097 | char cSep = '('; |
| 1098 | blob_appendf(&sql, " AND event.type IN "); |
| 1099 | if( g.perm.Read ){ |
| 1100 | blob_appendf(&sql, "%c'ci','g'", cSep); |
| 1101 | cSep = ','; |
| 1102 | } |
| 1103 | if( g.perm.RdWiki ){ |
| 1104 | blob_appendf(&sql, "%c'w','e'", cSep); |
| 1105 | cSep = ','; |
| @@ -1108,10 +1119,12 @@ | |
| 1119 | zEType = "wiki edit"; |
| 1120 | }else if( zType[0]=='t' ){ |
| 1121 | zEType = "ticket change"; |
| 1122 | }else if( zType[0]=='e' ){ |
| 1123 | zEType = "event"; |
| 1124 | }else if( zType[0]=='g' ){ |
| 1125 | zEType = "tag"; |
| 1126 | } |
| 1127 | } |
| 1128 | if( zUser ){ |
| 1129 | blob_appendf(&sql, " AND (event.user=%Q OR event.euser=%Q)", |
| 1130 | zUser, zUser); |
| @@ -1227,10 +1240,13 @@ | |
| 1240 | timeline_submenu(&url, "Tickets Only", "y", "t", 0); |
| 1241 | } |
| 1242 | if( zType[0]!='e' && g.perm.RdWiki ){ |
| 1243 | timeline_submenu(&url, "Events Only", "y", "e", 0); |
| 1244 | } |
| 1245 | if( zType[0]!='g' && g.perm.Read ){ |
| 1246 | timeline_submenu(&url, "Tags Only", "y", "g", 0); |
| 1247 | } |
| 1248 | } |
| 1249 | if( nEntry>20 ){ |
| 1250 | timeline_submenu(&url, "20 Entries", "n", "20", 0); |
| 1251 | } |
| 1252 | if( nEntry<200 ){ |
| 1253 |
-2
| --- src/tkt.c | ||
| +++ src/tkt.c | ||
| @@ -170,11 +170,10 @@ | ||
| 170 | 170 | */ |
| 171 | 171 | int ticket_insert(const Manifest *p, int createFlag, int rid){ |
| 172 | 172 | Blob sql; |
| 173 | 173 | Stmt q; |
| 174 | 174 | int i; |
| 175 | - const char *zSep; | |
| 176 | 175 | int rc = 0; |
| 177 | 176 | |
| 178 | 177 | getAllTicketFields(); |
| 179 | 178 | if( createFlag ){ |
| 180 | 179 | db_multi_exec("INSERT OR IGNORE INTO ticket(tkt_uuid, tkt_mtime) " |
| @@ -181,11 +180,10 @@ | ||
| 181 | 180 | "VALUES(%Q, 0)", p->zTicketUuid); |
| 182 | 181 | rc = db_changes(); |
| 183 | 182 | } |
| 184 | 183 | blob_zero(&sql); |
| 185 | 184 | blob_appendf(&sql, "UPDATE OR REPLACE ticket SET tkt_mtime=:mtime"); |
| 186 | - zSep = "SET"; | |
| 187 | 185 | for(i=0; i<p->nField; i++){ |
| 188 | 186 | const char *zName = p->aField[i].zName; |
| 189 | 187 | if( zName[0]=='+' ){ |
| 190 | 188 | zName++; |
| 191 | 189 | if( fieldId(zName)<0 ) continue; |
| 192 | 190 |
| --- src/tkt.c | |
| +++ src/tkt.c | |
| @@ -170,11 +170,10 @@ | |
| 170 | */ |
| 171 | int ticket_insert(const Manifest *p, int createFlag, int rid){ |
| 172 | Blob sql; |
| 173 | Stmt q; |
| 174 | int i; |
| 175 | const char *zSep; |
| 176 | int rc = 0; |
| 177 | |
| 178 | getAllTicketFields(); |
| 179 | if( createFlag ){ |
| 180 | db_multi_exec("INSERT OR IGNORE INTO ticket(tkt_uuid, tkt_mtime) " |
| @@ -181,11 +180,10 @@ | |
| 181 | "VALUES(%Q, 0)", p->zTicketUuid); |
| 182 | rc = db_changes(); |
| 183 | } |
| 184 | blob_zero(&sql); |
| 185 | blob_appendf(&sql, "UPDATE OR REPLACE ticket SET tkt_mtime=:mtime"); |
| 186 | zSep = "SET"; |
| 187 | for(i=0; i<p->nField; i++){ |
| 188 | const char *zName = p->aField[i].zName; |
| 189 | if( zName[0]=='+' ){ |
| 190 | zName++; |
| 191 | if( fieldId(zName)<0 ) continue; |
| 192 |
| --- src/tkt.c | |
| +++ src/tkt.c | |
| @@ -170,11 +170,10 @@ | |
| 170 | */ |
| 171 | int ticket_insert(const Manifest *p, int createFlag, int rid){ |
| 172 | Blob sql; |
| 173 | Stmt q; |
| 174 | int i; |
| 175 | int rc = 0; |
| 176 | |
| 177 | getAllTicketFields(); |
| 178 | if( createFlag ){ |
| 179 | db_multi_exec("INSERT OR IGNORE INTO ticket(tkt_uuid, tkt_mtime) " |
| @@ -181,11 +180,10 @@ | |
| 180 | "VALUES(%Q, 0)", p->zTicketUuid); |
| 181 | rc = db_changes(); |
| 182 | } |
| 183 | blob_zero(&sql); |
| 184 | blob_appendf(&sql, "UPDATE OR REPLACE ticket SET tkt_mtime=:mtime"); |
| 185 | for(i=0; i<p->nField; i++){ |
| 186 | const char *zName = p->aField[i].zName; |
| 187 | if( zName[0]=='+' ){ |
| 188 | zName++; |
| 189 | if( fieldId(zName)<0 ) continue; |
| 190 |
-2
| --- src/tkt.c | ||
| +++ src/tkt.c | ||
| @@ -170,11 +170,10 @@ | ||
| 170 | 170 | */ |
| 171 | 171 | int ticket_insert(const Manifest *p, int createFlag, int rid){ |
| 172 | 172 | Blob sql; |
| 173 | 173 | Stmt q; |
| 174 | 174 | int i; |
| 175 | - const char *zSep; | |
| 176 | 175 | int rc = 0; |
| 177 | 176 | |
| 178 | 177 | getAllTicketFields(); |
| 179 | 178 | if( createFlag ){ |
| 180 | 179 | db_multi_exec("INSERT OR IGNORE INTO ticket(tkt_uuid, tkt_mtime) " |
| @@ -181,11 +180,10 @@ | ||
| 181 | 180 | "VALUES(%Q, 0)", p->zTicketUuid); |
| 182 | 181 | rc = db_changes(); |
| 183 | 182 | } |
| 184 | 183 | blob_zero(&sql); |
| 185 | 184 | blob_appendf(&sql, "UPDATE OR REPLACE ticket SET tkt_mtime=:mtime"); |
| 186 | - zSep = "SET"; | |
| 187 | 185 | for(i=0; i<p->nField; i++){ |
| 188 | 186 | const char *zName = p->aField[i].zName; |
| 189 | 187 | if( zName[0]=='+' ){ |
| 190 | 188 | zName++; |
| 191 | 189 | if( fieldId(zName)<0 ) continue; |
| 192 | 190 |
| --- src/tkt.c | |
| +++ src/tkt.c | |
| @@ -170,11 +170,10 @@ | |
| 170 | */ |
| 171 | int ticket_insert(const Manifest *p, int createFlag, int rid){ |
| 172 | Blob sql; |
| 173 | Stmt q; |
| 174 | int i; |
| 175 | const char *zSep; |
| 176 | int rc = 0; |
| 177 | |
| 178 | getAllTicketFields(); |
| 179 | if( createFlag ){ |
| 180 | db_multi_exec("INSERT OR IGNORE INTO ticket(tkt_uuid, tkt_mtime) " |
| @@ -181,11 +180,10 @@ | |
| 181 | "VALUES(%Q, 0)", p->zTicketUuid); |
| 182 | rc = db_changes(); |
| 183 | } |
| 184 | blob_zero(&sql); |
| 185 | blob_appendf(&sql, "UPDATE OR REPLACE ticket SET tkt_mtime=:mtime"); |
| 186 | zSep = "SET"; |
| 187 | for(i=0; i<p->nField; i++){ |
| 188 | const char *zName = p->aField[i].zName; |
| 189 | if( zName[0]=='+' ){ |
| 190 | zName++; |
| 191 | if( fieldId(zName)<0 ) continue; |
| 192 |
| --- src/tkt.c | |
| +++ src/tkt.c | |
| @@ -170,11 +170,10 @@ | |
| 170 | */ |
| 171 | int ticket_insert(const Manifest *p, int createFlag, int rid){ |
| 172 | Blob sql; |
| 173 | Stmt q; |
| 174 | int i; |
| 175 | int rc = 0; |
| 176 | |
| 177 | getAllTicketFields(); |
| 178 | if( createFlag ){ |
| 179 | db_multi_exec("INSERT OR IGNORE INTO ticket(tkt_uuid, tkt_mtime) " |
| @@ -181,11 +180,10 @@ | |
| 180 | "VALUES(%Q, 0)", p->zTicketUuid); |
| 181 | rc = db_changes(); |
| 182 | } |
| 183 | blob_zero(&sql); |
| 184 | blob_appendf(&sql, "UPDATE OR REPLACE ticket SET tkt_mtime=:mtime"); |
| 185 | for(i=0; i<p->nField; i++){ |
| 186 | const char *zName = p->aField[i].zName; |
| 187 | if( zName[0]=='+' ){ |
| 188 | zName++; |
| 189 | if( fieldId(zName)<0 ) continue; |
| 190 |
+19
-8
| --- src/update.c | ||
| +++ src/update.c | ||
| @@ -96,10 +96,11 @@ | ||
| 96 | 96 | int debugFlag; /* --debug option */ |
| 97 | 97 | int nChng; /* Number of file renames */ |
| 98 | 98 | int *aChng; /* Array of file renames */ |
| 99 | 99 | int i; /* Loop counter */ |
| 100 | 100 | int nConflict = 0; /* Number of merge conflicts */ |
| 101 | + int nOverwrite = 0; /* Number of unmanaged files overwritten */ | |
| 101 | 102 | Stmt mtimeXfer; /* Statment to transfer mtimes */ |
| 102 | 103 | |
| 103 | 104 | if( !internalUpdate ){ |
| 104 | 105 | undo_capture_command_line(); |
| 105 | 106 | url_proxy_options(); |
| @@ -359,11 +360,16 @@ | ||
| 359 | 360 | */ |
| 360 | 361 | fossil_print("CONFLICT %s\n", zName); |
| 361 | 362 | nConflict++; |
| 362 | 363 | }else if( idt>0 && idv==0 ){ |
| 363 | 364 | /* File added in the target. */ |
| 364 | - fossil_print("ADD %s\n", zName); | |
| 365 | + if( file_wd_isfile_or_link(zFullPath) ){ | |
| 366 | + fossil_print("ADD %s (overwrites an unmanaged file)\n", zName); | |
| 367 | + nOverwrite++; | |
| 368 | + }else{ | |
| 369 | + fossil_print("ADD %s\n", zName); | |
| 370 | + } | |
| 365 | 371 | undo_save(zName); |
| 366 | 372 | if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0); |
| 367 | 373 | }else if( idt>0 && idv>0 && ridt!=ridv && chnged==0 ){ |
| 368 | 374 | /* The file is unedited. Change it to the target version */ |
| 369 | 375 | undo_save(zName); |
| @@ -449,17 +455,22 @@ | ||
| 449 | 455 | fossil_print("--------------\n"); |
| 450 | 456 | show_common_info(tid, "updated-to:", 1, 0); |
| 451 | 457 | |
| 452 | 458 | /* Report on conflicts |
| 453 | 459 | */ |
| 454 | - if( nConflict && !nochangeFlag ){ | |
| 455 | - if( internalUpdate ){ | |
| 456 | - internalConflictCnt = nConflict; | |
| 457 | - }else{ | |
| 458 | - fossil_print( | |
| 459 | - "WARNING: %d merge conflicts - see messages above for details.\n", | |
| 460 | - nConflict); | |
| 460 | + if( !nochangeFlag ){ | |
| 461 | + if( nConflict ){ | |
| 462 | + if( internalUpdate ){ | |
| 463 | + internalConflictCnt = nConflict; | |
| 464 | + nConflict = 0; | |
| 465 | + }else{ | |
| 466 | + fossil_print("WARNING: %d merge conflicts", nConflict); | |
| 467 | + } | |
| 468 | + } | |
| 469 | + if( nOverwrite ){ | |
| 470 | + fossil_warning("WARNING: %d unmanaged files where overwritten", | |
| 471 | + nOverwrite); | |
| 461 | 472 | } |
| 462 | 473 | } |
| 463 | 474 | |
| 464 | 475 | /* |
| 465 | 476 | ** Clean up the mid and pid VFILE entries. Then commit the changes. |
| 466 | 477 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -96,10 +96,11 @@ | |
| 96 | int debugFlag; /* --debug option */ |
| 97 | int nChng; /* Number of file renames */ |
| 98 | int *aChng; /* Array of file renames */ |
| 99 | int i; /* Loop counter */ |
| 100 | int nConflict = 0; /* Number of merge conflicts */ |
| 101 | Stmt mtimeXfer; /* Statment to transfer mtimes */ |
| 102 | |
| 103 | if( !internalUpdate ){ |
| 104 | undo_capture_command_line(); |
| 105 | url_proxy_options(); |
| @@ -359,11 +360,16 @@ | |
| 359 | */ |
| 360 | fossil_print("CONFLICT %s\n", zName); |
| 361 | nConflict++; |
| 362 | }else if( idt>0 && idv==0 ){ |
| 363 | /* File added in the target. */ |
| 364 | fossil_print("ADD %s\n", zName); |
| 365 | undo_save(zName); |
| 366 | if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0); |
| 367 | }else if( idt>0 && idv>0 && ridt!=ridv && chnged==0 ){ |
| 368 | /* The file is unedited. Change it to the target version */ |
| 369 | undo_save(zName); |
| @@ -449,17 +455,22 @@ | |
| 449 | fossil_print("--------------\n"); |
| 450 | show_common_info(tid, "updated-to:", 1, 0); |
| 451 | |
| 452 | /* Report on conflicts |
| 453 | */ |
| 454 | if( nConflict && !nochangeFlag ){ |
| 455 | if( internalUpdate ){ |
| 456 | internalConflictCnt = nConflict; |
| 457 | }else{ |
| 458 | fossil_print( |
| 459 | "WARNING: %d merge conflicts - see messages above for details.\n", |
| 460 | nConflict); |
| 461 | } |
| 462 | } |
| 463 | |
| 464 | /* |
| 465 | ** Clean up the mid and pid VFILE entries. Then commit the changes. |
| 466 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -96,10 +96,11 @@ | |
| 96 | int debugFlag; /* --debug option */ |
| 97 | int nChng; /* Number of file renames */ |
| 98 | int *aChng; /* Array of file renames */ |
| 99 | int i; /* Loop counter */ |
| 100 | int nConflict = 0; /* Number of merge conflicts */ |
| 101 | int nOverwrite = 0; /* Number of unmanaged files overwritten */ |
| 102 | Stmt mtimeXfer; /* Statment to transfer mtimes */ |
| 103 | |
| 104 | if( !internalUpdate ){ |
| 105 | undo_capture_command_line(); |
| 106 | url_proxy_options(); |
| @@ -359,11 +360,16 @@ | |
| 360 | */ |
| 361 | fossil_print("CONFLICT %s\n", zName); |
| 362 | nConflict++; |
| 363 | }else if( idt>0 && idv==0 ){ |
| 364 | /* File added in the target. */ |
| 365 | if( file_wd_isfile_or_link(zFullPath) ){ |
| 366 | fossil_print("ADD %s (overwrites an unmanaged file)\n", zName); |
| 367 | nOverwrite++; |
| 368 | }else{ |
| 369 | fossil_print("ADD %s\n", zName); |
| 370 | } |
| 371 | undo_save(zName); |
| 372 | if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0); |
| 373 | }else if( idt>0 && idv>0 && ridt!=ridv && chnged==0 ){ |
| 374 | /* The file is unedited. Change it to the target version */ |
| 375 | undo_save(zName); |
| @@ -449,17 +455,22 @@ | |
| 455 | fossil_print("--------------\n"); |
| 456 | show_common_info(tid, "updated-to:", 1, 0); |
| 457 | |
| 458 | /* Report on conflicts |
| 459 | */ |
| 460 | if( !nochangeFlag ){ |
| 461 | if( nConflict ){ |
| 462 | if( internalUpdate ){ |
| 463 | internalConflictCnt = nConflict; |
| 464 | nConflict = 0; |
| 465 | }else{ |
| 466 | fossil_print("WARNING: %d merge conflicts", nConflict); |
| 467 | } |
| 468 | } |
| 469 | if( nOverwrite ){ |
| 470 | fossil_warning("WARNING: %d unmanaged files where overwritten", |
| 471 | nOverwrite); |
| 472 | } |
| 473 | } |
| 474 | |
| 475 | /* |
| 476 | ** Clean up the mid and pid VFILE entries. Then commit the changes. |
| 477 |
+1
-3
| --- src/wikiformat.c | ||
| +++ src/wikiformat.c | ||
| @@ -1708,20 +1708,18 @@ | ||
| 1708 | 1708 | /* Enter <verbatim> processing. With verbatim enabled, all other |
| 1709 | 1709 | ** markup other than the corresponding end-tag with the same ID is |
| 1710 | 1710 | ** ignored. |
| 1711 | 1711 | */ |
| 1712 | 1712 | if( markup.iCode==MARKUP_VERBATIM ){ |
| 1713 | - int vAttrIdx, vAttrDidAppend=0; | |
| 1713 | + int vAttrIdx; | |
| 1714 | 1714 | renderer.zVerbatimId = 0; |
| 1715 | 1715 | renderer.inVerbatim = 1; |
| 1716 | 1716 | renderer.preVerbState = renderer.state; |
| 1717 | 1717 | renderer.state &= ~ALLOW_WIKI; |
| 1718 | 1718 | for (vAttrIdx = 0; vAttrIdx < markup.nAttr; vAttrIdx++){ |
| 1719 | 1719 | if( markup.aAttr[vAttrIdx].iACode == ATTR_ID ){ |
| 1720 | 1720 | renderer.zVerbatimId = markup.aAttr[0].zValue; |
| 1721 | - }else if( markup.aAttr[vAttrIdx].iACode == ATTR_TYPE ){ | |
| 1722 | - vAttrDidAppend=1; | |
| 1723 | 1721 | } |
| 1724 | 1722 | } |
| 1725 | 1723 | renderer.wantAutoParagraph = 0; |
| 1726 | 1724 | } |
| 1727 | 1725 | |
| 1728 | 1726 |
| --- src/wikiformat.c | |
| +++ src/wikiformat.c | |
| @@ -1708,20 +1708,18 @@ | |
| 1708 | /* Enter <verbatim> processing. With verbatim enabled, all other |
| 1709 | ** markup other than the corresponding end-tag with the same ID is |
| 1710 | ** ignored. |
| 1711 | */ |
| 1712 | if( markup.iCode==MARKUP_VERBATIM ){ |
| 1713 | int vAttrIdx, vAttrDidAppend=0; |
| 1714 | renderer.zVerbatimId = 0; |
| 1715 | renderer.inVerbatim = 1; |
| 1716 | renderer.preVerbState = renderer.state; |
| 1717 | renderer.state &= ~ALLOW_WIKI; |
| 1718 | for (vAttrIdx = 0; vAttrIdx < markup.nAttr; vAttrIdx++){ |
| 1719 | if( markup.aAttr[vAttrIdx].iACode == ATTR_ID ){ |
| 1720 | renderer.zVerbatimId = markup.aAttr[0].zValue; |
| 1721 | }else if( markup.aAttr[vAttrIdx].iACode == ATTR_TYPE ){ |
| 1722 | vAttrDidAppend=1; |
| 1723 | } |
| 1724 | } |
| 1725 | renderer.wantAutoParagraph = 0; |
| 1726 | } |
| 1727 | |
| 1728 |
| --- src/wikiformat.c | |
| +++ src/wikiformat.c | |
| @@ -1708,20 +1708,18 @@ | |
| 1708 | /* Enter <verbatim> processing. With verbatim enabled, all other |
| 1709 | ** markup other than the corresponding end-tag with the same ID is |
| 1710 | ** ignored. |
| 1711 | */ |
| 1712 | if( markup.iCode==MARKUP_VERBATIM ){ |
| 1713 | int vAttrIdx; |
| 1714 | renderer.zVerbatimId = 0; |
| 1715 | renderer.inVerbatim = 1; |
| 1716 | renderer.preVerbState = renderer.state; |
| 1717 | renderer.state &= ~ALLOW_WIKI; |
| 1718 | for (vAttrIdx = 0; vAttrIdx < markup.nAttr; vAttrIdx++){ |
| 1719 | if( markup.aAttr[vAttrIdx].iACode == ATTR_ID ){ |
| 1720 | renderer.zVerbatimId = markup.aAttr[0].zValue; |
| 1721 | } |
| 1722 | } |
| 1723 | renderer.wantAutoParagraph = 0; |
| 1724 | } |
| 1725 | |
| 1726 |
+1
-4
| --- src/xfer.c | ||
| +++ src/xfer.c | ||
| @@ -1198,20 +1198,19 @@ | ||
| 1198 | 1198 | ** |
| 1199 | 1199 | ** gdb fossil |
| 1200 | 1200 | ** r test-xfer out.txt |
| 1201 | 1201 | */ |
| 1202 | 1202 | void cmd_test_xfer(void){ |
| 1203 | - int notUsed; | |
| 1204 | 1203 | db_find_and_open_repository(0,0); |
| 1205 | 1204 | if( g.argc!=2 && g.argc!=3 ){ |
| 1206 | 1205 | usage("?MESSAGEFILE?"); |
| 1207 | 1206 | } |
| 1208 | 1207 | blob_zero(&g.cgiIn); |
| 1209 | 1208 | blob_read_from_file(&g.cgiIn, g.argc==2 ? "-" : g.argv[2]); |
| 1210 | 1209 | disableLogin = 1; |
| 1211 | 1210 | page_xfer(); |
| 1212 | - fossil_print("%s\n", cgi_extract_content(¬Used)); | |
| 1211 | + fossil_print("%s\n", cgi_extract_content()); | |
| 1213 | 1212 | } |
| 1214 | 1213 | |
| 1215 | 1214 | /* |
| 1216 | 1215 | ** Format strings for progress reporting. |
| 1217 | 1216 | */ |
| @@ -1238,11 +1237,10 @@ | ||
| 1238 | 1237 | int go = 1; /* Loop until zero */ |
| 1239 | 1238 | int nCardSent = 0; /* Number of cards sent */ |
| 1240 | 1239 | int nCardRcvd = 0; /* Number of cards received */ |
| 1241 | 1240 | int nCycle = 0; /* Number of round trips to the server */ |
| 1242 | 1241 | int size; /* Size of a config value */ |
| 1243 | - int nFileSend = 0; | |
| 1244 | 1242 | int origConfigRcvMask; /* Original value of configRcvMask */ |
| 1245 | 1243 | int nFileRecv; /* Number of files received */ |
| 1246 | 1244 | int mxPhantomReq = 200; /* Max number of phantoms to request per comm */ |
| 1247 | 1245 | const char *zCookie; /* Server cookie */ |
| 1248 | 1246 | i64 nSent, nRcvd; /* Bytes sent and received (after compression) */ |
| @@ -1380,11 +1378,10 @@ | ||
| 1380 | 1378 | zRandomness = db_text(0, "SELECT hex(randomblob(20))"); |
| 1381 | 1379 | blob_appendf(&send, "# %s\n", zRandomness); |
| 1382 | 1380 | free(zRandomness); |
| 1383 | 1381 | |
| 1384 | 1382 | /* Exchange messages with the server */ |
| 1385 | - nFileSend = xfer.nFileSent + xfer.nDeltaSent; | |
| 1386 | 1383 | fossil_print(zValueFormat, "Sent:", |
| 1387 | 1384 | blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent, |
| 1388 | 1385 | xfer.nFileSent, xfer.nDeltaSent); |
| 1389 | 1386 | nCardSent = 0; |
| 1390 | 1387 | nCardRcvd = 0; |
| 1391 | 1388 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -1198,20 +1198,19 @@ | |
| 1198 | ** |
| 1199 | ** gdb fossil |
| 1200 | ** r test-xfer out.txt |
| 1201 | */ |
| 1202 | void cmd_test_xfer(void){ |
| 1203 | int notUsed; |
| 1204 | db_find_and_open_repository(0,0); |
| 1205 | if( g.argc!=2 && g.argc!=3 ){ |
| 1206 | usage("?MESSAGEFILE?"); |
| 1207 | } |
| 1208 | blob_zero(&g.cgiIn); |
| 1209 | blob_read_from_file(&g.cgiIn, g.argc==2 ? "-" : g.argv[2]); |
| 1210 | disableLogin = 1; |
| 1211 | page_xfer(); |
| 1212 | fossil_print("%s\n", cgi_extract_content(¬Used)); |
| 1213 | } |
| 1214 | |
| 1215 | /* |
| 1216 | ** Format strings for progress reporting. |
| 1217 | */ |
| @@ -1238,11 +1237,10 @@ | |
| 1238 | int go = 1; /* Loop until zero */ |
| 1239 | int nCardSent = 0; /* Number of cards sent */ |
| 1240 | int nCardRcvd = 0; /* Number of cards received */ |
| 1241 | int nCycle = 0; /* Number of round trips to the server */ |
| 1242 | int size; /* Size of a config value */ |
| 1243 | int nFileSend = 0; |
| 1244 | int origConfigRcvMask; /* Original value of configRcvMask */ |
| 1245 | int nFileRecv; /* Number of files received */ |
| 1246 | int mxPhantomReq = 200; /* Max number of phantoms to request per comm */ |
| 1247 | const char *zCookie; /* Server cookie */ |
| 1248 | i64 nSent, nRcvd; /* Bytes sent and received (after compression) */ |
| @@ -1380,11 +1378,10 @@ | |
| 1380 | zRandomness = db_text(0, "SELECT hex(randomblob(20))"); |
| 1381 | blob_appendf(&send, "# %s\n", zRandomness); |
| 1382 | free(zRandomness); |
| 1383 | |
| 1384 | /* Exchange messages with the server */ |
| 1385 | nFileSend = xfer.nFileSent + xfer.nDeltaSent; |
| 1386 | fossil_print(zValueFormat, "Sent:", |
| 1387 | blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent, |
| 1388 | xfer.nFileSent, xfer.nDeltaSent); |
| 1389 | nCardSent = 0; |
| 1390 | nCardRcvd = 0; |
| 1391 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -1198,20 +1198,19 @@ | |
| 1198 | ** |
| 1199 | ** gdb fossil |
| 1200 | ** r test-xfer out.txt |
| 1201 | */ |
| 1202 | void cmd_test_xfer(void){ |
| 1203 | db_find_and_open_repository(0,0); |
| 1204 | if( g.argc!=2 && g.argc!=3 ){ |
| 1205 | usage("?MESSAGEFILE?"); |
| 1206 | } |
| 1207 | blob_zero(&g.cgiIn); |
| 1208 | blob_read_from_file(&g.cgiIn, g.argc==2 ? "-" : g.argv[2]); |
| 1209 | disableLogin = 1; |
| 1210 | page_xfer(); |
| 1211 | fossil_print("%s\n", cgi_extract_content()); |
| 1212 | } |
| 1213 | |
| 1214 | /* |
| 1215 | ** Format strings for progress reporting. |
| 1216 | */ |
| @@ -1238,11 +1237,10 @@ | |
| 1237 | int go = 1; /* Loop until zero */ |
| 1238 | int nCardSent = 0; /* Number of cards sent */ |
| 1239 | int nCardRcvd = 0; /* Number of cards received */ |
| 1240 | int nCycle = 0; /* Number of round trips to the server */ |
| 1241 | int size; /* Size of a config value */ |
| 1242 | int origConfigRcvMask; /* Original value of configRcvMask */ |
| 1243 | int nFileRecv; /* Number of files received */ |
| 1244 | int mxPhantomReq = 200; /* Max number of phantoms to request per comm */ |
| 1245 | const char *zCookie; /* Server cookie */ |
| 1246 | i64 nSent, nRcvd; /* Bytes sent and received (after compression) */ |
| @@ -1380,11 +1378,10 @@ | |
| 1378 | zRandomness = db_text(0, "SELECT hex(randomblob(20))"); |
| 1379 | blob_appendf(&send, "# %s\n", zRandomness); |
| 1380 | free(zRandomness); |
| 1381 | |
| 1382 | /* Exchange messages with the server */ |
| 1383 | fossil_print(zValueFormat, "Sent:", |
| 1384 | blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent, |
| 1385 | xfer.nFileSent, xfer.nDeltaSent); |
| 1386 | nCardSent = 0; |
| 1387 | nCardRcvd = 0; |
| 1388 |