Fossil SCM

Initial impl of (branch close) subcommand.

stephan 2021-07-22 05:59 trunk
Commit 0bdb19f3d333268866bab9a30e221b6489df70fedc5d38be909bdd56c9a61660
1 file changed +101 -1
+101 -1
--- src/branch.c
+++ src/branch.c
@@ -344,10 +344,92 @@
344344
" AND ox.rid=ix.rid)",
345345
TAG_BRANCH, zBrName, TAG_CLOSED
346346
);
347347
}
348348
349
+/*
350
+** Implementation of (branch close) subcommand. nStartAtArg is the
351
+** g.argv index to start reading branch names. If fDryRun is true then
352
+** the change is run in dry-run mode. Fails fatally on error.
353
+*/
354
+static void branch_cmd_close(int nStartAtArg, int fVerbose, int fDryRun){
355
+ int argPos = nStartAtArg;
356
+ Blob manifest = empty_blob; /* Control artifact */
357
+ Stmt q = empty_Stmt;
358
+ int nQueued = 0; /* # of branches queued for closing */
359
+ char * zUuid = 0;
360
+ int doRollback = fDryRun!=0;
361
+ db_begin_transaction();
362
+ db_multi_exec("create temp table brclose("
363
+ "rid INTEGER UNIQUE ON CONFLICT IGNORE"
364
+ ")");
365
+ db_prepare(&q, "INSERT INTO brclose(rid) "
366
+ "VALUES(:rid)");
367
+ for( ; argPos < g.argc; fossil_free(zUuid), ++argPos ){
368
+ const char * zBranch = g.argv[argPos];
369
+ const int rid = name_to_uuid2(zBranch, "ci", &zUuid);
370
+ if(0==rid){
371
+ fossil_fatal("Cannot resolve branch name: %s", zBranch);
372
+ }else if(rid<0){
373
+ fossil_fatal("Ambiguous branch name: %s", zBranch);
374
+ }else if(!is_a_leaf(rid)){
375
+ fossil_warning("Skipping non-leaf [%s] %s", zBranch, zUuid);
376
+ continue;
377
+ }else if(leaf_is_closed(rid)){
378
+ fossil_warning("Skipping closed [%s] %s", zBranch, zUuid);
379
+ continue;
380
+ }
381
+ ++nQueued;
382
+ db_bind_int(&q, ":rid", rid);
383
+ db_step(&q);
384
+ db_reset(&q);
385
+ if(fVerbose!=0){
386
+ fossil_print("Closing branch [%s] %s\n", zBranch, zUuid);
387
+ }
388
+ }
389
+ db_finalize(&q);
390
+ if(!nQueued){
391
+ fossil_warning("No branches queued for closing. Nothing to do.");
392
+ doRollback = 1;
393
+ goto br_close_end;
394
+ }
395
+ blob_appendf(&manifest, "D %z\n", date_in_standard_format("now"));
396
+ db_prepare(&q, "SELECT b.uuid "
397
+ "FROM brclose c, blob b "
398
+ "WHERE c.rid=b.rid "
399
+ "ORDER BY b.uuid");
400
+ while(SQLITE_ROW==db_step(&q)){
401
+ const char * zHash = db_column_text(&q, 0);
402
+ blob_appendf(&manifest, "T +closed %s\n", zHash);
403
+ }
404
+ user_select();
405
+ blob_appendf(&manifest, "U %F\n", login_name());
406
+ db_finalize(&q);
407
+ {
408
+ Blob cksum = empty_blob;
409
+ md5sum_blob(&manifest, &cksum);
410
+ blob_appendf(&manifest, "Z %b\n", &cksum);
411
+ blob_reset(&cksum);
412
+ }
413
+ if(fDryRun){
414
+ fossil_print("Dry-run mode. Not saving control artifact:\n%b",
415
+ &manifest);
416
+ }else{
417
+ const int newRid = content_put(&manifest);
418
+ if(0==newRid){
419
+ fossil_fatal("Problem saving new manifest: %s\n%b",
420
+ g.zErrMsg, &manifest);
421
+ }else if(manifest_crosslink(newRid, &manifest, 0)==0){
422
+ fossil_fatal("Crosslinking error: %s", g.zErrMsg);
423
+ }
424
+ fossil_print("Saved new control artifact (RID %d)\n", newRid);
425
+ }
426
+ blob_reset(&manifest);
427
+ br_close_end:
428
+ db_multi_exec("DROP TABLE brclose");
429
+ db_end_transaction(doRollback);
430
+}
349431
350432
/*
351433
** COMMAND: branch
352434
**
353435
** Usage: %fossil branch SUBCOMMAND ... ?OPTIONS?
@@ -390,10 +472,20 @@
390472
** DATE may be "now" or "YYYY-MM-DDTHH:MM:SS.SSS". If in
391473
** year-month-day form, it may be truncated, the "T" may be
392474
** replaced by a space, and it may also name a timezone offset
393475
** from UTC as "-HH:MM" (westward) or "+HH:MM" (eastward).
394476
** Either no timezone suffix or "Z" means UTC.
477
+**
478
+** > fossil branch close ?OPTIONS? BRANCH-NAME ?...BRANCH-NAMES?
479
+**
480
+** Close one or more branches by adding the "closed" tag
481
+** to them. It accepts arbitrary unambiguous symbolic names but
482
+** will only resolve checkin names and skips any which resolve
483
+** to non-leaf or closed checkins. Options:
484
+** -n|--dry-run do not commit changes and dump artifact
485
+** to stdout
486
+** -v|--verbose output more information
395487
**
396488
** Options valid for all subcommands:
397489
**
398490
** -R|--repository REPO Run commands on repository REPO
399491
*/
@@ -452,13 +544,21 @@
452544
fossil_print("%s%s\n", (isCur ? "* " : " "), zBr);
453545
}
454546
db_finalize(&q);
455547
}else if( strncmp(zCmd,"new",n)==0 ){
456548
branch_new();
549
+ }else if( strncmp(zCmd,"close",5)==0 ){
550
+ const int fDryRun = find_option("dry-run","n",0)!=0;
551
+ const int fVerbose = find_option("verbose","v",0)!=0;
552
+ verify_all_options();
553
+ if(g.argc<4){
554
+ usage("branch close branch-name(s)...");
555
+ }
556
+ branch_cmd_close(3, fVerbose, fDryRun);
457557
}else{
458558
fossil_fatal("branch subcommand should be one of: "
459
- "current info list ls new");
559
+ "close current info list ls new");
460560
}
461561
}
462562
463563
/*
464564
** This is the new-style branch-list page that shows the branch names
465565
--- src/branch.c
+++ src/branch.c
@@ -344,10 +344,92 @@
344 " AND ox.rid=ix.rid)",
345 TAG_BRANCH, zBrName, TAG_CLOSED
346 );
347 }
348
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
349
350 /*
351 ** COMMAND: branch
352 **
353 ** Usage: %fossil branch SUBCOMMAND ... ?OPTIONS?
@@ -390,10 +472,20 @@
390 ** DATE may be "now" or "YYYY-MM-DDTHH:MM:SS.SSS". If in
391 ** year-month-day form, it may be truncated, the "T" may be
392 ** replaced by a space, and it may also name a timezone offset
393 ** from UTC as "-HH:MM" (westward) or "+HH:MM" (eastward).
394 ** Either no timezone suffix or "Z" means UTC.
 
 
 
 
 
 
 
 
 
 
395 **
396 ** Options valid for all subcommands:
397 **
398 ** -R|--repository REPO Run commands on repository REPO
399 */
@@ -452,13 +544,21 @@
452 fossil_print("%s%s\n", (isCur ? "* " : " "), zBr);
453 }
454 db_finalize(&q);
455 }else if( strncmp(zCmd,"new",n)==0 ){
456 branch_new();
 
 
 
 
 
 
 
 
457 }else{
458 fossil_fatal("branch subcommand should be one of: "
459 "current info list ls new");
460 }
461 }
462
463 /*
464 ** This is the new-style branch-list page that shows the branch names
465
--- src/branch.c
+++ src/branch.c
@@ -344,10 +344,92 @@
344 " AND ox.rid=ix.rid)",
345 TAG_BRANCH, zBrName, TAG_CLOSED
346 );
347 }
348
349 /*
350 ** Implementation of (branch close) subcommand. nStartAtArg is the
351 ** g.argv index to start reading branch names. If fDryRun is true then
352 ** the change is run in dry-run mode. Fails fatally on error.
353 */
354 static void branch_cmd_close(int nStartAtArg, int fVerbose, int fDryRun){
355 int argPos = nStartAtArg;
356 Blob manifest = empty_blob; /* Control artifact */
357 Stmt q = empty_Stmt;
358 int nQueued = 0; /* # of branches queued for closing */
359 char * zUuid = 0;
360 int doRollback = fDryRun!=0;
361 db_begin_transaction();
362 db_multi_exec("create temp table brclose("
363 "rid INTEGER UNIQUE ON CONFLICT IGNORE"
364 ")");
365 db_prepare(&q, "INSERT INTO brclose(rid) "
366 "VALUES(:rid)");
367 for( ; argPos < g.argc; fossil_free(zUuid), ++argPos ){
368 const char * zBranch = g.argv[argPos];
369 const int rid = name_to_uuid2(zBranch, "ci", &zUuid);
370 if(0==rid){
371 fossil_fatal("Cannot resolve branch name: %s", zBranch);
372 }else if(rid<0){
373 fossil_fatal("Ambiguous branch name: %s", zBranch);
374 }else if(!is_a_leaf(rid)){
375 fossil_warning("Skipping non-leaf [%s] %s", zBranch, zUuid);
376 continue;
377 }else if(leaf_is_closed(rid)){
378 fossil_warning("Skipping closed [%s] %s", zBranch, zUuid);
379 continue;
380 }
381 ++nQueued;
382 db_bind_int(&q, ":rid", rid);
383 db_step(&q);
384 db_reset(&q);
385 if(fVerbose!=0){
386 fossil_print("Closing branch [%s] %s\n", zBranch, zUuid);
387 }
388 }
389 db_finalize(&q);
390 if(!nQueued){
391 fossil_warning("No branches queued for closing. Nothing to do.");
392 doRollback = 1;
393 goto br_close_end;
394 }
395 blob_appendf(&manifest, "D %z\n", date_in_standard_format("now"));
396 db_prepare(&q, "SELECT b.uuid "
397 "FROM brclose c, blob b "
398 "WHERE c.rid=b.rid "
399 "ORDER BY b.uuid");
400 while(SQLITE_ROW==db_step(&q)){
401 const char * zHash = db_column_text(&q, 0);
402 blob_appendf(&manifest, "T +closed %s\n", zHash);
403 }
404 user_select();
405 blob_appendf(&manifest, "U %F\n", login_name());
406 db_finalize(&q);
407 {
408 Blob cksum = empty_blob;
409 md5sum_blob(&manifest, &cksum);
410 blob_appendf(&manifest, "Z %b\n", &cksum);
411 blob_reset(&cksum);
412 }
413 if(fDryRun){
414 fossil_print("Dry-run mode. Not saving control artifact:\n%b",
415 &manifest);
416 }else{
417 const int newRid = content_put(&manifest);
418 if(0==newRid){
419 fossil_fatal("Problem saving new manifest: %s\n%b",
420 g.zErrMsg, &manifest);
421 }else if(manifest_crosslink(newRid, &manifest, 0)==0){
422 fossil_fatal("Crosslinking error: %s", g.zErrMsg);
423 }
424 fossil_print("Saved new control artifact (RID %d)\n", newRid);
425 }
426 blob_reset(&manifest);
427 br_close_end:
428 db_multi_exec("DROP TABLE brclose");
429 db_end_transaction(doRollback);
430 }
431
432 /*
433 ** COMMAND: branch
434 **
435 ** Usage: %fossil branch SUBCOMMAND ... ?OPTIONS?
@@ -390,10 +472,20 @@
472 ** DATE may be "now" or "YYYY-MM-DDTHH:MM:SS.SSS". If in
473 ** year-month-day form, it may be truncated, the "T" may be
474 ** replaced by a space, and it may also name a timezone offset
475 ** from UTC as "-HH:MM" (westward) or "+HH:MM" (eastward).
476 ** Either no timezone suffix or "Z" means UTC.
477 **
478 ** > fossil branch close ?OPTIONS? BRANCH-NAME ?...BRANCH-NAMES?
479 **
480 ** Close one or more branches by adding the "closed" tag
481 ** to them. It accepts arbitrary unambiguous symbolic names but
482 ** will only resolve checkin names and skips any which resolve
483 ** to non-leaf or closed checkins. Options:
484 ** -n|--dry-run do not commit changes and dump artifact
485 ** to stdout
486 ** -v|--verbose output more information
487 **
488 ** Options valid for all subcommands:
489 **
490 ** -R|--repository REPO Run commands on repository REPO
491 */
@@ -452,13 +544,21 @@
544 fossil_print("%s%s\n", (isCur ? "* " : " "), zBr);
545 }
546 db_finalize(&q);
547 }else if( strncmp(zCmd,"new",n)==0 ){
548 branch_new();
549 }else if( strncmp(zCmd,"close",5)==0 ){
550 const int fDryRun = find_option("dry-run","n",0)!=0;
551 const int fVerbose = find_option("verbose","v",0)!=0;
552 verify_all_options();
553 if(g.argc<4){
554 usage("branch close branch-name(s)...");
555 }
556 branch_cmd_close(3, fVerbose, fDryRun);
557 }else{
558 fossil_fatal("branch subcommand should be one of: "
559 "close current info list ls new");
560 }
561 }
562
563 /*
564 ** This is the new-style branch-list page that shows the branch names
565

Keyboard Shortcuts

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