Fossil SCM
Prompt user to publish artifacts when merging a private branch into a public branch.
Commit
c07679128e4439020a57498f431e212bc84aff9e2a612102a10a41182c0613e1
Parent
593e801bdfaba3b…
1 file changed
+60
+60
| --- src/merge.c | ||
| +++ src/merge.c | ||
| @@ -337,10 +337,11 @@ | ||
| 337 | 337 | int showVfileFlag; /* True if the --show-vfile flag is present */ |
| 338 | 338 | int keepMergeFlag; /* True if --keep-merge-files is present */ |
| 339 | 339 | int nConflict = 0; /* Number of conflicts seen */ |
| 340 | 340 | int nOverwrite = 0; /* Number of unmanaged files overwritten */ |
| 341 | 341 | char vAncestor = 'p'; /* If P is an ancestor of V then 'p', else 'n' */ |
| 342 | + char *zRefName = 0; /* Name of branch being merged, or fork reference. */ | |
| 342 | 343 | Stmt q; |
| 343 | 344 | |
| 344 | 345 | |
| 345 | 346 | /* Notation: |
| 346 | 347 | ** |
| @@ -409,10 +410,11 @@ | ||
| 409 | 410 | /* Mid is specified as an argument on the command-line */ |
| 410 | 411 | mid = name_to_typed_rid(g.argv[2], "ci"); |
| 411 | 412 | if( mid==0 || !is_a_version(mid) ){ |
| 412 | 413 | fossil_fatal("not a version: %s", g.argv[2]); |
| 413 | 414 | } |
| 415 | + zRefName = mprintf("%s", g.argv[2]); | |
| 414 | 416 | }else if( g.argc==2 ){ |
| 415 | 417 | /* No version specified on the command-line so pick the most recent |
| 416 | 418 | ** leaf that is (1) not the version currently checked out and (2) |
| 417 | 419 | ** has not already been merged into the current check-out and (3) |
| 418 | 420 | ** the leaf is not closed and (4) the leaf is in the same branch |
| @@ -444,16 +446,65 @@ | ||
| 444 | 446 | char *zCom = mprintf("Merging fork [%S] at %s by %s: \"%s\"", |
| 445 | 447 | db_column_text(&q, 0), db_column_text(&q, 1), |
| 446 | 448 | db_column_text(&q, 3), db_column_text(&q, 2)); |
| 447 | 449 | comment_print(zCom, db_column_text(&q,2), 0, -1, get_comment_format()); |
| 448 | 450 | fossil_free(zCom); |
| 451 | + zRefName = mprintf("%s", db_column_text(&q, 0)); | |
| 449 | 452 | } |
| 450 | 453 | db_finalize(&q); |
| 451 | 454 | }else{ |
| 452 | 455 | usage("?OPTIONS? ?VERSION?"); |
| 453 | 456 | return; |
| 454 | 457 | } |
| 458 | + | |
| 459 | + db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY);"); | |
| 460 | + | |
| 461 | + if( forceFlag==0 && content_is_private(mid) && !content_is_private(vid) ){ | |
| 462 | + Blob ans; | |
| 463 | + char cReply; | |
| 464 | + fossil_warning("Merging UNPUBLISHED %s", zRefName); | |
| 465 | + prompt_user("Publish history before merging (y/n/Abort)? ", &ans); | |
| 466 | + cReply = blob_str(&ans)[0]; | |
| 467 | + blob_reset(&ans); | |
| 468 | + switch( cReply ){ | |
| 469 | + case 'n': | |
| 470 | + case 'N': { | |
| 471 | + break; | |
| 472 | + } | |
| 473 | + | |
| 474 | + case 'y': | |
| 475 | + case 'Y': { | |
| 476 | + db_begin_transaction(); | |
| 477 | + if( db_exists("SELECT 1 FROM tagxref" | |
| 478 | + " WHERE rid=%d AND tagid=%d" | |
| 479 | + " AND tagtype>0 AND value=%Q", | |
| 480 | + mid, TAG_BRANCH, zRefName) ){ | |
| 481 | + int rid = start_of_branch(mid, 1); | |
| 482 | + compute_descendants(rid, 1000000000); | |
| 483 | + }else{ | |
| 484 | + db_multi_exec("INSERT OR IGNORE INTO ok VALUES(%d)", mid); | |
| 485 | + } | |
| 486 | + db_end_transaction(0); | |
| 487 | + fossil_warning("The following artifacts will be published:"); | |
| 488 | + describe_artifacts_to_stdout("IN ok", 0); | |
| 489 | + prompt_user("Publish the listed artifacts (y/N)? ", &ans); | |
| 490 | + cReply = blob_str(&ans)[0]; | |
| 491 | + blob_reset(&ans); | |
| 492 | + if( cReply!='y' && cReply!='Y' ){ | |
| 493 | + fossil_free(zRefName); | |
| 494 | + return; | |
| 495 | + } | |
| 496 | + break; | |
| 497 | + } | |
| 498 | + | |
| 499 | + default: { | |
| 500 | + fossil_free(zRefName); | |
| 501 | + return; | |
| 502 | + } | |
| 503 | + } | |
| 504 | + } | |
| 505 | + fossil_free(zRefName); | |
| 455 | 506 | |
| 456 | 507 | if( zPivot ){ |
| 457 | 508 | pid = name_to_typed_rid(zPivot, "ci"); |
| 458 | 509 | if( pid==0 || !is_a_version(pid) ){ |
| 459 | 510 | fossil_fatal("not a version: %s", zPivot); |
| @@ -532,10 +583,19 @@ | ||
| 532 | 583 | fossil_fatal("missing content, unable to merge"); |
| 533 | 584 | } |
| 534 | 585 | if( load_vfile_from_rid(pid) && !forceMissingFlag ){ |
| 535 | 586 | fossil_fatal("missing content, unable to merge"); |
| 536 | 587 | } |
| 588 | + | |
| 589 | + /* Publish artifacts from private branches if selected above. */ | |
| 590 | + db_multi_exec( | |
| 591 | + "DELETE FROM ok WHERE rid NOT IN private;" | |
| 592 | + "DELETE FROM private WHERE rid IN ok;" | |
| 593 | + "INSERT OR IGNORE INTO unsent SELECT rid FROM ok;" | |
| 594 | + "INSERT OR IGNORE INTO unclustered SELECT rid FROM ok;" | |
| 595 | + ); | |
| 596 | + | |
| 537 | 597 | if( zPivot ){ |
| 538 | 598 | vAncestor = db_exists( |
| 539 | 599 | "WITH RECURSIVE ancestor(id) AS (" |
| 540 | 600 | " VALUES(%d)" |
| 541 | 601 | " UNION" |
| 542 | 602 |
| --- src/merge.c | |
| +++ src/merge.c | |
| @@ -337,10 +337,11 @@ | |
| 337 | int showVfileFlag; /* True if the --show-vfile flag is present */ |
| 338 | int keepMergeFlag; /* True if --keep-merge-files is present */ |
| 339 | int nConflict = 0; /* Number of conflicts seen */ |
| 340 | int nOverwrite = 0; /* Number of unmanaged files overwritten */ |
| 341 | char vAncestor = 'p'; /* If P is an ancestor of V then 'p', else 'n' */ |
| 342 | Stmt q; |
| 343 | |
| 344 | |
| 345 | /* Notation: |
| 346 | ** |
| @@ -409,10 +410,11 @@ | |
| 409 | /* Mid is specified as an argument on the command-line */ |
| 410 | mid = name_to_typed_rid(g.argv[2], "ci"); |
| 411 | if( mid==0 || !is_a_version(mid) ){ |
| 412 | fossil_fatal("not a version: %s", g.argv[2]); |
| 413 | } |
| 414 | }else if( g.argc==2 ){ |
| 415 | /* No version specified on the command-line so pick the most recent |
| 416 | ** leaf that is (1) not the version currently checked out and (2) |
| 417 | ** has not already been merged into the current check-out and (3) |
| 418 | ** the leaf is not closed and (4) the leaf is in the same branch |
| @@ -444,16 +446,65 @@ | |
| 444 | char *zCom = mprintf("Merging fork [%S] at %s by %s: \"%s\"", |
| 445 | db_column_text(&q, 0), db_column_text(&q, 1), |
| 446 | db_column_text(&q, 3), db_column_text(&q, 2)); |
| 447 | comment_print(zCom, db_column_text(&q,2), 0, -1, get_comment_format()); |
| 448 | fossil_free(zCom); |
| 449 | } |
| 450 | db_finalize(&q); |
| 451 | }else{ |
| 452 | usage("?OPTIONS? ?VERSION?"); |
| 453 | return; |
| 454 | } |
| 455 | |
| 456 | if( zPivot ){ |
| 457 | pid = name_to_typed_rid(zPivot, "ci"); |
| 458 | if( pid==0 || !is_a_version(pid) ){ |
| 459 | fossil_fatal("not a version: %s", zPivot); |
| @@ -532,10 +583,19 @@ | |
| 532 | fossil_fatal("missing content, unable to merge"); |
| 533 | } |
| 534 | if( load_vfile_from_rid(pid) && !forceMissingFlag ){ |
| 535 | fossil_fatal("missing content, unable to merge"); |
| 536 | } |
| 537 | if( zPivot ){ |
| 538 | vAncestor = db_exists( |
| 539 | "WITH RECURSIVE ancestor(id) AS (" |
| 540 | " VALUES(%d)" |
| 541 | " UNION" |
| 542 |
| --- src/merge.c | |
| +++ src/merge.c | |
| @@ -337,10 +337,11 @@ | |
| 337 | int showVfileFlag; /* True if the --show-vfile flag is present */ |
| 338 | int keepMergeFlag; /* True if --keep-merge-files is present */ |
| 339 | int nConflict = 0; /* Number of conflicts seen */ |
| 340 | int nOverwrite = 0; /* Number of unmanaged files overwritten */ |
| 341 | char vAncestor = 'p'; /* If P is an ancestor of V then 'p', else 'n' */ |
| 342 | char *zRefName = 0; /* Name of branch being merged, or fork reference. */ |
| 343 | Stmt q; |
| 344 | |
| 345 | |
| 346 | /* Notation: |
| 347 | ** |
| @@ -409,10 +410,11 @@ | |
| 410 | /* Mid is specified as an argument on the command-line */ |
| 411 | mid = name_to_typed_rid(g.argv[2], "ci"); |
| 412 | if( mid==0 || !is_a_version(mid) ){ |
| 413 | fossil_fatal("not a version: %s", g.argv[2]); |
| 414 | } |
| 415 | zRefName = mprintf("%s", g.argv[2]); |
| 416 | }else if( g.argc==2 ){ |
| 417 | /* No version specified on the command-line so pick the most recent |
| 418 | ** leaf that is (1) not the version currently checked out and (2) |
| 419 | ** has not already been merged into the current check-out and (3) |
| 420 | ** the leaf is not closed and (4) the leaf is in the same branch |
| @@ -444,16 +446,65 @@ | |
| 446 | char *zCom = mprintf("Merging fork [%S] at %s by %s: \"%s\"", |
| 447 | db_column_text(&q, 0), db_column_text(&q, 1), |
| 448 | db_column_text(&q, 3), db_column_text(&q, 2)); |
| 449 | comment_print(zCom, db_column_text(&q,2), 0, -1, get_comment_format()); |
| 450 | fossil_free(zCom); |
| 451 | zRefName = mprintf("%s", db_column_text(&q, 0)); |
| 452 | } |
| 453 | db_finalize(&q); |
| 454 | }else{ |
| 455 | usage("?OPTIONS? ?VERSION?"); |
| 456 | return; |
| 457 | } |
| 458 | |
| 459 | db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY);"); |
| 460 | |
| 461 | if( forceFlag==0 && content_is_private(mid) && !content_is_private(vid) ){ |
| 462 | Blob ans; |
| 463 | char cReply; |
| 464 | fossil_warning("Merging UNPUBLISHED %s", zRefName); |
| 465 | prompt_user("Publish history before merging (y/n/Abort)? ", &ans); |
| 466 | cReply = blob_str(&ans)[0]; |
| 467 | blob_reset(&ans); |
| 468 | switch( cReply ){ |
| 469 | case 'n': |
| 470 | case 'N': { |
| 471 | break; |
| 472 | } |
| 473 | |
| 474 | case 'y': |
| 475 | case 'Y': { |
| 476 | db_begin_transaction(); |
| 477 | if( db_exists("SELECT 1 FROM tagxref" |
| 478 | " WHERE rid=%d AND tagid=%d" |
| 479 | " AND tagtype>0 AND value=%Q", |
| 480 | mid, TAG_BRANCH, zRefName) ){ |
| 481 | int rid = start_of_branch(mid, 1); |
| 482 | compute_descendants(rid, 1000000000); |
| 483 | }else{ |
| 484 | db_multi_exec("INSERT OR IGNORE INTO ok VALUES(%d)", mid); |
| 485 | } |
| 486 | db_end_transaction(0); |
| 487 | fossil_warning("The following artifacts will be published:"); |
| 488 | describe_artifacts_to_stdout("IN ok", 0); |
| 489 | prompt_user("Publish the listed artifacts (y/N)? ", &ans); |
| 490 | cReply = blob_str(&ans)[0]; |
| 491 | blob_reset(&ans); |
| 492 | if( cReply!='y' && cReply!='Y' ){ |
| 493 | fossil_free(zRefName); |
| 494 | return; |
| 495 | } |
| 496 | break; |
| 497 | } |
| 498 | |
| 499 | default: { |
| 500 | fossil_free(zRefName); |
| 501 | return; |
| 502 | } |
| 503 | } |
| 504 | } |
| 505 | fossil_free(zRefName); |
| 506 | |
| 507 | if( zPivot ){ |
| 508 | pid = name_to_typed_rid(zPivot, "ci"); |
| 509 | if( pid==0 || !is_a_version(pid) ){ |
| 510 | fossil_fatal("not a version: %s", zPivot); |
| @@ -532,10 +583,19 @@ | |
| 583 | fossil_fatal("missing content, unable to merge"); |
| 584 | } |
| 585 | if( load_vfile_from_rid(pid) && !forceMissingFlag ){ |
| 586 | fossil_fatal("missing content, unable to merge"); |
| 587 | } |
| 588 | |
| 589 | /* Publish artifacts from private branches if selected above. */ |
| 590 | db_multi_exec( |
| 591 | "DELETE FROM ok WHERE rid NOT IN private;" |
| 592 | "DELETE FROM private WHERE rid IN ok;" |
| 593 | "INSERT OR IGNORE INTO unsent SELECT rid FROM ok;" |
| 594 | "INSERT OR IGNORE INTO unclustered SELECT rid FROM ok;" |
| 595 | ); |
| 596 | |
| 597 | if( zPivot ){ |
| 598 | vAncestor = db_exists( |
| 599 | "WITH RECURSIVE ancestor(id) AS (" |
| 600 | " VALUES(%d)" |
| 601 | " UNION" |
| 602 |