Fossil SCM

Internal refactoring of (branch close) subcommand in prep for pending addition of similar (branch hide/unhide) feature.

stephan 2021-07-22 23:21 branch-close-subcommand
Commit 9baa9768f6ae5a68d4d2ddacddc701edd90ab1069a1e5ae284bf10a16814db4e
1 file changed +98 -55
+98 -55
--- src/branch.c
+++ src/branch.c
@@ -345,70 +345,76 @@
345345
TAG_BRANCH, zBrName, TAG_CLOSED
346346
);
347347
}
348348
349349
/*
350
-** Implementation of (branch close) subcommand. nStartAtArg is the
351
-** g.argv index to start reading branch names. Fails fatally on error.
350
+** Internal helper for branch_cmd_close() and friends. Adds a row to
351
+** the to the brcmdtag TEMP table, initializing that table if needed,
352
+** holding a pending tag for the given blob.rid (which is assumed to
353
+** be valid). zTag must be a fully-formed tag name, including the
354
+** (+,-,*) prefix character.
355
+**
356
+*/
357
+static void branch_cmd_tag_add(int rid, const char *zTag){
358
+ static int once = 0;
359
+ assert(zTag && ('+'==zTag[0] || '-'==zTag[0] || '*'==zTag[0]));
360
+ if(0==once++){
361
+ db_multi_exec("CREATE TEMP TABLE brcmdtag("
362
+ "rid INTEGER UNIQUE ON CONFLICT IGNORE,"
363
+ "tag TEXT NOT NULL"
364
+ ")");
365
+ }
366
+ db_multi_exec("INSERT INTO brcmdtag(rid,tag) VALUES(%d,%Q)",
367
+ rid, zTag);
368
+}
369
+
370
+/*
371
+** Internal helper for branch_cmd_close() and friends. Creates and
372
+** saves a control artifact of tag changes stored via
373
+** branch_cmd_tag_add(). Fails fatally on error, returns 0 if it saves
374
+** an artifact, and a negative value if it does not save anything
375
+** because no tags were queued up. A positive return value is reserved
376
+** for potential future semantics.
377
+**
378
+** This function asserts that a transaction is underway and it ends
379
+** the transaction, committing or rolling back, as appropriate.
352380
*/
353
-static void branch_cmd_close(int nStartAtArg){
354
- int argPos = nStartAtArg; /* g.argv pos with first branch name */
355
- Blob manifest = empty_blob; /* Control artifact */
381
+static int branch_cmd_tag_finalize(int fDryRun /* roll back if true */,
382
+ int fVerbose /* output extra info */,
383
+ const char *zDateOvrd /* --date-override */,
384
+ const char *zUserOvrd /* --user-override */){
385
+ int nTags = 0;
356386
Stmt q = empty_Stmt;
357
- int nQueued = 0; /* # of branches queued for closing */
358
- char * zUuid = 0; /* Resolved branch UUID. */
359
- const int fVerbose = find_option("verbose","v",0)!=0;
360
- const int fDryRun = find_option("dry-run","n",0)!=0;
361
- const char *zDateOvrd = find_option("date-override",0,1);
362
- const char *zUserOvrd = find_option("user-override",0,1);
363
- int doRollback = fDryRun!=0; /* Roll back transaction if true */
364
-
365
- verify_all_options();
366
- db_begin_transaction();
367
- db_multi_exec("CREATE TEMP TABLE brclose("
368
- "rid INTEGER UNIQUE ON CONFLICT IGNORE"
369
- ")");
370
- db_prepare(&q, "INSERT INTO brclose(rid) VALUES(:rid)");
371
- for( ; argPos < g.argc; fossil_free(zUuid), ++argPos ){
372
- const char * zBranch = g.argv[argPos];
373
- const int rid = name_to_uuid2(zBranch, "ci", &zUuid);
374
- if(0==rid){
375
- fossil_fatal("Cannot resolve branch name: %s", zBranch);
376
- }else if(rid<0){
377
- fossil_fatal("Ambiguous branch name: %s", zBranch);
378
- }else if(!is_a_leaf(rid)){
379
- fossil_warning("Skipping non-leaf [%s] %s", zBranch, zUuid);
380
- continue;
381
- }else if(leaf_is_closed(rid)){
382
- fossil_warning("Skipping closed [%s] %s", zBranch, zUuid);
383
- continue;
384
- }
385
- ++nQueued;
386
- db_bind_int(&q, ":rid", rid);
387
- db_step(&q);
388
- db_reset(&q);
389
- if(fVerbose!=0){
390
- fossil_print("Closing branch [%s] %s\n", zBranch, zUuid);
391
- }
392
- }
393
- db_finalize(&q);
394
- if(!nQueued){
395
- fossil_warning("No branches queued for closing. Nothing to do.");
396
- doRollback = 1;
397
- goto br_close_end;
398
- }
387
+ Blob manifest = empty_blob;
388
+ int doRollback = fDryRun!=0;
389
+
390
+ assert(db_transaction_nesting_depth() > 0);
391
+ if(!db_table_exists("temp","brcmdtag")){
392
+ fossil_warning("No tags added - nothing to do.");
393
+ db_end_transaction(1);
394
+ return -1;
395
+ }
396
+ db_prepare(&q, "SELECT b.uuid, t.tag "
397
+ "FROM blob b, brcmdtag t "
398
+ "WHERE b.rid=t.rid "
399
+ "ORDER BY t.tag, b.uuid");
399400
blob_appendf(&manifest, "D %z\n",
400401
date_in_standard_format( zDateOvrd ? zDateOvrd : "now"));
401
- db_prepare(&q, "SELECT uuid FROM blob WHERE rid IN brclose");
402402
while(SQLITE_ROW==db_step(&q)){
403403
const char * zHash = db_column_text(&q, 0);
404
- blob_appendf(&manifest, "T +closed %s\n", zHash);
404
+ const char * zTag = db_column_text(&q, 1);
405
+ blob_appendf(&manifest, "T %s %s\n", zTag, zHash);
406
+ ++nTags;
405407
}
406
- db_finalize(&q);
408
+ if(!nTags){
409
+ fossil_warning("No tags added - nothing to do.");
410
+ db_end_transaction(1);
411
+ blob_reset(&manifest);
412
+ return -1;
413
+ }
407414
user_select();
408
- blob_appendf(&manifest, "U %F\n",
409
- zUserOvrd ? zUserOvrd : login_name());
415
+ blob_appendf(&manifest, "U %F\n", zUserOvrd ? zUserOvrd : login_name());
410416
{ /* Z-card and save artifact */
411417
int newRid;
412418
Blob cksum = empty_blob;
413419
md5sum_blob(&manifest, &cksum);
414420
blob_appendf(&manifest, "Z %b\n", &cksum);
@@ -427,19 +433,56 @@
427433
}else if(manifest_crosslink(newRid, &manifest, 0)==0){
428434
fossil_fatal("Crosslinking error: %s", g.zErrMsg);
429435
}
430436
fossil_print("Saved new control artifact %z (RID %d).\n",
431437
rid_to_uuid(newRid), newRid);
438
+ db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", newRid);
432439
if(fDryRun){
433440
fossil_print("Dry-run mode: rolling back new artifact.\n");
434
- assert(doRollback!=0);
441
+ assert(0!=doRollback);
435442
}
436443
}
444
+ db_multi_exec("DROP TABLE brcmdtag");
437445
blob_reset(&manifest);
438
- br_close_end:
439
- db_multi_exec("DROP TABLE brclose");
440446
db_end_transaction(doRollback);
447
+ return 0;
448
+}
449
+
450
+/*
451
+** Implementation of (branch close) subcommand. nStartAtArg is the
452
+** g.argv index to start reading branch names. Fails fatally on error.
453
+*/
454
+static void branch_cmd_close(int nStartAtArg){
455
+ int argPos = nStartAtArg; /* g.argv pos with first branch name */
456
+ char * zUuid = 0; /* Resolved branch UUID. */
457
+ const int fVerbose = find_option("verbose","v",0)!=0;
458
+ const int fDryRun = find_option("dry-run","n",0)!=0;
459
+ const char *zDateOvrd = find_option("date-override",0,1);
460
+ const char *zUserOvrd = find_option("user-override",0,1);
461
+
462
+ verify_all_options();
463
+ db_begin_transaction();
464
+ for( ; argPos < g.argc; fossil_free(zUuid), ++argPos ){
465
+ const char * zBranch = g.argv[argPos];
466
+ const int rid = name_to_uuid2(zBranch, "ci", &zUuid);
467
+ if(0==rid){
468
+ fossil_fatal("Cannot resolve branch name: %s", zBranch);
469
+ }else if(rid<0){
470
+ fossil_fatal("Ambiguous branch name: %s", zBranch);
471
+ }else if(!is_a_leaf(rid)){
472
+ fossil_warning("Skipping non-leaf [%s] %s", zBranch, zUuid);
473
+ continue;
474
+ }else if(leaf_is_closed(rid)){
475
+ fossil_warning("Skipping closed [%s] %s", zBranch, zUuid);
476
+ continue;
477
+ }
478
+ branch_cmd_tag_add(rid, "+closed");
479
+ if(fVerbose!=0){
480
+ fossil_print("Closing branch [%s] %s\n", zBranch, zUuid);
481
+ }
482
+ }
483
+ branch_cmd_tag_finalize(fDryRun, fVerbose, zDateOvrd, zUserOvrd);
441484
}
442485
443486
/*
444487
** COMMAND: branch
445488
**
446489
--- src/branch.c
+++ src/branch.c
@@ -345,70 +345,76 @@
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. Fails fatally on error.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
352 */
353 static void branch_cmd_close(int nStartAtArg){
354 int argPos = nStartAtArg; /* g.argv pos with first branch name */
355 Blob manifest = empty_blob; /* Control artifact */
 
 
356 Stmt q = empty_Stmt;
357 int nQueued = 0; /* # of branches queued for closing */
358 char * zUuid = 0; /* Resolved branch UUID. */
359 const int fVerbose = find_option("verbose","v",0)!=0;
360 const int fDryRun = find_option("dry-run","n",0)!=0;
361 const char *zDateOvrd = find_option("date-override",0,1);
362 const char *zUserOvrd = find_option("user-override",0,1);
363 int doRollback = fDryRun!=0; /* Roll back transaction if true */
364
365 verify_all_options();
366 db_begin_transaction();
367 db_multi_exec("CREATE TEMP TABLE brclose("
368 "rid INTEGER UNIQUE ON CONFLICT IGNORE"
369 ")");
370 db_prepare(&q, "INSERT INTO brclose(rid) VALUES(:rid)");
371 for( ; argPos < g.argc; fossil_free(zUuid), ++argPos ){
372 const char * zBranch = g.argv[argPos];
373 const int rid = name_to_uuid2(zBranch, "ci", &zUuid);
374 if(0==rid){
375 fossil_fatal("Cannot resolve branch name: %s", zBranch);
376 }else if(rid<0){
377 fossil_fatal("Ambiguous branch name: %s", zBranch);
378 }else if(!is_a_leaf(rid)){
379 fossil_warning("Skipping non-leaf [%s] %s", zBranch, zUuid);
380 continue;
381 }else if(leaf_is_closed(rid)){
382 fossil_warning("Skipping closed [%s] %s", zBranch, zUuid);
383 continue;
384 }
385 ++nQueued;
386 db_bind_int(&q, ":rid", rid);
387 db_step(&q);
388 db_reset(&q);
389 if(fVerbose!=0){
390 fossil_print("Closing branch [%s] %s\n", zBranch, zUuid);
391 }
392 }
393 db_finalize(&q);
394 if(!nQueued){
395 fossil_warning("No branches queued for closing. Nothing to do.");
396 doRollback = 1;
397 goto br_close_end;
398 }
399 blob_appendf(&manifest, "D %z\n",
400 date_in_standard_format( zDateOvrd ? zDateOvrd : "now"));
401 db_prepare(&q, "SELECT uuid FROM blob WHERE rid IN brclose");
402 while(SQLITE_ROW==db_step(&q)){
403 const char * zHash = db_column_text(&q, 0);
404 blob_appendf(&manifest, "T +closed %s\n", zHash);
 
 
405 }
406 db_finalize(&q);
 
 
 
 
 
407 user_select();
408 blob_appendf(&manifest, "U %F\n",
409 zUserOvrd ? zUserOvrd : login_name());
410 { /* Z-card and save artifact */
411 int newRid;
412 Blob cksum = empty_blob;
413 md5sum_blob(&manifest, &cksum);
414 blob_appendf(&manifest, "Z %b\n", &cksum);
@@ -427,19 +433,56 @@
427 }else if(manifest_crosslink(newRid, &manifest, 0)==0){
428 fossil_fatal("Crosslinking error: %s", g.zErrMsg);
429 }
430 fossil_print("Saved new control artifact %z (RID %d).\n",
431 rid_to_uuid(newRid), newRid);
 
432 if(fDryRun){
433 fossil_print("Dry-run mode: rolling back new artifact.\n");
434 assert(doRollback!=0);
435 }
436 }
 
437 blob_reset(&manifest);
438 br_close_end:
439 db_multi_exec("DROP TABLE brclose");
440 db_end_transaction(doRollback);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
441 }
442
443 /*
444 ** COMMAND: branch
445 **
446
--- src/branch.c
+++ src/branch.c
@@ -345,70 +345,76 @@
345 TAG_BRANCH, zBrName, TAG_CLOSED
346 );
347 }
348
349 /*
350 ** Internal helper for branch_cmd_close() and friends. Adds a row to
351 ** the to the brcmdtag TEMP table, initializing that table if needed,
352 ** holding a pending tag for the given blob.rid (which is assumed to
353 ** be valid). zTag must be a fully-formed tag name, including the
354 ** (+,-,*) prefix character.
355 **
356 */
357 static void branch_cmd_tag_add(int rid, const char *zTag){
358 static int once = 0;
359 assert(zTag && ('+'==zTag[0] || '-'==zTag[0] || '*'==zTag[0]));
360 if(0==once++){
361 db_multi_exec("CREATE TEMP TABLE brcmdtag("
362 "rid INTEGER UNIQUE ON CONFLICT IGNORE,"
363 "tag TEXT NOT NULL"
364 ")");
365 }
366 db_multi_exec("INSERT INTO brcmdtag(rid,tag) VALUES(%d,%Q)",
367 rid, zTag);
368 }
369
370 /*
371 ** Internal helper for branch_cmd_close() and friends. Creates and
372 ** saves a control artifact of tag changes stored via
373 ** branch_cmd_tag_add(). Fails fatally on error, returns 0 if it saves
374 ** an artifact, and a negative value if it does not save anything
375 ** because no tags were queued up. A positive return value is reserved
376 ** for potential future semantics.
377 **
378 ** This function asserts that a transaction is underway and it ends
379 ** the transaction, committing or rolling back, as appropriate.
380 */
381 static int branch_cmd_tag_finalize(int fDryRun /* roll back if true */,
382 int fVerbose /* output extra info */,
383 const char *zDateOvrd /* --date-override */,
384 const char *zUserOvrd /* --user-override */){
385 int nTags = 0;
386 Stmt q = empty_Stmt;
387 Blob manifest = empty_blob;
388 int doRollback = fDryRun!=0;
389
390 assert(db_transaction_nesting_depth() > 0);
391 if(!db_table_exists("temp","brcmdtag")){
392 fossil_warning("No tags added - nothing to do.");
393 db_end_transaction(1);
394 return -1;
395 }
396 db_prepare(&q, "SELECT b.uuid, t.tag "
397 "FROM blob b, brcmdtag t "
398 "WHERE b.rid=t.rid "
399 "ORDER BY t.tag, b.uuid");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
400 blob_appendf(&manifest, "D %z\n",
401 date_in_standard_format( zDateOvrd ? zDateOvrd : "now"));
 
402 while(SQLITE_ROW==db_step(&q)){
403 const char * zHash = db_column_text(&q, 0);
404 const char * zTag = db_column_text(&q, 1);
405 blob_appendf(&manifest, "T %s %s\n", zTag, zHash);
406 ++nTags;
407 }
408 if(!nTags){
409 fossil_warning("No tags added - nothing to do.");
410 db_end_transaction(1);
411 blob_reset(&manifest);
412 return -1;
413 }
414 user_select();
415 blob_appendf(&manifest, "U %F\n", zUserOvrd ? zUserOvrd : login_name());
 
416 { /* Z-card and save artifact */
417 int newRid;
418 Blob cksum = empty_blob;
419 md5sum_blob(&manifest, &cksum);
420 blob_appendf(&manifest, "Z %b\n", &cksum);
@@ -427,19 +433,56 @@
433 }else if(manifest_crosslink(newRid, &manifest, 0)==0){
434 fossil_fatal("Crosslinking error: %s", g.zErrMsg);
435 }
436 fossil_print("Saved new control artifact %z (RID %d).\n",
437 rid_to_uuid(newRid), newRid);
438 db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", newRid);
439 if(fDryRun){
440 fossil_print("Dry-run mode: rolling back new artifact.\n");
441 assert(0!=doRollback);
442 }
443 }
444 db_multi_exec("DROP TABLE brcmdtag");
445 blob_reset(&manifest);
 
 
446 db_end_transaction(doRollback);
447 return 0;
448 }
449
450 /*
451 ** Implementation of (branch close) subcommand. nStartAtArg is the
452 ** g.argv index to start reading branch names. Fails fatally on error.
453 */
454 static void branch_cmd_close(int nStartAtArg){
455 int argPos = nStartAtArg; /* g.argv pos with first branch name */
456 char * zUuid = 0; /* Resolved branch UUID. */
457 const int fVerbose = find_option("verbose","v",0)!=0;
458 const int fDryRun = find_option("dry-run","n",0)!=0;
459 const char *zDateOvrd = find_option("date-override",0,1);
460 const char *zUserOvrd = find_option("user-override",0,1);
461
462 verify_all_options();
463 db_begin_transaction();
464 for( ; argPos < g.argc; fossil_free(zUuid), ++argPos ){
465 const char * zBranch = g.argv[argPos];
466 const int rid = name_to_uuid2(zBranch, "ci", &zUuid);
467 if(0==rid){
468 fossil_fatal("Cannot resolve branch name: %s", zBranch);
469 }else if(rid<0){
470 fossil_fatal("Ambiguous branch name: %s", zBranch);
471 }else if(!is_a_leaf(rid)){
472 fossil_warning("Skipping non-leaf [%s] %s", zBranch, zUuid);
473 continue;
474 }else if(leaf_is_closed(rid)){
475 fossil_warning("Skipping closed [%s] %s", zBranch, zUuid);
476 continue;
477 }
478 branch_cmd_tag_add(rid, "+closed");
479 if(fVerbose!=0){
480 fossil_print("Closing branch [%s] %s\n", zBranch, zUuid);
481 }
482 }
483 branch_cmd_tag_finalize(fDryRun, fVerbose, zDateOvrd, zUserOvrd);
484 }
485
486 /*
487 ** COMMAND: branch
488 **
489

Keyboard Shortcuts

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