Fossil SCM
Attempt to add the exbase=PATH query parameter as an option to the /ckout page.
Commit
700b5031fdb85eabd997401833071a3d582be20fbb6d078b68208998745dbf3e
Parent
99d0baa61508415…
1 file changed
+125
-37
+125
-37
| --- src/info.c | ||
| +++ src/info.c | ||
| @@ -609,54 +609,21 @@ | ||
| 609 | 609 | db_finalize(&q); |
| 610 | 610 | style_finish_page(); |
| 611 | 611 | } |
| 612 | 612 | |
| 613 | 613 | /* |
| 614 | -** WEBPAGE: ckout | |
| 615 | -** | |
| 616 | -** Show information about the current checkout. This page only functions | |
| 617 | -** if the web server is run on a loopback interface (in other words, was | |
| 618 | -** started using "fossil ui" or similar) from with on open check-out. | |
| 614 | +** Render a web-page diff of the changes in the working check-out | |
| 619 | 615 | */ |
| 620 | -void ckout_page(void){ | |
| 621 | - int vid; | |
| 622 | - char *zHostname; | |
| 623 | - char *zCwd; | |
| 616 | +static void ckout_normal_diff(int vid){ | |
| 624 | 617 | int diffType; /* 0: no diff, 1: unified, 2: side-by-side */ |
| 625 | 618 | DiffConfig DCfg,*pCfg; /* Diff details */ |
| 626 | - const char *zHome; /* Home directory */ | |
| 627 | 619 | const char *zW; /* The "w" query parameter */ |
| 628 | 620 | int nChng; /* Number of changes */ |
| 629 | 621 | Stmt q; |
| 630 | 622 | |
| 631 | - if( !db_open_local(0) || !cgi_is_loopback(g.zIpAddr) ){ | |
| 632 | - cgi_redirectf("%R/home"); | |
| 633 | - return; | |
| 634 | - } | |
| 635 | - file_chdir(g.zLocalRoot, 0); | |
| 636 | 623 | diffType = preferred_diff_type(); |
| 637 | 624 | pCfg = construct_diff_flags(diffType, &DCfg); |
| 638 | - vid = db_lget_int("checkout", 0); | |
| 639 | - db_unprotect(PROTECT_ALL); | |
| 640 | - vfile_check_signature(vid, CKSIG_ENOTFILE); | |
| 641 | - db_protect_pop(); | |
| 642 | - style_set_current_feature("vinfo"); | |
| 643 | - zHostname = fossil_hostname(); | |
| 644 | - zCwd = file_getcwd(0,0); | |
| 645 | - zHome = fossil_getenv("HOME"); | |
| 646 | - if( zHome ){ | |
| 647 | - int nHome = (int)strlen(zHome); | |
| 648 | - if( strncmp(zCwd, zHome, nHome)==0 && zCwd[nHome]=='/' ){ | |
| 649 | - zCwd = mprintf("~%s", zCwd+nHome); | |
| 650 | - } | |
| 651 | - } | |
| 652 | - if( zHostname ){ | |
| 653 | - style_header("Checkout Status: %h on %h", zCwd, zHostname); | |
| 654 | - }else{ | |
| 655 | - style_header("Checkout Status: %h", zCwd); | |
| 656 | - } | |
| 657 | - render_checkin_context(vid, 0, 0, 0); | |
| 658 | 625 | nChng = db_int(0, "SELECT count(*) FROM vfile" |
| 659 | 626 | " WHERE vid=%d AND (deleted OR chnged OR rid==0)", vid); |
| 660 | 627 | if( nChng==0 ){ |
| 661 | 628 | @ <p>No uncommitted changes</p> |
| 662 | 629 | style_finish_page(); |
| @@ -674,11 +641,10 @@ | ||
| 674 | 641 | if( DCfg.diffFlags & DIFF_SIDEBYSIDE ){ |
| 675 | 642 | DCfg.diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG; |
| 676 | 643 | }else{ |
| 677 | 644 | DCfg.diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG; |
| 678 | 645 | } |
| 679 | - @ <hr> | |
| 680 | 646 | @ <div class="sectionmenu info-changes-menu"> |
| 681 | 647 | zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":""; |
| 682 | 648 | if( diffType!=1 ){ |
| 683 | 649 | @ %z(chref("button","%R?diff=1%s",zW))Unified Diff</a> |
| 684 | 650 | } |
| @@ -750,12 +716,134 @@ | ||
| 750 | 716 | blob_reset(&old); |
| 751 | 717 | blob_reset(&new); |
| 752 | 718 | } |
| 753 | 719 | } |
| 754 | 720 | db_finalize(&q); |
| 755 | - // @ </div> <!-- ap-002 --> | |
| 721 | + append_diff_javascript(diffType); | |
| 722 | +} | |
| 723 | + | |
| 724 | +/* | |
| 725 | +** Render a web-page diff of the changes in the working check-out to | |
| 726 | +** an external reference. | |
| 727 | +*/ | |
| 728 | +static void ckout_external_base_diff(int vid, const char *zExBase){ | |
| 729 | + int diffType; /* 0: no diff, 1: unified, 2: side-by-side */ | |
| 730 | + DiffConfig DCfg,*pCfg; /* Diff details */ | |
| 731 | + const char *zW; /* The "w" query parameter */ | |
| 732 | + Stmt q; | |
| 733 | + | |
| 734 | + diffType = preferred_diff_type(); | |
| 735 | + pCfg = construct_diff_flags(diffType, &DCfg); | |
| 736 | + db_prepare(&q, | |
| 737 | + "SELECT pathname FROM vfile WHERE vid=%d ORDER BY pathname", vid | |
| 738 | + ); | |
| 739 | + if( DCfg.diffFlags & DIFF_SIDEBYSIDE ){ | |
| 740 | + DCfg.diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG; | |
| 741 | + }else{ | |
| 742 | + DCfg.diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG; | |
| 743 | + } | |
| 744 | + @ <div class="sectionmenu info-changes-menu"> | |
| 745 | + zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":""; | |
| 746 | + if( diffType!=1 ){ | |
| 747 | + @ %z(chref("button","%R?diff=1&exbase=%h%s",zExBase,zW))\ | |
| 748 | + @ Unified Diff</a> | |
| 749 | + } | |
| 750 | + if( diffType!=2 ){ | |
| 751 | + @ %z(chref("button","%R?diff=2&exbase=%h%s",zExBase,zW))\ | |
| 752 | + @ Side-by-Side Diff</a> | |
| 753 | + } | |
| 754 | + if( diffType!=0 ){ | |
| 755 | + if( *zW ){ | |
| 756 | + @ %z(chref("button","%R?diff=%d&exbase=%h",diffType,zExBase))\ | |
| 757 | + @ Show Whitespace Changes</a> | |
| 758 | + }else{ | |
| 759 | + @ %z(chref("button","%R?diff=%d&exbase=%h&w",diffType,zExBase))\ | |
| 760 | + @ Ignore Whitespace</a> | |
| 761 | + } | |
| 762 | + } | |
| 763 | + @ </div> | |
| 764 | + while( db_step(&q)==SQLITE_ROW ){ | |
| 765 | + const char *zFile; /* Name of file in the repository */ | |
| 766 | + char *zLhs; /* Full name of left-hand side file */ | |
| 767 | + char *zRhs; /* Full name of right-hand side file */ | |
| 768 | + Blob rhs; /* Full text of RHS */ | |
| 769 | + Blob lhs; /* Full text of LHS */ | |
| 770 | + | |
| 771 | + zFile = db_column_text(&q,0); | |
| 772 | + zLhs = mprintf("%s/%s", zExBase, zFile); | |
| 773 | + zRhs = mprintf("%s%s", g.zLocalRoot, zFile); | |
| 774 | + if( file_size(zLhs, ExtFILE)<0 ){ | |
| 775 | + blob_zero(&lhs); | |
| 776 | + }else{ | |
| 777 | + blob_read_from_file(&lhs, zLhs, ExtFILE); | |
| 778 | + } | |
| 779 | + blob_read_from_file(&rhs, zRhs, ExtFILE); | |
| 780 | + if( blob_size(&lhs)!=blob_size(&rhs) | |
| 781 | + || memcmp(blob_buffer(&lhs), blob_buffer(&rhs), blob_size(&lhs))!=0 | |
| 782 | + ){ | |
| 783 | + @ <div class='file-change-line'><span> | |
| 784 | + @ Changes to %h(zFile) | |
| 785 | + @ </span></div> | |
| 786 | + if( pCfg ){ | |
| 787 | + text_diff(&lhs, &rhs, cgi_output_blob(), pCfg); | |
| 788 | + } | |
| 789 | + } | |
| 790 | + blob_reset(&lhs); | |
| 791 | + blob_reset(&rhs); | |
| 792 | + fossil_free(zLhs); | |
| 793 | + fossil_free(zRhs); | |
| 794 | + } | |
| 795 | + db_finalize(&q); | |
| 756 | 796 | append_diff_javascript(diffType); |
| 797 | +} | |
| 798 | + | |
| 799 | +/* | |
| 800 | +** WEBPAGE: ckout | |
| 801 | +** | |
| 802 | +** Show information about the current checkout. This page only functions | |
| 803 | +** if the web server is run on a loopback interface (in other words, was | |
| 804 | +** started using "fossil ui" or similar) from with on open check-out. | |
| 805 | +*/ | |
| 806 | +void ckout_page(void){ | |
| 807 | + int vid; | |
| 808 | + const char *zHome; /* Home directory */ | |
| 809 | + const char *zExBase; | |
| 810 | + char *zHostname; | |
| 811 | + char *zCwd; | |
| 812 | + | |
| 813 | + if( !db_open_local(0) || !cgi_is_loopback(g.zIpAddr) ){ | |
| 814 | + cgi_redirectf("%R/home"); | |
| 815 | + return; | |
| 816 | + } | |
| 817 | + file_chdir(g.zLocalRoot, 0); | |
| 818 | + vid = db_lget_int("checkout", 0); | |
| 819 | + db_unprotect(PROTECT_ALL); | |
| 820 | + vfile_check_signature(vid, CKSIG_ENOTFILE); | |
| 821 | + db_protect_pop(); | |
| 822 | + style_set_current_feature("vinfo"); | |
| 823 | + zHostname = fossil_hostname(); | |
| 824 | + zCwd = file_getcwd(0,0); | |
| 825 | + zHome = fossil_getenv("HOME"); | |
| 826 | + if( zHome ){ | |
| 827 | + int nHome = (int)strlen(zHome); | |
| 828 | + if( strncmp(zCwd, zHome, nHome)==0 && zCwd[nHome]=='/' ){ | |
| 829 | + zCwd = mprintf("~%s", zCwd+nHome); | |
| 830 | + } | |
| 831 | + } | |
| 832 | + if( zHostname ){ | |
| 833 | + style_header("Checkout Status: %h on %h", zCwd, zHostname); | |
| 834 | + }else{ | |
| 835 | + style_header("Checkout Status: %h", zCwd); | |
| 836 | + } | |
| 837 | + render_checkin_context(vid, 0, 0, 0); | |
| 838 | + @ <hr> | |
| 839 | + zExBase = P("exbase"); | |
| 840 | + if( zExBase && zExBase[0] ){ | |
| 841 | + ckout_external_base_diff(vid, zExBase); | |
| 842 | + }else{ | |
| 843 | + ckout_normal_diff(vid); | |
| 844 | + } | |
| 757 | 845 | style_finish_page(); |
| 758 | 846 | } |
| 759 | 847 | |
| 760 | 848 | /* |
| 761 | 849 | ** WEBPAGE: vinfo |
| 762 | 850 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -609,54 +609,21 @@ | |
| 609 | db_finalize(&q); |
| 610 | style_finish_page(); |
| 611 | } |
| 612 | |
| 613 | /* |
| 614 | ** WEBPAGE: ckout |
| 615 | ** |
| 616 | ** Show information about the current checkout. This page only functions |
| 617 | ** if the web server is run on a loopback interface (in other words, was |
| 618 | ** started using "fossil ui" or similar) from with on open check-out. |
| 619 | */ |
| 620 | void ckout_page(void){ |
| 621 | int vid; |
| 622 | char *zHostname; |
| 623 | char *zCwd; |
| 624 | int diffType; /* 0: no diff, 1: unified, 2: side-by-side */ |
| 625 | DiffConfig DCfg,*pCfg; /* Diff details */ |
| 626 | const char *zHome; /* Home directory */ |
| 627 | const char *zW; /* The "w" query parameter */ |
| 628 | int nChng; /* Number of changes */ |
| 629 | Stmt q; |
| 630 | |
| 631 | if( !db_open_local(0) || !cgi_is_loopback(g.zIpAddr) ){ |
| 632 | cgi_redirectf("%R/home"); |
| 633 | return; |
| 634 | } |
| 635 | file_chdir(g.zLocalRoot, 0); |
| 636 | diffType = preferred_diff_type(); |
| 637 | pCfg = construct_diff_flags(diffType, &DCfg); |
| 638 | vid = db_lget_int("checkout", 0); |
| 639 | db_unprotect(PROTECT_ALL); |
| 640 | vfile_check_signature(vid, CKSIG_ENOTFILE); |
| 641 | db_protect_pop(); |
| 642 | style_set_current_feature("vinfo"); |
| 643 | zHostname = fossil_hostname(); |
| 644 | zCwd = file_getcwd(0,0); |
| 645 | zHome = fossil_getenv("HOME"); |
| 646 | if( zHome ){ |
| 647 | int nHome = (int)strlen(zHome); |
| 648 | if( strncmp(zCwd, zHome, nHome)==0 && zCwd[nHome]=='/' ){ |
| 649 | zCwd = mprintf("~%s", zCwd+nHome); |
| 650 | } |
| 651 | } |
| 652 | if( zHostname ){ |
| 653 | style_header("Checkout Status: %h on %h", zCwd, zHostname); |
| 654 | }else{ |
| 655 | style_header("Checkout Status: %h", zCwd); |
| 656 | } |
| 657 | render_checkin_context(vid, 0, 0, 0); |
| 658 | nChng = db_int(0, "SELECT count(*) FROM vfile" |
| 659 | " WHERE vid=%d AND (deleted OR chnged OR rid==0)", vid); |
| 660 | if( nChng==0 ){ |
| 661 | @ <p>No uncommitted changes</p> |
| 662 | style_finish_page(); |
| @@ -674,11 +641,10 @@ | |
| 674 | if( DCfg.diffFlags & DIFF_SIDEBYSIDE ){ |
| 675 | DCfg.diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG; |
| 676 | }else{ |
| 677 | DCfg.diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG; |
| 678 | } |
| 679 | @ <hr> |
| 680 | @ <div class="sectionmenu info-changes-menu"> |
| 681 | zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":""; |
| 682 | if( diffType!=1 ){ |
| 683 | @ %z(chref("button","%R?diff=1%s",zW))Unified Diff</a> |
| 684 | } |
| @@ -750,12 +716,134 @@ | |
| 750 | blob_reset(&old); |
| 751 | blob_reset(&new); |
| 752 | } |
| 753 | } |
| 754 | db_finalize(&q); |
| 755 | // @ </div> <!-- ap-002 --> |
| 756 | append_diff_javascript(diffType); |
| 757 | style_finish_page(); |
| 758 | } |
| 759 | |
| 760 | /* |
| 761 | ** WEBPAGE: vinfo |
| 762 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -609,54 +609,21 @@ | |
| 609 | db_finalize(&q); |
| 610 | style_finish_page(); |
| 611 | } |
| 612 | |
| 613 | /* |
| 614 | ** Render a web-page diff of the changes in the working check-out |
| 615 | */ |
| 616 | static void ckout_normal_diff(int vid){ |
| 617 | int diffType; /* 0: no diff, 1: unified, 2: side-by-side */ |
| 618 | DiffConfig DCfg,*pCfg; /* Diff details */ |
| 619 | const char *zW; /* The "w" query parameter */ |
| 620 | int nChng; /* Number of changes */ |
| 621 | Stmt q; |
| 622 | |
| 623 | diffType = preferred_diff_type(); |
| 624 | pCfg = construct_diff_flags(diffType, &DCfg); |
| 625 | nChng = db_int(0, "SELECT count(*) FROM vfile" |
| 626 | " WHERE vid=%d AND (deleted OR chnged OR rid==0)", vid); |
| 627 | if( nChng==0 ){ |
| 628 | @ <p>No uncommitted changes</p> |
| 629 | style_finish_page(); |
| @@ -674,11 +641,10 @@ | |
| 641 | if( DCfg.diffFlags & DIFF_SIDEBYSIDE ){ |
| 642 | DCfg.diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG; |
| 643 | }else{ |
| 644 | DCfg.diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG; |
| 645 | } |
| 646 | @ <div class="sectionmenu info-changes-menu"> |
| 647 | zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":""; |
| 648 | if( diffType!=1 ){ |
| 649 | @ %z(chref("button","%R?diff=1%s",zW))Unified Diff</a> |
| 650 | } |
| @@ -750,12 +716,134 @@ | |
| 716 | blob_reset(&old); |
| 717 | blob_reset(&new); |
| 718 | } |
| 719 | } |
| 720 | db_finalize(&q); |
| 721 | append_diff_javascript(diffType); |
| 722 | } |
| 723 | |
| 724 | /* |
| 725 | ** Render a web-page diff of the changes in the working check-out to |
| 726 | ** an external reference. |
| 727 | */ |
| 728 | static void ckout_external_base_diff(int vid, const char *zExBase){ |
| 729 | int diffType; /* 0: no diff, 1: unified, 2: side-by-side */ |
| 730 | DiffConfig DCfg,*pCfg; /* Diff details */ |
| 731 | const char *zW; /* The "w" query parameter */ |
| 732 | Stmt q; |
| 733 | |
| 734 | diffType = preferred_diff_type(); |
| 735 | pCfg = construct_diff_flags(diffType, &DCfg); |
| 736 | db_prepare(&q, |
| 737 | "SELECT pathname FROM vfile WHERE vid=%d ORDER BY pathname", vid |
| 738 | ); |
| 739 | if( DCfg.diffFlags & DIFF_SIDEBYSIDE ){ |
| 740 | DCfg.diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG; |
| 741 | }else{ |
| 742 | DCfg.diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG; |
| 743 | } |
| 744 | @ <div class="sectionmenu info-changes-menu"> |
| 745 | zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":""; |
| 746 | if( diffType!=1 ){ |
| 747 | @ %z(chref("button","%R?diff=1&exbase=%h%s",zExBase,zW))\ |
| 748 | @ Unified Diff</a> |
| 749 | } |
| 750 | if( diffType!=2 ){ |
| 751 | @ %z(chref("button","%R?diff=2&exbase=%h%s",zExBase,zW))\ |
| 752 | @ Side-by-Side Diff</a> |
| 753 | } |
| 754 | if( diffType!=0 ){ |
| 755 | if( *zW ){ |
| 756 | @ %z(chref("button","%R?diff=%d&exbase=%h",diffType,zExBase))\ |
| 757 | @ Show Whitespace Changes</a> |
| 758 | }else{ |
| 759 | @ %z(chref("button","%R?diff=%d&exbase=%h&w",diffType,zExBase))\ |
| 760 | @ Ignore Whitespace</a> |
| 761 | } |
| 762 | } |
| 763 | @ </div> |
| 764 | while( db_step(&q)==SQLITE_ROW ){ |
| 765 | const char *zFile; /* Name of file in the repository */ |
| 766 | char *zLhs; /* Full name of left-hand side file */ |
| 767 | char *zRhs; /* Full name of right-hand side file */ |
| 768 | Blob rhs; /* Full text of RHS */ |
| 769 | Blob lhs; /* Full text of LHS */ |
| 770 | |
| 771 | zFile = db_column_text(&q,0); |
| 772 | zLhs = mprintf("%s/%s", zExBase, zFile); |
| 773 | zRhs = mprintf("%s%s", g.zLocalRoot, zFile); |
| 774 | if( file_size(zLhs, ExtFILE)<0 ){ |
| 775 | blob_zero(&lhs); |
| 776 | }else{ |
| 777 | blob_read_from_file(&lhs, zLhs, ExtFILE); |
| 778 | } |
| 779 | blob_read_from_file(&rhs, zRhs, ExtFILE); |
| 780 | if( blob_size(&lhs)!=blob_size(&rhs) |
| 781 | || memcmp(blob_buffer(&lhs), blob_buffer(&rhs), blob_size(&lhs))!=0 |
| 782 | ){ |
| 783 | @ <div class='file-change-line'><span> |
| 784 | @ Changes to %h(zFile) |
| 785 | @ </span></div> |
| 786 | if( pCfg ){ |
| 787 | text_diff(&lhs, &rhs, cgi_output_blob(), pCfg); |
| 788 | } |
| 789 | } |
| 790 | blob_reset(&lhs); |
| 791 | blob_reset(&rhs); |
| 792 | fossil_free(zLhs); |
| 793 | fossil_free(zRhs); |
| 794 | } |
| 795 | db_finalize(&q); |
| 796 | append_diff_javascript(diffType); |
| 797 | } |
| 798 | |
| 799 | /* |
| 800 | ** WEBPAGE: ckout |
| 801 | ** |
| 802 | ** Show information about the current checkout. This page only functions |
| 803 | ** if the web server is run on a loopback interface (in other words, was |
| 804 | ** started using "fossil ui" or similar) from with on open check-out. |
| 805 | */ |
| 806 | void ckout_page(void){ |
| 807 | int vid; |
| 808 | const char *zHome; /* Home directory */ |
| 809 | const char *zExBase; |
| 810 | char *zHostname; |
| 811 | char *zCwd; |
| 812 | |
| 813 | if( !db_open_local(0) || !cgi_is_loopback(g.zIpAddr) ){ |
| 814 | cgi_redirectf("%R/home"); |
| 815 | return; |
| 816 | } |
| 817 | file_chdir(g.zLocalRoot, 0); |
| 818 | vid = db_lget_int("checkout", 0); |
| 819 | db_unprotect(PROTECT_ALL); |
| 820 | vfile_check_signature(vid, CKSIG_ENOTFILE); |
| 821 | db_protect_pop(); |
| 822 | style_set_current_feature("vinfo"); |
| 823 | zHostname = fossil_hostname(); |
| 824 | zCwd = file_getcwd(0,0); |
| 825 | zHome = fossil_getenv("HOME"); |
| 826 | if( zHome ){ |
| 827 | int nHome = (int)strlen(zHome); |
| 828 | if( strncmp(zCwd, zHome, nHome)==0 && zCwd[nHome]=='/' ){ |
| 829 | zCwd = mprintf("~%s", zCwd+nHome); |
| 830 | } |
| 831 | } |
| 832 | if( zHostname ){ |
| 833 | style_header("Checkout Status: %h on %h", zCwd, zHostname); |
| 834 | }else{ |
| 835 | style_header("Checkout Status: %h", zCwd); |
| 836 | } |
| 837 | render_checkin_context(vid, 0, 0, 0); |
| 838 | @ <hr> |
| 839 | zExBase = P("exbase"); |
| 840 | if( zExBase && zExBase[0] ){ |
| 841 | ckout_external_base_diff(vid, zExBase); |
| 842 | }else{ |
| 843 | ckout_normal_diff(vid); |
| 844 | } |
| 845 | style_finish_page(); |
| 846 | } |
| 847 | |
| 848 | /* |
| 849 | ** WEBPAGE: vinfo |
| 850 |