Fossil SCM
Implement the --keep-merge-files option for the merge and update commands. Merge-conflict files are omitted without this option. The merge conflict files continue to exist for the stash command.
Commit
d20ead10c34909d4ef289a347baabd2be0a8fe221a522dcbc4a0ed931013c63c
Parent
14c81d9d2b259d3…
5 files changed
+8
+16
-8
+1
-1
+7
+4
+8
| --- src/merge.c | ||
| +++ src/merge.c | ||
| @@ -224,10 +224,14 @@ | ||
| 224 | 224 | ** -f|--force Force the merge even if it would be a no-op. |
| 225 | 225 | ** |
| 226 | 226 | ** --force-missing Force the merge even if there is missing content. |
| 227 | 227 | ** |
| 228 | 228 | ** --integrate Merged branch will be closed when committing. |
| 229 | +** | |
| 230 | +** -K|--keep-merge-files On merge conflict, retain the temporary files | |
| 231 | +** used for merging, named *-baseline, *-original, | |
| 232 | +** and *-merge. | |
| 229 | 233 | ** |
| 230 | 234 | ** -n|--dry-run If given, display instead of run actions |
| 231 | 235 | ** |
| 232 | 236 | ** -v|--verbose Show additional details of the merge |
| 233 | 237 | */ |
| @@ -244,10 +248,11 @@ | ||
| 244 | 248 | int forceFlag; /* True if the --force or -f option is present */ |
| 245 | 249 | int forceMissingFlag; /* True if the --force-missing option is present */ |
| 246 | 250 | const char *zBinGlob; /* The value of --binary */ |
| 247 | 251 | const char *zPivot; /* The value of --baseline */ |
| 248 | 252 | int debugFlag; /* True if --debug is present */ |
| 253 | + int keepMergeFlag; /* True if --keep-merge-files is present */ | |
| 249 | 254 | int nConflict = 0; /* Number of conflicts seen */ |
| 250 | 255 | int nOverwrite = 0; /* Number of unmanaged files overwritten */ |
| 251 | 256 | char vAncestor = 'p'; /* If P is an ancestor of V then 'p', else 'n' */ |
| 252 | 257 | Stmt q; |
| 253 | 258 | |
| @@ -275,10 +280,12 @@ | ||
| 275 | 280 | if( !dryRunFlag ){ |
| 276 | 281 | dryRunFlag = find_option("nochange",0,0)!=0; /* deprecated */ |
| 277 | 282 | } |
| 278 | 283 | forceFlag = find_option("force","f",0)!=0; |
| 279 | 284 | zPivot = find_option("baseline",0,1); |
| 285 | + keepMergeFlag = find_option("keep-merge-files", "K",0)!=0; | |
| 286 | + | |
| 280 | 287 | verify_all_options(); |
| 281 | 288 | db_must_be_within_tree(); |
| 282 | 289 | if( zBinGlob==0 ) zBinGlob = db_get("binary-glob",0); |
| 283 | 290 | vid = db_lget_int("checkout", 0); |
| 284 | 291 | if( vid==0 ){ |
| @@ -665,10 +672,11 @@ | ||
| 665 | 672 | if( isBinary ){ |
| 666 | 673 | rc = -1; |
| 667 | 674 | blob_zero(&r); |
| 668 | 675 | }else{ |
| 669 | 676 | unsigned mergeFlags = dryRunFlag ? MERGE_DRYRUN : 0; |
| 677 | + if(keepMergeFlag!=0) mergeFlags |= MERGE_KEEP_FILES; | |
| 670 | 678 | rc = merge_3way(&p, zFullPath, &m, &r, mergeFlags); |
| 671 | 679 | } |
| 672 | 680 | if( rc>=0 ){ |
| 673 | 681 | if( !dryRunFlag ){ |
| 674 | 682 | blob_write_to_file(&r, zFullPath); |
| 675 | 683 |
| --- src/merge.c | |
| +++ src/merge.c | |
| @@ -224,10 +224,14 @@ | |
| 224 | ** -f|--force Force the merge even if it would be a no-op. |
| 225 | ** |
| 226 | ** --force-missing Force the merge even if there is missing content. |
| 227 | ** |
| 228 | ** --integrate Merged branch will be closed when committing. |
| 229 | ** |
| 230 | ** -n|--dry-run If given, display instead of run actions |
| 231 | ** |
| 232 | ** -v|--verbose Show additional details of the merge |
| 233 | */ |
| @@ -244,10 +248,11 @@ | |
| 244 | int forceFlag; /* True if the --force or -f option is present */ |
| 245 | int forceMissingFlag; /* True if the --force-missing option is present */ |
| 246 | const char *zBinGlob; /* The value of --binary */ |
| 247 | const char *zPivot; /* The value of --baseline */ |
| 248 | int debugFlag; /* True if --debug is present */ |
| 249 | int nConflict = 0; /* Number of conflicts seen */ |
| 250 | int nOverwrite = 0; /* Number of unmanaged files overwritten */ |
| 251 | char vAncestor = 'p'; /* If P is an ancestor of V then 'p', else 'n' */ |
| 252 | Stmt q; |
| 253 | |
| @@ -275,10 +280,12 @@ | |
| 275 | if( !dryRunFlag ){ |
| 276 | dryRunFlag = find_option("nochange",0,0)!=0; /* deprecated */ |
| 277 | } |
| 278 | forceFlag = find_option("force","f",0)!=0; |
| 279 | zPivot = find_option("baseline",0,1); |
| 280 | verify_all_options(); |
| 281 | db_must_be_within_tree(); |
| 282 | if( zBinGlob==0 ) zBinGlob = db_get("binary-glob",0); |
| 283 | vid = db_lget_int("checkout", 0); |
| 284 | if( vid==0 ){ |
| @@ -665,10 +672,11 @@ | |
| 665 | if( isBinary ){ |
| 666 | rc = -1; |
| 667 | blob_zero(&r); |
| 668 | }else{ |
| 669 | unsigned mergeFlags = dryRunFlag ? MERGE_DRYRUN : 0; |
| 670 | rc = merge_3way(&p, zFullPath, &m, &r, mergeFlags); |
| 671 | } |
| 672 | if( rc>=0 ){ |
| 673 | if( !dryRunFlag ){ |
| 674 | blob_write_to_file(&r, zFullPath); |
| 675 |
| --- src/merge.c | |
| +++ src/merge.c | |
| @@ -224,10 +224,14 @@ | |
| 224 | ** -f|--force Force the merge even if it would be a no-op. |
| 225 | ** |
| 226 | ** --force-missing Force the merge even if there is missing content. |
| 227 | ** |
| 228 | ** --integrate Merged branch will be closed when committing. |
| 229 | ** |
| 230 | ** -K|--keep-merge-files On merge conflict, retain the temporary files |
| 231 | ** used for merging, named *-baseline, *-original, |
| 232 | ** and *-merge. |
| 233 | ** |
| 234 | ** -n|--dry-run If given, display instead of run actions |
| 235 | ** |
| 236 | ** -v|--verbose Show additional details of the merge |
| 237 | */ |
| @@ -244,10 +248,11 @@ | |
| 248 | int forceFlag; /* True if the --force or -f option is present */ |
| 249 | int forceMissingFlag; /* True if the --force-missing option is present */ |
| 250 | const char *zBinGlob; /* The value of --binary */ |
| 251 | const char *zPivot; /* The value of --baseline */ |
| 252 | int debugFlag; /* True if --debug is present */ |
| 253 | int keepMergeFlag; /* True if --keep-merge-files is present */ |
| 254 | int nConflict = 0; /* Number of conflicts seen */ |
| 255 | int nOverwrite = 0; /* Number of unmanaged files overwritten */ |
| 256 | char vAncestor = 'p'; /* If P is an ancestor of V then 'p', else 'n' */ |
| 257 | Stmt q; |
| 258 | |
| @@ -275,10 +280,12 @@ | |
| 280 | if( !dryRunFlag ){ |
| 281 | dryRunFlag = find_option("nochange",0,0)!=0; /* deprecated */ |
| 282 | } |
| 283 | forceFlag = find_option("force","f",0)!=0; |
| 284 | zPivot = find_option("baseline",0,1); |
| 285 | keepMergeFlag = find_option("keep-merge-files", "K",0)!=0; |
| 286 | |
| 287 | verify_all_options(); |
| 288 | db_must_be_within_tree(); |
| 289 | if( zBinGlob==0 ) zBinGlob = db_get("binary-glob",0); |
| 290 | vid = db_lget_int("checkout", 0); |
| 291 | if( vid==0 ){ |
| @@ -665,10 +672,11 @@ | |
| 672 | if( isBinary ){ |
| 673 | rc = -1; |
| 674 | blob_zero(&r); |
| 675 | }else{ |
| 676 | unsigned mergeFlags = dryRunFlag ? MERGE_DRYRUN : 0; |
| 677 | if(keepMergeFlag!=0) mergeFlags |= MERGE_KEEP_FILES; |
| 678 | rc = merge_3way(&p, zFullPath, &m, &r, mergeFlags); |
| 679 | } |
| 680 | if( rc>=0 ){ |
| 681 | if( !dryRunFlag ){ |
| 682 | blob_write_to_file(&r, zFullPath); |
| 683 |
+16
-8
| --- src/merge3.c | ||
| +++ src/merge3.c | ||
| @@ -436,10 +436,16 @@ | ||
| 436 | 436 | #if INTERFACE |
| 437 | 437 | /* |
| 438 | 438 | ** Flags to the 3-way merger |
| 439 | 439 | */ |
| 440 | 440 | #define MERGE_DRYRUN 0x0001 |
| 441 | +/* | |
| 442 | +** The MERGE_KEEP_FILES flag specifies that merge_3way() should retain | |
| 443 | +** its temporary files on error. By default they are removed after the | |
| 444 | +** merge, regardless of success or failure. | |
| 445 | +*/ | |
| 446 | +#define MERGE_KEEP_FILES 0x0002 | |
| 441 | 447 | #endif |
| 442 | 448 | |
| 443 | 449 | |
| 444 | 450 | /* |
| 445 | 451 | ** This routine is a wrapper around blob_merge() with the following |
| @@ -465,14 +471,18 @@ | ||
| 465 | 471 | Blob *pOut, /* Output written here */ |
| 466 | 472 | unsigned mergeFlags /* Flags that control operation */ |
| 467 | 473 | ){ |
| 468 | 474 | Blob v1; /* Content of zV1 */ |
| 469 | 475 | int rc; /* Return code of subroutines and this routine */ |
| 476 | + const char *zGMerge; /* Name of the gmerge command */ | |
| 470 | 477 | |
| 471 | 478 | blob_read_from_file(&v1, zV1, ExtFILE); |
| 472 | 479 | rc = blob_merge(pPivot, &v1, pV2, pOut); |
| 473 | - if( rc!=0 && (mergeFlags & MERGE_DRYRUN)==0 ){ | |
| 480 | + zGMerge = rc<=0 ? 0 : db_get("gmerge-command", 0); | |
| 481 | + if( (mergeFlags & MERGE_DRYRUN)==0 | |
| 482 | + && ((zGMerge!=0 && zGMerge[0]!=0) | |
| 483 | + || (rc!=0 && (mergeFlags & MERGE_KEEP_FILES)!=0)) ){ | |
| 474 | 484 | char *zPivot; /* Name of the pivot file */ |
| 475 | 485 | char *zOrig; /* Name of the original content file */ |
| 476 | 486 | char *zOther; /* Name of the merge file */ |
| 477 | 487 | |
| 478 | 488 | zPivot = file_newname(zV1, "baseline", 1); |
| @@ -480,18 +490,14 @@ | ||
| 480 | 490 | zOrig = file_newname(zV1, "original", 1); |
| 481 | 491 | blob_write_to_file(&v1, zOrig); |
| 482 | 492 | zOther = file_newname(zV1, "merge", 1); |
| 483 | 493 | blob_write_to_file(pV2, zOther); |
| 484 | 494 | if( rc>0 ){ |
| 485 | - const char *zGMerge; /* Name of the gmerge command */ | |
| 486 | - | |
| 487 | - zGMerge = db_get("gmerge-command", 0); | |
| 488 | 495 | if( zGMerge && zGMerge[0] ){ |
| 489 | 496 | char *zOut; /* Temporary output file */ |
| 490 | 497 | char *zCmd; /* Command to invoke */ |
| 491 | 498 | const char *azSubst[8]; /* Strings to be substituted */ |
| 492 | - | |
| 493 | 499 | zOut = file_newname(zV1, "output", 1); |
| 494 | 500 | azSubst[0] = "%baseline"; azSubst[1] = zPivot; |
| 495 | 501 | azSubst[2] = "%original"; azSubst[3] = zOrig; |
| 496 | 502 | azSubst[4] = "%merge"; azSubst[5] = zOther; |
| 497 | 503 | azSubst[6] = "%output"; azSubst[7] = zOut; |
| @@ -498,21 +504,23 @@ | ||
| 498 | 504 | zCmd = string_subst(zGMerge, 8, azSubst); |
| 499 | 505 | printf("%s\n", zCmd); fflush(stdout); |
| 500 | 506 | fossil_system(zCmd); |
| 501 | 507 | if( file_size(zOut, RepoFILE)>=0 ){ |
| 502 | 508 | blob_read_from_file(pOut, zOut, ExtFILE); |
| 503 | - file_delete(zPivot); | |
| 504 | - file_delete(zOrig); | |
| 505 | - file_delete(zOther); | |
| 506 | 509 | file_delete(zOut); |
| 507 | 510 | } |
| 508 | 511 | fossil_free(zCmd); |
| 509 | 512 | fossil_free(zOut); |
| 510 | 513 | } |
| 514 | + } | |
| 515 | + if( (mergeFlags & MERGE_KEEP_FILES)==0 ){ | |
| 516 | + file_delete(zPivot); | |
| 517 | + file_delete(zOrig); | |
| 518 | + file_delete(zOther); | |
| 511 | 519 | } |
| 512 | 520 | fossil_free(zPivot); |
| 513 | 521 | fossil_free(zOrig); |
| 514 | 522 | fossil_free(zOther); |
| 515 | 523 | } |
| 516 | 524 | blob_reset(&v1); |
| 517 | 525 | return rc; |
| 518 | 526 | } |
| 519 | 527 |
| --- src/merge3.c | |
| +++ src/merge3.c | |
| @@ -436,10 +436,16 @@ | |
| 436 | #if INTERFACE |
| 437 | /* |
| 438 | ** Flags to the 3-way merger |
| 439 | */ |
| 440 | #define MERGE_DRYRUN 0x0001 |
| 441 | #endif |
| 442 | |
| 443 | |
| 444 | /* |
| 445 | ** This routine is a wrapper around blob_merge() with the following |
| @@ -465,14 +471,18 @@ | |
| 465 | Blob *pOut, /* Output written here */ |
| 466 | unsigned mergeFlags /* Flags that control operation */ |
| 467 | ){ |
| 468 | Blob v1; /* Content of zV1 */ |
| 469 | int rc; /* Return code of subroutines and this routine */ |
| 470 | |
| 471 | blob_read_from_file(&v1, zV1, ExtFILE); |
| 472 | rc = blob_merge(pPivot, &v1, pV2, pOut); |
| 473 | if( rc!=0 && (mergeFlags & MERGE_DRYRUN)==0 ){ |
| 474 | char *zPivot; /* Name of the pivot file */ |
| 475 | char *zOrig; /* Name of the original content file */ |
| 476 | char *zOther; /* Name of the merge file */ |
| 477 | |
| 478 | zPivot = file_newname(zV1, "baseline", 1); |
| @@ -480,18 +490,14 @@ | |
| 480 | zOrig = file_newname(zV1, "original", 1); |
| 481 | blob_write_to_file(&v1, zOrig); |
| 482 | zOther = file_newname(zV1, "merge", 1); |
| 483 | blob_write_to_file(pV2, zOther); |
| 484 | if( rc>0 ){ |
| 485 | const char *zGMerge; /* Name of the gmerge command */ |
| 486 | |
| 487 | zGMerge = db_get("gmerge-command", 0); |
| 488 | if( zGMerge && zGMerge[0] ){ |
| 489 | char *zOut; /* Temporary output file */ |
| 490 | char *zCmd; /* Command to invoke */ |
| 491 | const char *azSubst[8]; /* Strings to be substituted */ |
| 492 | |
| 493 | zOut = file_newname(zV1, "output", 1); |
| 494 | azSubst[0] = "%baseline"; azSubst[1] = zPivot; |
| 495 | azSubst[2] = "%original"; azSubst[3] = zOrig; |
| 496 | azSubst[4] = "%merge"; azSubst[5] = zOther; |
| 497 | azSubst[6] = "%output"; azSubst[7] = zOut; |
| @@ -498,21 +504,23 @@ | |
| 498 | zCmd = string_subst(zGMerge, 8, azSubst); |
| 499 | printf("%s\n", zCmd); fflush(stdout); |
| 500 | fossil_system(zCmd); |
| 501 | if( file_size(zOut, RepoFILE)>=0 ){ |
| 502 | blob_read_from_file(pOut, zOut, ExtFILE); |
| 503 | file_delete(zPivot); |
| 504 | file_delete(zOrig); |
| 505 | file_delete(zOther); |
| 506 | file_delete(zOut); |
| 507 | } |
| 508 | fossil_free(zCmd); |
| 509 | fossil_free(zOut); |
| 510 | } |
| 511 | } |
| 512 | fossil_free(zPivot); |
| 513 | fossil_free(zOrig); |
| 514 | fossil_free(zOther); |
| 515 | } |
| 516 | blob_reset(&v1); |
| 517 | return rc; |
| 518 | } |
| 519 |
| --- src/merge3.c | |
| +++ src/merge3.c | |
| @@ -436,10 +436,16 @@ | |
| 436 | #if INTERFACE |
| 437 | /* |
| 438 | ** Flags to the 3-way merger |
| 439 | */ |
| 440 | #define MERGE_DRYRUN 0x0001 |
| 441 | /* |
| 442 | ** The MERGE_KEEP_FILES flag specifies that merge_3way() should retain |
| 443 | ** its temporary files on error. By default they are removed after the |
| 444 | ** merge, regardless of success or failure. |
| 445 | */ |
| 446 | #define MERGE_KEEP_FILES 0x0002 |
| 447 | #endif |
| 448 | |
| 449 | |
| 450 | /* |
| 451 | ** This routine is a wrapper around blob_merge() with the following |
| @@ -465,14 +471,18 @@ | |
| 471 | Blob *pOut, /* Output written here */ |
| 472 | unsigned mergeFlags /* Flags that control operation */ |
| 473 | ){ |
| 474 | Blob v1; /* Content of zV1 */ |
| 475 | int rc; /* Return code of subroutines and this routine */ |
| 476 | const char *zGMerge; /* Name of the gmerge command */ |
| 477 | |
| 478 | blob_read_from_file(&v1, zV1, ExtFILE); |
| 479 | rc = blob_merge(pPivot, &v1, pV2, pOut); |
| 480 | zGMerge = rc<=0 ? 0 : db_get("gmerge-command", 0); |
| 481 | if( (mergeFlags & MERGE_DRYRUN)==0 |
| 482 | && ((zGMerge!=0 && zGMerge[0]!=0) |
| 483 | || (rc!=0 && (mergeFlags & MERGE_KEEP_FILES)!=0)) ){ |
| 484 | char *zPivot; /* Name of the pivot file */ |
| 485 | char *zOrig; /* Name of the original content file */ |
| 486 | char *zOther; /* Name of the merge file */ |
| 487 | |
| 488 | zPivot = file_newname(zV1, "baseline", 1); |
| @@ -480,18 +490,14 @@ | |
| 490 | zOrig = file_newname(zV1, "original", 1); |
| 491 | blob_write_to_file(&v1, zOrig); |
| 492 | zOther = file_newname(zV1, "merge", 1); |
| 493 | blob_write_to_file(pV2, zOther); |
| 494 | if( rc>0 ){ |
| 495 | if( zGMerge && zGMerge[0] ){ |
| 496 | char *zOut; /* Temporary output file */ |
| 497 | char *zCmd; /* Command to invoke */ |
| 498 | const char *azSubst[8]; /* Strings to be substituted */ |
| 499 | zOut = file_newname(zV1, "output", 1); |
| 500 | azSubst[0] = "%baseline"; azSubst[1] = zPivot; |
| 501 | azSubst[2] = "%original"; azSubst[3] = zOrig; |
| 502 | azSubst[4] = "%merge"; azSubst[5] = zOther; |
| 503 | azSubst[6] = "%output"; azSubst[7] = zOut; |
| @@ -498,21 +504,23 @@ | |
| 504 | zCmd = string_subst(zGMerge, 8, azSubst); |
| 505 | printf("%s\n", zCmd); fflush(stdout); |
| 506 | fossil_system(zCmd); |
| 507 | if( file_size(zOut, RepoFILE)>=0 ){ |
| 508 | blob_read_from_file(pOut, zOut, ExtFILE); |
| 509 | file_delete(zOut); |
| 510 | } |
| 511 | fossil_free(zCmd); |
| 512 | fossil_free(zOut); |
| 513 | } |
| 514 | } |
| 515 | if( (mergeFlags & MERGE_KEEP_FILES)==0 ){ |
| 516 | file_delete(zPivot); |
| 517 | file_delete(zOrig); |
| 518 | file_delete(zOther); |
| 519 | } |
| 520 | fossil_free(zPivot); |
| 521 | fossil_free(zOrig); |
| 522 | fossil_free(zOther); |
| 523 | } |
| 524 | blob_reset(&v1); |
| 525 | return rc; |
| 526 | } |
| 527 |
+1
-1
| --- src/stash.c | ||
| +++ src/stash.c | ||
| @@ -359,11 +359,11 @@ | ||
| 359 | 359 | if( isLink || isNewLink ){ |
| 360 | 360 | rc = -1; |
| 361 | 361 | blob_zero(&b); /* because we reset it later */ |
| 362 | 362 | fossil_print("***** Cannot merge symlink %s\n", zNew); |
| 363 | 363 | }else{ |
| 364 | - rc = merge_3way(&a, zOPath, &b, &out, 0); | |
| 364 | + rc = merge_3way(&a, zOPath, &b, &out, MERGE_KEEP_FILES); | |
| 365 | 365 | blob_write_to_file(&out, zNPath); |
| 366 | 366 | blob_reset(&out); |
| 367 | 367 | file_setexe(zNPath, isExec); |
| 368 | 368 | } |
| 369 | 369 | if( rc ){ |
| 370 | 370 |
| --- src/stash.c | |
| +++ src/stash.c | |
| @@ -359,11 +359,11 @@ | |
| 359 | if( isLink || isNewLink ){ |
| 360 | rc = -1; |
| 361 | blob_zero(&b); /* because we reset it later */ |
| 362 | fossil_print("***** Cannot merge symlink %s\n", zNew); |
| 363 | }else{ |
| 364 | rc = merge_3way(&a, zOPath, &b, &out, 0); |
| 365 | blob_write_to_file(&out, zNPath); |
| 366 | blob_reset(&out); |
| 367 | file_setexe(zNPath, isExec); |
| 368 | } |
| 369 | if( rc ){ |
| 370 |
| --- src/stash.c | |
| +++ src/stash.c | |
| @@ -359,11 +359,11 @@ | |
| 359 | if( isLink || isNewLink ){ |
| 360 | rc = -1; |
| 361 | blob_zero(&b); /* because we reset it later */ |
| 362 | fossil_print("***** Cannot merge symlink %s\n", zNew); |
| 363 | }else{ |
| 364 | rc = merge_3way(&a, zOPath, &b, &out, MERGE_KEEP_FILES); |
| 365 | blob_write_to_file(&out, zNPath); |
| 366 | blob_reset(&out); |
| 367 | file_setexe(zNPath, isExec); |
| 368 | } |
| 369 | if( rc ){ |
| 370 |
+7
| --- src/update.c | ||
| +++ src/update.c | ||
| @@ -103,10 +103,14 @@ | ||
| 103 | 103 | ** or 0 (= no limit, resulting in a single line per entry). |
| 104 | 104 | ** --setmtime Set timestamps of all files to match their SCM-side |
| 105 | 105 | ** times (the timestamp of the last checkin which modified |
| 106 | 106 | ** them). |
| 107 | 107 | ** |
| 108 | +** -K|--keep-merge-files On merge conflict, retain the temporary files | |
| 109 | +** used for merging, named *-baseline, *-original, | |
| 110 | +** and *-merge. | |
| 111 | +** | |
| 108 | 112 | ** See also: revert |
| 109 | 113 | */ |
| 110 | 114 | void update_cmd(void){ |
| 111 | 115 | int vid; /* Current version */ |
| 112 | 116 | int tid=0; /* Target version - version we are changing to */ |
| @@ -115,10 +119,11 @@ | ||
| 115 | 119 | int dryRunFlag; /* -n or --dry-run. Do a dry run */ |
| 116 | 120 | int verboseFlag; /* -v or --verbose. Output extra information */ |
| 117 | 121 | int forceMissingFlag; /* --force-missing. Continue if missing content */ |
| 118 | 122 | int debugFlag; /* --debug option */ |
| 119 | 123 | int setmtimeFlag; /* --setmtime. Set mtimes on files */ |
| 124 | + int keepMergeFlag; /* True if --keep-merge-files is present */ | |
| 120 | 125 | int nChng; /* Number of file renames */ |
| 121 | 126 | int *aChng; /* Array of file renames */ |
| 122 | 127 | int i; /* Loop counter */ |
| 123 | 128 | int nConflict = 0; /* Number of merge conflicts */ |
| 124 | 129 | int nOverwrite = 0; /* Number of unmanaged files overwritten */ |
| @@ -147,10 +152,11 @@ | ||
| 147 | 152 | } |
| 148 | 153 | verboseFlag = find_option("verbose","v",0)!=0; |
| 149 | 154 | forceMissingFlag = find_option("force-missing",0,0)!=0; |
| 150 | 155 | debugFlag = find_option("debug",0,0)!=0; |
| 151 | 156 | setmtimeFlag = find_option("setmtime",0,0)!=0; |
| 157 | + keepMergeFlag = find_option("keep-merge-files", "K",0)!=0; | |
| 152 | 158 | |
| 153 | 159 | /* We should be done with options.. */ |
| 154 | 160 | verify_all_options(); |
| 155 | 161 | |
| 156 | 162 | db_must_be_within_tree(); |
| @@ -490,10 +496,11 @@ | ||
| 490 | 496 | if( islinkv || islinkt ){ |
| 491 | 497 | fossil_print("***** Cannot merge symlink %s\n", zNewName); |
| 492 | 498 | nConflict++; |
| 493 | 499 | }else{ |
| 494 | 500 | unsigned mergeFlags = dryRunFlag ? MERGE_DRYRUN : 0; |
| 501 | + if(keepMergeFlag!=0) mergeFlags |= MERGE_KEEP_FILES; | |
| 495 | 502 | if( !dryRunFlag && !internalUpdate ) undo_save(zName); |
| 496 | 503 | content_get(ridt, &t); |
| 497 | 504 | content_get(ridv, &v); |
| 498 | 505 | rc = merge_3way(&v, zFullPath, &t, &r, mergeFlags); |
| 499 | 506 | if( rc>=0 ){ |
| 500 | 507 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -103,10 +103,14 @@ | |
| 103 | ** or 0 (= no limit, resulting in a single line per entry). |
| 104 | ** --setmtime Set timestamps of all files to match their SCM-side |
| 105 | ** times (the timestamp of the last checkin which modified |
| 106 | ** them). |
| 107 | ** |
| 108 | ** See also: revert |
| 109 | */ |
| 110 | void update_cmd(void){ |
| 111 | int vid; /* Current version */ |
| 112 | int tid=0; /* Target version - version we are changing to */ |
| @@ -115,10 +119,11 @@ | |
| 115 | int dryRunFlag; /* -n or --dry-run. Do a dry run */ |
| 116 | int verboseFlag; /* -v or --verbose. Output extra information */ |
| 117 | int forceMissingFlag; /* --force-missing. Continue if missing content */ |
| 118 | int debugFlag; /* --debug option */ |
| 119 | int setmtimeFlag; /* --setmtime. Set mtimes on files */ |
| 120 | int nChng; /* Number of file renames */ |
| 121 | int *aChng; /* Array of file renames */ |
| 122 | int i; /* Loop counter */ |
| 123 | int nConflict = 0; /* Number of merge conflicts */ |
| 124 | int nOverwrite = 0; /* Number of unmanaged files overwritten */ |
| @@ -147,10 +152,11 @@ | |
| 147 | } |
| 148 | verboseFlag = find_option("verbose","v",0)!=0; |
| 149 | forceMissingFlag = find_option("force-missing",0,0)!=0; |
| 150 | debugFlag = find_option("debug",0,0)!=0; |
| 151 | setmtimeFlag = find_option("setmtime",0,0)!=0; |
| 152 | |
| 153 | /* We should be done with options.. */ |
| 154 | verify_all_options(); |
| 155 | |
| 156 | db_must_be_within_tree(); |
| @@ -490,10 +496,11 @@ | |
| 490 | if( islinkv || islinkt ){ |
| 491 | fossil_print("***** Cannot merge symlink %s\n", zNewName); |
| 492 | nConflict++; |
| 493 | }else{ |
| 494 | unsigned mergeFlags = dryRunFlag ? MERGE_DRYRUN : 0; |
| 495 | if( !dryRunFlag && !internalUpdate ) undo_save(zName); |
| 496 | content_get(ridt, &t); |
| 497 | content_get(ridv, &v); |
| 498 | rc = merge_3way(&v, zFullPath, &t, &r, mergeFlags); |
| 499 | if( rc>=0 ){ |
| 500 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -103,10 +103,14 @@ | |
| 103 | ** or 0 (= no limit, resulting in a single line per entry). |
| 104 | ** --setmtime Set timestamps of all files to match their SCM-side |
| 105 | ** times (the timestamp of the last checkin which modified |
| 106 | ** them). |
| 107 | ** |
| 108 | ** -K|--keep-merge-files On merge conflict, retain the temporary files |
| 109 | ** used for merging, named *-baseline, *-original, |
| 110 | ** and *-merge. |
| 111 | ** |
| 112 | ** See also: revert |
| 113 | */ |
| 114 | void update_cmd(void){ |
| 115 | int vid; /* Current version */ |
| 116 | int tid=0; /* Target version - version we are changing to */ |
| @@ -115,10 +119,11 @@ | |
| 119 | int dryRunFlag; /* -n or --dry-run. Do a dry run */ |
| 120 | int verboseFlag; /* -v or --verbose. Output extra information */ |
| 121 | int forceMissingFlag; /* --force-missing. Continue if missing content */ |
| 122 | int debugFlag; /* --debug option */ |
| 123 | int setmtimeFlag; /* --setmtime. Set mtimes on files */ |
| 124 | int keepMergeFlag; /* True if --keep-merge-files is present */ |
| 125 | int nChng; /* Number of file renames */ |
| 126 | int *aChng; /* Array of file renames */ |
| 127 | int i; /* Loop counter */ |
| 128 | int nConflict = 0; /* Number of merge conflicts */ |
| 129 | int nOverwrite = 0; /* Number of unmanaged files overwritten */ |
| @@ -147,10 +152,11 @@ | |
| 152 | } |
| 153 | verboseFlag = find_option("verbose","v",0)!=0; |
| 154 | forceMissingFlag = find_option("force-missing",0,0)!=0; |
| 155 | debugFlag = find_option("debug",0,0)!=0; |
| 156 | setmtimeFlag = find_option("setmtime",0,0)!=0; |
| 157 | keepMergeFlag = find_option("keep-merge-files", "K",0)!=0; |
| 158 | |
| 159 | /* We should be done with options.. */ |
| 160 | verify_all_options(); |
| 161 | |
| 162 | db_must_be_within_tree(); |
| @@ -490,10 +496,11 @@ | |
| 496 | if( islinkv || islinkt ){ |
| 497 | fossil_print("***** Cannot merge symlink %s\n", zNewName); |
| 498 | nConflict++; |
| 499 | }else{ |
| 500 | unsigned mergeFlags = dryRunFlag ? MERGE_DRYRUN : 0; |
| 501 | if(keepMergeFlag!=0) mergeFlags |= MERGE_KEEP_FILES; |
| 502 | if( !dryRunFlag && !internalUpdate ) undo_save(zName); |
| 503 | content_get(ridt, &t); |
| 504 | content_get(ridv, &v); |
| 505 | rc = merge_3way(&v, zFullPath, &t, &r, mergeFlags); |
| 506 | if( rc>=0 ){ |
| 507 |
+4
| --- www/changes.wiki | ||
| +++ www/changes.wiki | ||
| @@ -21,10 +21,14 @@ | ||
| 21 | 21 | of the form "/doc/$CURRENT/..." the "$CURRENT" text is translated |
| 22 | 22 | into the check-in hash for the document currently being viewed. |
| 23 | 23 | * Proactive security: Fossil now assumes that the schema of every |
| 24 | 24 | database it opens has been tampered with by an adversary and takes |
| 25 | 25 | extra precautions to ensure that such tampering is harmless. |
| 26 | + * Merge conflicts caused via the [/help?cmd=merge|merge] and | |
| 27 | + [/help?cmd=update|update] commands no longer leave temporary | |
| 28 | + files behind unless the new <tt>--keep-merge-file</tt> flag | |
| 29 | + is used. | |
| 26 | 30 | * Bug fix: the "fossil git export" command is now working on Windows |
| 27 | 31 | * Bug fix: display Technote items on the timeline correctly |
| 28 | 32 | * Bug fix: fix the capability summary matrix of the Security Audit |
| 29 | 33 | page so that it does not add "anonymous" capabilities to the |
| 30 | 34 | "nobody" user. |
| 31 | 35 |
| --- www/changes.wiki | |
| +++ www/changes.wiki | |
| @@ -21,10 +21,14 @@ | |
| 21 | of the form "/doc/$CURRENT/..." the "$CURRENT" text is translated |
| 22 | into the check-in hash for the document currently being viewed. |
| 23 | * Proactive security: Fossil now assumes that the schema of every |
| 24 | database it opens has been tampered with by an adversary and takes |
| 25 | extra precautions to ensure that such tampering is harmless. |
| 26 | * Bug fix: the "fossil git export" command is now working on Windows |
| 27 | * Bug fix: display Technote items on the timeline correctly |
| 28 | * Bug fix: fix the capability summary matrix of the Security Audit |
| 29 | page so that it does not add "anonymous" capabilities to the |
| 30 | "nobody" user. |
| 31 |
| --- www/changes.wiki | |
| +++ www/changes.wiki | |
| @@ -21,10 +21,14 @@ | |
| 21 | of the form "/doc/$CURRENT/..." the "$CURRENT" text is translated |
| 22 | into the check-in hash for the document currently being viewed. |
| 23 | * Proactive security: Fossil now assumes that the schema of every |
| 24 | database it opens has been tampered with by an adversary and takes |
| 25 | extra precautions to ensure that such tampering is harmless. |
| 26 | * Merge conflicts caused via the [/help?cmd=merge|merge] and |
| 27 | [/help?cmd=update|update] commands no longer leave temporary |
| 28 | files behind unless the new <tt>--keep-merge-file</tt> flag |
| 29 | is used. |
| 30 | * Bug fix: the "fossil git export" command is now working on Windows |
| 31 | * Bug fix: display Technote items on the timeline correctly |
| 32 | * Bug fix: fix the capability summary matrix of the Security Audit |
| 33 | page so that it does not add "anonymous" capabilities to the |
| 34 | "nobody" user. |
| 35 |