Fossil SCM

Fix a bug in the "fossil patch pull" command that caused "fossil revert" that occurs after a "fossil merge" to be lost. Also, improve "fossil patch pull" so that it does not mess with the undo log and does not do unnecessary syncs.

drh 2024-12-16 16:17 trunk merge
Commit 3a39ae4c87773acf4c86e5229c49d7cd4a0c851a8222776834ce47e9dac18e77
3 files changed +12 -8 +42 -3 +11 -4
+12 -8
--- src/merge.c
+++ src/merge.c
@@ -687,10 +687,11 @@
687687
** -K|--keep-merge-files On merge conflict, retain the temporary files
688688
** used for merging, named *-baseline, *-original,
689689
** and *-merge.
690690
** -n|--dry-run Do not actually change files on disk
691691
** --nosync Do not auto-sync prior to merging
692
+** --noundo Do not changes in the undo log
692693
** -v|--verbose Show additional details of the merge
693694
*/
694695
void merge_cmd(void){
695696
int vid; /* Current version "V" */
696697
int mid; /* Version we are merging from "M" */
@@ -712,10 +713,11 @@
712713
int nOverwrite = 0; /* Number of unmanaged files overwritten */
713714
char vAncestor = 'p'; /* If P is an ancestor of V then 'p', else 'n' */
714715
const char *zVersion; /* The VERSION argument */
715716
int bMultiMerge = 0; /* True if there are two or more VERSION arguments */
716717
int nMerge = 0; /* Number of prior merges processed */
718
+ int useUndo = 1; /* True to record changes in the undo log */
717719
Stmt q; /* SQL statment used for merge processing */
718720
719721
720722
/* Notation:
721723
**
@@ -760,10 +762,12 @@
760762
** * The --dry-run option is also useful in combination with --debug.
761763
*/
762764
debugFlag = find_option("debug",0,0)!=0;
763765
if( debugFlag && verboseFlag ) debugFlag = 2;
764766
showVfileFlag = find_option("show-vfile",0,0)!=0;
767
+ useUndo = find_option("noundo",0,0)==0;
768
+ if( dryRunFlag ) useUndo = 0;
765769
766770
verify_all_options();
767771
db_must_be_within_tree();
768772
if( zBinGlob==0 ) zBinGlob = db_get("binary-glob",0);
769773
vid = db_lget_int("checkout", 0);
@@ -926,11 +930,11 @@
926930
integrateFlag ? "integrate:" : "merge-from:");
927931
print_checkin_description(pid, 12, "baseline:");
928932
}
929933
vfile_check_signature(vid, CKSIG_ENOTFILE);
930934
if( nMerge==0 ) db_begin_transaction();
931
- if( !dryRunFlag ) undo_begin();
935
+ if( useUndo ) undo_begin();
932936
if( load_vfile_from_rid(mid) && !forceMissingFlag ){
933937
fossil_fatal("missing content, unable to merge");
934938
}
935939
if( load_vfile_from_rid(pid) && !forceMissingFlag ){
936940
fossil_fatal("missing content, unable to merge");
@@ -1183,12 +1187,12 @@
11831187
int ridm = db_column_int(&q, 1);
11841188
const char *zName = db_column_text(&q, 2);
11851189
int islinkm = db_column_int(&q, 3);
11861190
/* Copy content from idm over into idv. Overwrite idv. */
11871191
fossil_print("UPDATE %s\n", zName);
1192
+ if( useUndo ) undo_save(zName);
11881193
if( !dryRunFlag ){
1189
- undo_save(zName);
11901194
db_multi_exec(
11911195
"UPDATE vfile SET mtime=0, mrid=%d, chnged=%d, islink=%d,"
11921196
" mhash=CASE WHEN rid<>%d"
11931197
" THEN (SELECT uuid FROM blob WHERE blob.rid=%d) END"
11941198
" WHERE id=%d", ridm, integrateFlag?4:2, islinkm, ridm, ridm, idv
@@ -1265,11 +1269,11 @@
12651269
}else{
12661270
i64 sz;
12671271
const char *zErrMsg = 0;
12681272
int nc = 0;
12691273
1270
- if( !dryRunFlag ) undo_save(zName);
1274
+ if( useUndo ) undo_save(zName);
12711275
zFullPath = mprintf("%s/%s", g.zLocalRoot, zName);
12721276
sz = file_size(zFullPath, ExtFILE);
12731277
content_get(ridp, &p);
12741278
content_get(ridm, &m);
12751279
if( isBinary ){
@@ -1352,11 +1356,11 @@
13521356
zErrMsg = "local edits lost";
13531357
zFullPath = mprintf("%s/%s", g.zLocalRoot, zName);
13541358
sz = file_size(zFullPath, ExtFILE);
13551359
fossil_free(zFullPath);
13561360
}
1357
- if( !dryRunFlag ) undo_save(zName);
1361
+ if( useUndo ) undo_save(zName);
13581362
db_multi_exec(
13591363
"UPDATE vfile SET deleted=1 WHERE id=%d", idv
13601364
);
13611365
if( !dryRunFlag ){
13621366
char *zFullPath = mprintf("%s%s", g.zLocalRoot, zName);
@@ -1399,12 +1403,12 @@
13991403
int idv = db_column_int(&q, 0);
14001404
const char *zOldName = db_column_text(&q, 1);
14011405
const char *zNewName = db_column_text(&q, 2);
14021406
int isExe = db_column_int(&q, 3);
14031407
fossil_print("RENAME %s -> %s\n", zOldName, zNewName);
1404
- if( !dryRunFlag ) undo_save(zOldName);
1405
- if( !dryRunFlag ) undo_save(zNewName);
1408
+ if( useUndo ) undo_save(zOldName);
1409
+ if( useUndo ) undo_save(zNewName);
14061410
db_multi_exec(
14071411
"UPDATE mergestat SET fnr=fnm WHERE fnp=%Q",
14081412
zOldName
14091413
);
14101414
db_multi_exec(
@@ -1498,12 +1502,12 @@
14981502
"VALUES('ADDED',%Q,%d,%Q)",
14991503
/* fnm */ zName,
15001504
/* ridm */ db_column_int(&q,2),
15011505
/* fnr */ zName
15021506
);
1507
+ if( useUndo ) undo_save(zName);
15031508
if( !dryRunFlag ){
1504
- undo_save(zName);
15051509
vfile_to_disk(0, idm, 0, 0);
15061510
}
15071511
}
15081512
db_finalize(&q);
15091513
@@ -1558,9 +1562,9 @@
15581562
}
15591563
if( bMultiMerge && nConflict==0 ){
15601564
nMerge++;
15611565
goto merge_next_child;
15621566
}
1563
- if( !dryRunFlag ) undo_finish();
1567
+ if( useUndo ) undo_finish();
15641568
15651569
db_end_transaction(dryRunFlag);
15661570
}
15671571
--- src/merge.c
+++ src/merge.c
@@ -687,10 +687,11 @@
687 ** -K|--keep-merge-files On merge conflict, retain the temporary files
688 ** used for merging, named *-baseline, *-original,
689 ** and *-merge.
690 ** -n|--dry-run Do not actually change files on disk
691 ** --nosync Do not auto-sync prior to merging
 
692 ** -v|--verbose Show additional details of the merge
693 */
694 void merge_cmd(void){
695 int vid; /* Current version "V" */
696 int mid; /* Version we are merging from "M" */
@@ -712,10 +713,11 @@
712 int nOverwrite = 0; /* Number of unmanaged files overwritten */
713 char vAncestor = 'p'; /* If P is an ancestor of V then 'p', else 'n' */
714 const char *zVersion; /* The VERSION argument */
715 int bMultiMerge = 0; /* True if there are two or more VERSION arguments */
716 int nMerge = 0; /* Number of prior merges processed */
 
717 Stmt q; /* SQL statment used for merge processing */
718
719
720 /* Notation:
721 **
@@ -760,10 +762,12 @@
760 ** * The --dry-run option is also useful in combination with --debug.
761 */
762 debugFlag = find_option("debug",0,0)!=0;
763 if( debugFlag && verboseFlag ) debugFlag = 2;
764 showVfileFlag = find_option("show-vfile",0,0)!=0;
 
 
765
766 verify_all_options();
767 db_must_be_within_tree();
768 if( zBinGlob==0 ) zBinGlob = db_get("binary-glob",0);
769 vid = db_lget_int("checkout", 0);
@@ -926,11 +930,11 @@
926 integrateFlag ? "integrate:" : "merge-from:");
927 print_checkin_description(pid, 12, "baseline:");
928 }
929 vfile_check_signature(vid, CKSIG_ENOTFILE);
930 if( nMerge==0 ) db_begin_transaction();
931 if( !dryRunFlag ) undo_begin();
932 if( load_vfile_from_rid(mid) && !forceMissingFlag ){
933 fossil_fatal("missing content, unable to merge");
934 }
935 if( load_vfile_from_rid(pid) && !forceMissingFlag ){
936 fossil_fatal("missing content, unable to merge");
@@ -1183,12 +1187,12 @@
1183 int ridm = db_column_int(&q, 1);
1184 const char *zName = db_column_text(&q, 2);
1185 int islinkm = db_column_int(&q, 3);
1186 /* Copy content from idm over into idv. Overwrite idv. */
1187 fossil_print("UPDATE %s\n", zName);
 
1188 if( !dryRunFlag ){
1189 undo_save(zName);
1190 db_multi_exec(
1191 "UPDATE vfile SET mtime=0, mrid=%d, chnged=%d, islink=%d,"
1192 " mhash=CASE WHEN rid<>%d"
1193 " THEN (SELECT uuid FROM blob WHERE blob.rid=%d) END"
1194 " WHERE id=%d", ridm, integrateFlag?4:2, islinkm, ridm, ridm, idv
@@ -1265,11 +1269,11 @@
1265 }else{
1266 i64 sz;
1267 const char *zErrMsg = 0;
1268 int nc = 0;
1269
1270 if( !dryRunFlag ) undo_save(zName);
1271 zFullPath = mprintf("%s/%s", g.zLocalRoot, zName);
1272 sz = file_size(zFullPath, ExtFILE);
1273 content_get(ridp, &p);
1274 content_get(ridm, &m);
1275 if( isBinary ){
@@ -1352,11 +1356,11 @@
1352 zErrMsg = "local edits lost";
1353 zFullPath = mprintf("%s/%s", g.zLocalRoot, zName);
1354 sz = file_size(zFullPath, ExtFILE);
1355 fossil_free(zFullPath);
1356 }
1357 if( !dryRunFlag ) undo_save(zName);
1358 db_multi_exec(
1359 "UPDATE vfile SET deleted=1 WHERE id=%d", idv
1360 );
1361 if( !dryRunFlag ){
1362 char *zFullPath = mprintf("%s%s", g.zLocalRoot, zName);
@@ -1399,12 +1403,12 @@
1399 int idv = db_column_int(&q, 0);
1400 const char *zOldName = db_column_text(&q, 1);
1401 const char *zNewName = db_column_text(&q, 2);
1402 int isExe = db_column_int(&q, 3);
1403 fossil_print("RENAME %s -> %s\n", zOldName, zNewName);
1404 if( !dryRunFlag ) undo_save(zOldName);
1405 if( !dryRunFlag ) undo_save(zNewName);
1406 db_multi_exec(
1407 "UPDATE mergestat SET fnr=fnm WHERE fnp=%Q",
1408 zOldName
1409 );
1410 db_multi_exec(
@@ -1498,12 +1502,12 @@
1498 "VALUES('ADDED',%Q,%d,%Q)",
1499 /* fnm */ zName,
1500 /* ridm */ db_column_int(&q,2),
1501 /* fnr */ zName
1502 );
 
1503 if( !dryRunFlag ){
1504 undo_save(zName);
1505 vfile_to_disk(0, idm, 0, 0);
1506 }
1507 }
1508 db_finalize(&q);
1509
@@ -1558,9 +1562,9 @@
1558 }
1559 if( bMultiMerge && nConflict==0 ){
1560 nMerge++;
1561 goto merge_next_child;
1562 }
1563 if( !dryRunFlag ) undo_finish();
1564
1565 db_end_transaction(dryRunFlag);
1566 }
1567
--- src/merge.c
+++ src/merge.c
@@ -687,10 +687,11 @@
687 ** -K|--keep-merge-files On merge conflict, retain the temporary files
688 ** used for merging, named *-baseline, *-original,
689 ** and *-merge.
690 ** -n|--dry-run Do not actually change files on disk
691 ** --nosync Do not auto-sync prior to merging
692 ** --noundo Do not changes in the undo log
693 ** -v|--verbose Show additional details of the merge
694 */
695 void merge_cmd(void){
696 int vid; /* Current version "V" */
697 int mid; /* Version we are merging from "M" */
@@ -712,10 +713,11 @@
713 int nOverwrite = 0; /* Number of unmanaged files overwritten */
714 char vAncestor = 'p'; /* If P is an ancestor of V then 'p', else 'n' */
715 const char *zVersion; /* The VERSION argument */
716 int bMultiMerge = 0; /* True if there are two or more VERSION arguments */
717 int nMerge = 0; /* Number of prior merges processed */
718 int useUndo = 1; /* True to record changes in the undo log */
719 Stmt q; /* SQL statment used for merge processing */
720
721
722 /* Notation:
723 **
@@ -760,10 +762,12 @@
762 ** * The --dry-run option is also useful in combination with --debug.
763 */
764 debugFlag = find_option("debug",0,0)!=0;
765 if( debugFlag && verboseFlag ) debugFlag = 2;
766 showVfileFlag = find_option("show-vfile",0,0)!=0;
767 useUndo = find_option("noundo",0,0)==0;
768 if( dryRunFlag ) useUndo = 0;
769
770 verify_all_options();
771 db_must_be_within_tree();
772 if( zBinGlob==0 ) zBinGlob = db_get("binary-glob",0);
773 vid = db_lget_int("checkout", 0);
@@ -926,11 +930,11 @@
930 integrateFlag ? "integrate:" : "merge-from:");
931 print_checkin_description(pid, 12, "baseline:");
932 }
933 vfile_check_signature(vid, CKSIG_ENOTFILE);
934 if( nMerge==0 ) db_begin_transaction();
935 if( useUndo ) undo_begin();
936 if( load_vfile_from_rid(mid) && !forceMissingFlag ){
937 fossil_fatal("missing content, unable to merge");
938 }
939 if( load_vfile_from_rid(pid) && !forceMissingFlag ){
940 fossil_fatal("missing content, unable to merge");
@@ -1183,12 +1187,12 @@
1187 int ridm = db_column_int(&q, 1);
1188 const char *zName = db_column_text(&q, 2);
1189 int islinkm = db_column_int(&q, 3);
1190 /* Copy content from idm over into idv. Overwrite idv. */
1191 fossil_print("UPDATE %s\n", zName);
1192 if( useUndo ) undo_save(zName);
1193 if( !dryRunFlag ){
 
1194 db_multi_exec(
1195 "UPDATE vfile SET mtime=0, mrid=%d, chnged=%d, islink=%d,"
1196 " mhash=CASE WHEN rid<>%d"
1197 " THEN (SELECT uuid FROM blob WHERE blob.rid=%d) END"
1198 " WHERE id=%d", ridm, integrateFlag?4:2, islinkm, ridm, ridm, idv
@@ -1265,11 +1269,11 @@
1269 }else{
1270 i64 sz;
1271 const char *zErrMsg = 0;
1272 int nc = 0;
1273
1274 if( useUndo ) undo_save(zName);
1275 zFullPath = mprintf("%s/%s", g.zLocalRoot, zName);
1276 sz = file_size(zFullPath, ExtFILE);
1277 content_get(ridp, &p);
1278 content_get(ridm, &m);
1279 if( isBinary ){
@@ -1352,11 +1356,11 @@
1356 zErrMsg = "local edits lost";
1357 zFullPath = mprintf("%s/%s", g.zLocalRoot, zName);
1358 sz = file_size(zFullPath, ExtFILE);
1359 fossil_free(zFullPath);
1360 }
1361 if( useUndo ) undo_save(zName);
1362 db_multi_exec(
1363 "UPDATE vfile SET deleted=1 WHERE id=%d", idv
1364 );
1365 if( !dryRunFlag ){
1366 char *zFullPath = mprintf("%s%s", g.zLocalRoot, zName);
@@ -1399,12 +1403,12 @@
1403 int idv = db_column_int(&q, 0);
1404 const char *zOldName = db_column_text(&q, 1);
1405 const char *zNewName = db_column_text(&q, 2);
1406 int isExe = db_column_int(&q, 3);
1407 fossil_print("RENAME %s -> %s\n", zOldName, zNewName);
1408 if( useUndo ) undo_save(zOldName);
1409 if( useUndo ) undo_save(zNewName);
1410 db_multi_exec(
1411 "UPDATE mergestat SET fnr=fnm WHERE fnp=%Q",
1412 zOldName
1413 );
1414 db_multi_exec(
@@ -1498,12 +1502,12 @@
1502 "VALUES('ADDED',%Q,%d,%Q)",
1503 /* fnm */ zName,
1504 /* ridm */ db_column_int(&q,2),
1505 /* fnr */ zName
1506 );
1507 if( useUndo ) undo_save(zName);
1508 if( !dryRunFlag ){
 
1509 vfile_to_disk(0, idm, 0, 0);
1510 }
1511 }
1512 db_finalize(&q);
1513
@@ -1558,9 +1562,9 @@
1562 }
1563 if( bMultiMerge && nConflict==0 ){
1564 nMerge++;
1565 goto merge_next_child;
1566 }
1567 if( useUndo ) undo_finish();
1568
1569 db_end_transaction(dryRunFlag);
1570 }
1571
+42 -3
--- src/patch.c
+++ src/patch.c
@@ -387,11 +387,11 @@
387387
if( unsaved_changes(0) ){
388388
if( (mFlags & PATCH_FORCE)==0 ){
389389
fossil_fatal("Cannot apply patch: there are unsaved changes "
390390
"in the current check-out");
391391
}else{
392
- blob_appendf(&cmd, "%$ revert", g.nameOfExe);
392
+ blob_appendf(&cmd, "%$ revert --noundo", g.nameOfExe);
393393
if( mFlags & PATCH_DRYRUN ){
394394
fossil_print("%s\n", blob_str(&cmd));
395395
}else{
396396
int rc = fossil_system(blob_str(&cmd));
397397
if( rc ){
@@ -429,23 +429,27 @@
429429
}
430430
}
431431
}
432432
blob_reset(&cmd);
433433
if( db_table_exists("patch","patchmerge") ){
434
+ int nMerge = 0;
434435
db_prepare(&q,
435436
"SELECT type, mhash, upper(type) FROM patch.patchmerge"
436437
" WHERE type IN ('merge','cherrypick','backout','integrate')"
437438
" AND mhash NOT GLOB '*[^a-fA-F0-9]*';"
438439
);
439440
while( db_step(&q)==SQLITE_ROW ){
440441
const char *zType = db_column_text(&q,0);
441442
blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
442443
if( strcmp(zType,"merge")==0 ){
443
- blob_appendf(&cmd, " merge %s\n", db_column_text(&q,1));
444
+ blob_appendf(&cmd, " merge --noundo --nosync %s\n",
445
+ db_column_text(&q,1));
444446
}else{
445
- blob_appendf(&cmd, " merge --%s %s\n", zType, db_column_text(&q,1));
447
+ blob_appendf(&cmd, " merge --%s --noundo --nosync %s\n",
448
+ zType, db_column_text(&q,1));
446449
}
450
+ nMerge++;
447451
if( mFlags & PATCH_VERBOSE ){
448452
fossil_print("%-10s %s\n", db_column_text(&q,2),
449453
db_column_text(&q,0));
450454
}
451455
}
@@ -458,10 +462,45 @@
458462
fossil_fatal("unable to do merges:\n%s",
459463
blob_str(&cmd));
460464
}
461465
}
462466
blob_reset(&cmd);
467
+
468
+ /* 2024-12-16 https://fossil-scm.org/home/forumpost/51a37054
469
+ ** If one or more merge operations occurred in the patch and there are
470
+ ** files that are marked as "chnged' in the local VFILE but which
471
+ ** are not mentioned as having been modified in the patch, then
472
+ ** revert those files.
473
+ */
474
+ if( nMerge ){
475
+ int vid = db_lget_int("checkout", 0);
476
+ int nRevert = 0;
477
+ blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
478
+ blob_appendf(&cmd, " revert --noundo ");
479
+ db_prepare(&q,
480
+ "SELECT pathname FROM vfile WHERE vid=%d AND chnged "
481
+ "EXCEPT SELECT pathname FROM chng",
482
+ vid
483
+ );
484
+ while( db_step(&q)==SQLITE_ROW ){
485
+ blob_append_escaped_arg(&cmd, db_column_text(&q,0), 1);
486
+ nRevert++;
487
+ }
488
+ db_finalize(&q);
489
+ if( nRevert ){
490
+ if( mFlags & PATCH_DRYRUN ){
491
+ fossil_print("%s", blob_str(&cmd));
492
+ }else{
493
+ int rc = fossil_unsafe_system(blob_str(&cmd));
494
+ if( rc ){
495
+ fossil_fatal("unable to do reverts:\n%s",
496
+ blob_str(&cmd));
497
+ }
498
+ }
499
+ }
500
+ blob_reset(&cmd);
501
+ }
463502
}
464503
465504
/* Deletions */
466505
db_prepare(&q, "SELECT pathname FROM patch.chng"
467506
" WHERE origname IS NULL AND delta IS NULL");
468507
--- src/patch.c
+++ src/patch.c
@@ -387,11 +387,11 @@
387 if( unsaved_changes(0) ){
388 if( (mFlags & PATCH_FORCE)==0 ){
389 fossil_fatal("Cannot apply patch: there are unsaved changes "
390 "in the current check-out");
391 }else{
392 blob_appendf(&cmd, "%$ revert", g.nameOfExe);
393 if( mFlags & PATCH_DRYRUN ){
394 fossil_print("%s\n", blob_str(&cmd));
395 }else{
396 int rc = fossil_system(blob_str(&cmd));
397 if( rc ){
@@ -429,23 +429,27 @@
429 }
430 }
431 }
432 blob_reset(&cmd);
433 if( db_table_exists("patch","patchmerge") ){
 
434 db_prepare(&q,
435 "SELECT type, mhash, upper(type) FROM patch.patchmerge"
436 " WHERE type IN ('merge','cherrypick','backout','integrate')"
437 " AND mhash NOT GLOB '*[^a-fA-F0-9]*';"
438 );
439 while( db_step(&q)==SQLITE_ROW ){
440 const char *zType = db_column_text(&q,0);
441 blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
442 if( strcmp(zType,"merge")==0 ){
443 blob_appendf(&cmd, " merge %s\n", db_column_text(&q,1));
 
444 }else{
445 blob_appendf(&cmd, " merge --%s %s\n", zType, db_column_text(&q,1));
 
446 }
 
447 if( mFlags & PATCH_VERBOSE ){
448 fossil_print("%-10s %s\n", db_column_text(&q,2),
449 db_column_text(&q,0));
450 }
451 }
@@ -458,10 +462,45 @@
458 fossil_fatal("unable to do merges:\n%s",
459 blob_str(&cmd));
460 }
461 }
462 blob_reset(&cmd);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
463 }
464
465 /* Deletions */
466 db_prepare(&q, "SELECT pathname FROM patch.chng"
467 " WHERE origname IS NULL AND delta IS NULL");
468
--- src/patch.c
+++ src/patch.c
@@ -387,11 +387,11 @@
387 if( unsaved_changes(0) ){
388 if( (mFlags & PATCH_FORCE)==0 ){
389 fossil_fatal("Cannot apply patch: there are unsaved changes "
390 "in the current check-out");
391 }else{
392 blob_appendf(&cmd, "%$ revert --noundo", g.nameOfExe);
393 if( mFlags & PATCH_DRYRUN ){
394 fossil_print("%s\n", blob_str(&cmd));
395 }else{
396 int rc = fossil_system(blob_str(&cmd));
397 if( rc ){
@@ -429,23 +429,27 @@
429 }
430 }
431 }
432 blob_reset(&cmd);
433 if( db_table_exists("patch","patchmerge") ){
434 int nMerge = 0;
435 db_prepare(&q,
436 "SELECT type, mhash, upper(type) FROM patch.patchmerge"
437 " WHERE type IN ('merge','cherrypick','backout','integrate')"
438 " AND mhash NOT GLOB '*[^a-fA-F0-9]*';"
439 );
440 while( db_step(&q)==SQLITE_ROW ){
441 const char *zType = db_column_text(&q,0);
442 blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
443 if( strcmp(zType,"merge")==0 ){
444 blob_appendf(&cmd, " merge --noundo --nosync %s\n",
445 db_column_text(&q,1));
446 }else{
447 blob_appendf(&cmd, " merge --%s --noundo --nosync %s\n",
448 zType, db_column_text(&q,1));
449 }
450 nMerge++;
451 if( mFlags & PATCH_VERBOSE ){
452 fossil_print("%-10s %s\n", db_column_text(&q,2),
453 db_column_text(&q,0));
454 }
455 }
@@ -458,10 +462,45 @@
462 fossil_fatal("unable to do merges:\n%s",
463 blob_str(&cmd));
464 }
465 }
466 blob_reset(&cmd);
467
468 /* 2024-12-16 https://fossil-scm.org/home/forumpost/51a37054
469 ** If one or more merge operations occurred in the patch and there are
470 ** files that are marked as "chnged' in the local VFILE but which
471 ** are not mentioned as having been modified in the patch, then
472 ** revert those files.
473 */
474 if( nMerge ){
475 int vid = db_lget_int("checkout", 0);
476 int nRevert = 0;
477 blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
478 blob_appendf(&cmd, " revert --noundo ");
479 db_prepare(&q,
480 "SELECT pathname FROM vfile WHERE vid=%d AND chnged "
481 "EXCEPT SELECT pathname FROM chng",
482 vid
483 );
484 while( db_step(&q)==SQLITE_ROW ){
485 blob_append_escaped_arg(&cmd, db_column_text(&q,0), 1);
486 nRevert++;
487 }
488 db_finalize(&q);
489 if( nRevert ){
490 if( mFlags & PATCH_DRYRUN ){
491 fossil_print("%s", blob_str(&cmd));
492 }else{
493 int rc = fossil_unsafe_system(blob_str(&cmd));
494 if( rc ){
495 fossil_fatal("unable to do reverts:\n%s",
496 blob_str(&cmd));
497 }
498 }
499 }
500 blob_reset(&cmd);
501 }
502 }
503
504 /* Deletions */
505 db_prepare(&q, "SELECT pathname FROM patch.chng"
506 " WHERE origname IS NULL AND delta IS NULL");
507
+11 -4
--- src/update.c
+++ src/update.c
@@ -854,10 +854,11 @@
854854
**
855855
** If a file is reverted accidentally, it can be restored using
856856
** the "fossil undo" command.
857857
**
858858
** Options:
859
+** --noundo Do not record changes in the undo/redo log.
859860
** -r|--revision VERSION Revert given FILE(s) back to given
860861
** VERSION
861862
**
862863
** See also: [[redo]], [[undo]], [[checkout]], [[update]]
863864
*/
@@ -867,17 +868,19 @@
867868
ManifestFile *pCoFile; /* File within current check-out manifest */
868869
ManifestFile *pRvFile; /* File within revert version manifest */
869870
const char *zFile; /* Filename relative to check-out root */
870871
const char *zRevision; /* Selected revert version, NULL if current */
871872
Blob record = BLOB_INITIALIZER; /* Contents of each reverted file */
873
+ int useUndo = 1; /* True to record changes in UNDO */
872874
int i;
873875
Stmt q;
874876
int revertAll = 0;
875877
int revisionOptNotSupported = 0;
876878
877879
undo_capture_command_line();
878880
zRevision = find_option("revision", "r", 1);
881
+ useUndo = find_option("noundo", 0, 0)==0;
879882
verify_all_options();
880883
881884
if( g.argc<2 ){
882885
usage("?OPTIONS? [FILE] ...");
883886
}
@@ -890,11 +893,15 @@
890893
/* Get manifests of revert version and (if different) current check-out. */
891894
pRvManifest = historical_manifest(zRevision);
892895
pCoManifest = zRevision ? historical_manifest(0) : 0;
893896
894897
db_begin_transaction();
895
- undo_begin();
898
+ if( useUndo ){
899
+ undo_begin();
900
+ }else{
901
+ undo_reset();
902
+ }
896903
db_multi_exec("CREATE TEMP TABLE torevert(name UNIQUE);");
897904
898905
if( g.argc>2 ){
899906
for(i=2; i<g.argc; i++){
900907
Blob fname;
@@ -987,11 +994,11 @@
987994
if( !pRvFile ){
988995
if( db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q OR origname=%Q",
989996
zFile, zFile)==0 ){
990997
fossil_print("UNMANAGE %s\n", zFile);
991998
}else{
992
- undo_save(zFile);
999
+ if( useUndo ) undo_save(zFile);
9931000
file_delete(zFull);
9941001
fossil_print("DELETE %s\n", zFile);
9951002
}
9961003
db_multi_exec(
9971004
"UPDATE OR REPLACE vfile"
@@ -1014,11 +1021,11 @@
10141021
}
10151022
10161023
/* Get contents of reverted-to file. */
10171024
content_get(fast_uuid_to_rid(pRvFile->zUuid), &record);
10181025
1019
- undo_save(zFile);
1026
+ if( useUndo ) undo_save(zFile);
10201027
if( file_size(zFull, RepoFILE)>=0
10211028
&& (rvPerm==PERM_LNK || file_islink(0))
10221029
){
10231030
file_delete(zFull);
10241031
}
@@ -1040,12 +1047,12 @@
10401047
}
10411048
blob_reset(&record);
10421049
free(zFull);
10431050
}
10441051
db_finalize(&q);
1045
- undo_finish();
1052
+ if( useUndo) undo_finish();
10461053
db_end_transaction(0);
10471054
10481055
/* Deallocate parsed manifest structures. */
10491056
manifest_destroy(pRvManifest);
10501057
manifest_destroy(pCoManifest);
10511058
}
10521059
--- src/update.c
+++ src/update.c
@@ -854,10 +854,11 @@
854 **
855 ** If a file is reverted accidentally, it can be restored using
856 ** the "fossil undo" command.
857 **
858 ** Options:
 
859 ** -r|--revision VERSION Revert given FILE(s) back to given
860 ** VERSION
861 **
862 ** See also: [[redo]], [[undo]], [[checkout]], [[update]]
863 */
@@ -867,17 +868,19 @@
867 ManifestFile *pCoFile; /* File within current check-out manifest */
868 ManifestFile *pRvFile; /* File within revert version manifest */
869 const char *zFile; /* Filename relative to check-out root */
870 const char *zRevision; /* Selected revert version, NULL if current */
871 Blob record = BLOB_INITIALIZER; /* Contents of each reverted file */
 
872 int i;
873 Stmt q;
874 int revertAll = 0;
875 int revisionOptNotSupported = 0;
876
877 undo_capture_command_line();
878 zRevision = find_option("revision", "r", 1);
 
879 verify_all_options();
880
881 if( g.argc<2 ){
882 usage("?OPTIONS? [FILE] ...");
883 }
@@ -890,11 +893,15 @@
890 /* Get manifests of revert version and (if different) current check-out. */
891 pRvManifest = historical_manifest(zRevision);
892 pCoManifest = zRevision ? historical_manifest(0) : 0;
893
894 db_begin_transaction();
895 undo_begin();
 
 
 
 
896 db_multi_exec("CREATE TEMP TABLE torevert(name UNIQUE);");
897
898 if( g.argc>2 ){
899 for(i=2; i<g.argc; i++){
900 Blob fname;
@@ -987,11 +994,11 @@
987 if( !pRvFile ){
988 if( db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q OR origname=%Q",
989 zFile, zFile)==0 ){
990 fossil_print("UNMANAGE %s\n", zFile);
991 }else{
992 undo_save(zFile);
993 file_delete(zFull);
994 fossil_print("DELETE %s\n", zFile);
995 }
996 db_multi_exec(
997 "UPDATE OR REPLACE vfile"
@@ -1014,11 +1021,11 @@
1014 }
1015
1016 /* Get contents of reverted-to file. */
1017 content_get(fast_uuid_to_rid(pRvFile->zUuid), &record);
1018
1019 undo_save(zFile);
1020 if( file_size(zFull, RepoFILE)>=0
1021 && (rvPerm==PERM_LNK || file_islink(0))
1022 ){
1023 file_delete(zFull);
1024 }
@@ -1040,12 +1047,12 @@
1040 }
1041 blob_reset(&record);
1042 free(zFull);
1043 }
1044 db_finalize(&q);
1045 undo_finish();
1046 db_end_transaction(0);
1047
1048 /* Deallocate parsed manifest structures. */
1049 manifest_destroy(pRvManifest);
1050 manifest_destroy(pCoManifest);
1051 }
1052
--- src/update.c
+++ src/update.c
@@ -854,10 +854,11 @@
854 **
855 ** If a file is reverted accidentally, it can be restored using
856 ** the "fossil undo" command.
857 **
858 ** Options:
859 ** --noundo Do not record changes in the undo/redo log.
860 ** -r|--revision VERSION Revert given FILE(s) back to given
861 ** VERSION
862 **
863 ** See also: [[redo]], [[undo]], [[checkout]], [[update]]
864 */
@@ -867,17 +868,19 @@
868 ManifestFile *pCoFile; /* File within current check-out manifest */
869 ManifestFile *pRvFile; /* File within revert version manifest */
870 const char *zFile; /* Filename relative to check-out root */
871 const char *zRevision; /* Selected revert version, NULL if current */
872 Blob record = BLOB_INITIALIZER; /* Contents of each reverted file */
873 int useUndo = 1; /* True to record changes in UNDO */
874 int i;
875 Stmt q;
876 int revertAll = 0;
877 int revisionOptNotSupported = 0;
878
879 undo_capture_command_line();
880 zRevision = find_option("revision", "r", 1);
881 useUndo = find_option("noundo", 0, 0)==0;
882 verify_all_options();
883
884 if( g.argc<2 ){
885 usage("?OPTIONS? [FILE] ...");
886 }
@@ -890,11 +893,15 @@
893 /* Get manifests of revert version and (if different) current check-out. */
894 pRvManifest = historical_manifest(zRevision);
895 pCoManifest = zRevision ? historical_manifest(0) : 0;
896
897 db_begin_transaction();
898 if( useUndo ){
899 undo_begin();
900 }else{
901 undo_reset();
902 }
903 db_multi_exec("CREATE TEMP TABLE torevert(name UNIQUE);");
904
905 if( g.argc>2 ){
906 for(i=2; i<g.argc; i++){
907 Blob fname;
@@ -987,11 +994,11 @@
994 if( !pRvFile ){
995 if( db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q OR origname=%Q",
996 zFile, zFile)==0 ){
997 fossil_print("UNMANAGE %s\n", zFile);
998 }else{
999 if( useUndo ) undo_save(zFile);
1000 file_delete(zFull);
1001 fossil_print("DELETE %s\n", zFile);
1002 }
1003 db_multi_exec(
1004 "UPDATE OR REPLACE vfile"
@@ -1014,11 +1021,11 @@
1021 }
1022
1023 /* Get contents of reverted-to file. */
1024 content_get(fast_uuid_to_rid(pRvFile->zUuid), &record);
1025
1026 if( useUndo ) undo_save(zFile);
1027 if( file_size(zFull, RepoFILE)>=0
1028 && (rvPerm==PERM_LNK || file_islink(0))
1029 ){
1030 file_delete(zFull);
1031 }
@@ -1040,12 +1047,12 @@
1047 }
1048 blob_reset(&record);
1049 free(zFull);
1050 }
1051 db_finalize(&q);
1052 if( useUndo) undo_finish();
1053 db_end_transaction(0);
1054
1055 /* Deallocate parsed manifest structures. */
1056 manifest_destroy(pRvManifest);
1057 manifest_destroy(pCoManifest);
1058 }
1059

Keyboard Shortcuts

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