Fossil SCM

Attempt to add the exbase=PATH query parameter as an option to the /ckout page.

drh 2024-12-14 21:20 trunk
Commit 700b5031fdb85eabd997401833071a3d582be20fbb6d078b68208998745dbf3e
1 file changed +125 -37
+125 -37
--- src/info.c
+++ src/info.c
@@ -609,54 +609,21 @@
609609
db_finalize(&q);
610610
style_finish_page();
611611
}
612612
613613
/*
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
619615
*/
620
-void ckout_page(void){
621
- int vid;
622
- char *zHostname;
623
- char *zCwd;
616
+static void ckout_normal_diff(int vid){
624617
int diffType; /* 0: no diff, 1: unified, 2: side-by-side */
625618
DiffConfig DCfg,*pCfg; /* Diff details */
626
- const char *zHome; /* Home directory */
627619
const char *zW; /* The "w" query parameter */
628620
int nChng; /* Number of changes */
629621
Stmt q;
630622
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);
636623
diffType = preferred_diff_type();
637624
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);
658625
nChng = db_int(0, "SELECT count(*) FROM vfile"
659626
" WHERE vid=%d AND (deleted OR chnged OR rid==0)", vid);
660627
if( nChng==0 ){
661628
@ <p>No uncommitted changes</p>
662629
style_finish_page();
@@ -674,11 +641,10 @@
674641
if( DCfg.diffFlags & DIFF_SIDEBYSIDE ){
675642
DCfg.diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
676643
}else{
677644
DCfg.diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG;
678645
}
679
- @ <hr>
680646
@ <div class="sectionmenu info-changes-menu">
681647
zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
682648
if( diffType!=1 ){
683649
@ %z(chref("button","%R?diff=1%s",zW))Unified&nbsp;Diff</a>
684650
}
@@ -750,12 +716,134 @@
750716
blob_reset(&old);
751717
blob_reset(&new);
752718
}
753719
}
754720
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&nbsp;Diff</a>
749
+ }
750
+ if( diffType!=2 ){
751
+ @ %z(chref("button","%R?diff=2&exbase=%h%s",zExBase,zW))\
752
+ @ Side-by-Side&nbsp;Diff</a>
753
+ }
754
+ if( diffType!=0 ){
755
+ if( *zW ){
756
+ @ %z(chref("button","%R?diff=%d&exbase=%h",diffType,zExBase))\
757
+ @ Show&nbsp;Whitespace&nbsp;Changes</a>
758
+ }else{
759
+ @ %z(chref("button","%R?diff=%d&exbase=%h&w",diffType,zExBase))\
760
+ @ Ignore&nbsp;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);
756796
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
+ }
757845
style_finish_page();
758846
}
759847
760848
/*
761849
** WEBPAGE: vinfo
762850
--- 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&nbsp;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&nbsp;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&nbsp;Diff</a>
749 }
750 if( diffType!=2 ){
751 @ %z(chref("button","%R?diff=2&exbase=%h%s",zExBase,zW))\
752 @ Side-by-Side&nbsp;Diff</a>
753 }
754 if( diffType!=0 ){
755 if( *zW ){
756 @ %z(chref("button","%R?diff=%d&exbase=%h",diffType,zExBase))\
757 @ Show&nbsp;Whitespace&nbsp;Changes</a>
758 }else{
759 @ %z(chref("button","%R?diff=%d&exbase=%h&w",diffType,zExBase))\
760 @ Ignore&nbsp;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

Keyboard Shortcuts

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