Fossil SCM

New mechanism for doing 2-way diffs in merge-info that does not require the new "fdiff" command - though the fdiff command is retained for now as it might be useful separately. Still has issues with column names.

drh 2025-02-20 02:46 merge-info
Commit 3f3e3019567289cbbecea4d8b714d05ce32949cac0466fec01f55b94f733700b
3 files changed +1 -2 +6 +125 -121
+1 -2
--- src/diff.tcl
+++ src/diff.tcl
@@ -111,12 +111,11 @@
111111
set fromIndex [lsearch -glob $fossilcmd *-from]
112112
set toIndex [lsearch -glob $fossilcmd *-to]
113113
set branchIndex [lsearch -glob $fossilcmd *-branch]
114114
set checkinIndex [lsearch -glob $fossilcmd *-checkin]
115115
if {[lsearch -glob $fossilcmd *-label]>=0
116
- || [lindex $fossilcmd 2]=="xdiff"
117
- || [lindex $fossilcmd 2]=="fdiff"
116
+ || [lsearch [lindex $fossilcmd 2] {xdiff fdiff merge-info}]>=0
118117
} {
119118
set fA {}
120119
set fB {}
121120
} else {
122121
if {[string match *?--external-baseline* $fossilcmd]} {
123122
--- src/diff.tcl
+++ src/diff.tcl
@@ -111,12 +111,11 @@
111 set fromIndex [lsearch -glob $fossilcmd *-from]
112 set toIndex [lsearch -glob $fossilcmd *-to]
113 set branchIndex [lsearch -glob $fossilcmd *-branch]
114 set checkinIndex [lsearch -glob $fossilcmd *-checkin]
115 if {[lsearch -glob $fossilcmd *-label]>=0
116 || [lindex $fossilcmd 2]=="xdiff"
117 || [lindex $fossilcmd 2]=="fdiff"
118 } {
119 set fA {}
120 set fB {}
121 } else {
122 if {[string match *?--external-baseline* $fossilcmd]} {
123
--- src/diff.tcl
+++ src/diff.tcl
@@ -111,12 +111,11 @@
111 set fromIndex [lsearch -glob $fossilcmd *-from]
112 set toIndex [lsearch -glob $fossilcmd *-to]
113 set branchIndex [lsearch -glob $fossilcmd *-branch]
114 set checkinIndex [lsearch -glob $fossilcmd *-checkin]
115 if {[lsearch -glob $fossilcmd *-label]>=0
116 || [lsearch [lindex $fossilcmd 2] {xdiff fdiff merge-info}]>=0
 
117 } {
118 set fA {}
119 set fB {}
120 } else {
121 if {[string match *?--external-baseline* $fossilcmd]} {
122
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -1190,10 +1190,16 @@
11901190
const char *zTempFile = 0;
11911191
char *zCmd;
11921192
const char *zTclsh;
11931193
int bDarkMode = find_option("dark",0,0)!=0;
11941194
blob_zero(&script);
1195
+ /* Caution: When this routine is called from the merge-info command,
1196
+ ** the --tcl argument requires an argument. But merge-info does not
1197
+ ** use -i, so we can take -i as that argument. This routine needs to
1198
+ ** always have -i after --tcl.
1199
+ ** CAUTION!
1200
+ ** vvvvvvv */
11951201
blob_appendf(&script, "set fossilcmd {| \"%/\" %s -tcl -i -v",
11961202
g.nameOfExe, zSubCmd);
11971203
find_option("tcl",0,0);
11981204
find_option("html",0,0);
11991205
find_option("side-by-side","y",0);
12001206
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -1190,10 +1190,16 @@
1190 const char *zTempFile = 0;
1191 char *zCmd;
1192 const char *zTclsh;
1193 int bDarkMode = find_option("dark",0,0)!=0;
1194 blob_zero(&script);
 
 
 
 
 
 
1195 blob_appendf(&script, "set fossilcmd {| \"%/\" %s -tcl -i -v",
1196 g.nameOfExe, zSubCmd);
1197 find_option("tcl",0,0);
1198 find_option("html",0,0);
1199 find_option("side-by-side","y",0);
1200
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -1190,10 +1190,16 @@
1190 const char *zTempFile = 0;
1191 char *zCmd;
1192 const char *zTclsh;
1193 int bDarkMode = find_option("dark",0,0)!=0;
1194 blob_zero(&script);
1195 /* Caution: When this routine is called from the merge-info command,
1196 ** the --tcl argument requires an argument. But merge-info does not
1197 ** use -i, so we can take -i as that argument. This routine needs to
1198 ** always have -i after --tcl.
1199 ** CAUTION!
1200 ** vvvvvvv */
1201 blob_appendf(&script, "set fossilcmd {| \"%/\" %s -tcl -i -v",
1202 g.nameOfExe, zSubCmd);
1203 find_option("tcl",0,0);
1204 find_option("html",0,0);
1205 find_option("side-by-side","y",0);
1206
+125 -121
--- src/merge.c
+++ src/merge.c
@@ -137,12 +137,19 @@
137137
** command associated with file "zFName". zFName must be the filename
138138
** relative to the root of the check-in - in other words a "tree name".
139139
**
140140
** When this routine is called, we know that the mergestat table
141141
** exists, but we do not know if zFName is mentioned in that table.
142
+**
143
+** The diffMode variable has these values:
144
+**
145
+** 0 Standard 3-way diff
146
+** 12 2-way diff between baseline and local
147
+** 13 2-way diff between baseline and merge-in
148
+** 23 2-way diff between local and merge-in
142149
*/
143
-static void merge_info_tcl(const char *zFName, int nContext){
150
+static void merge_info_tcl(const char *zFName, int nContext, int diffMode){
144151
const char *zTreename;/* Name of the file in the tree */
145152
Stmt q; /* To query the MERGESTAT table */
146153
MergeBuilder mb; /* The merge builder object */
147154
Blob pivot,v1,v2,out; /* Blobs for holding content */
148155
const char *zFN; /* A filename */
@@ -163,134 +170,124 @@
163170
return;
164171
}
165172
mergebuilder_init_tcl(&mb);
166173
mb.nContext = nContext;
167174
168
- /* Set up the pivot or baseline */
169
- zFN = db_column_text(&q, 0);
170
- if( zFN==0 ){
171
- /* No pivot because the file was added */
172
- mb.zPivot = "(no baseline)";
173
- blob_zero(&pivot);
174
- }else{
175
- mb.zPivot = mprintf("%s (baseline)", file_tail(zFN));
176
- rid = db_column_int(&q, 1);
177
- content_get(rid, &pivot);
178
- }
179
- mb.pPivot = &pivot;
180
-
181
- /* Set up the merge-in as V2 */
182
- zFN = db_column_text(&q, 5);
183
- if( zFN==0 ){
184
- /* File deleted in the merged-in branch */
185
- mb.zV2 = "(deleted file)";
186
- blob_zero(&v2);
187
- }else{
188
- mb.zV2 = mprintf("%s (merge-in)", file_tail(zFN));
189
- rid = db_column_int(&q, 6);
190
- content_get(rid, &v2);
191
- }
192
- mb.pV2 = &v2;
193
-
194
- /* Set up the local content as V1 */
195
- zFN = db_column_text(&q, 2);
196
- if( zFN==0 ){
197
- /* File added by merge */
198
- mb.zV1 = "(no original)";
199
- blob_zero(&v1);
200
- }else{
201
- mb.zV1 = mprintf("%s (local)", file_tail(zFN));
202
- rid = db_column_int(&q, 3);
203
- sz = db_column_int(&q, 4);
204
- if( rid==0 && sz>0 ){
205
- /* The origin file had been edited so we'll have to pull its
206
- ** original content out of the undo buffer */
207
- Stmt q2;
208
- db_prepare(&q2,
209
- "SELECT content FROM undo"
210
- " WHERE pathname=%Q AND octet_length(content)=%d",
211
- zFN, sz
212
- );
213
- blob_zero(&v1);
214
- if( db_step(&q2)==SQLITE_ROW ){
215
- db_column_blob(&q2, 0, &v1);
216
- }else{
217
- mb.zV1 = "(local content missing)";
218
- }
219
- db_finalize(&q2);
220
- }else{
221
- /* The origin file was unchanged when the merge first occurred */
222
- content_get(rid, &v1);
223
- }
224
- }
225
- mb.pV1 = &v1;
226
-
227
- /* Set up the output */
228
- zFN = db_column_text(&q, 7);
229
- if( zFN==0 ){
230
- mb.zOut = "(Merge Result)";
231
- }else{
232
- mb.zOut = mprintf("%s (after merge)", file_tail(zFN));
233
- }
234
- blob_zero(&out);
235
- mb.pOut = &out;
236
-
237
- merge_three_blobs(&mb);
238
- blob_write_to_file(&out, "-");
239
-
175
+ blob_zero(&pivot);
176
+ if( diffMode!=23 ){
177
+ /* Set up the pivot or baseline */
178
+ zFN = db_column_text(&q, 0);
179
+ if( zFN==0 ){
180
+ /* No pivot because the file was added */
181
+ mb.zPivot = "(no baseline)";
182
+ }else{
183
+ mb.zPivot = mprintf("%s (baseline)", file_tail(zFN));
184
+ rid = db_column_int(&q, 1);
185
+ content_get(rid, &pivot);
186
+ }
187
+ mb.pPivot = &pivot;
188
+ }
189
+
190
+ blob_zero(&v2);
191
+ if( diffMode!=12 ){
192
+ /* Set up the merge-in as V2 */
193
+ zFN = db_column_text(&q, 5);
194
+ if( zFN==0 ){
195
+ /* File deleted in the merged-in branch */
196
+ mb.zV2 = "(deleted file)";
197
+ }else{
198
+ mb.zV2 = mprintf("%s (merge-in)", file_tail(zFN));
199
+ rid = db_column_int(&q, 6);
200
+ content_get(rid, &v2);
201
+ }
202
+ mb.pV2 = &v2;
203
+ }
204
+
205
+ blob_zero(&v1);
206
+ if( diffMode!=13 ){
207
+ /* Set up the local content as V1 */
208
+ zFN = db_column_text(&q, 2);
209
+ if( zFN==0 ){
210
+ /* File added by merge */
211
+ mb.zV1 = "(no original)";
212
+ }else{
213
+ mb.zV1 = mprintf("%s (local)", file_tail(zFN));
214
+ rid = db_column_int(&q, 3);
215
+ sz = db_column_int(&q, 4);
216
+ if( rid==0 && sz>0 ){
217
+ /* The origin file had been edited so we'll have to pull its
218
+ ** original content out of the undo buffer */
219
+ Stmt q2;
220
+ db_prepare(&q2,
221
+ "SELECT content FROM undo"
222
+ " WHERE pathname=%Q AND octet_length(content)=%d",
223
+ zFN, sz
224
+ );
225
+ blob_zero(&v1);
226
+ if( db_step(&q2)==SQLITE_ROW ){
227
+ db_column_blob(&q2, 0, &v1);
228
+ }else{
229
+ mb.zV1 = "(local content missing)";
230
+ }
231
+ db_finalize(&q2);
232
+ }else{
233
+ /* The origin file was unchanged when the merge first occurred */
234
+ content_get(rid, &v1);
235
+ }
236
+ }
237
+ mb.pV1 = &v1;
238
+ }
239
+
240
+ blob_zero(&out);
241
+ if( diffMode==0 ){
242
+ /* Set up the output and do a 3-way diff */
243
+ zFN = db_column_text(&q, 7);
244
+ if( zFN==0 ){
245
+ mb.zOut = "(Merge Result)";
246
+ }else{
247
+ mb.zOut = mprintf("%s (after merge)", file_tail(zFN));
248
+ }
249
+ mb.pOut = &out;
250
+ merge_three_blobs(&mb);
251
+ }else{
252
+ /* Set up to do a two-way diff */
253
+ Blob *pLeft, *pRight;
254
+ const char *zTagLeft, *zTagRight;
255
+ DiffConfig cfg;
256
+ memset(&cfg, 0, sizeof(cfg));
257
+ cfg.diffFlags = DIFF_TCL;
258
+ cfg.nContext = mb.nContext;
259
+ if( diffMode==12 || diffMode==13 ){
260
+ pLeft = &pivot;
261
+ zTagLeft = "baselines";
262
+ }else{
263
+ pLeft = &v1;
264
+ zTagLeft = "local";
265
+ }
266
+ if( diffMode==12 ){
267
+ pRight = &v1;
268
+ zTagRight = "local";
269
+ }else{
270
+ pRight = &v2;
271
+ zTagRight = "merge-in";
272
+ }
273
+ cfg.azLabel[0] = mprintf("%s (%s)", zFName, zTagLeft);
274
+ cfg.azLabel[1] = mprintf("%s (%s)", zFName, zTagRight);
275
+ diff_print_filenames("", "", &cfg, &out);
276
+ text_diff(pLeft, pRight, &out, &cfg);
277
+ fossil_free((char*)cfg.azLabel[0]);
278
+ fossil_free((char*)cfg.azLabel[1]);
279
+ }
280
+
281
+ blob_write_to_file(&out, "-");
240282
mb.xDestroy(&mb);
241283
blob_reset(&pivot);
242284
blob_reset(&v1);
243285
blob_reset(&v2);
244286
blob_reset(&out);
245287
db_finalize(&q);
246288
}
247
-
248
-/*
249
-** Respond to one of the options --diff12, --diff13, or --diff23.
250
-**
251
-** The diffMode is one of 12, 13, or 23 according to which option provoked
252
-** this routine. zFile is the name of the file on which to run the
253
-** two-way diff.
254
-**
255
-** This routine constructs a sub-command that runs "fossil diff" to show
256
-** the appropriate two-way diff.
257
-*/
258
-static void merge_two_way_file_diff(
259
- int diffMode,
260
- const char *zDiff2,
261
- int nContext,
262
- int bDark
263
-){
264
- int ridLeft; /* RID for the left file */
265
- int ridRight; /* RID for the right file */
266
- char *zLeft;
267
- char *zRight;
268
- char *zCmd;
269
-
270
- ridLeft = db_int(0,
271
- "SELECT iif(%d,ridp,ridv) FROM mergestat"
272
- " WHERE coalesce(fnr,fn)=%Q",
273
- diffMode<20, zDiff2
274
- );
275
- ridRight = db_int(0,
276
- "SELECT iif(%d,ridv,ridm) FROM mergestat"
277
- " WHERE coalesce(fnr,fn)=%Q",
278
- (diffMode%10)==2, zDiff2
279
- );
280
- zLeft = mprintf("%s (%s)", zDiff2, diffMode<20 ? "baseline" : "local");
281
- zRight = mprintf("%s (%s)", zDiff2,
282
- (diffMode%10)==2 ? "local" : "merge-in");
283
- zCmd = mprintf(
284
- "%!$ fdiff --tk --label %!$ --label %!$ -c %d%s rid:%d rid:%d &",
285
- g.nameOfExe, zLeft, zRight, nContext,
286
- bDark ? " -dark" : "",
287
- ridLeft, ridRight);
288
- fossil_system(zCmd);
289
- return;
290
-}
291
-
292289
293290
/*
294291
** COMMAND: merge-info
295292
**
296293
** Usage: %fossil merge-info [OPTIONS]
@@ -334,12 +331,12 @@
334331
int cnt = 0;
335332
const char *zDiff2 = 0;
336333
int diffMode = 0;
337334
338335
db_must_be_within_tree();
339
- zTcl = find_option("tcl", 0, 1);
340336
bTk = find_option("tk", 0, 0)!=0;
337
+ zTcl = find_option("tcl", 0, 1);
341338
zCnt = find_option("context", "c", 1);
342339
bDark = find_option("dark", 0, 0)!=0;
343340
bAll = find_option("all", "a", 0)!=0;
344341
if( (zDiff2 = find_option("diff12", 0, 1))!=0 ){
345342
diffMode = 12;
@@ -348,11 +345,13 @@
348345
diffMode = 13;
349346
}else
350347
if( (zDiff2 = find_option("diff23", 0, 1))!=0 ){
351348
diffMode = 23;
352349
}
350
+
353351
if( bTk==0 ){
352
+ find_option("v",0,0);
354353
verify_all_options();
355354
if( g.argc>2 ){
356355
usage("[OPTIONS]");
357356
}
358357
}
@@ -373,15 +372,20 @@
373372
if( bTk ){
374373
merge_info_tk(bDark, bAll, nContext);
375374
return;
376375
}
377376
if( zTcl ){
378
- merge_info_tcl(zTcl, nContext);
377
+ if( diffMode ) zTcl = zDiff2;
378
+ merge_info_tcl(zTcl, nContext, diffMode);
379379
return;
380380
}
381381
if( diffMode ){
382
- merge_two_way_file_diff(diffMode, zDiff2, nContext, bDark);
382
+ char *zCmd;
383
+ zCmd = mprintf("merge-info --diff%d %!$ -c %d%s",
384
+ diffMode, zDiff2, nContext, bDark ? " --dark" : "");
385
+ diff_tk(zCmd, g.argc);
386
+ fossil_free(zCmd);
383387
return;
384388
}
385389
if( bAll ){
386390
zWhere = "";
387391
}else{
388392
--- src/merge.c
+++ src/merge.c
@@ -137,12 +137,19 @@
137 ** command associated with file "zFName". zFName must be the filename
138 ** relative to the root of the check-in - in other words a "tree name".
139 **
140 ** When this routine is called, we know that the mergestat table
141 ** exists, but we do not know if zFName is mentioned in that table.
 
 
 
 
 
 
 
142 */
143 static void merge_info_tcl(const char *zFName, int nContext){
144 const char *zTreename;/* Name of the file in the tree */
145 Stmt q; /* To query the MERGESTAT table */
146 MergeBuilder mb; /* The merge builder object */
147 Blob pivot,v1,v2,out; /* Blobs for holding content */
148 const char *zFN; /* A filename */
@@ -163,134 +170,124 @@
163 return;
164 }
165 mergebuilder_init_tcl(&mb);
166 mb.nContext = nContext;
167
168 /* Set up the pivot or baseline */
169 zFN = db_column_text(&q, 0);
170 if( zFN==0 ){
171 /* No pivot because the file was added */
172 mb.zPivot = "(no baseline)";
173 blob_zero(&pivot);
174 }else{
175 mb.zPivot = mprintf("%s (baseline)", file_tail(zFN));
176 rid = db_column_int(&q, 1);
177 content_get(rid, &pivot);
178 }
179 mb.pPivot = &pivot;
180
181 /* Set up the merge-in as V2 */
182 zFN = db_column_text(&q, 5);
183 if( zFN==0 ){
184 /* File deleted in the merged-in branch */
185 mb.zV2 = "(deleted file)";
186 blob_zero(&v2);
187 }else{
188 mb.zV2 = mprintf("%s (merge-in)", file_tail(zFN));
189 rid = db_column_int(&q, 6);
190 content_get(rid, &v2);
191 }
192 mb.pV2 = &v2;
193
194 /* Set up the local content as V1 */
195 zFN = db_column_text(&q, 2);
196 if( zFN==0 ){
197 /* File added by merge */
198 mb.zV1 = "(no original)";
199 blob_zero(&v1);
200 }else{
201 mb.zV1 = mprintf("%s (local)", file_tail(zFN));
202 rid = db_column_int(&q, 3);
203 sz = db_column_int(&q, 4);
204 if( rid==0 && sz>0 ){
205 /* The origin file had been edited so we'll have to pull its
206 ** original content out of the undo buffer */
207 Stmt q2;
208 db_prepare(&q2,
209 "SELECT content FROM undo"
210 " WHERE pathname=%Q AND octet_length(content)=%d",
211 zFN, sz
212 );
213 blob_zero(&v1);
214 if( db_step(&q2)==SQLITE_ROW ){
215 db_column_blob(&q2, 0, &v1);
216 }else{
217 mb.zV1 = "(local content missing)";
218 }
219 db_finalize(&q2);
220 }else{
221 /* The origin file was unchanged when the merge first occurred */
222 content_get(rid, &v1);
223 }
224 }
225 mb.pV1 = &v1;
226
227 /* Set up the output */
228 zFN = db_column_text(&q, 7);
229 if( zFN==0 ){
230 mb.zOut = "(Merge Result)";
231 }else{
232 mb.zOut = mprintf("%s (after merge)", file_tail(zFN));
233 }
234 blob_zero(&out);
235 mb.pOut = &out;
236
237 merge_three_blobs(&mb);
238 blob_write_to_file(&out, "-");
239
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
240 mb.xDestroy(&mb);
241 blob_reset(&pivot);
242 blob_reset(&v1);
243 blob_reset(&v2);
244 blob_reset(&out);
245 db_finalize(&q);
246 }
247
248 /*
249 ** Respond to one of the options --diff12, --diff13, or --diff23.
250 **
251 ** The diffMode is one of 12, 13, or 23 according to which option provoked
252 ** this routine. zFile is the name of the file on which to run the
253 ** two-way diff.
254 **
255 ** This routine constructs a sub-command that runs "fossil diff" to show
256 ** the appropriate two-way diff.
257 */
258 static void merge_two_way_file_diff(
259 int diffMode,
260 const char *zDiff2,
261 int nContext,
262 int bDark
263 ){
264 int ridLeft; /* RID for the left file */
265 int ridRight; /* RID for the right file */
266 char *zLeft;
267 char *zRight;
268 char *zCmd;
269
270 ridLeft = db_int(0,
271 "SELECT iif(%d,ridp,ridv) FROM mergestat"
272 " WHERE coalesce(fnr,fn)=%Q",
273 diffMode<20, zDiff2
274 );
275 ridRight = db_int(0,
276 "SELECT iif(%d,ridv,ridm) FROM mergestat"
277 " WHERE coalesce(fnr,fn)=%Q",
278 (diffMode%10)==2, zDiff2
279 );
280 zLeft = mprintf("%s (%s)", zDiff2, diffMode<20 ? "baseline" : "local");
281 zRight = mprintf("%s (%s)", zDiff2,
282 (diffMode%10)==2 ? "local" : "merge-in");
283 zCmd = mprintf(
284 "%!$ fdiff --tk --label %!$ --label %!$ -c %d%s rid:%d rid:%d &",
285 g.nameOfExe, zLeft, zRight, nContext,
286 bDark ? " -dark" : "",
287 ridLeft, ridRight);
288 fossil_system(zCmd);
289 return;
290 }
291
292
293 /*
294 ** COMMAND: merge-info
295 **
296 ** Usage: %fossil merge-info [OPTIONS]
@@ -334,12 +331,12 @@
334 int cnt = 0;
335 const char *zDiff2 = 0;
336 int diffMode = 0;
337
338 db_must_be_within_tree();
339 zTcl = find_option("tcl", 0, 1);
340 bTk = find_option("tk", 0, 0)!=0;
 
341 zCnt = find_option("context", "c", 1);
342 bDark = find_option("dark", 0, 0)!=0;
343 bAll = find_option("all", "a", 0)!=0;
344 if( (zDiff2 = find_option("diff12", 0, 1))!=0 ){
345 diffMode = 12;
@@ -348,11 +345,13 @@
348 diffMode = 13;
349 }else
350 if( (zDiff2 = find_option("diff23", 0, 1))!=0 ){
351 diffMode = 23;
352 }
 
353 if( bTk==0 ){
 
354 verify_all_options();
355 if( g.argc>2 ){
356 usage("[OPTIONS]");
357 }
358 }
@@ -373,15 +372,20 @@
373 if( bTk ){
374 merge_info_tk(bDark, bAll, nContext);
375 return;
376 }
377 if( zTcl ){
378 merge_info_tcl(zTcl, nContext);
 
379 return;
380 }
381 if( diffMode ){
382 merge_two_way_file_diff(diffMode, zDiff2, nContext, bDark);
 
 
 
 
383 return;
384 }
385 if( bAll ){
386 zWhere = "";
387 }else{
388
--- src/merge.c
+++ src/merge.c
@@ -137,12 +137,19 @@
137 ** command associated with file "zFName". zFName must be the filename
138 ** relative to the root of the check-in - in other words a "tree name".
139 **
140 ** When this routine is called, we know that the mergestat table
141 ** exists, but we do not know if zFName is mentioned in that table.
142 **
143 ** The diffMode variable has these values:
144 **
145 ** 0 Standard 3-way diff
146 ** 12 2-way diff between baseline and local
147 ** 13 2-way diff between baseline and merge-in
148 ** 23 2-way diff between local and merge-in
149 */
150 static void merge_info_tcl(const char *zFName, int nContext, int diffMode){
151 const char *zTreename;/* Name of the file in the tree */
152 Stmt q; /* To query the MERGESTAT table */
153 MergeBuilder mb; /* The merge builder object */
154 Blob pivot,v1,v2,out; /* Blobs for holding content */
155 const char *zFN; /* A filename */
@@ -163,134 +170,124 @@
170 return;
171 }
172 mergebuilder_init_tcl(&mb);
173 mb.nContext = nContext;
174
175 blob_zero(&pivot);
176 if( diffMode!=23 ){
177 /* Set up the pivot or baseline */
178 zFN = db_column_text(&q, 0);
179 if( zFN==0 ){
180 /* No pivot because the file was added */
181 mb.zPivot = "(no baseline)";
182 }else{
183 mb.zPivot = mprintf("%s (baseline)", file_tail(zFN));
184 rid = db_column_int(&q, 1);
185 content_get(rid, &pivot);
186 }
187 mb.pPivot = &pivot;
188 }
189
190 blob_zero(&v2);
191 if( diffMode!=12 ){
192 /* Set up the merge-in as V2 */
193 zFN = db_column_text(&q, 5);
194 if( zFN==0 ){
195 /* File deleted in the merged-in branch */
196 mb.zV2 = "(deleted file)";
197 }else{
198 mb.zV2 = mprintf("%s (merge-in)", file_tail(zFN));
199 rid = db_column_int(&q, 6);
200 content_get(rid, &v2);
201 }
202 mb.pV2 = &v2;
203 }
204
205 blob_zero(&v1);
206 if( diffMode!=13 ){
207 /* Set up the local content as V1 */
208 zFN = db_column_text(&q, 2);
209 if( zFN==0 ){
210 /* File added by merge */
211 mb.zV1 = "(no original)";
212 }else{
213 mb.zV1 = mprintf("%s (local)", file_tail(zFN));
214 rid = db_column_int(&q, 3);
215 sz = db_column_int(&q, 4);
216 if( rid==0 && sz>0 ){
217 /* The origin file had been edited so we'll have to pull its
218 ** original content out of the undo buffer */
219 Stmt q2;
220 db_prepare(&q2,
221 "SELECT content FROM undo"
222 " WHERE pathname=%Q AND octet_length(content)=%d",
223 zFN, sz
224 );
225 blob_zero(&v1);
226 if( db_step(&q2)==SQLITE_ROW ){
227 db_column_blob(&q2, 0, &v1);
228 }else{
229 mb.zV1 = "(local content missing)";
230 }
231 db_finalize(&q2);
232 }else{
233 /* The origin file was unchanged when the merge first occurred */
234 content_get(rid, &v1);
235 }
236 }
237 mb.pV1 = &v1;
238 }
239
240 blob_zero(&out);
241 if( diffMode==0 ){
242 /* Set up the output and do a 3-way diff */
243 zFN = db_column_text(&q, 7);
244 if( zFN==0 ){
245 mb.zOut = "(Merge Result)";
246 }else{
247 mb.zOut = mprintf("%s (after merge)", file_tail(zFN));
248 }
249 mb.pOut = &out;
250 merge_three_blobs(&mb);
251 }else{
252 /* Set up to do a two-way diff */
253 Blob *pLeft, *pRight;
254 const char *zTagLeft, *zTagRight;
255 DiffConfig cfg;
256 memset(&cfg, 0, sizeof(cfg));
257 cfg.diffFlags = DIFF_TCL;
258 cfg.nContext = mb.nContext;
259 if( diffMode==12 || diffMode==13 ){
260 pLeft = &pivot;
261 zTagLeft = "baselines";
262 }else{
263 pLeft = &v1;
264 zTagLeft = "local";
265 }
266 if( diffMode==12 ){
267 pRight = &v1;
268 zTagRight = "local";
269 }else{
270 pRight = &v2;
271 zTagRight = "merge-in";
272 }
273 cfg.azLabel[0] = mprintf("%s (%s)", zFName, zTagLeft);
274 cfg.azLabel[1] = mprintf("%s (%s)", zFName, zTagRight);
275 diff_print_filenames("", "", &cfg, &out);
276 text_diff(pLeft, pRight, &out, &cfg);
277 fossil_free((char*)cfg.azLabel[0]);
278 fossil_free((char*)cfg.azLabel[1]);
279 }
280
281 blob_write_to_file(&out, "-");
282 mb.xDestroy(&mb);
283 blob_reset(&pivot);
284 blob_reset(&v1);
285 blob_reset(&v2);
286 blob_reset(&out);
287 db_finalize(&q);
288 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
289
290 /*
291 ** COMMAND: merge-info
292 **
293 ** Usage: %fossil merge-info [OPTIONS]
@@ -334,12 +331,12 @@
331 int cnt = 0;
332 const char *zDiff2 = 0;
333 int diffMode = 0;
334
335 db_must_be_within_tree();
 
336 bTk = find_option("tk", 0, 0)!=0;
337 zTcl = find_option("tcl", 0, 1);
338 zCnt = find_option("context", "c", 1);
339 bDark = find_option("dark", 0, 0)!=0;
340 bAll = find_option("all", "a", 0)!=0;
341 if( (zDiff2 = find_option("diff12", 0, 1))!=0 ){
342 diffMode = 12;
@@ -348,11 +345,13 @@
345 diffMode = 13;
346 }else
347 if( (zDiff2 = find_option("diff23", 0, 1))!=0 ){
348 diffMode = 23;
349 }
350
351 if( bTk==0 ){
352 find_option("v",0,0);
353 verify_all_options();
354 if( g.argc>2 ){
355 usage("[OPTIONS]");
356 }
357 }
@@ -373,15 +372,20 @@
372 if( bTk ){
373 merge_info_tk(bDark, bAll, nContext);
374 return;
375 }
376 if( zTcl ){
377 if( diffMode ) zTcl = zDiff2;
378 merge_info_tcl(zTcl, nContext, diffMode);
379 return;
380 }
381 if( diffMode ){
382 char *zCmd;
383 zCmd = mprintf("merge-info --diff%d %!$ -c %d%s",
384 diffMode, zDiff2, nContext, bDark ? " --dark" : "");
385 diff_tk(zCmd, g.argc);
386 fossil_free(zCmd);
387 return;
388 }
389 if( bAll ){
390 zWhere = "";
391 }else{
392

Keyboard Shortcuts

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