Fossil SCM

By default, the merge-info command only shows "interesting" change - actual merges, errors, and conflicts. Use the --all option to see everything.

drh 2024-12-04 13:38 merge-enhancements
Commit b764f2d007a380d3347b4419a9231fb2d6a1832ac7526f8ad70714e633359a16
2 files changed +56 -23 +7 -4
+56 -23
--- src/merge.c
+++ src/merge.c
@@ -24,11 +24,11 @@
2424
2525
2626
/*
2727
** Bring up a Tcl/Tk GUI to show details of the most recent merge.
2828
*/
29
-static void merge_info_tk(int bDark, int nContext){
29
+static void merge_info_tk(int bDark, int bAll, int nContext){
3030
int i;
3131
Blob script;
3232
const char *zTempFile = 0;
3333
char *zCmd;
3434
const char *zTclsh;
@@ -48,36 +48,45 @@
4848
blob_appendf(&script, "set filelist [list");
4949
if( g.argc==2 ){
5050
/* No files named on the command-line. Use every file mentioned
5151
** in the MERGESTAT table to generate the file list. */
5252
Stmt q;
53
+ int cnt;
5354
db_prepare(&q,
54
- "SELECT coalesce(fnr,fn) FROM mergestat ORDER BY 1"
55
+ "SELECT coalesce(fnr,fn), op FROM mergestat %s ORDER BY 1",
56
+ bAll ? "" : "WHERE op IN ('MERGE','CONFLICT')" /*safe-for-%s*/
5557
);
5658
while( db_step(&q)==SQLITE_ROW ){
57
- blob_append_char(&script, ' ');
59
+ blob_appendf(&script," %s ", db_column_text(&q,1));
5860
blob_append_tcl_literal(&script, db_column_text(&q,0),
5961
db_column_bytes(&q,0));
62
+ cnt++;
63
+ }
64
+ db_finalize(&q);
65
+ if( cnt==0 ){
66
+ fossil_print(
67
+ "No interesting changes in this merge. Use --all to see everything\n"
68
+ );
69
+ return;
6070
}
6171
}else{
6272
/* Use only files named on the command-line in the file list.
6373
** But verify each file named is actually found in the MERGESTAT
6474
** table first. */
6575
for(i=2; i<g.argc; i++){
6676
char *zFile; /* Input filename */
6777
char *zTreename; /* Name of the file in the tree */
6878
Blob fname; /* Filename relative to root */
79
+ char *zOp; /* Operation on this file */
6980
zFile = mprintf("%/", g.argv[i]);
7081
file_tree_name(zFile, &fname, 0, 1);
82
+ fossil_free(zFile);
7183
zTreename = blob_str(&fname);
72
- if( !db_exists("SELECT 1 FROM mergestat WHERE fn=%Q OR fnr=%Q",
73
- zTreename, zTreename) ){
74
- fossil_fatal("file \"%s\" is not part of the most recent merge",
75
- g.argv[i]);
76
- }
77
- blob_append_char(&script, ' ');
78
- fossil_free(zFile);
84
+ zOp = db_text(0, "SELECT op FROM mergestat WHERE fn=%Q or fnr=%Q",
85
+ zTreename, zTreename);
86
+ blob_appendf(&script, " %s ", zOp);
87
+ fossil_free(zOp);
7988
blob_append_tcl_literal(&script, zTreename, (int)strlen(zTreename));
8089
blob_reset(&fname);
8190
}
8291
}
8392
blob_appendf(&script, "]\n");
@@ -235,10 +244,12 @@
235244
** table. The plan moving forward is that it can generate data for
236245
** a Tk-based GUI to show the details of the merge. This command is
237246
** a work-in-progress.
238247
**
239248
** Options:
249
+** -a|--all Show all changes. Normally only merges, conflicts,
250
+** and errors are shown.
240251
** -c|--context N Show N lines of context around each change,
241252
** with negative N meaning show all content. Only
242253
** meaningful in combination with --tcl or --tk.
243254
** --dark Use dark mode for the Tcl/Tk-based GUI
244255
** --tcl FILE Generate (to stdout) a TCL list containing
@@ -251,19 +262,23 @@
251262
*/
252263
void merge_info_cmd(void){
253264
const char *zCnt;
254265
const char *zTcl;
255266
int bTk;
256
- int bDark = 0;
267
+ int bDark;
268
+ int bAll;
257269
int nContext;
258270
Stmt q;
271
+ const char *zWhere;
272
+ int cnt = 0;
259273
260274
db_must_be_within_tree();
261275
zTcl = find_option("tcl", 0, 1);
262276
bTk = find_option("tk", 0, 0)!=0;
263277
zCnt = find_option("context", "c", 1);
264
- bDark = find_option("dark", 0, 0)!=0;
278
+ bDark = find_option("dark", 0, 0)!=0;
279
+ bAll = find_option("all", "a", 0)!=0;
265280
if( bTk==0 ){
266281
verify_all_options();
267282
if( g.argc>2 ){
268283
usage("[OPTIONS]");
269284
}
@@ -281,33 +296,47 @@
281296
fossil_print("No merge data is available\n");
282297
}
283298
return;
284299
}
285300
if( bTk ){
286
- merge_info_tk(bDark, nContext);
301
+ merge_info_tk(bDark, bAll, nContext);
287302
return;
288303
}
289304
if( zTcl ){
290305
merge_info_tcl(zTcl, nContext);
291306
return;
292307
}
308
+ if( bAll ){
309
+ zWhere = "";
310
+ }else{
311
+ zWhere = "WHERE op IN ('MERGE','CONFLICT','ERROR')";
312
+ }
293313
db_prepare(&q,
294
- /* 0 1 2 3 4 */
295
- "SELECT op, fn, fnr, nc, msg FROM mergestat ORDER BY coalesce(fnr,fn)"
314
+ /* 0 1 2 */
315
+ "SELECT op, coalesce(fnr,fn), msg"
316
+ " FROM mergestat"
317
+ " %s"
318
+ " ORDER BY coalesce(fnr,fn)",
319
+ zWhere /*safe-for-%s*/
296320
);
297321
while( db_step(&q)==SQLITE_ROW ){
298322
const char *zOp = db_column_text(&q, 0);
299
- const char *zName = db_column_text(&q, 2);
300
- const char *zErr = db_column_text(&q, 4);
301
- if( zName==0 ) zName = db_column_text(&q, 1);
302
- if( zErr ){
303
- fossil_print("%-7s %s ** %s **\n", zOp, zName, zErr);
323
+ const char *zName = db_column_text(&q, 1);
324
+ const char *zErr = db_column_text(&q, 2);
325
+ if( zErr && fossil_strcmp(zOp,"CONFLICT")!=0 ){
326
+ fossil_print("%-9s %s (%s)\n", zOp, zName, zErr);
304327
}else{
305
- fossil_print("%-7s %s\n", zOp, zName);
328
+ fossil_print("%-9s %s\n", zOp, zName);
306329
}
330
+ cnt++;
307331
}
308332
db_finalize(&q);
333
+ if( !bAll && cnt==0 ){
334
+ fossil_print(
335
+ "No interesting change in this merge. Use --all to see everything.\n"
336
+ );
337
+ }
309338
}
310339
311340
/*
312341
** Erase all information about prior merges. Do this, for example, after
313342
** a commit.
@@ -1202,10 +1231,11 @@
12021231
int islinkv = db_column_int(&q, 7);
12031232
int islinkm = db_column_int(&q, 8);
12041233
int chnged = db_column_int(&q, 11);
12051234
int rc;
12061235
char *zFullPath;
1236
+ const char *zType = "MERGE";
12071237
Blob m, p, r;
12081238
/* Do a 3-way merge of idp->idm into idp->idv. The results go into idv. */
12091239
if( verboseFlag ){
12101240
fossil_print("MERGE %s (pivot=%d v1=%d v2=%d)\n",
12111241
zName, ridp, ridm, ridv);
@@ -1215,11 +1245,11 @@
12151245
if( islinkv || islinkm ){
12161246
fossil_print("***** Cannot merge symlink %s\n", zName);
12171247
nConflict++;
12181248
db_multi_exec(
12191249
"INSERT INTO mergestat(op,fnp,ridp,fn,ridv,fnm,ridm,fnr,nc,msg)"
1220
- "VALUES('MERGE',%Q,%d,%Q,%d,%Q,%d,%Q,1,'cannot merge symlink')",
1250
+ "VALUES('ERROR',%Q,%d,%Q,%d,%Q,%d,%Q,1,'cannot merge symlink')",
12211251
/* fnp */ db_column_text(&q, 9),
12221252
/* ridp */ ridp,
12231253
/* fn */ zName,
12241254
/* ridv */ ridv,
12251255
/* fnm */ db_column_text(&q, 10),
@@ -1254,21 +1284,24 @@
12541284
fossil_print("***** %d merge conflict%s in %s\n",
12551285
rc, rc>1 ? "s" : "", zName);
12561286
nConflict++;
12571287
nc = rc;
12581288
zErrMsg = "merge conflicts";
1289
+ zType = "CONFLICT";
12591290
}
12601291
}else{
12611292
fossil_print("***** Cannot merge binary file %s\n", zName);
12621293
nConflict++;
12631294
nc = 1;
12641295
zErrMsg = "cannot merge binary file";
1296
+ zType = "ERROR";
12651297
}
12661298
db_multi_exec(
12671299
"INSERT INTO mergestat(op,fnp,ridp,fn,ridv,sz,fnm,ridm,fnr,nc,msg)"
1268
- "VALUES('MERGE',%Q,%d,%Q,iif(%d,%d,NULL),iif(%d,%d,NULL),%Q,%d,"
1300
+ "VALUES(%Q,%Q,%d,%Q,iif(%d,%d,NULL),iif(%d,%d,NULL),%Q,%d,"
12691301
"%Q,%d,%Q)",
1302
+ /* op */ zType,
12701303
/* fnp */ db_column_text(&q, 9),
12711304
/* ridp */ ridp,
12721305
/* fn */ zName,
12731306
/* ridv */ chnged==0, ridv,
12741307
/* sz */ chnged!=0, sz,
12751308
--- src/merge.c
+++ src/merge.c
@@ -24,11 +24,11 @@
24
25
26 /*
27 ** Bring up a Tcl/Tk GUI to show details of the most recent merge.
28 */
29 static void merge_info_tk(int bDark, int nContext){
30 int i;
31 Blob script;
32 const char *zTempFile = 0;
33 char *zCmd;
34 const char *zTclsh;
@@ -48,36 +48,45 @@
48 blob_appendf(&script, "set filelist [list");
49 if( g.argc==2 ){
50 /* No files named on the command-line. Use every file mentioned
51 ** in the MERGESTAT table to generate the file list. */
52 Stmt q;
 
53 db_prepare(&q,
54 "SELECT coalesce(fnr,fn) FROM mergestat ORDER BY 1"
 
55 );
56 while( db_step(&q)==SQLITE_ROW ){
57 blob_append_char(&script, ' ');
58 blob_append_tcl_literal(&script, db_column_text(&q,0),
59 db_column_bytes(&q,0));
 
 
 
 
 
 
 
 
60 }
61 }else{
62 /* Use only files named on the command-line in the file list.
63 ** But verify each file named is actually found in the MERGESTAT
64 ** table first. */
65 for(i=2; i<g.argc; i++){
66 char *zFile; /* Input filename */
67 char *zTreename; /* Name of the file in the tree */
68 Blob fname; /* Filename relative to root */
 
69 zFile = mprintf("%/", g.argv[i]);
70 file_tree_name(zFile, &fname, 0, 1);
 
71 zTreename = blob_str(&fname);
72 if( !db_exists("SELECT 1 FROM mergestat WHERE fn=%Q OR fnr=%Q",
73 zTreename, zTreename) ){
74 fossil_fatal("file \"%s\" is not part of the most recent merge",
75 g.argv[i]);
76 }
77 blob_append_char(&script, ' ');
78 fossil_free(zFile);
79 blob_append_tcl_literal(&script, zTreename, (int)strlen(zTreename));
80 blob_reset(&fname);
81 }
82 }
83 blob_appendf(&script, "]\n");
@@ -235,10 +244,12 @@
235 ** table. The plan moving forward is that it can generate data for
236 ** a Tk-based GUI to show the details of the merge. This command is
237 ** a work-in-progress.
238 **
239 ** Options:
 
 
240 ** -c|--context N Show N lines of context around each change,
241 ** with negative N meaning show all content. Only
242 ** meaningful in combination with --tcl or --tk.
243 ** --dark Use dark mode for the Tcl/Tk-based GUI
244 ** --tcl FILE Generate (to stdout) a TCL list containing
@@ -251,19 +262,23 @@
251 */
252 void merge_info_cmd(void){
253 const char *zCnt;
254 const char *zTcl;
255 int bTk;
256 int bDark = 0;
 
257 int nContext;
258 Stmt q;
 
 
259
260 db_must_be_within_tree();
261 zTcl = find_option("tcl", 0, 1);
262 bTk = find_option("tk", 0, 0)!=0;
263 zCnt = find_option("context", "c", 1);
264 bDark = find_option("dark", 0, 0)!=0;
 
265 if( bTk==0 ){
266 verify_all_options();
267 if( g.argc>2 ){
268 usage("[OPTIONS]");
269 }
@@ -281,33 +296,47 @@
281 fossil_print("No merge data is available\n");
282 }
283 return;
284 }
285 if( bTk ){
286 merge_info_tk(bDark, nContext);
287 return;
288 }
289 if( zTcl ){
290 merge_info_tcl(zTcl, nContext);
291 return;
292 }
 
 
 
 
 
293 db_prepare(&q,
294 /* 0 1 2 3 4 */
295 "SELECT op, fn, fnr, nc, msg FROM mergestat ORDER BY coalesce(fnr,fn)"
 
 
 
 
296 );
297 while( db_step(&q)==SQLITE_ROW ){
298 const char *zOp = db_column_text(&q, 0);
299 const char *zName = db_column_text(&q, 2);
300 const char *zErr = db_column_text(&q, 4);
301 if( zName==0 ) zName = db_column_text(&q, 1);
302 if( zErr ){
303 fossil_print("%-7s %s ** %s **\n", zOp, zName, zErr);
304 }else{
305 fossil_print("%-7s %s\n", zOp, zName);
306 }
 
307 }
308 db_finalize(&q);
 
 
 
 
 
309 }
310
311 /*
312 ** Erase all information about prior merges. Do this, for example, after
313 ** a commit.
@@ -1202,10 +1231,11 @@
1202 int islinkv = db_column_int(&q, 7);
1203 int islinkm = db_column_int(&q, 8);
1204 int chnged = db_column_int(&q, 11);
1205 int rc;
1206 char *zFullPath;
 
1207 Blob m, p, r;
1208 /* Do a 3-way merge of idp->idm into idp->idv. The results go into idv. */
1209 if( verboseFlag ){
1210 fossil_print("MERGE %s (pivot=%d v1=%d v2=%d)\n",
1211 zName, ridp, ridm, ridv);
@@ -1215,11 +1245,11 @@
1215 if( islinkv || islinkm ){
1216 fossil_print("***** Cannot merge symlink %s\n", zName);
1217 nConflict++;
1218 db_multi_exec(
1219 "INSERT INTO mergestat(op,fnp,ridp,fn,ridv,fnm,ridm,fnr,nc,msg)"
1220 "VALUES('MERGE',%Q,%d,%Q,%d,%Q,%d,%Q,1,'cannot merge symlink')",
1221 /* fnp */ db_column_text(&q, 9),
1222 /* ridp */ ridp,
1223 /* fn */ zName,
1224 /* ridv */ ridv,
1225 /* fnm */ db_column_text(&q, 10),
@@ -1254,21 +1284,24 @@
1254 fossil_print("***** %d merge conflict%s in %s\n",
1255 rc, rc>1 ? "s" : "", zName);
1256 nConflict++;
1257 nc = rc;
1258 zErrMsg = "merge conflicts";
 
1259 }
1260 }else{
1261 fossil_print("***** Cannot merge binary file %s\n", zName);
1262 nConflict++;
1263 nc = 1;
1264 zErrMsg = "cannot merge binary file";
 
1265 }
1266 db_multi_exec(
1267 "INSERT INTO mergestat(op,fnp,ridp,fn,ridv,sz,fnm,ridm,fnr,nc,msg)"
1268 "VALUES('MERGE',%Q,%d,%Q,iif(%d,%d,NULL),iif(%d,%d,NULL),%Q,%d,"
1269 "%Q,%d,%Q)",
 
1270 /* fnp */ db_column_text(&q, 9),
1271 /* ridp */ ridp,
1272 /* fn */ zName,
1273 /* ridv */ chnged==0, ridv,
1274 /* sz */ chnged!=0, sz,
1275
--- src/merge.c
+++ src/merge.c
@@ -24,11 +24,11 @@
24
25
26 /*
27 ** Bring up a Tcl/Tk GUI to show details of the most recent merge.
28 */
29 static void merge_info_tk(int bDark, int bAll, int nContext){
30 int i;
31 Blob script;
32 const char *zTempFile = 0;
33 char *zCmd;
34 const char *zTclsh;
@@ -48,36 +48,45 @@
48 blob_appendf(&script, "set filelist [list");
49 if( g.argc==2 ){
50 /* No files named on the command-line. Use every file mentioned
51 ** in the MERGESTAT table to generate the file list. */
52 Stmt q;
53 int cnt;
54 db_prepare(&q,
55 "SELECT coalesce(fnr,fn), op FROM mergestat %s ORDER BY 1",
56 bAll ? "" : "WHERE op IN ('MERGE','CONFLICT')" /*safe-for-%s*/
57 );
58 while( db_step(&q)==SQLITE_ROW ){
59 blob_appendf(&script," %s ", db_column_text(&q,1));
60 blob_append_tcl_literal(&script, db_column_text(&q,0),
61 db_column_bytes(&q,0));
62 cnt++;
63 }
64 db_finalize(&q);
65 if( cnt==0 ){
66 fossil_print(
67 "No interesting changes in this merge. Use --all to see everything\n"
68 );
69 return;
70 }
71 }else{
72 /* Use only files named on the command-line in the file list.
73 ** But verify each file named is actually found in the MERGESTAT
74 ** table first. */
75 for(i=2; i<g.argc; i++){
76 char *zFile; /* Input filename */
77 char *zTreename; /* Name of the file in the tree */
78 Blob fname; /* Filename relative to root */
79 char *zOp; /* Operation on this file */
80 zFile = mprintf("%/", g.argv[i]);
81 file_tree_name(zFile, &fname, 0, 1);
82 fossil_free(zFile);
83 zTreename = blob_str(&fname);
84 zOp = db_text(0, "SELECT op FROM mergestat WHERE fn=%Q or fnr=%Q",
85 zTreename, zTreename);
86 blob_appendf(&script, " %s ", zOp);
87 fossil_free(zOp);
 
 
 
88 blob_append_tcl_literal(&script, zTreename, (int)strlen(zTreename));
89 blob_reset(&fname);
90 }
91 }
92 blob_appendf(&script, "]\n");
@@ -235,10 +244,12 @@
244 ** table. The plan moving forward is that it can generate data for
245 ** a Tk-based GUI to show the details of the merge. This command is
246 ** a work-in-progress.
247 **
248 ** Options:
249 ** -a|--all Show all changes. Normally only merges, conflicts,
250 ** and errors are shown.
251 ** -c|--context N Show N lines of context around each change,
252 ** with negative N meaning show all content. Only
253 ** meaningful in combination with --tcl or --tk.
254 ** --dark Use dark mode for the Tcl/Tk-based GUI
255 ** --tcl FILE Generate (to stdout) a TCL list containing
@@ -251,19 +262,23 @@
262 */
263 void merge_info_cmd(void){
264 const char *zCnt;
265 const char *zTcl;
266 int bTk;
267 int bDark;
268 int bAll;
269 int nContext;
270 Stmt q;
271 const char *zWhere;
272 int cnt = 0;
273
274 db_must_be_within_tree();
275 zTcl = find_option("tcl", 0, 1);
276 bTk = find_option("tk", 0, 0)!=0;
277 zCnt = find_option("context", "c", 1);
278 bDark = find_option("dark", 0, 0)!=0;
279 bAll = find_option("all", "a", 0)!=0;
280 if( bTk==0 ){
281 verify_all_options();
282 if( g.argc>2 ){
283 usage("[OPTIONS]");
284 }
@@ -281,33 +296,47 @@
296 fossil_print("No merge data is available\n");
297 }
298 return;
299 }
300 if( bTk ){
301 merge_info_tk(bDark, bAll, nContext);
302 return;
303 }
304 if( zTcl ){
305 merge_info_tcl(zTcl, nContext);
306 return;
307 }
308 if( bAll ){
309 zWhere = "";
310 }else{
311 zWhere = "WHERE op IN ('MERGE','CONFLICT','ERROR')";
312 }
313 db_prepare(&q,
314 /* 0 1 2 */
315 "SELECT op, coalesce(fnr,fn), msg"
316 " FROM mergestat"
317 " %s"
318 " ORDER BY coalesce(fnr,fn)",
319 zWhere /*safe-for-%s*/
320 );
321 while( db_step(&q)==SQLITE_ROW ){
322 const char *zOp = db_column_text(&q, 0);
323 const char *zName = db_column_text(&q, 1);
324 const char *zErr = db_column_text(&q, 2);
325 if( zErr && fossil_strcmp(zOp,"CONFLICT")!=0 ){
326 fossil_print("%-9s %s (%s)\n", zOp, zName, zErr);
 
327 }else{
328 fossil_print("%-9s %s\n", zOp, zName);
329 }
330 cnt++;
331 }
332 db_finalize(&q);
333 if( !bAll && cnt==0 ){
334 fossil_print(
335 "No interesting change in this merge. Use --all to see everything.\n"
336 );
337 }
338 }
339
340 /*
341 ** Erase all information about prior merges. Do this, for example, after
342 ** a commit.
@@ -1202,10 +1231,11 @@
1231 int islinkv = db_column_int(&q, 7);
1232 int islinkm = db_column_int(&q, 8);
1233 int chnged = db_column_int(&q, 11);
1234 int rc;
1235 char *zFullPath;
1236 const char *zType = "MERGE";
1237 Blob m, p, r;
1238 /* Do a 3-way merge of idp->idm into idp->idv. The results go into idv. */
1239 if( verboseFlag ){
1240 fossil_print("MERGE %s (pivot=%d v1=%d v2=%d)\n",
1241 zName, ridp, ridm, ridv);
@@ -1215,11 +1245,11 @@
1245 if( islinkv || islinkm ){
1246 fossil_print("***** Cannot merge symlink %s\n", zName);
1247 nConflict++;
1248 db_multi_exec(
1249 "INSERT INTO mergestat(op,fnp,ridp,fn,ridv,fnm,ridm,fnr,nc,msg)"
1250 "VALUES('ERROR',%Q,%d,%Q,%d,%Q,%d,%Q,1,'cannot merge symlink')",
1251 /* fnp */ db_column_text(&q, 9),
1252 /* ridp */ ridp,
1253 /* fn */ zName,
1254 /* ridv */ ridv,
1255 /* fnm */ db_column_text(&q, 10),
@@ -1254,21 +1284,24 @@
1284 fossil_print("***** %d merge conflict%s in %s\n",
1285 rc, rc>1 ? "s" : "", zName);
1286 nConflict++;
1287 nc = rc;
1288 zErrMsg = "merge conflicts";
1289 zType = "CONFLICT";
1290 }
1291 }else{
1292 fossil_print("***** Cannot merge binary file %s\n", zName);
1293 nConflict++;
1294 nc = 1;
1295 zErrMsg = "cannot merge binary file";
1296 zType = "ERROR";
1297 }
1298 db_multi_exec(
1299 "INSERT INTO mergestat(op,fnp,ridp,fn,ridv,sz,fnm,ridm,fnr,nc,msg)"
1300 "VALUES(%Q,%Q,%d,%Q,iif(%d,%d,NULL),iif(%d,%d,NULL),%Q,%d,"
1301 "%Q,%d,%Q)",
1302 /* op */ zType,
1303 /* fnp */ db_column_text(&q, 9),
1304 /* ridp */ ridp,
1305 /* fn */ zName,
1306 /* ridv */ chnged==0, ridv,
1307 /* sz */ chnged!=0, sz,
1308
+7 -4
--- src/merge.tcl
+++ src/merge.tcl
@@ -319,15 +319,17 @@
319319
toplevel .wfiles
320320
wm withdraw .wfiles
321321
update idletasks
322322
wm transient .wfiles .
323323
wm overrideredirect .wfiles 1
324
- set ht [llength $filelist]
324
+ set ht [expr {[llength $filelist]/2}]
325325
if {$ht>$CFG(LB_HEIGHT)} {set ht $CFG(LB_HEIGHT)}
326326
listbox .wfiles.lb -width 0 -height $ht -activestyle none \
327327
-yscroll {.wfiles.sb set}
328
- .wfiles.lb insert end {*}$filelist
328
+ foreach {op fn} $filelist {
329
+ .wfiles.lb insert end [format "%-9s %s" $op $fn]
330
+ }
329331
::ttk::scrollbar .wfiles.sb -command {.wfiles.lb yview}
330332
grid .wfiles.lb .wfiles.sb -sticky ns
331333
bind .bb.files <1> {
332334
set x [winfo rootx %W]
333335
set y [expr {[winfo rooty %W]+[winfo height %W]}]
@@ -337,11 +339,12 @@
337339
}
338340
bind .wfiles <FocusOut> {wm withdraw .wfiles}
339341
bind .wfiles <Escape> {focus .}
340342
foreach evt {1 Return} {
341343
bind .wfiles.lb <$evt> {
342
- readMerge "$::fossilcmd [list [lindex $::filelist [%W curselection]]]"
344
+ set ii [%W curselection]
345
+ readMerge "$::fossilcmd [list [lindex $::filelist [expr {$ii*2+1}]]]"
343346
focus .
344347
break
345348
}
346349
}
347350
bind .wfiles.lb <Motion> {
@@ -394,11 +397,11 @@
394397
::ttk::scrollbar .sbxC -command {.txtC xview} -orient horizontal
395398
::ttk::scrollbar .sbxD -command {.txtD xview} -orient horizontal
396399
frame .spacer
397400
398401
if {[info exists filelist]} {
399
- readMerge "$fossilcmd [list [lindex $filelist 0]]"
402
+ readMerge "$fossilcmd [list [lindex $filelist 1]]"
400403
} else {
401404
readMerge $fossilcmd
402405
}
403406
update idletasks
404407
405408
--- src/merge.tcl
+++ src/merge.tcl
@@ -319,15 +319,17 @@
319 toplevel .wfiles
320 wm withdraw .wfiles
321 update idletasks
322 wm transient .wfiles .
323 wm overrideredirect .wfiles 1
324 set ht [llength $filelist]
325 if {$ht>$CFG(LB_HEIGHT)} {set ht $CFG(LB_HEIGHT)}
326 listbox .wfiles.lb -width 0 -height $ht -activestyle none \
327 -yscroll {.wfiles.sb set}
328 .wfiles.lb insert end {*}$filelist
 
 
329 ::ttk::scrollbar .wfiles.sb -command {.wfiles.lb yview}
330 grid .wfiles.lb .wfiles.sb -sticky ns
331 bind .bb.files <1> {
332 set x [winfo rootx %W]
333 set y [expr {[winfo rooty %W]+[winfo height %W]}]
@@ -337,11 +339,12 @@
337 }
338 bind .wfiles <FocusOut> {wm withdraw .wfiles}
339 bind .wfiles <Escape> {focus .}
340 foreach evt {1 Return} {
341 bind .wfiles.lb <$evt> {
342 readMerge "$::fossilcmd [list [lindex $::filelist [%W curselection]]]"
 
343 focus .
344 break
345 }
346 }
347 bind .wfiles.lb <Motion> {
@@ -394,11 +397,11 @@
394 ::ttk::scrollbar .sbxC -command {.txtC xview} -orient horizontal
395 ::ttk::scrollbar .sbxD -command {.txtD xview} -orient horizontal
396 frame .spacer
397
398 if {[info exists filelist]} {
399 readMerge "$fossilcmd [list [lindex $filelist 0]]"
400 } else {
401 readMerge $fossilcmd
402 }
403 update idletasks
404
405
--- src/merge.tcl
+++ src/merge.tcl
@@ -319,15 +319,17 @@
319 toplevel .wfiles
320 wm withdraw .wfiles
321 update idletasks
322 wm transient .wfiles .
323 wm overrideredirect .wfiles 1
324 set ht [expr {[llength $filelist]/2}]
325 if {$ht>$CFG(LB_HEIGHT)} {set ht $CFG(LB_HEIGHT)}
326 listbox .wfiles.lb -width 0 -height $ht -activestyle none \
327 -yscroll {.wfiles.sb set}
328 foreach {op fn} $filelist {
329 .wfiles.lb insert end [format "%-9s %s" $op $fn]
330 }
331 ::ttk::scrollbar .wfiles.sb -command {.wfiles.lb yview}
332 grid .wfiles.lb .wfiles.sb -sticky ns
333 bind .bb.files <1> {
334 set x [winfo rootx %W]
335 set y [expr {[winfo rooty %W]+[winfo height %W]}]
@@ -337,11 +339,12 @@
339 }
340 bind .wfiles <FocusOut> {wm withdraw .wfiles}
341 bind .wfiles <Escape> {focus .}
342 foreach evt {1 Return} {
343 bind .wfiles.lb <$evt> {
344 set ii [%W curselection]
345 readMerge "$::fossilcmd [list [lindex $::filelist [expr {$ii*2+1}]]]"
346 focus .
347 break
348 }
349 }
350 bind .wfiles.lb <Motion> {
@@ -394,11 +397,11 @@
397 ::ttk::scrollbar .sbxC -command {.txtC xview} -orient horizontal
398 ::ttk::scrollbar .sbxD -command {.txtD xview} -orient horizontal
399 frame .spacer
400
401 if {[info exists filelist]} {
402 readMerge "$fossilcmd [list [lindex $filelist 1]]"
403 } else {
404 readMerge $fossilcmd
405 }
406 update idletasks
407
408

Keyboard Shortcuts

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