Fossil SCM

Merge trunk for the new 'fossil tag -root' flag, which is useful in testing this branch's feature.

stephan 2026-05-27 19:50 UTC forum-statuses merge
Commit 63fee24a3a04121af39aab8a37c2b6a0ce930def7db1a600b9d10a55014cf1e2
--- 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
+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