Fossil SCM

Add the -root flag to [/help/tag|fossil tag add/cancel/ls] which translates the given name to the root-most primary parent of the given artifact. This is primarily intended to simplify tagging of forum pages, where we apply tags to the initial version for consistent handling of tags across a post's history.

stephan 2026-05-27 19:43 UTC trunk
Commit ab0f06a5acb9e5a268bedc4b40575651ab2edde9bb84b5534f399c3642a14720
3 files changed +22 +1 -1 +70 -25
--- src/manifest.c
+++ src/manifest.c
@@ -3232,5 +3232,27 @@
32323232
db_finalize(&q);
32333233
if( nErr ){
32343234
fossil_warning("Error count: %d", nErr);
32353235
}
32363236
}
3237
+
3238
+/*
3239
+** Given the RID of an artifact, if that artifact type supports
3240
+** P-cards then this returns the root-most RID of the P-card chain by
3241
+** traversing the plink table, considering only primary parents. If
3242
+** rid refers to anything other than such an artifact, or if the
3243
+** artifact has no primary parent, rid is returned as-is.
3244
+*/
3245
+int rid_root_parent(int rid){
3246
+ Stmt q;
3247
+ db_prepare(
3248
+ &q, "SELECT pid FROM plink WHERE isprim AND cid=:cid"
3249
+ );
3250
+ db_bind_int(&q, ":cid", rid);
3251
+ while( SQLITE_ROW==db_step(&q) ){
3252
+ rid = db_column_int(&q, 0);
3253
+ db_reset(&q);
3254
+ db_bind_int(&q, ":cid", rid);
3255
+ }
3256
+ db_finalize(&q);
3257
+ return rid;
3258
+}
32373259
--- src/manifest.c
+++ src/manifest.c
@@ -3232,5 +3232,27 @@
3232 db_finalize(&q);
3233 if( nErr ){
3234 fossil_warning("Error count: %d", nErr);
3235 }
3236 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3237
--- src/manifest.c
+++ src/manifest.c
@@ -3232,5 +3232,27 @@
3232 db_finalize(&q);
3233 if( nErr ){
3234 fossil_warning("Error count: %d", nErr);
3235 }
3236 }
3237
3238 /*
3239 ** Given the RID of an artifact, if that artifact type supports
3240 ** P-cards then this returns the root-most RID of the P-card chain by
3241 ** traversing the plink table, considering only primary parents. If
3242 ** rid refers to anything other than such an artifact, or if the
3243 ** artifact has no primary parent, rid is returned as-is.
3244 */
3245 int rid_root_parent(int rid){
3246 Stmt q;
3247 db_prepare(
3248 &q, "SELECT pid FROM plink WHERE isprim AND cid=:cid"
3249 );
3250 db_bind_int(&q, ":cid", rid);
3251 while( SQLITE_ROW==db_step(&q) ){
3252 rid = db_column_int(&q, 0);
3253 db_reset(&q);
3254 db_bind_int(&q, ":cid", rid);
3255 }
3256 db_finalize(&q);
3257 return rid;
3258 }
3259
+1 -1
--- src/schema.c
+++ src/schema.c
@@ -277,11 +277,11 @@
277277
@ CREATE INDEX mlink_i1 ON mlink(mid);
278278
@ CREATE INDEX mlink_i2 ON mlink(fnid);
279279
@ CREATE INDEX mlink_i3 ON mlink(fid);
280280
@ CREATE INDEX mlink_i4 ON mlink(pid);
281281
@
282
-@ -- Parent/child linkages between check-ins
282
+@ -- Parent/child linkages between artifacts with P-cards.
283283
@ --
284284
@ CREATE TABLE plink(
285285
@ pid INTEGER REFERENCES blob, -- Parent manifest
286286
@ cid INTEGER REFERENCES blob, -- Child manifest
287287
@ isprim BOOLEAN, -- pid is the primary parent of cid
288288
--- src/schema.c
+++ src/schema.c
@@ -277,11 +277,11 @@
277 @ CREATE INDEX mlink_i1 ON mlink(mid);
278 @ CREATE INDEX mlink_i2 ON mlink(fnid);
279 @ CREATE INDEX mlink_i3 ON mlink(fid);
280 @ CREATE INDEX mlink_i4 ON mlink(pid);
281 @
282 @ -- Parent/child linkages between check-ins
283 @ --
284 @ CREATE TABLE plink(
285 @ pid INTEGER REFERENCES blob, -- Parent manifest
286 @ cid INTEGER REFERENCES blob, -- Child manifest
287 @ isprim BOOLEAN, -- pid is the primary parent of cid
288
--- src/schema.c
+++ src/schema.c
@@ -277,11 +277,11 @@
277 @ CREATE INDEX mlink_i1 ON mlink(mid);
278 @ CREATE INDEX mlink_i2 ON mlink(fnid);
279 @ CREATE INDEX mlink_i3 ON mlink(fid);
280 @ CREATE INDEX mlink_i4 ON mlink(pid);
281 @
282 @ -- Parent/child linkages between artifacts with P-cards.
283 @ --
284 @ CREATE TABLE plink(
285 @ pid INTEGER REFERENCES blob, -- Parent manifest
286 @ cid INTEGER REFERENCES blob, -- Child manifest
287 @ isprim BOOLEAN, -- pid is the primary parent of cid
288
+70 -25
--- src/tag.c
+++ src/tag.c
@@ -384,10 +384,30 @@
384384
|| strncmp(zTag,"tkt-",4)==0
385385
|| strncmp(zTag,"event-",6)==0)){
386386
fossil_fatal("Invalid prefix for tag name: %s", zTag);
387387
}
388388
}
389
+
390
+/*
391
+** Internal helper for the tag command. Fetches rid_root_parent(rid)
392
+** and if it differs from the input, assigns *zSym to the root object's
393
+** UUID (intentionally leaking it).
394
+*/
395
+static int tag_cmd_root(int rid, char const **zSym, int bVerbose){
396
+ const int origRid = rid;
397
+ rid = rid_root_parent(rid);
398
+ assert( rid>0 );
399
+ if( origRid!=rid ){
400
+ char const *zOrig = *zSym;
401
+ *zSym = rid_to_uuid(rid)/*intentional leak*/;
402
+ if( bVerbose ){
403
+ fossil_print("Redirecting tag from %!S to root ancestor %!S.\n",
404
+ zOrig, *zSym);
405
+ }
406
+ }
407
+ return rid;
408
+}
389409
390410
/*
391411
** COMMAND: tag
392412
**
393413
** Usage: %fossil tag SUBCOMMAND ...
@@ -409,19 +429,30 @@
409429
** actually insert it into the database
410430
** --propagate Propagating tag
411431
** --raw Raw tag name. Ignored for
412432
** non-CHECK-IN artifacts.
413433
** --user-override USER Name USER when adding the tag
434
+** --root If ARTIFACT-ID refers to an artifact
435
+** with a P-card, it gets translated to the
436
+** oldest parent of that artifact and
437
+** --propagate is assumed. This is
438
+** most useful with forum posts, wiki
439
+** pages, and tech notes, where tags are
440
+** most easliy managed via their initial
441
+** version.
414442
**
415443
** The --date-override and --user-override options support
416444
** importing history from other SCM systems. DATETIME has
417445
** the form 'YYYY-MM-DD HH:MM:SS'.
418446
**
419447
** Note that fossil uses some tag prefixes internally and this
420448
** command will reject tags with these prefixes to avoid
421449
** causing problems or confusion: "wiki-", "tkt-", "event-".
422450
**
451
+** When tagging forum posts, the ARTIFACT-ID is translated to
452
+** the initial version of that post and --propagate is implied.
453
+**
423454
** > fossil tag cancel ?--raw? TAGNAME ARTIFACT-ID
424455
**
425456
** Remove the tag TAGNAME from the artifact referenced by
426457
** ARTIFACT-ID, and also remove the propagation of the tag to
427458
** any descendants. Use the -n|--dry-run option to see
@@ -433,10 +464,11 @@
433464
** -n|--dry-run Display the control artifact, but do
434465
** not insert it into the database
435466
** --raw Raw tag name. Ignored for
436467
** non-CHECK-IN artifacts.
437468
** --user-override USER Name USER when deleting the tag
469
+** --root As described for 'add'.
438470
**
439471
** > fossil tag find ?OPTIONS? TAGNAME
440472
**
441473
** List all objects that use TAGNAME.
442474
**
@@ -452,12 +484,11 @@
452484
** if --raw is used.
453485
**
454486
** > fossil tag list|ls ?OPTIONS? ?ARTIFACT-ID?
455487
**
456488
** List all tags or, if ARTIFACT-ID is supplied, all tags and
457
-** their values for that artifact. The tagtype option accepts
458
-** one of: propagated, singleton, cancel. For historical
489
+** their values for that artifact. For historical
459490
** scripting compatibility, the internal tag types "wiki-",
460491
** "tkt-", and "event-" (technote) are elided by default
461492
** unless the --raw or --prefix options are used.
462493
**
463494
** Options:
@@ -475,10 +506,12 @@
475506
** be one of: cancel, singleton, propagated
476507
** --values List tag values
477508
** If --sep is supplied, list all values of a tag on
478509
** the same line, separated by SEP; otherwise list
479510
** each value on its own line.
511
+** --root As described for 'add' and only if ARTIFACT-ID is
512
+** provided.
480513
**
481514
** The option --raw allows the manipulation of all types of tags
482515
** used for various internal purposes in fossil. It also shows
483516
** "cancel" tags for the "find" and "list" subcommands. You should
484517
** not use this option to make changes unless you are sure what
@@ -512,34 +545,38 @@
512545
513546
if( strncmp(g.argv[2],"add",n)==0 ){
514547
char *zValue;
515548
int dryRun = 0;
516549
int fRaw = find_option("raw","",0)!=0;
517
- const char *zPrefix = "";
518550
int fPropagate = find_option("propagate","",0)!=0;
551
+ int fRoot = find_option("root","",0)!=0;
552
+ int objType;
553
+ int rid;
554
+ const char *zPrefix = "";
519555
const char *zDateOvrd = find_option("date-override",0,1);
520556
const char *zUserOvrd = find_option("user-override",0,1);
521557
const char *zTag;
522558
const char *zObjId;
523
- int objType;
524559
if( find_option("dry-run","n",0)!=0 ) dryRun = TAG_ADD_DRYRUN;
525560
if( g.argc!=5 && g.argc!=6 ){
526561
usage("add ?options? TAGNAME ARTIFACT-ID ?VALUE?");
527562
}
528563
zTag = g.argv[3];
529564
tag_cmd_tagname_check(zTag);
530565
zObjId = g.argv[4];
531566
zValue = g.argc==6 ? g.argv[5] : 0;
532
- objType = whatis_rid_type(symbolic_name_to_rid(zObjId, 0));
533
- switch(objType){
534
- case 0:
535
- fossil_fatal("Cannot resolve artifact ID: %s", zObjId);
536
- break;
537
- case CFTYPE_MANIFEST:
538
- zPrefix = fRaw ? "" : "sym-";
539
- break;
540
- default: break;
567
+ rid = symbolic_name_to_rid(zObjId, 0);
568
+ if( rid<=0 ){
569
+ fossil_fatal("Cannot resolve artifact ID: %s", zObjId);
570
+ }
571
+ if( fRoot ){
572
+ rid = tag_cmd_root(rid, &zObjId, dryRun);
573
+ fPropagate = 1;
574
+ }
575
+ objType = whatis_rid_type(rid);
576
+ if( CFTYPE_MANIFEST==objType ){
577
+ zPrefix = fRaw ? "" : "sym-";
541578
}
542579
db_begin_transaction();
543580
tag_add_artifact(zPrefix, zTag, zObjId, zValue,
544581
1+fPropagate+dryRun,zDateOvrd,zUserOvrd);
545582
db_end_transaction(0);
@@ -551,32 +588,35 @@
551588
}else
552589
553590
if( strncmp(g.argv[2],"cancel",n)==0 ){
554591
int dryRun = 0;
555592
int fRaw = find_option("raw","",0)!=0;
593
+ int fRoot = find_option("root","",0)!=0;
594
+ int objType;
595
+ int rid;
556596
const char *zPrefix = "";
557597
const char *zDateOvrd = find_option("date-override",0,1);
558598
const char *zUserOvrd = find_option("user-override",0,1);
559599
const char *zTag;
560600
const char *zObjId;
561
- int objType;
562601
if( find_option("dry-run","n",0)!=0 ) dryRun = TAG_ADD_DRYRUN;
563602
if( g.argc!=5 ){
564603
usage("cancel ?options? TAGNAME ARTIFACT-ID");
565604
}
566605
zTag = g.argv[3];
567606
tag_cmd_tagname_check(zTag);
568607
zObjId = g.argv[4];
569
- objType = whatis_rid_type(symbolic_name_to_rid(zObjId, 0));
570
- switch(objType){
571
- case 0:
572
- fossil_fatal("Cannot resolve artifact ID: %s", zObjId);
573
- break;
574
- case CFTYPE_MANIFEST:
575
- zPrefix = fRaw ? "" : "sym-";
576
- break;
577
- default: break;
608
+ rid = symbolic_name_to_rid(zObjId, 0);
609
+ if( rid<=0 ){
610
+ fossil_fatal("Cannot resolve artifact ID: %s", zObjId);
611
+ }
612
+ if( fRoot ){
613
+ rid = tag_cmd_root(rid, &zObjId, dryRun);
614
+ }
615
+ objType = whatis_rid_type(rid);
616
+ if( CFTYPE_MANIFEST==objType ){
617
+ zPrefix = fRaw ? "" : "sym-";
578618
}
579619
db_begin_transaction();
580620
tag_add_artifact(zPrefix, zTag, zObjId, 0, dryRun,
581621
zDateOvrd, zUserOvrd);
582622
db_end_transaction(0);
@@ -639,10 +679,11 @@
639679
const char *zTagType = find_option("tagtype","t",1);
640680
const int fInverse = find_option("inverse","v",0)!=0;
641681
const char *zTagPrefix = find_option("prefix","",1);
642682
int nTagType = fRaw ? -1 : 0;
643683
int fValues = find_option("values","",0)!=0;
684
+ int fRoot = find_option("root","",0)!=0;
644685
const char *zSep = find_option("sep","",1);
645686
646687
647688
if( zTagType!=0 ){
648689
int l = strlen(zTagType);
@@ -712,15 +753,19 @@
712753
}
713754
}
714755
db_finalize(&q);
715756
}else if( g.argc==4 ){
716757
char const *zObjId = g.argv[3];
717
- const int rid = name_to_rid(zObjId);
718
- const int objType = whatis_rid_type(rid);
758
+ int rid = name_to_rid(zObjId);
759
+ int objType;
719760
int nTagOffset = 0;
720761
762
+ if( fRoot ){
763
+ rid = tag_cmd_root(rid, &zObjId, 0);
764
+ }
721765
zTagPrefix = 0;
766
+ objType = rid>=0 ? whatis_rid_type(rid) : 0;
722767
if(objType<=0){
723768
fossil_fatal("Cannot resolve artifact ID: %s", zObjId);
724769
}else if(fRaw==0){
725770
/* Figure out the tag prefix to strip */
726771
switch(objType){
727772
--- src/tag.c
+++ src/tag.c
@@ -384,10 +384,30 @@
384 || strncmp(zTag,"tkt-",4)==0
385 || strncmp(zTag,"event-",6)==0)){
386 fossil_fatal("Invalid prefix for tag name: %s", zTag);
387 }
388 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
389
390 /*
391 ** COMMAND: tag
392 **
393 ** Usage: %fossil tag SUBCOMMAND ...
@@ -409,19 +429,30 @@
409 ** actually insert it into the database
410 ** --propagate Propagating tag
411 ** --raw Raw tag name. Ignored for
412 ** non-CHECK-IN artifacts.
413 ** --user-override USER Name USER when adding the tag
 
 
 
 
 
 
 
 
414 **
415 ** The --date-override and --user-override options support
416 ** importing history from other SCM systems. DATETIME has
417 ** the form 'YYYY-MM-DD HH:MM:SS'.
418 **
419 ** Note that fossil uses some tag prefixes internally and this
420 ** command will reject tags with these prefixes to avoid
421 ** causing problems or confusion: "wiki-", "tkt-", "event-".
422 **
 
 
 
423 ** > fossil tag cancel ?--raw? TAGNAME ARTIFACT-ID
424 **
425 ** Remove the tag TAGNAME from the artifact referenced by
426 ** ARTIFACT-ID, and also remove the propagation of the tag to
427 ** any descendants. Use the -n|--dry-run option to see
@@ -433,10 +464,11 @@
433 ** -n|--dry-run Display the control artifact, but do
434 ** not insert it into the database
435 ** --raw Raw tag name. Ignored for
436 ** non-CHECK-IN artifacts.
437 ** --user-override USER Name USER when deleting the tag
 
438 **
439 ** > fossil tag find ?OPTIONS? TAGNAME
440 **
441 ** List all objects that use TAGNAME.
442 **
@@ -452,12 +484,11 @@
452 ** if --raw is used.
453 **
454 ** > fossil tag list|ls ?OPTIONS? ?ARTIFACT-ID?
455 **
456 ** List all tags or, if ARTIFACT-ID is supplied, all tags and
457 ** their values for that artifact. The tagtype option accepts
458 ** one of: propagated, singleton, cancel. For historical
459 ** scripting compatibility, the internal tag types "wiki-",
460 ** "tkt-", and "event-" (technote) are elided by default
461 ** unless the --raw or --prefix options are used.
462 **
463 ** Options:
@@ -475,10 +506,12 @@
475 ** be one of: cancel, singleton, propagated
476 ** --values List tag values
477 ** If --sep is supplied, list all values of a tag on
478 ** the same line, separated by SEP; otherwise list
479 ** each value on its own line.
 
 
480 **
481 ** The option --raw allows the manipulation of all types of tags
482 ** used for various internal purposes in fossil. It also shows
483 ** "cancel" tags for the "find" and "list" subcommands. You should
484 ** not use this option to make changes unless you are sure what
@@ -512,34 +545,38 @@
512
513 if( strncmp(g.argv[2],"add",n)==0 ){
514 char *zValue;
515 int dryRun = 0;
516 int fRaw = find_option("raw","",0)!=0;
517 const char *zPrefix = "";
518 int fPropagate = find_option("propagate","",0)!=0;
 
 
 
 
519 const char *zDateOvrd = find_option("date-override",0,1);
520 const char *zUserOvrd = find_option("user-override",0,1);
521 const char *zTag;
522 const char *zObjId;
523 int objType;
524 if( find_option("dry-run","n",0)!=0 ) dryRun = TAG_ADD_DRYRUN;
525 if( g.argc!=5 && g.argc!=6 ){
526 usage("add ?options? TAGNAME ARTIFACT-ID ?VALUE?");
527 }
528 zTag = g.argv[3];
529 tag_cmd_tagname_check(zTag);
530 zObjId = g.argv[4];
531 zValue = g.argc==6 ? g.argv[5] : 0;
532 objType = whatis_rid_type(symbolic_name_to_rid(zObjId, 0));
533 switch(objType){
534 case 0:
535 fossil_fatal("Cannot resolve artifact ID: %s", zObjId);
536 break;
537 case CFTYPE_MANIFEST:
538 zPrefix = fRaw ? "" : "sym-";
539 break;
540 default: break;
 
 
541 }
542 db_begin_transaction();
543 tag_add_artifact(zPrefix, zTag, zObjId, zValue,
544 1+fPropagate+dryRun,zDateOvrd,zUserOvrd);
545 db_end_transaction(0);
@@ -551,32 +588,35 @@
551 }else
552
553 if( strncmp(g.argv[2],"cancel",n)==0 ){
554 int dryRun = 0;
555 int fRaw = find_option("raw","",0)!=0;
 
 
 
556 const char *zPrefix = "";
557 const char *zDateOvrd = find_option("date-override",0,1);
558 const char *zUserOvrd = find_option("user-override",0,1);
559 const char *zTag;
560 const char *zObjId;
561 int objType;
562 if( find_option("dry-run","n",0)!=0 ) dryRun = TAG_ADD_DRYRUN;
563 if( g.argc!=5 ){
564 usage("cancel ?options? TAGNAME ARTIFACT-ID");
565 }
566 zTag = g.argv[3];
567 tag_cmd_tagname_check(zTag);
568 zObjId = g.argv[4];
569 objType = whatis_rid_type(symbolic_name_to_rid(zObjId, 0));
570 switch(objType){
571 case 0:
572 fossil_fatal("Cannot resolve artifact ID: %s", zObjId);
573 break;
574 case CFTYPE_MANIFEST:
575 zPrefix = fRaw ? "" : "sym-";
576 break;
577 default: break;
 
578 }
579 db_begin_transaction();
580 tag_add_artifact(zPrefix, zTag, zObjId, 0, dryRun,
581 zDateOvrd, zUserOvrd);
582 db_end_transaction(0);
@@ -639,10 +679,11 @@
639 const char *zTagType = find_option("tagtype","t",1);
640 const int fInverse = find_option("inverse","v",0)!=0;
641 const char *zTagPrefix = find_option("prefix","",1);
642 int nTagType = fRaw ? -1 : 0;
643 int fValues = find_option("values","",0)!=0;
 
644 const char *zSep = find_option("sep","",1);
645
646
647 if( zTagType!=0 ){
648 int l = strlen(zTagType);
@@ -712,15 +753,19 @@
712 }
713 }
714 db_finalize(&q);
715 }else if( g.argc==4 ){
716 char const *zObjId = g.argv[3];
717 const int rid = name_to_rid(zObjId);
718 const int objType = whatis_rid_type(rid);
719 int nTagOffset = 0;
720
 
 
 
721 zTagPrefix = 0;
 
722 if(objType<=0){
723 fossil_fatal("Cannot resolve artifact ID: %s", zObjId);
724 }else if(fRaw==0){
725 /* Figure out the tag prefix to strip */
726 switch(objType){
727
--- src/tag.c
+++ src/tag.c
@@ -384,10 +384,30 @@
384 || strncmp(zTag,"tkt-",4)==0
385 || strncmp(zTag,"event-",6)==0)){
386 fossil_fatal("Invalid prefix for tag name: %s", zTag);
387 }
388 }
389
390 /*
391 ** Internal helper for the tag command. Fetches rid_root_parent(rid)
392 ** and if it differs from the input, assigns *zSym to the root object's
393 ** UUID (intentionally leaking it).
394 */
395 static int tag_cmd_root(int rid, char const **zSym, int bVerbose){
396 const int origRid = rid;
397 rid = rid_root_parent(rid);
398 assert( rid>0 );
399 if( origRid!=rid ){
400 char const *zOrig = *zSym;
401 *zSym = rid_to_uuid(rid)/*intentional leak*/;
402 if( bVerbose ){
403 fossil_print("Redirecting tag from %!S to root ancestor %!S.\n",
404 zOrig, *zSym);
405 }
406 }
407 return rid;
408 }
409
410 /*
411 ** COMMAND: tag
412 **
413 ** Usage: %fossil tag SUBCOMMAND ...
@@ -409,19 +429,30 @@
429 ** actually insert it into the database
430 ** --propagate Propagating tag
431 ** --raw Raw tag name. Ignored for
432 ** non-CHECK-IN artifacts.
433 ** --user-override USER Name USER when adding the tag
434 ** --root If ARTIFACT-ID refers to an artifact
435 ** with a P-card, it gets translated to the
436 ** oldest parent of that artifact and
437 ** --propagate is assumed. This is
438 ** most useful with forum posts, wiki
439 ** pages, and tech notes, where tags are
440 ** most easliy managed via their initial
441 ** version.
442 **
443 ** The --date-override and --user-override options support
444 ** importing history from other SCM systems. DATETIME has
445 ** the form 'YYYY-MM-DD HH:MM:SS'.
446 **
447 ** Note that fossil uses some tag prefixes internally and this
448 ** command will reject tags with these prefixes to avoid
449 ** causing problems or confusion: "wiki-", "tkt-", "event-".
450 **
451 ** When tagging forum posts, the ARTIFACT-ID is translated to
452 ** the initial version of that post and --propagate is implied.
453 **
454 ** > fossil tag cancel ?--raw? TAGNAME ARTIFACT-ID
455 **
456 ** Remove the tag TAGNAME from the artifact referenced by
457 ** ARTIFACT-ID, and also remove the propagation of the tag to
458 ** any descendants. Use the -n|--dry-run option to see
@@ -433,10 +464,11 @@
464 ** -n|--dry-run Display the control artifact, but do
465 ** not insert it into the database
466 ** --raw Raw tag name. Ignored for
467 ** non-CHECK-IN artifacts.
468 ** --user-override USER Name USER when deleting the tag
469 ** --root As described for 'add'.
470 **
471 ** > fossil tag find ?OPTIONS? TAGNAME
472 **
473 ** List all objects that use TAGNAME.
474 **
@@ -452,12 +484,11 @@
484 ** if --raw is used.
485 **
486 ** > fossil tag list|ls ?OPTIONS? ?ARTIFACT-ID?
487 **
488 ** List all tags or, if ARTIFACT-ID is supplied, all tags and
489 ** their values for that artifact. For historical
 
490 ** scripting compatibility, the internal tag types "wiki-",
491 ** "tkt-", and "event-" (technote) are elided by default
492 ** unless the --raw or --prefix options are used.
493 **
494 ** Options:
@@ -475,10 +506,12 @@
506 ** be one of: cancel, singleton, propagated
507 ** --values List tag values
508 ** If --sep is supplied, list all values of a tag on
509 ** the same line, separated by SEP; otherwise list
510 ** each value on its own line.
511 ** --root As described for 'add' and only if ARTIFACT-ID is
512 ** provided.
513 **
514 ** The option --raw allows the manipulation of all types of tags
515 ** used for various internal purposes in fossil. It also shows
516 ** "cancel" tags for the "find" and "list" subcommands. You should
517 ** not use this option to make changes unless you are sure what
@@ -512,34 +545,38 @@
545
546 if( strncmp(g.argv[2],"add",n)==0 ){
547 char *zValue;
548 int dryRun = 0;
549 int fRaw = find_option("raw","",0)!=0;
 
550 int fPropagate = find_option("propagate","",0)!=0;
551 int fRoot = find_option("root","",0)!=0;
552 int objType;
553 int rid;
554 const char *zPrefix = "";
555 const char *zDateOvrd = find_option("date-override",0,1);
556 const char *zUserOvrd = find_option("user-override",0,1);
557 const char *zTag;
558 const char *zObjId;
 
559 if( find_option("dry-run","n",0)!=0 ) dryRun = TAG_ADD_DRYRUN;
560 if( g.argc!=5 && g.argc!=6 ){
561 usage("add ?options? TAGNAME ARTIFACT-ID ?VALUE?");
562 }
563 zTag = g.argv[3];
564 tag_cmd_tagname_check(zTag);
565 zObjId = g.argv[4];
566 zValue = g.argc==6 ? g.argv[5] : 0;
567 rid = symbolic_name_to_rid(zObjId, 0);
568 if( rid<=0 ){
569 fossil_fatal("Cannot resolve artifact ID: %s", zObjId);
570 }
571 if( fRoot ){
572 rid = tag_cmd_root(rid, &zObjId, dryRun);
573 fPropagate = 1;
574 }
575 objType = whatis_rid_type(rid);
576 if( CFTYPE_MANIFEST==objType ){
577 zPrefix = fRaw ? "" : "sym-";
578 }
579 db_begin_transaction();
580 tag_add_artifact(zPrefix, zTag, zObjId, zValue,
581 1+fPropagate+dryRun,zDateOvrd,zUserOvrd);
582 db_end_transaction(0);
@@ -551,32 +588,35 @@
588 }else
589
590 if( strncmp(g.argv[2],"cancel",n)==0 ){
591 int dryRun = 0;
592 int fRaw = find_option("raw","",0)!=0;
593 int fRoot = find_option("root","",0)!=0;
594 int objType;
595 int rid;
596 const char *zPrefix = "";
597 const char *zDateOvrd = find_option("date-override",0,1);
598 const char *zUserOvrd = find_option("user-override",0,1);
599 const char *zTag;
600 const char *zObjId;
 
601 if( find_option("dry-run","n",0)!=0 ) dryRun = TAG_ADD_DRYRUN;
602 if( g.argc!=5 ){
603 usage("cancel ?options? TAGNAME ARTIFACT-ID");
604 }
605 zTag = g.argv[3];
606 tag_cmd_tagname_check(zTag);
607 zObjId = g.argv[4];
608 rid = symbolic_name_to_rid(zObjId, 0);
609 if( rid<=0 ){
610 fossil_fatal("Cannot resolve artifact ID: %s", zObjId);
611 }
612 if( fRoot ){
613 rid = tag_cmd_root(rid, &zObjId, dryRun);
614 }
615 objType = whatis_rid_type(rid);
616 if( CFTYPE_MANIFEST==objType ){
617 zPrefix = fRaw ? "" : "sym-";
618 }
619 db_begin_transaction();
620 tag_add_artifact(zPrefix, zTag, zObjId, 0, dryRun,
621 zDateOvrd, zUserOvrd);
622 db_end_transaction(0);
@@ -639,10 +679,11 @@
679 const char *zTagType = find_option("tagtype","t",1);
680 const int fInverse = find_option("inverse","v",0)!=0;
681 const char *zTagPrefix = find_option("prefix","",1);
682 int nTagType = fRaw ? -1 : 0;
683 int fValues = find_option("values","",0)!=0;
684 int fRoot = find_option("root","",0)!=0;
685 const char *zSep = find_option("sep","",1);
686
687
688 if( zTagType!=0 ){
689 int l = strlen(zTagType);
@@ -712,15 +753,19 @@
753 }
754 }
755 db_finalize(&q);
756 }else if( g.argc==4 ){
757 char const *zObjId = g.argv[3];
758 int rid = name_to_rid(zObjId);
759 int objType;
760 int nTagOffset = 0;
761
762 if( fRoot ){
763 rid = tag_cmd_root(rid, &zObjId, 0);
764 }
765 zTagPrefix = 0;
766 objType = rid>=0 ? whatis_rid_type(rid) : 0;
767 if(objType<=0){
768 fossil_fatal("Cannot resolve artifact ID: %s", zObjId);
769 }else if(fRaw==0){
770 /* Figure out the tag prefix to strip */
771 switch(objType){
772

Keyboard Shortcuts

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