Fossil SCM

Preliminary implementation of a --tk option to the 3-way-merge command. Lots of work left to do to get this working well.

drh 2024-11-28 21:54 merge-enhancements
Commit bdcacd55be6762ea2269784caa2bb987c7fd0278722a91c4feeb8e14a3367487
--- src/main.mk
+++ src/main.mk
@@ -248,10 +248,11 @@
248248
$(SRCDIR)/hbmenu.js \
249249
$(SRCDIR)/href.js \
250250
$(SRCDIR)/login.js \
251251
$(SRCDIR)/markdown.md \
252252
$(SRCDIR)/menu.js \
253
+ $(SRCDIR)/merge.tcl \
253254
$(SRCDIR)/scroll.js \
254255
$(SRCDIR)/skin.js \
255256
$(SRCDIR)/sorttable.js \
256257
$(SRCDIR)/sounds/0.wav \
257258
$(SRCDIR)/sounds/1.wav \
258259
259260
ADDED src/merge.tcl
--- src/main.mk
+++ src/main.mk
@@ -248,10 +248,11 @@
248 $(SRCDIR)/hbmenu.js \
249 $(SRCDIR)/href.js \
250 $(SRCDIR)/login.js \
251 $(SRCDIR)/markdown.md \
252 $(SRCDIR)/menu.js \
 
253 $(SRCDIR)/scroll.js \
254 $(SRCDIR)/skin.js \
255 $(SRCDIR)/sorttable.js \
256 $(SRCDIR)/sounds/0.wav \
257 $(SRCDIR)/sounds/1.wav \
258
259 DDED src/merge.tcl
--- src/main.mk
+++ src/main.mk
@@ -248,10 +248,11 @@
248 $(SRCDIR)/hbmenu.js \
249 $(SRCDIR)/href.js \
250 $(SRCDIR)/login.js \
251 $(SRCDIR)/markdown.md \
252 $(SRCDIR)/menu.js \
253 $(SRCDIR)/merge.tcl \
254 $(SRCDIR)/scroll.js \
255 $(SRCDIR)/skin.js \
256 $(SRCDIR)/sorttable.js \
257 $(SRCDIR)/sounds/0.wav \
258 $(SRCDIR)/sounds/1.wav \
259
260 DDED src/merge.tcl
+108
--- a/src/merge.tcl
+++ b/src/merge.tcl
@@ -0,0 +1,108 @@
1
+ "--tk" option to vari%W curseleC# The "diff --tk" command ommand outputs prepends a "set fossilcmd {...}" line
2
+# toplevel ." || $usform(os)=="Dadisplay the
3
+# graphical ion to various merge commands p
4
+#to various mset fossilcmd(NAME) {...}" lines to this file, then runs this file using
5
+# "tclsh" in order to show a graphical analysis of the merge results.
6
+# A typical "setset prog {t fossilcmd" line looks like this:
7
+#
8
+# set fossilcmd(file1.tDiffvt> {
9
+ catch {
10
+ set idxo prevent the diff screen from
11
+# disappearing ahe "--tk" option to vari%W curselection0getLine {mergetff N iivar} {
12
+ upvar $iivar ii
13
+ if {$ii>=$N} {return -1}
14
+ set x [lindex $mergetxtglobal mergetxt
15
+ if {![ close $in
16
+ }
17
+}
18
+toplevel .wfiles
19
+
20
+update idletasks
21
+CFG(LB_HEIGHT)length $filngth $filelist %W%yt %W%y
22
+ }
23
+ wm deiconDiffvt> {
24
+ catch {
25
+ set idx [lindex [.txtA tag ranges fn] [expr {[%W curselection]*2}]]
26
+ viewDiff $idx
27
+ }
28
+ focus .
29
+ break
30
+ }
31
+}
32
+}
33
+#B3 grifc$sb
34
+ength $filelist }
35
+ } @%x,%y
36
+)=="Dar
37
+ set keyPrellength $filelist %W%y
38
+ }
39
+ } @%x,%y
40
+ text-_fplatform(os)==ommands prepends one or more
41
+# "set fossilcmd(NAME) {...}" lines to this -
42
+ }
43
+cl -i -v}(TITLE)ile, then runs this file using
44
+#-l "set fossilcmd" line looks like this:
45
+#
46
+# set fossilcmd(file1.txt) {| "./fossil"- --tcl -i -v}(TITLE)
47
+# . Disable them, to prevent the diff screen from
48
+# disappearing ahe "--tk" option to vari%W curselection0getLine {mergetxt N iivar} {
49
+ upvar $iivar ii
50
+ if {$ii>=$N} {return -1}
51
+ set x [lind-xt
52
+ if {![ close $in
53
+ }
54
+}
55
+toplevel .wfiles
56
+
57
+update idletasks
58
+CFG(LB_HEIGHT)length - %W%y
59
+ }
60
+ wm deiconify .wm(os)=="Darwin" || llength $filelist %W%y
61
+ $evt> {
62
+ catch {
63
+ set idx [lindex [.txtA tag ranges fn] [expr {[%W curselection]*2}]]
64
+ viewDiff $idx
65
+ }} more
66
+# "set fossilcmd(NA } @%x,%y
67
+ " \n" rm[.txtA tag ranges fn] [expr D %W%y
68
+ }
69
+ wm deicD
70
+ } set id-eDiff {} {
71
+ set fn [tk_getSaveFile]
72
+ if {$fn==""} return
73
+ set out [open $fn wb]
74
+ puts $out "#!/usr/bin/tclsh\n#\n# Run this script using 'tclsh' or 'wish'"
75
+ puts $out "# to see the graphical diff.\n#"
76
+ puts $out "set fossilcmd {}"
77
+ text-_fplatforA 0]
78
+ if {$key=="."} lines to this -
79
+ }
80
+cl\n - runs this file using
81
+#-# The "diff --tk" command o "--tk" option to vari%W curseleC# The "diff --tk" command ommand outputs prepends a "set fossilcmset key text-_fplatforB 0]
82
+ if {$key=="."}them, to prevent the diff\n -
83
+files
84
+
85
+update idletasks# The "diff --tk" command o "--tk" option to vari%W iivar} {
86
+ upvar $iivar ii
87
+ if -lind-xt
88
+ if {![ close $in
89
+ }
90
+}
91
+toplevel .wfiles
92
+
93
+update idletask-
94
+ }
95
+ }
96
+ set key text-_fplatforC 0]
97
+ if {$key=="."} set idx [lindex [.txtA t="Darwin" || llength $filelist %W%y
98
+ $evt> {
99
+ catch {
100
+ set idx ts $out "set mergetxt " \n "--tk" option to varition " \n" rm[.txtA tag rB "--tk" option to vari%W "--tk" option to vari%W cu-
101
+ }
102
+ }
103
+ set key text-_fplatform(os)==ommands pr=="."}ut "set fossilcmd {}"
104
+ p\n -
105
+# The "diff --tk" command ommand outputs prepends a "set fossilcmd {...}" line "--tk" option to vari%W curseleC# The "diff --tk" command ommand outputs prepends=="2
106
+CFG(LB_HEIGHT)length - %W "--tk" option to varition puts $out "#!/usr/bin/tc-lind-xt
107
+ if {![ close $in
108
+D set idx [lindex [.
--- a/src/merge.tcl
+++ b/src/merge.tcl
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/src/merge.tcl
+++ b/src/merge.tcl
@@ -0,0 +1,108 @@
1 "--tk" option to vari%W curseleC# The "diff --tk" command ommand outputs prepends a "set fossilcmd {...}" line
2 # toplevel ." || $usform(os)=="Dadisplay the
3 # graphical ion to various merge commands p
4 #to various mset fossilcmd(NAME) {...}" lines to this file, then runs this file using
5 # "tclsh" in order to show a graphical analysis of the merge results.
6 # A typical "setset prog {t fossilcmd" line looks like this:
7 #
8 # set fossilcmd(file1.tDiffvt> {
9 catch {
10 set idxo prevent the diff screen from
11 # disappearing ahe "--tk" option to vari%W curselection0getLine {mergetff N iivar} {
12 upvar $iivar ii
13 if {$ii>=$N} {return -1}
14 set x [lindex $mergetxtglobal mergetxt
15 if {![ close $in
16 }
17 }
18 toplevel .wfiles
19
20 update idletasks
21 CFG(LB_HEIGHT)length $filngth $filelist %W%yt %W%y
22 }
23 wm deiconDiffvt> {
24 catch {
25 set idx [lindex [.txtA tag ranges fn] [expr {[%W curselection]*2}]]
26 viewDiff $idx
27 }
28 focus .
29 break
30 }
31 }
32 }
33 #B3 grifc$sb
34 ength $filelist }
35 } @%x,%y
36 )=="Dar
37 set keyPrellength $filelist %W%y
38 }
39 } @%x,%y
40 text-_fplatform(os)==ommands prepends one or more
41 # "set fossilcmd(NAME) {...}" lines to this -
42 }
43 cl -i -v}(TITLE)ile, then runs this file using
44 #-l "set fossilcmd" line looks like this:
45 #
46 # set fossilcmd(file1.txt) {| "./fossil"- --tcl -i -v}(TITLE)
47 # . Disable them, to prevent the diff screen from
48 # disappearing ahe "--tk" option to vari%W curselection0getLine {mergetxt N iivar} {
49 upvar $iivar ii
50 if {$ii>=$N} {return -1}
51 set x [lind-xt
52 if {![ close $in
53 }
54 }
55 toplevel .wfiles
56
57 update idletasks
58 CFG(LB_HEIGHT)length - %W%y
59 }
60 wm deiconify .wm(os)=="Darwin" || llength $filelist %W%y
61 $evt> {
62 catch {
63 set idx [lindex [.txtA tag ranges fn] [expr {[%W curselection]*2}]]
64 viewDiff $idx
65 }} more
66 # "set fossilcmd(NA } @%x,%y
67 " \n" rm[.txtA tag ranges fn] [expr D %W%y
68 }
69 wm deicD
70 } set id-eDiff {} {
71 set fn [tk_getSaveFile]
72 if {$fn==""} return
73 set out [open $fn wb]
74 puts $out "#!/usr/bin/tclsh\n#\n# Run this script using 'tclsh' or 'wish'"
75 puts $out "# to see the graphical diff.\n#"
76 puts $out "set fossilcmd {}"
77 text-_fplatforA 0]
78 if {$key=="."} lines to this -
79 }
80 cl\n - runs this file using
81 #-# The "diff --tk" command o "--tk" option to vari%W curseleC# The "diff --tk" command ommand outputs prepends a "set fossilcmset key text-_fplatforB 0]
82 if {$key=="."}them, to prevent the diff\n -
83 files
84
85 update idletasks# The "diff --tk" command o "--tk" option to vari%W iivar} {
86 upvar $iivar ii
87 if -lind-xt
88 if {![ close $in
89 }
90 }
91 toplevel .wfiles
92
93 update idletask-
94 }
95 }
96 set key text-_fplatforC 0]
97 if {$key=="."} set idx [lindex [.txtA t="Darwin" || llength $filelist %W%y
98 $evt> {
99 catch {
100 set idx ts $out "set mergetxt " \n "--tk" option to varition " \n" rm[.txtA tag rB "--tk" option to vari%W "--tk" option to vari%W cu-
101 }
102 }
103 set key text-_fplatform(os)==ommands pr=="."}ut "set fossilcmd {}"
104 p\n -
105 # The "diff --tk" command ommand outputs prepends a "set fossilcmd {...}" line "--tk" option to vari%W curseleC# The "diff --tk" command ommand outputs prepends=="2
106 CFG(LB_HEIGHT)length - %W "--tk" option to varition puts $out "#!/usr/bin/tc-lind-xt
107 if {![ close $in
108 D set idx [lindex [.
+86 -1
--- src/merge3.c
+++ src/merge3.c
@@ -713,10 +713,81 @@
713713
blob_read_from_file(&file, zFullpath, ExtFILE);
714714
rc = contains_merge_marker(&file);
715715
blob_reset(&file);
716716
return rc;
717717
}
718
+
719
+/*
720
+** Show merge output in a Tcl/Tk window, in response to the --tk option
721
+** to the "merge" or "3-way-merge" command.
722
+**
723
+** If fossil has direct access to a Tcl interpreter (either loaded
724
+** dynamically through stubs or linked in statically), we can use it
725
+** directly. Otherwise:
726
+** (1) Write the Tcl/Tk script used for rendering into a temp file.
727
+** (2) Invoke "tclsh" on the temp file using fossil_system().
728
+** (3) Delete the temp file.
729
+*/
730
+void merge_tk(const char *zSubCmd, int firstArg){
731
+ int i;
732
+ Blob script;
733
+ const char *zTempFile = 0;
734
+ char *zCmd;
735
+ const char *zTclsh;
736
+ int bDarkMode = find_option("dark",0,0)!=0;
737
+ blob_zero(&script);
738
+ blob_appendf(&script, "set fossilcmd {| \"%/\" %s -tcl",
739
+ g.nameOfExe, zSubCmd);
740
+ find_option("tcl",0,0);
741
+ find_option("debug",0,0);
742
+ zTclsh = find_option("tclsh",0,1);
743
+ if( zTclsh==0 ){
744
+ zTclsh = db_get("tclsh",0);
745
+ }
746
+ /* The undocumented --script FILENAME option causes the Tk script to
747
+ ** be written into the FILENAME instead of being run. This is used
748
+ ** for testing and debugging. */
749
+ zTempFile = find_option("script",0,1);
750
+ for(i=firstArg; i<g.argc; i++){
751
+ const char *z = g.argv[i];
752
+ if( sqlite3_strglob("*}*",z) ){
753
+ blob_appendf(&script, " {%/}", z);
754
+ }else{
755
+ int j;
756
+ blob_append(&script, " ", 1);
757
+ for(j=0; z[j]; j++) blob_appendf(&script, "\\%03o", (unsigned char)z[j]);
758
+ }
759
+ }
760
+ blob_appendf(&script, "}\nset darkmode %d\n", bDarkMode);
761
+ blob_appendf(&script, "%s", builtin_file("merge.tcl", 0));
762
+ if( zTempFile ){
763
+ blob_write_to_file(&script, zTempFile);
764
+ fossil_print("To see the merge, run: %s \"%s\"\n", zTclsh, zTempFile);
765
+ }else{
766
+#if defined(FOSSIL_ENABLE_TCL)
767
+ Th_FossilInit(TH_INIT_DEFAULT);
768
+ if( evaluateTclWithEvents(g.interp, &g.tcl, blob_str(&script),
769
+ blob_size(&script), 1, 1, 0)==TCL_OK ){
770
+ blob_reset(&script);
771
+ return;
772
+ }
773
+ /*
774
+ * If evaluation of the Tcl script fails, the reason may be that Tk
775
+ * could not be found by the loaded Tcl, or that Tcl cannot be loaded
776
+ * dynamically (e.g. x64 Tcl with x86 Fossil). Therefore, fallback
777
+ * to using the external "tclsh", if available.
778
+ */
779
+#endif
780
+ zTempFile = write_blob_to_temp_file(&script);
781
+ zCmd = mprintf("%$ %$", zTclsh, zTempFile);
782
+ fossil_system(zCmd);
783
+ file_delete(zTempFile);
784
+ fossil_free(zCmd);
785
+ }
786
+ blob_reset(&script);
787
+}
788
+
718789
719790
/*
720791
** COMMAND: 3-way-merge*
721792
**
722793
** Usage: %fossil 3-way-merge BASELINE V1 V2 [MERGED]
@@ -746,18 +817,22 @@
746817
*/
747818
void merge_3way_cmd(void){
748819
MergeBuilder s;
749820
int nConflict;
750821
Blob pivot, v1, v2, out;
822
+ int noWarn = 0;
823
+ int flagTk = 0;
751824
752825
mergebuilder_init_text(&s);
753826
if( find_option("debug", 0, 0) ){
754827
mergebuilder_init(&s);
755828
}
756829
if( find_option("tcl", 0, 0) ){
757830
mergebuilder_init_tcl(&s);
831
+ noWarn = 1;
758832
}
833
+ flagTk = find_option("tk", 0, 0);
759834
blob_zero(&pivot); s.pPivot = &pivot;
760835
blob_zero(&v1); s.pV1 = &v1;
761836
blob_zero(&v2); s.pV2 = &v2;
762837
blob_zero(&out); s.pOut = &out;
763838
@@ -764,10 +839,18 @@
764839
/* We should be done with options.. */
765840
verify_all_options();
766841
767842
if( g.argc!=6 && g.argc!=5 ){
768843
usage("[OPTIONS] PIVOT V1 V2 [MERGED]");
844
+ }
845
+ if( flagTk ){
846
+ if( g.argc==6 ){
847
+ fossil_fatal("Cannot use an output file (\"%s\") with the --tk option",
848
+ g.argv[5]);
849
+ }
850
+ merge_tk("3-way-merge", 2);
851
+ return;
769852
}
770853
if( blob_read_from_file(s.pPivot, g.argv[2], ExtFILE)<0 ){
771854
fossil_fatal("cannot read %s", g.argv[2]);
772855
}
773856
if( blob_read_from_file(s.pV1, g.argv[3], ExtFILE)<0 ){
@@ -785,11 +868,13 @@
785868
s.xDestroy(&s);
786869
blob_reset(&pivot);
787870
blob_reset(&v1);
788871
blob_reset(&v2);
789872
blob_reset(&out);
790
- if( nConflict>0 ) fossil_warning("WARNING: %d merge conflicts", nConflict);
873
+ if( nConflict>0 && !noWarn ){
874
+ fossil_warning("WARNING: %d merge conflicts", nConflict);
875
+ }
791876
}
792877
793878
/*
794879
** aSubst is an array of string pairs. The first element of each pair is
795880
** a string that begins with %. The second element is a replacement for that
796881
--- src/merge3.c
+++ src/merge3.c
@@ -713,10 +713,81 @@
713 blob_read_from_file(&file, zFullpath, ExtFILE);
714 rc = contains_merge_marker(&file);
715 blob_reset(&file);
716 return rc;
717 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
718
719 /*
720 ** COMMAND: 3-way-merge*
721 **
722 ** Usage: %fossil 3-way-merge BASELINE V1 V2 [MERGED]
@@ -746,18 +817,22 @@
746 */
747 void merge_3way_cmd(void){
748 MergeBuilder s;
749 int nConflict;
750 Blob pivot, v1, v2, out;
 
 
751
752 mergebuilder_init_text(&s);
753 if( find_option("debug", 0, 0) ){
754 mergebuilder_init(&s);
755 }
756 if( find_option("tcl", 0, 0) ){
757 mergebuilder_init_tcl(&s);
 
758 }
 
759 blob_zero(&pivot); s.pPivot = &pivot;
760 blob_zero(&v1); s.pV1 = &v1;
761 blob_zero(&v2); s.pV2 = &v2;
762 blob_zero(&out); s.pOut = &out;
763
@@ -764,10 +839,18 @@
764 /* We should be done with options.. */
765 verify_all_options();
766
767 if( g.argc!=6 && g.argc!=5 ){
768 usage("[OPTIONS] PIVOT V1 V2 [MERGED]");
 
 
 
 
 
 
 
 
769 }
770 if( blob_read_from_file(s.pPivot, g.argv[2], ExtFILE)<0 ){
771 fossil_fatal("cannot read %s", g.argv[2]);
772 }
773 if( blob_read_from_file(s.pV1, g.argv[3], ExtFILE)<0 ){
@@ -785,11 +868,13 @@
785 s.xDestroy(&s);
786 blob_reset(&pivot);
787 blob_reset(&v1);
788 blob_reset(&v2);
789 blob_reset(&out);
790 if( nConflict>0 ) fossil_warning("WARNING: %d merge conflicts", nConflict);
 
 
791 }
792
793 /*
794 ** aSubst is an array of string pairs. The first element of each pair is
795 ** a string that begins with %. The second element is a replacement for that
796
--- src/merge3.c
+++ src/merge3.c
@@ -713,10 +713,81 @@
713 blob_read_from_file(&file, zFullpath, ExtFILE);
714 rc = contains_merge_marker(&file);
715 blob_reset(&file);
716 return rc;
717 }
718
719 /*
720 ** Show merge output in a Tcl/Tk window, in response to the --tk option
721 ** to the "merge" or "3-way-merge" command.
722 **
723 ** If fossil has direct access to a Tcl interpreter (either loaded
724 ** dynamically through stubs or linked in statically), we can use it
725 ** directly. Otherwise:
726 ** (1) Write the Tcl/Tk script used for rendering into a temp file.
727 ** (2) Invoke "tclsh" on the temp file using fossil_system().
728 ** (3) Delete the temp file.
729 */
730 void merge_tk(const char *zSubCmd, int firstArg){
731 int i;
732 Blob script;
733 const char *zTempFile = 0;
734 char *zCmd;
735 const char *zTclsh;
736 int bDarkMode = find_option("dark",0,0)!=0;
737 blob_zero(&script);
738 blob_appendf(&script, "set fossilcmd {| \"%/\" %s -tcl",
739 g.nameOfExe, zSubCmd);
740 find_option("tcl",0,0);
741 find_option("debug",0,0);
742 zTclsh = find_option("tclsh",0,1);
743 if( zTclsh==0 ){
744 zTclsh = db_get("tclsh",0);
745 }
746 /* The undocumented --script FILENAME option causes the Tk script to
747 ** be written into the FILENAME instead of being run. This is used
748 ** for testing and debugging. */
749 zTempFile = find_option("script",0,1);
750 for(i=firstArg; i<g.argc; i++){
751 const char *z = g.argv[i];
752 if( sqlite3_strglob("*}*",z) ){
753 blob_appendf(&script, " {%/}", z);
754 }else{
755 int j;
756 blob_append(&script, " ", 1);
757 for(j=0; z[j]; j++) blob_appendf(&script, "\\%03o", (unsigned char)z[j]);
758 }
759 }
760 blob_appendf(&script, "}\nset darkmode %d\n", bDarkMode);
761 blob_appendf(&script, "%s", builtin_file("merge.tcl", 0));
762 if( zTempFile ){
763 blob_write_to_file(&script, zTempFile);
764 fossil_print("To see the merge, run: %s \"%s\"\n", zTclsh, zTempFile);
765 }else{
766 #if defined(FOSSIL_ENABLE_TCL)
767 Th_FossilInit(TH_INIT_DEFAULT);
768 if( evaluateTclWithEvents(g.interp, &g.tcl, blob_str(&script),
769 blob_size(&script), 1, 1, 0)==TCL_OK ){
770 blob_reset(&script);
771 return;
772 }
773 /*
774 * If evaluation of the Tcl script fails, the reason may be that Tk
775 * could not be found by the loaded Tcl, or that Tcl cannot be loaded
776 * dynamically (e.g. x64 Tcl with x86 Fossil). Therefore, fallback
777 * to using the external "tclsh", if available.
778 */
779 #endif
780 zTempFile = write_blob_to_temp_file(&script);
781 zCmd = mprintf("%$ %$", zTclsh, zTempFile);
782 fossil_system(zCmd);
783 file_delete(zTempFile);
784 fossil_free(zCmd);
785 }
786 blob_reset(&script);
787 }
788
789
790 /*
791 ** COMMAND: 3-way-merge*
792 **
793 ** Usage: %fossil 3-way-merge BASELINE V1 V2 [MERGED]
@@ -746,18 +817,22 @@
817 */
818 void merge_3way_cmd(void){
819 MergeBuilder s;
820 int nConflict;
821 Blob pivot, v1, v2, out;
822 int noWarn = 0;
823 int flagTk = 0;
824
825 mergebuilder_init_text(&s);
826 if( find_option("debug", 0, 0) ){
827 mergebuilder_init(&s);
828 }
829 if( find_option("tcl", 0, 0) ){
830 mergebuilder_init_tcl(&s);
831 noWarn = 1;
832 }
833 flagTk = find_option("tk", 0, 0);
834 blob_zero(&pivot); s.pPivot = &pivot;
835 blob_zero(&v1); s.pV1 = &v1;
836 blob_zero(&v2); s.pV2 = &v2;
837 blob_zero(&out); s.pOut = &out;
838
@@ -764,10 +839,18 @@
839 /* We should be done with options.. */
840 verify_all_options();
841
842 if( g.argc!=6 && g.argc!=5 ){
843 usage("[OPTIONS] PIVOT V1 V2 [MERGED]");
844 }
845 if( flagTk ){
846 if( g.argc==6 ){
847 fossil_fatal("Cannot use an output file (\"%s\") with the --tk option",
848 g.argv[5]);
849 }
850 merge_tk("3-way-merge", 2);
851 return;
852 }
853 if( blob_read_from_file(s.pPivot, g.argv[2], ExtFILE)<0 ){
854 fossil_fatal("cannot read %s", g.argv[2]);
855 }
856 if( blob_read_from_file(s.pV1, g.argv[3], ExtFILE)<0 ){
@@ -785,11 +868,13 @@
868 s.xDestroy(&s);
869 blob_reset(&pivot);
870 blob_reset(&v1);
871 blob_reset(&v2);
872 blob_reset(&out);
873 if( nConflict>0 && !noWarn ){
874 fossil_warning("WARNING: %d merge conflicts", nConflict);
875 }
876 }
877
878 /*
879 ** aSubst is an array of string pairs. The first element of each pair is
880 ** a string that begins with %. The second element is a replacement for that
881
--- tools/makemake.tcl
+++ tools/makemake.tcl
@@ -209,10 +209,11 @@
209209
# Additional resource files that get built into the executable.
210210
# These paths are all resolved from the src/ directory, so must
211211
# be relative to that.
212212
set extra_files {
213213
diff.tcl
214
+ merge.tcl
214215
markdown.md
215216
wiki.wiki
216217
*.js
217218
default.css
218219
style.*.css
219220
--- tools/makemake.tcl
+++ tools/makemake.tcl
@@ -209,10 +209,11 @@
209 # Additional resource files that get built into the executable.
210 # These paths are all resolved from the src/ directory, so must
211 # be relative to that.
212 set extra_files {
213 diff.tcl
 
214 markdown.md
215 wiki.wiki
216 *.js
217 default.css
218 style.*.css
219
--- tools/makemake.tcl
+++ tools/makemake.tcl
@@ -209,10 +209,11 @@
209 # Additional resource files that get built into the executable.
210 # These paths are all resolved from the src/ directory, so must
211 # be relative to that.
212 set extra_files {
213 diff.tcl
214 merge.tcl
215 markdown.md
216 wiki.wiki
217 *.js
218 default.css
219 style.*.css
220
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -634,10 +634,11 @@
634634
$(SRCDIR)/hbmenu.js \
635635
$(SRCDIR)/href.js \
636636
$(SRCDIR)/login.js \
637637
$(SRCDIR)/markdown.md \
638638
$(SRCDIR)/menu.js \
639
+ $(SRCDIR)/merge.tcl \
639640
$(SRCDIR)/scroll.js \
640641
$(SRCDIR)/skin.js \
641642
$(SRCDIR)/sorttable.js \
642643
$(SRCDIR)/sounds/0.wav \
643644
$(SRCDIR)/sounds/1.wav \
644645
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -634,10 +634,11 @@
634 $(SRCDIR)/hbmenu.js \
635 $(SRCDIR)/href.js \
636 $(SRCDIR)/login.js \
637 $(SRCDIR)/markdown.md \
638 $(SRCDIR)/menu.js \
 
639 $(SRCDIR)/scroll.js \
640 $(SRCDIR)/skin.js \
641 $(SRCDIR)/sorttable.js \
642 $(SRCDIR)/sounds/0.wav \
643 $(SRCDIR)/sounds/1.wav \
644
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -634,10 +634,11 @@
634 $(SRCDIR)/hbmenu.js \
635 $(SRCDIR)/href.js \
636 $(SRCDIR)/login.js \
637 $(SRCDIR)/markdown.md \
638 $(SRCDIR)/menu.js \
639 $(SRCDIR)/merge.tcl \
640 $(SRCDIR)/scroll.js \
641 $(SRCDIR)/skin.js \
642 $(SRCDIR)/sorttable.js \
643 $(SRCDIR)/sounds/0.wav \
644 $(SRCDIR)/sounds/1.wav \
645
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -592,10 +592,11 @@
592592
"$(SRCDIR)\hbmenu.js" \
593593
"$(SRCDIR)\href.js" \
594594
"$(SRCDIR)\login.js" \
595595
"$(SRCDIR)\markdown.md" \
596596
"$(SRCDIR)\menu.js" \
597
+ "$(SRCDIR)\merge.tcl" \
597598
"$(SRCDIR)\scroll.js" \
598599
"$(SRCDIR)\skin.js" \
599600
"$(SRCDIR)\sorttable.js" \
600601
"$(SRCDIR)\sounds\0.wav" \
601602
"$(SRCDIR)\sounds\1.wav" \
@@ -1222,10 +1223,11 @@
12221223
echo "$(SRCDIR)\hbmenu.js" >> $@
12231224
echo "$(SRCDIR)\href.js" >> $@
12241225
echo "$(SRCDIR)\login.js" >> $@
12251226
echo "$(SRCDIR)\markdown.md" >> $@
12261227
echo "$(SRCDIR)\menu.js" >> $@
1228
+ echo "$(SRCDIR)\merge.tcl" >> $@
12271229
echo "$(SRCDIR)\scroll.js" >> $@
12281230
echo "$(SRCDIR)\skin.js" >> $@
12291231
echo "$(SRCDIR)\sorttable.js" >> $@
12301232
echo "$(SRCDIR)\sounds/0.wav" >> $@
12311233
echo "$(SRCDIR)\sounds/1.wav" >> $@
12321234
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -592,10 +592,11 @@
592 "$(SRCDIR)\hbmenu.js" \
593 "$(SRCDIR)\href.js" \
594 "$(SRCDIR)\login.js" \
595 "$(SRCDIR)\markdown.md" \
596 "$(SRCDIR)\menu.js" \
 
597 "$(SRCDIR)\scroll.js" \
598 "$(SRCDIR)\skin.js" \
599 "$(SRCDIR)\sorttable.js" \
600 "$(SRCDIR)\sounds\0.wav" \
601 "$(SRCDIR)\sounds\1.wav" \
@@ -1222,10 +1223,11 @@
1222 echo "$(SRCDIR)\hbmenu.js" >> $@
1223 echo "$(SRCDIR)\href.js" >> $@
1224 echo "$(SRCDIR)\login.js" >> $@
1225 echo "$(SRCDIR)\markdown.md" >> $@
1226 echo "$(SRCDIR)\menu.js" >> $@
 
1227 echo "$(SRCDIR)\scroll.js" >> $@
1228 echo "$(SRCDIR)\skin.js" >> $@
1229 echo "$(SRCDIR)\sorttable.js" >> $@
1230 echo "$(SRCDIR)\sounds/0.wav" >> $@
1231 echo "$(SRCDIR)\sounds/1.wav" >> $@
1232
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -592,10 +592,11 @@
592 "$(SRCDIR)\hbmenu.js" \
593 "$(SRCDIR)\href.js" \
594 "$(SRCDIR)\login.js" \
595 "$(SRCDIR)\markdown.md" \
596 "$(SRCDIR)\menu.js" \
597 "$(SRCDIR)\merge.tcl" \
598 "$(SRCDIR)\scroll.js" \
599 "$(SRCDIR)\skin.js" \
600 "$(SRCDIR)\sorttable.js" \
601 "$(SRCDIR)\sounds\0.wav" \
602 "$(SRCDIR)\sounds\1.wav" \
@@ -1222,10 +1223,11 @@
1223 echo "$(SRCDIR)\hbmenu.js" >> $@
1224 echo "$(SRCDIR)\href.js" >> $@
1225 echo "$(SRCDIR)\login.js" >> $@
1226 echo "$(SRCDIR)\markdown.md" >> $@
1227 echo "$(SRCDIR)\menu.js" >> $@
1228 echo "$(SRCDIR)\merge.tcl" >> $@
1229 echo "$(SRCDIR)\scroll.js" >> $@
1230 echo "$(SRCDIR)\skin.js" >> $@
1231 echo "$(SRCDIR)\sorttable.js" >> $@
1232 echo "$(SRCDIR)\sounds/0.wav" >> $@
1233 echo "$(SRCDIR)\sounds/1.wav" >> $@
1234

Keyboard Shortcuts

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