Fossil SCM

Further improvements to the --debug option on "fossil merge".

drh 2021-04-15 15:03 trunk
Commit 0d4d85b05d45a032ca28c9a82bd1e1a95f801a4eb7f8e153cbed6de13bd9bd54
1 file changed +51 -20
+51 -20
--- src/merge.c
+++ src/merge.c
@@ -178,17 +178,27 @@
178178
}
179179
180180
/*
181181
** Print the contents of the "fv" table on standard output, for debugging
182182
** purposes.
183
+**
184
+** Only show entries where a file has changed, unless showAll is true.
183185
*/
184
-static void debug_fv_dump(void){
186
+static void debug_fv_dump(int showAll){
185187
Stmt q;
186
- db_prepare(&q,
187
- "SELECT rowid, fn, fnp, fnm, chnged, ridv, ridp, ridm, "
188
- " isexe, islinkv, islinkm, fnn FROM fv"
189
- );
188
+ if( showAll ){
189
+ db_prepare(&q,
190
+ "SELECT rowid, fn, fnp, fnm, chnged, ridv, ridp, ridm, "
191
+ " isexe, islinkv, islinkm, fnn FROM fv"
192
+ );
193
+ }else{
194
+ db_prepare(&q,
195
+ "SELECT rowid, fn, fnp, fnm, chnged, ridv, ridp, ridm, "
196
+ " isexe, islinkv, islinkm, fnn FROM fv"
197
+ " WHERE chnged OR (ridv!=ridm AND ridm!=ridp)"
198
+ );
199
+ }
190200
while( db_step(&q)==SQLITE_ROW ){
191201
fossil_print("%3d: ridv=%-4d ridp=%-4d ridm=%-4d chnged=%d isexe=%d "
192202
" islinkv=%d islinkm=%d\n",
193203
db_column_int(&q, 0),
194204
db_column_int(&q, 5),
@@ -302,20 +312,32 @@
302312
verboseFlag = find_option("detail",0,0)!=0; /* deprecated */
303313
}
304314
pickFlag = find_option("cherrypick",0,0)!=0;
305315
integrateFlag = find_option("integrate",0,0)!=0;
306316
backoutFlag = find_option("backout",0,0)!=0;
307
- debugFlag = find_option("debug",0,0)!=0;
308317
zBinGlob = find_option("binary",0,1);
309318
dryRunFlag = find_option("dry-run","n",0)!=0;
310319
if( !dryRunFlag ){
311320
dryRunFlag = find_option("nochange",0,0)!=0; /* deprecated */
312321
}
313322
forceFlag = find_option("force","f",0)!=0;
314323
zPivot = find_option("baseline",0,1);
315324
keepMergeFlag = find_option("keep-merge-files", "K",0)!=0;
316325
326
+ /* Undocumented --debug option:
327
+ **
328
+ ** When included on the command-line, --debug causes lots of state
329
+ ** information to be displayed. This option is undocumented as it
330
+ ** might change or be eliminated in future releases.
331
+ **
332
+ ** Hints:
333
+ ** * Combine --debug and --verbose for still more output.
334
+ ** * The --dry-run option is also useful in combination with --debug.
335
+ */
336
+ debugFlag = find_option("debug",0,0)!=0;
337
+ if( debugFlag && verboseFlag ) debugFlag = 2;
338
+
317339
verify_all_options();
318340
db_must_be_within_tree();
319341
if( zBinGlob==0 ) zBinGlob = db_get("binary-glob",0);
320342
vid = db_lget_int("checkout", 0);
321343
if( vid==0 ){
@@ -478,10 +500,11 @@
478500
fossil_print("P=%-4d %z (file content pivot)\n", pid, z);
479501
z = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", mid);
480502
fossil_print("M=%-4d %z (merged-in version)\n", mid, z);
481503
z = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
482504
fossil_print("V=%-4d %z (current version)\n", vid, z);
505
+ fossil_print("vAncestor = '%c'\n", vAncestor);
483506
}
484507
485508
/*
486509
** The vfile.pathname field is used to match files against each other. The
487510
** FV table contains one row for each each unique filename in
@@ -515,11 +538,11 @@
515538
add_renames("fn", vid, nid, 0, debugFlag ? "N->V" : 0);
516539
add_renames("fnp", pid, nid, 0, debugFlag ? "N->P" : 0);
517540
add_renames("fnm", mid, nid, backoutFlag, debugFlag ? "N->M" : 0);
518541
if( debugFlag ){
519542
fossil_print("******** FV after name change search *******\n");
520
- debug_fv_dump();
543
+ debug_fv_dump(1);
521544
}
522545
523546
/*
524547
** Add files found in V
525548
*/
@@ -531,13 +554,13 @@
531554
" LEFT JOIN fv ON fn=coalesce(origname,pathname)"
532555
" AND rid>0 AND vf.chnged NOT IN (3,5)"
533556
" WHERE vid=%d;",
534557
vAncestor, vid
535558
);
536
- if( debugFlag ){
559
+ if( debugFlag>=2 ){
537560
fossil_print("******** FV after adding files in current version *******\n");
538
- debug_fv_dump();
561
+ debug_fv_dump(1);
539562
}
540563
541564
/*
542565
** Add files found in P
543566
*/
@@ -547,10 +570,14 @@
547570
" WHERE fnp IS NULL;"
548571
"INSERT OR IGNORE INTO fv(fnp)"
549572
" SELECT coalesce(origname,pathname) FROM vfile WHERE vid=%d;",
550573
pid
551574
);
575
+ if( debugFlag>=2 ){
576
+ fossil_print("******** FV after adding pivot files *******\n");
577
+ debug_fv_dump(1);
578
+ }
552579
553580
/*
554581
** Add files found in M
555582
*/
556583
db_multi_exec(
@@ -557,13 +584,13 @@
557584
"UPDATE OR IGNORE fv SET fnm=fnp WHERE fnm IS NULL;"
558585
"INSERT OR IGNORE INTO fv(fnm)"
559586
" SELECT pathname FROM vfile WHERE vid=%d;",
560587
mid
561588
);
562
- if( debugFlag ){
563
- fossil_print("******** FV after adding pivot and merge-in files *******\n");
564
- debug_fv_dump();
589
+ if( debugFlag>=2 ){
590
+ fossil_print("******** FV after adding merge-in files *******\n");
591
+ debug_fv_dump(1);
565592
}
566593
567594
/*
568595
** Compute the file version ids for P and M
569596
*/
@@ -587,14 +614,10 @@
587614
" WHERE vid=%d AND fnm=pathname),0),"
588615
" isexe=coalesce((SELECT isexe FROM vfile WHERE vid=%d AND fnm=pathname),"
589616
" isexe)",
590617
mid, mid, mid, mid
591618
);
592
- if( debugFlag ){
593
- fossil_print("******** FV Final *******\n");
594
- debug_fv_dump();
595
- }
596619
597620
/*
598621
** Update the execute bit on files where it's changed from P->M but not P->V
599622
*/
600623
db_prepare(&q,
@@ -612,13 +635,20 @@
612635
free(zFullPath);
613636
db_multi_exec("UPDATE vfile SET isexe=%d WHERE id=%d", isExe, idv);
614637
}
615638
}
616639
db_finalize(&q);
640
+ if( debugFlag ){
641
+ fossil_print("******** FV final *******\n");
642
+ debug_fv_dump( debugFlag>=2 );
643
+ }
617644
618
- /*
619
- ** Find files in M and V but not in P and report conflicts.
645
+ /************************************************************************
646
+ ** All of the information needed to do the merge is now contained in the
647
+ ** FV table. Starting here, we begin to actually carry out the merge.
648
+ **
649
+ ** First, find files in M and V but not in P and report conflicts.
620650
** The file in M will be ignored. It will be treated as if it
621651
** does not exist.
622652
*/
623653
db_prepare(&q,
624654
"SELECT idm FROM fv WHERE idp=0 AND idv>0 AND idm>0"
@@ -711,11 +741,12 @@
711741
blob_write_to_file(&r, zFullPath);
712742
file_setexe(zFullPath, isExe);
713743
}
714744
db_multi_exec("UPDATE vfile SET mtime=0 WHERE id=%d", idv);
715745
if( rc>0 ){
716
- fossil_print("***** %d merge conflicts in %s\n", rc, zName);
746
+ fossil_print("***** %d merge conflict%s in %s\n",
747
+ rc, rc>1 ? "s" : "", zName);
717748
nConflict++;
718749
}
719750
}else{
720751
fossil_print("***** Cannot merge binary file %s\n", zName);
721752
nConflict++;
@@ -832,11 +863,11 @@
832863
"UPDATE vfile SET pathname=origname || ' (overwritten by rename)'"
833864
" WHERE pathname IS NULL"
834865
);
835866
836867
/*
837
- ** Add to V files that are not in V or P but are in M
868
+ ** Insert into V any files that are not in V or P but are in M.
838869
*/
839870
db_prepare(&q,
840871
"SELECT idm, fnm FROM fv"
841872
" WHERE idp=0 AND idv=0 AND idm>0"
842873
);
843874
--- src/merge.c
+++ src/merge.c
@@ -178,17 +178,27 @@
178 }
179
180 /*
181 ** Print the contents of the "fv" table on standard output, for debugging
182 ** purposes.
 
 
183 */
184 static void debug_fv_dump(void){
185 Stmt q;
186 db_prepare(&q,
187 "SELECT rowid, fn, fnp, fnm, chnged, ridv, ridp, ridm, "
188 " isexe, islinkv, islinkm, fnn FROM fv"
189 );
 
 
 
 
 
 
 
 
190 while( db_step(&q)==SQLITE_ROW ){
191 fossil_print("%3d: ridv=%-4d ridp=%-4d ridm=%-4d chnged=%d isexe=%d "
192 " islinkv=%d islinkm=%d\n",
193 db_column_int(&q, 0),
194 db_column_int(&q, 5),
@@ -302,20 +312,32 @@
302 verboseFlag = find_option("detail",0,0)!=0; /* deprecated */
303 }
304 pickFlag = find_option("cherrypick",0,0)!=0;
305 integrateFlag = find_option("integrate",0,0)!=0;
306 backoutFlag = find_option("backout",0,0)!=0;
307 debugFlag = find_option("debug",0,0)!=0;
308 zBinGlob = find_option("binary",0,1);
309 dryRunFlag = find_option("dry-run","n",0)!=0;
310 if( !dryRunFlag ){
311 dryRunFlag = find_option("nochange",0,0)!=0; /* deprecated */
312 }
313 forceFlag = find_option("force","f",0)!=0;
314 zPivot = find_option("baseline",0,1);
315 keepMergeFlag = find_option("keep-merge-files", "K",0)!=0;
316
 
 
 
 
 
 
 
 
 
 
 
 
 
317 verify_all_options();
318 db_must_be_within_tree();
319 if( zBinGlob==0 ) zBinGlob = db_get("binary-glob",0);
320 vid = db_lget_int("checkout", 0);
321 if( vid==0 ){
@@ -478,10 +500,11 @@
478 fossil_print("P=%-4d %z (file content pivot)\n", pid, z);
479 z = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", mid);
480 fossil_print("M=%-4d %z (merged-in version)\n", mid, z);
481 z = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
482 fossil_print("V=%-4d %z (current version)\n", vid, z);
 
483 }
484
485 /*
486 ** The vfile.pathname field is used to match files against each other. The
487 ** FV table contains one row for each each unique filename in
@@ -515,11 +538,11 @@
515 add_renames("fn", vid, nid, 0, debugFlag ? "N->V" : 0);
516 add_renames("fnp", pid, nid, 0, debugFlag ? "N->P" : 0);
517 add_renames("fnm", mid, nid, backoutFlag, debugFlag ? "N->M" : 0);
518 if( debugFlag ){
519 fossil_print("******** FV after name change search *******\n");
520 debug_fv_dump();
521 }
522
523 /*
524 ** Add files found in V
525 */
@@ -531,13 +554,13 @@
531 " LEFT JOIN fv ON fn=coalesce(origname,pathname)"
532 " AND rid>0 AND vf.chnged NOT IN (3,5)"
533 " WHERE vid=%d;",
534 vAncestor, vid
535 );
536 if( debugFlag ){
537 fossil_print("******** FV after adding files in current version *******\n");
538 debug_fv_dump();
539 }
540
541 /*
542 ** Add files found in P
543 */
@@ -547,10 +570,14 @@
547 " WHERE fnp IS NULL;"
548 "INSERT OR IGNORE INTO fv(fnp)"
549 " SELECT coalesce(origname,pathname) FROM vfile WHERE vid=%d;",
550 pid
551 );
 
 
 
 
552
553 /*
554 ** Add files found in M
555 */
556 db_multi_exec(
@@ -557,13 +584,13 @@
557 "UPDATE OR IGNORE fv SET fnm=fnp WHERE fnm IS NULL;"
558 "INSERT OR IGNORE INTO fv(fnm)"
559 " SELECT pathname FROM vfile WHERE vid=%d;",
560 mid
561 );
562 if( debugFlag ){
563 fossil_print("******** FV after adding pivot and merge-in files *******\n");
564 debug_fv_dump();
565 }
566
567 /*
568 ** Compute the file version ids for P and M
569 */
@@ -587,14 +614,10 @@
587 " WHERE vid=%d AND fnm=pathname),0),"
588 " isexe=coalesce((SELECT isexe FROM vfile WHERE vid=%d AND fnm=pathname),"
589 " isexe)",
590 mid, mid, mid, mid
591 );
592 if( debugFlag ){
593 fossil_print("******** FV Final *******\n");
594 debug_fv_dump();
595 }
596
597 /*
598 ** Update the execute bit on files where it's changed from P->M but not P->V
599 */
600 db_prepare(&q,
@@ -612,13 +635,20 @@
612 free(zFullPath);
613 db_multi_exec("UPDATE vfile SET isexe=%d WHERE id=%d", isExe, idv);
614 }
615 }
616 db_finalize(&q);
 
 
 
 
617
618 /*
619 ** Find files in M and V but not in P and report conflicts.
 
 
 
620 ** The file in M will be ignored. It will be treated as if it
621 ** does not exist.
622 */
623 db_prepare(&q,
624 "SELECT idm FROM fv WHERE idp=0 AND idv>0 AND idm>0"
@@ -711,11 +741,12 @@
711 blob_write_to_file(&r, zFullPath);
712 file_setexe(zFullPath, isExe);
713 }
714 db_multi_exec("UPDATE vfile SET mtime=0 WHERE id=%d", idv);
715 if( rc>0 ){
716 fossil_print("***** %d merge conflicts in %s\n", rc, zName);
 
717 nConflict++;
718 }
719 }else{
720 fossil_print("***** Cannot merge binary file %s\n", zName);
721 nConflict++;
@@ -832,11 +863,11 @@
832 "UPDATE vfile SET pathname=origname || ' (overwritten by rename)'"
833 " WHERE pathname IS NULL"
834 );
835
836 /*
837 ** Add to V files that are not in V or P but are in M
838 */
839 db_prepare(&q,
840 "SELECT idm, fnm FROM fv"
841 " WHERE idp=0 AND idv=0 AND idm>0"
842 );
843
--- src/merge.c
+++ src/merge.c
@@ -178,17 +178,27 @@
178 }
179
180 /*
181 ** Print the contents of the "fv" table on standard output, for debugging
182 ** purposes.
183 **
184 ** Only show entries where a file has changed, unless showAll is true.
185 */
186 static void debug_fv_dump(int showAll){
187 Stmt q;
188 if( showAll ){
189 db_prepare(&q,
190 "SELECT rowid, fn, fnp, fnm, chnged, ridv, ridp, ridm, "
191 " isexe, islinkv, islinkm, fnn FROM fv"
192 );
193 }else{
194 db_prepare(&q,
195 "SELECT rowid, fn, fnp, fnm, chnged, ridv, ridp, ridm, "
196 " isexe, islinkv, islinkm, fnn FROM fv"
197 " WHERE chnged OR (ridv!=ridm AND ridm!=ridp)"
198 );
199 }
200 while( db_step(&q)==SQLITE_ROW ){
201 fossil_print("%3d: ridv=%-4d ridp=%-4d ridm=%-4d chnged=%d isexe=%d "
202 " islinkv=%d islinkm=%d\n",
203 db_column_int(&q, 0),
204 db_column_int(&q, 5),
@@ -302,20 +312,32 @@
312 verboseFlag = find_option("detail",0,0)!=0; /* deprecated */
313 }
314 pickFlag = find_option("cherrypick",0,0)!=0;
315 integrateFlag = find_option("integrate",0,0)!=0;
316 backoutFlag = find_option("backout",0,0)!=0;
 
317 zBinGlob = find_option("binary",0,1);
318 dryRunFlag = find_option("dry-run","n",0)!=0;
319 if( !dryRunFlag ){
320 dryRunFlag = find_option("nochange",0,0)!=0; /* deprecated */
321 }
322 forceFlag = find_option("force","f",0)!=0;
323 zPivot = find_option("baseline",0,1);
324 keepMergeFlag = find_option("keep-merge-files", "K",0)!=0;
325
326 /* Undocumented --debug option:
327 **
328 ** When included on the command-line, --debug causes lots of state
329 ** information to be displayed. This option is undocumented as it
330 ** might change or be eliminated in future releases.
331 **
332 ** Hints:
333 ** * Combine --debug and --verbose for still more output.
334 ** * The --dry-run option is also useful in combination with --debug.
335 */
336 debugFlag = find_option("debug",0,0)!=0;
337 if( debugFlag && verboseFlag ) debugFlag = 2;
338
339 verify_all_options();
340 db_must_be_within_tree();
341 if( zBinGlob==0 ) zBinGlob = db_get("binary-glob",0);
342 vid = db_lget_int("checkout", 0);
343 if( vid==0 ){
@@ -478,10 +500,11 @@
500 fossil_print("P=%-4d %z (file content pivot)\n", pid, z);
501 z = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", mid);
502 fossil_print("M=%-4d %z (merged-in version)\n", mid, z);
503 z = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
504 fossil_print("V=%-4d %z (current version)\n", vid, z);
505 fossil_print("vAncestor = '%c'\n", vAncestor);
506 }
507
508 /*
509 ** The vfile.pathname field is used to match files against each other. The
510 ** FV table contains one row for each each unique filename in
@@ -515,11 +538,11 @@
538 add_renames("fn", vid, nid, 0, debugFlag ? "N->V" : 0);
539 add_renames("fnp", pid, nid, 0, debugFlag ? "N->P" : 0);
540 add_renames("fnm", mid, nid, backoutFlag, debugFlag ? "N->M" : 0);
541 if( debugFlag ){
542 fossil_print("******** FV after name change search *******\n");
543 debug_fv_dump(1);
544 }
545
546 /*
547 ** Add files found in V
548 */
@@ -531,13 +554,13 @@
554 " LEFT JOIN fv ON fn=coalesce(origname,pathname)"
555 " AND rid>0 AND vf.chnged NOT IN (3,5)"
556 " WHERE vid=%d;",
557 vAncestor, vid
558 );
559 if( debugFlag>=2 ){
560 fossil_print("******** FV after adding files in current version *******\n");
561 debug_fv_dump(1);
562 }
563
564 /*
565 ** Add files found in P
566 */
@@ -547,10 +570,14 @@
570 " WHERE fnp IS NULL;"
571 "INSERT OR IGNORE INTO fv(fnp)"
572 " SELECT coalesce(origname,pathname) FROM vfile WHERE vid=%d;",
573 pid
574 );
575 if( debugFlag>=2 ){
576 fossil_print("******** FV after adding pivot files *******\n");
577 debug_fv_dump(1);
578 }
579
580 /*
581 ** Add files found in M
582 */
583 db_multi_exec(
@@ -557,13 +584,13 @@
584 "UPDATE OR IGNORE fv SET fnm=fnp WHERE fnm IS NULL;"
585 "INSERT OR IGNORE INTO fv(fnm)"
586 " SELECT pathname FROM vfile WHERE vid=%d;",
587 mid
588 );
589 if( debugFlag>=2 ){
590 fossil_print("******** FV after adding merge-in files *******\n");
591 debug_fv_dump(1);
592 }
593
594 /*
595 ** Compute the file version ids for P and M
596 */
@@ -587,14 +614,10 @@
614 " WHERE vid=%d AND fnm=pathname),0),"
615 " isexe=coalesce((SELECT isexe FROM vfile WHERE vid=%d AND fnm=pathname),"
616 " isexe)",
617 mid, mid, mid, mid
618 );
 
 
 
 
619
620 /*
621 ** Update the execute bit on files where it's changed from P->M but not P->V
622 */
623 db_prepare(&q,
@@ -612,13 +635,20 @@
635 free(zFullPath);
636 db_multi_exec("UPDATE vfile SET isexe=%d WHERE id=%d", isExe, idv);
637 }
638 }
639 db_finalize(&q);
640 if( debugFlag ){
641 fossil_print("******** FV final *******\n");
642 debug_fv_dump( debugFlag>=2 );
643 }
644
645 /************************************************************************
646 ** All of the information needed to do the merge is now contained in the
647 ** FV table. Starting here, we begin to actually carry out the merge.
648 **
649 ** First, find files in M and V but not in P and report conflicts.
650 ** The file in M will be ignored. It will be treated as if it
651 ** does not exist.
652 */
653 db_prepare(&q,
654 "SELECT idm FROM fv WHERE idp=0 AND idv>0 AND idm>0"
@@ -711,11 +741,12 @@
741 blob_write_to_file(&r, zFullPath);
742 file_setexe(zFullPath, isExe);
743 }
744 db_multi_exec("UPDATE vfile SET mtime=0 WHERE id=%d", idv);
745 if( rc>0 ){
746 fossil_print("***** %d merge conflict%s in %s\n",
747 rc, rc>1 ? "s" : "", zName);
748 nConflict++;
749 }
750 }else{
751 fossil_print("***** Cannot merge binary file %s\n", zName);
752 nConflict++;
@@ -832,11 +863,11 @@
863 "UPDATE vfile SET pathname=origname || ' (overwritten by rename)'"
864 " WHERE pathname IS NULL"
865 );
866
867 /*
868 ** Insert into V any files that are not in V or P but are in M.
869 */
870 db_prepare(&q,
871 "SELECT idm, fnm FROM fv"
872 " WHERE idp=0 AND idv=0 AND idm>0"
873 );
874

Keyboard Shortcuts

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