Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Track the origin of tags and display that origin in the tag and properities information field of the "vinfo" page. Must "fossil rebuild" after this change. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
08db9e11cb6f86f943893cc154bc86c6 |
| User & Date: | drh 2009-01-21 23:40:17.000 |
Context
|
2009-01-22
| ||
| 01:10 | Improved messages in the "tags and properties" section of the vinfo page. Distinguish between a merge between forks and a merge between branches. A merge from forks, closes the fork, but not a merge from a branch. check-in: 042a08b564 user: drh tags: trunk | |
|
2009-01-21
| ||
| 23:40 | Track the origin of tags and display that origin in the tag and properities information field of the "vinfo" page. Must "fossil rebuild" after this change. check-in: 08db9e11cb user: drh tags: trunk | |
| 18:59 | Add timeline links on the leaves page. Also on the leaves page, do not show Merge labels on check-ins. The second part is the fix for ticket [d6bb26f436d8299f95d63f45fa51c92acdc91c5a]. check-in: 2fa4df1e47 user: drh tags: trunk | |
Changes
Changes to src/branch.c.
| ︙ | ︙ | |||
255 256 257 258 259 260 261 262 263 264 265 266 267 268 |
"%s AND blob.rid IN (SELECT rid FROM tagxref WHERE tagtype>0 AND tagid=%d)"
" ORDER BY event.mtime DESC",
timeline_query_for_www(), TAG_NEWBRANCH
);
www_print_timeline(&q, 0, brlist_extra);
db_finalize(&q);
@ <br clear="both">
@ <script>
@ function xin(id){
@ }
@ function xout(id){
@ }
@ </script>
style_footer();
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 |
"%s AND blob.rid IN (SELECT rid FROM tagxref WHERE tagtype>0 AND tagid=%d)"
" ORDER BY event.mtime DESC",
timeline_query_for_www(), TAG_NEWBRANCH
);
www_print_timeline(&q, 0, brlist_extra);
db_finalize(&q);
@ <br clear="both">
@ <script>
@ function xin(id){
@ }
@ function xout(id){
@ }
@ </script>
style_footer();
}
/*
** WEBPAGE: symtaglist
**
** Show a timeline of all check-ins that have a primary symbolic tag.
*/
void symtaglist_page(void){
Stmt q;
login_check_credentials();
if( !g.okRead ){ login_needed(); return; }
style_header("Tagged Check-ins");
login_anonymous_available();
@ <h2>Check-ins that have one or more primary symbolic tags</h2>
db_prepare(&q,
"%s AND blob.rid IN (SELECT rid FROM tagxref"
" WHERE tagtype>1 AND srcid>0"
" AND tagid IN (SELECT tagid FROM tag "
" WHERE tagname GLOB 'sym-*'))"
" ORDER BY event.mtime DESC",
timeline_query_for_www(), TAG_NEWBRANCH
);
www_print_timeline(&q, 0, 0);
db_finalize(&q);
@ <br clear="both">
@ <script>
@ function xin(id){
@ }
@ function xout(id){
@ }
@ </script>
style_footer();
|
| ︙ | ︙ |
Changes to src/info.c.
| ︙ | ︙ | |||
267 268 269 270 271 272 273 |
/*
** Show information about all tags on a given node.
*/
static void showTags(int rid, const char *zNotGlob){
Stmt q;
int cnt = 0;
db_prepare(&q,
| | > | > < | < | | | | > > > | < < | | > | > | > > > > | | > | | 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 |
/*
** Show information about all tags on a given node.
*/
static void showTags(int rid, const char *zNotGlob){
Stmt q;
int cnt = 0;
db_prepare(&q,
"SELECT tag.tagid, tagname, "
" (SELECT uuid FROM blob WHERE rid=tagxref.srcid AND rid!=%d),"
" value, datetime(tagxref.mtime,'localtime'), tagtype,"
" (SELECT uuid FROM blob WHERE rid=tagxref.origid)"
" FROM tagxref JOIN tag ON tagxref.tagid=tag.tagid"
" WHERE tagxref.rid=%d AND tagname NOT GLOB '%s'"
" ORDER BY tagname", rid, rid, zNotGlob
);
while( db_step(&q)==SQLITE_ROW ){
const char *zTagname = db_column_text(&q, 1);
const char *zSrcUuid = db_column_text(&q, 2);
const char *zValue = db_column_text(&q, 3);
const char *zDate = db_column_text(&q, 4);
int tagtype = db_column_int(&q, 5);
const char *zOrigUuid = db_column_text(&q, 6);
cnt++;
if( cnt==1 ){
@ <div class="section">Tags And Properties</div>
@ <ul>
}
@ <li>
@ <b>%h(zTagname)</b>
if( tagtype==0 ){
@ <i>cancelled.
}else if( zValue ){
@ = %h(zValue)<i>
}else {
@ <i>
}
if( tagtype==2 ){
if( zOrigUuid && zOrigUuid[0] ){
@ inherited from
hyperlink_to_uuid(zOrigUuid);
}else{
@ propagates to descendants
}
}
if( zSrcUuid && zSrcUuid[0] ){
@ added by
hyperlink_to_uuid(zSrcUuid);
@ on %s(zDate)
}
@ </i>
}
db_finalize(&q);
if( cnt ){
@ </ul>
}
}
|
| ︙ | ︙ |
Changes to src/manifest.c.
| ︙ | ︙ | |||
499 500 501 502 503 504 505 |
/* A valid uuid */
}else if( blob_size(&a2)==1 && zUuid[0]=='*' ){
zUuid = 0;
}else{
goto manifest_syntax_error;
}
defossilize(zName);
| | | 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 |
/* A valid uuid */
}else if( blob_size(&a2)==1 && zUuid[0]=='*' ){
zUuid = 0;
}else{
goto manifest_syntax_error;
}
defossilize(zName);
if( zName[0]!='-' && zName[0]!='+' && zName[0]!='*' ){
goto manifest_syntax_error;
}
if( validate16(&zName[1], strlen(&zName[1])) ){
/* Do not allow tags whose names look like UUIDs */
goto manifest_syntax_error;
}
if( p->nTag>=p->nTagAlloc ){
|
| ︙ | ︙ | |||
946 947 948 949 950 951 952 |
if( m.aTag[i].zUuid ){
tid = uuid_to_rid(m.aTag[i].zUuid, 1);
}else{
tid = rid;
}
if( tid ){
switch( m.aTag[i].zName[0] ){
| > | | < < | 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 |
if( m.aTag[i].zUuid ){
tid = uuid_to_rid(m.aTag[i].zUuid, 1);
}else{
tid = rid;
}
if( tid ){
switch( m.aTag[i].zName[0] ){
case '-': type = 0; break; /* Cancel prior occurances */
case '+': type = 1; break; /* Apply to target only */
case '*': type = 2; break; /* Propagate to descendants */
default:
fossil_fatal("unknown tag type in manifest: %s", m.aTag);
return 0;
}
tag_insert(&m.aTag[i].zName[1], type, m.aTag[i].zValue,
rid, m.rDate, tid);
}
|
| ︙ | ︙ |
Changes to src/schema.c.
| ︙ | ︙ | |||
288 289 290 291 292 293 294 | @ -- have values assigned to them. So we are not really dealing with @ -- tags here. These are really properties. But we are going to @ -- keep calling them tags because in many cases the value is ignored. @ -- @ CREATE TABLE tagxref( @ tagid INTEGER REFERENCES tag, -- The tag that added or removed @ tagtype INTEGER, -- 0:cancel 1:single 2:branch | | > | | 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 | @ -- have values assigned to them. So we are not really dealing with @ -- tags here. These are really properties. But we are going to @ -- keep calling them tags because in many cases the value is ignored. @ -- @ CREATE TABLE tagxref( @ tagid INTEGER REFERENCES tag, -- The tag that added or removed @ tagtype INTEGER, -- 0:cancel 1:single 2:branch @ srcid INTEGER REFERENCES blob, -- Artifact of tag. 0 for propagated tags @ origid INTEGER REFERENCES blob, -- check-in holding propagated tag @ value TEXT, -- Value of the tag. Might be NULL. @ mtime TIMESTAMP, -- Time of addition or removal @ rid INTEGER REFERENCE blob, -- Artifact tag is applied to @ UNIQUE(rid, tagid) @ ); @ CREATE INDEX tagxref_i1 ON tagxref(tagid, mtime); @ @ -- Template for the TICKET table @ -- @ -- NB: when changing the schema of the TICKET table here, also make the |
| ︙ | ︙ |
Changes to src/tag.c.
| ︙ | ︙ | |||
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
** ancestor node. If tagtype is 0 it means a branch tag is
** being cancelled.
*/
void tag_propagate(
int pid, /* Propagate the tag to children of this node */
int tagid, /* Tag to propagate */
int tagType, /* 2 for a propagating tag. 0 for an antitag */
const char *zValue, /* Value of the tag. Might be NULL */
double mtime /* Timestamp on the tag */
){
PQueue queue;
Stmt s, ins, eventupdate;
assert( tagType==0 || tagType==2 );
pqueue_init(&queue);
pqueue_insert(&queue, pid, 0.0);
db_prepare(&s,
"SELECT cid, plink.mtime,"
" coalesce(srcid=0 AND tagxref.mtime<:mtime, %d) AS doit"
" FROM plink LEFT JOIN tagxref ON cid=rid AND tagid=%d"
" WHERE pid=:pid AND isprim",
tagType!=0, tagid
);
db_bind_double(&s, ":mtime", mtime);
if( tagType==2 ){
db_prepare(&ins,
| > | | | | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
** ancestor node. If tagtype is 0 it means a branch tag is
** being cancelled.
*/
void tag_propagate(
int pid, /* Propagate the tag to children of this node */
int tagid, /* Tag to propagate */
int tagType, /* 2 for a propagating tag. 0 for an antitag */
int origId, /* Artifact of tag, when tagType==2 */
const char *zValue, /* Value of the tag. Might be NULL */
double mtime /* Timestamp on the tag */
){
PQueue queue;
Stmt s, ins, eventupdate;
assert( tagType==0 || tagType==2 );
pqueue_init(&queue);
pqueue_insert(&queue, pid, 0.0);
db_prepare(&s,
"SELECT cid, plink.mtime,"
" coalesce(srcid=0 AND tagxref.mtime<:mtime, %d) AS doit"
" FROM plink LEFT JOIN tagxref ON cid=rid AND tagid=%d"
" WHERE pid=:pid AND isprim",
tagType!=0, tagid
);
db_bind_double(&s, ":mtime", mtime);
if( tagType==2 ){
db_prepare(&ins,
"REPLACE INTO tagxref(tagid, tagtype, srcid, origid, value, mtime, rid)"
"VALUES(%d,2,0,%d,%Q,:mtime,:rid)",
tagid, origId, zValue
);
db_bind_double(&ins, ":mtime", mtime);
}else{
zValue = 0;
db_prepare(&ins,
"DELETE FROM tagxref WHERE tagid=%d AND rid=:rid", tagid
);
|
| ︙ | ︙ | |||
106 107 108 109 110 111 112 |
/*
** Propagate all propagatable tags in pid to its children.
*/
void tag_propagate_all(int pid){
Stmt q;
db_prepare(&q,
| | > | | 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
/*
** Propagate all propagatable tags in pid to its children.
*/
void tag_propagate_all(int pid){
Stmt q;
db_prepare(&q,
"SELECT tagid, tagtype, mtime, value, origid FROM tagxref"
" WHERE rid=%d"
" AND (tagtype=0 OR tagtype=2)",
pid
);
while( db_step(&q)==SQLITE_ROW ){
int tagid = db_column_int(&q, 0);
int tagtype = db_column_int(&q, 1);
double mtime = db_column_double(&q, 2);
const char *zValue = db_column_text(&q, 3);
int origid = db_column_int(&q, 4);
tag_propagate(pid, tagid, tagtype, origid, zValue, mtime);
}
db_finalize(&q);
}
/*
** Get a tagid for the given TAG. Create a new tag if necessary
** if createFlag is 1.
|
| ︙ | ︙ | |||
140 141 142 143 144 145 146 | } /* ** Insert a tag into the database. */ void tag_insert( const char *zTag, /* Name of the tag (w/o the "+" or "-" prefix */ | | | 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
}
/*
** Insert a tag into the database.
*/
void tag_insert(
const char *zTag, /* Name of the tag (w/o the "+" or "-" prefix */
int tagtype, /* 0:cancel 1:singleton 2:propagated */
const char *zValue, /* Value if the tag is really a property */
int srcId, /* Artifact that contains this tag */
double mtime, /* Timestamp. Use default if <=0.0 */
int rid /* Artifact to which the tag is to attached */
){
Stmt s;
const char *zCol;
|
| ︙ | ︙ | |||
168 169 170 171 172 173 174 |
db_bind_double(&s, ":mtime", mtime);
rc = db_step(&s);
db_finalize(&s);
if( rc==SQLITE_ROW ){
/* Another entry that is more recent already exists. Do nothing */
return;
}
| < < < < | 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
db_bind_double(&s, ":mtime", mtime);
rc = db_step(&s);
db_finalize(&s);
if( rc==SQLITE_ROW ){
/* Another entry that is more recent already exists. Do nothing */
return;
}
db_prepare(&s,
"REPLACE INTO tagxref(tagid,tagtype,srcId,value,mtime,rid)"
" VALUES(%d,%d,%d,%Q,:mtime,%d)",
tagid, tagtype, srcId, zValue, rid
);
db_bind_double(&s, ":mtime", mtime);
db_step(&s);
|
| ︙ | ︙ | |||
202 203 204 205 206 207 208 |
break;
}
}
if( zCol ){
db_multi_exec("UPDATE event SET %s=%Q WHERE objid=%d", zCol, zValue, rid);
}
if( tagtype==0 || tagtype==2 ){
| | | 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
break;
}
}
if( zCol ){
db_multi_exec("UPDATE event SET %s=%Q WHERE objid=%d", zCol, zValue, rid);
}
if( tagtype==0 || tagtype==2 ){
tag_propagate(rid, tagid, tagtype, rid, zValue, mtime);
}
}
/*
** COMMAND: test-tag
** %fossil test-tag (+|*|-)TAGNAME ARTIFACT-ID ?VALUE?
|
| ︙ | ︙ |