Overview
SHA1 Hash: | 42c2a18e736b0cc75a93daa63a7afb6cec0d7856 |
---|---|
Date: | 2009-01-22 12:03:51 |
User: | drh |
Comment: | Change the way branches are tagged: The value of the "branch" property is used to identify the branch name. Repository rebuild required. Also, branches must be retagged. |
Timelines: | ancestors | descendants | both | trunk |
Other Links: | files | ZIP archive | manifest |
Tags And Properties
- branch=trunk inherited from [a28c83647d]
- sym-trunk inherited from [a28c83647d]
Changes
[hide diffs]Modified src/branch.c from [ffbb452f74] to [4a024d4405].
@@ -105,17 +105,17 @@ zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rootid); blob_appendf(&branch, "P %s\n", zUuid); blob_appendf(&branch, "R %s\n", mParent.zRepoCksum); manifest_clear(&mParent); - /* Add the symbolic branch name and the "newbranch" tag to identify + /* Add the symbolic branch name and the "branch" tag to identify ** this as a new branch */ if( zColor!=0 ){ blob_appendf(&branch, "T *bgcolor * %F\n", zColor); } - blob_appendf(&branch, "T *sym-%F *\n", zBranch); - blob_appendf(&branch, "T +newbranch *\n"); + blob_appendf(&branch, "T *branch * %F\n", zBranch); + blob_appendf(&branch, "T *sym-%F *\n", zBranch); /* Cancel all other symbolic tags */ db_prepare(&q, "SELECT tagname FROM tagxref, tag" " WHERE tagxref.rid=%d AND tagxref.tagid=tag.tagid" @@ -201,13 +201,13 @@ }else if( n>=2 && strncmp(g.argv[2],"list",n)==0 ){ Stmt q; db_prepare(&q, "%s" " AND blob.rid IN (SELECT rid FROM tagxref" - " WHERE tagid=%d AND tagtype==1)" + " WHERE tagid=%d AND tagtype==2 AND srcid!=0)" " ORDER BY event.mtime DESC", - timeline_query_for_tty(), TAG_NEWBRANCH + timeline_query_for_tty(), TAG_BRANCH ); print_timeline(&q, 2000); db_finalize(&q); }else{ fossil_panic("branch subcommand should be one of: " @@ -250,13 +250,14 @@ style_header("Branches"); login_anonymous_available(); @ <h2>The initial check-in for each branch:</h2> db_prepare(&q, - "%s AND blob.rid IN (SELECT rid FROM tagxref WHERE tagtype>0 AND tagid=%d)" + "%s AND blob.rid IN (SELECT rid FROM tagxref" + " WHERE tagtype>0 AND tagid=%d AND srcid!=0)" " ORDER BY event.mtime DESC", - timeline_query_for_www(), TAG_NEWBRANCH + timeline_query_for_www(), TAG_BRANCH ); www_print_timeline(&q, 0, brlist_extra); db_finalize(&q); @ <br clear="both"> @ <script> @@ -286,11 +287,11 @@ "%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 + timeline_query_for_www() ); www_print_timeline(&q, 0, 0); db_finalize(&q); @ <br clear="both"> @ <script>
Modified src/checkin.c from [dbcea16417] to [b209458847].
@@ -347,44 +347,24 @@ } } /* ** Return true if the check-in with RID=rid is a leaf. -** -** A leaf has no children in the same branch. For the purposes of -** this definition, a two check-ins are in same branch they have the -** same set of propagated symbolic tags. +** A leaf has no children in the same branch. */ int is_a_leaf(int rid){ - - /* This query selects all children in the same branch as rid */ + int rc; static const char zSql[] = - @ SELECT cid FROM plink - @ WHERE pid=:rid - @ AND (SELECT group_concat(x) FROM ( - @ SELECT tag.tagid AS x FROM tagxref, tag - @ WHERE tagxref.rid=:rid AND tagxref.tagtype=2 - @ AND tag.tagid=tagxref.tagid AND tagxref.srcid=0 - @ AND tag.tagname GLOB 'sym-*' - @ ORDER BY 1) - @ ) == - @ (SELECT group_concat(x) FROM ( - @ SELECT tag.tagid AS x FROM tagxref, tag - @ WHERE tagxref.rid=plink.cid AND tagxref.tagtype=2 - @ AND tag.tagid=tagxref.tagid - @ AND tag.tagname GLOB 'sym-*' - @ ORDER BY 1) - @ ) + @ SELECT 1 FROM plink + @ WHERE pid=%d + @ AND coalesce((SELECT value FROM tagxref + @ WHERE tagid=%d AND rid=plink.pid), 'trunk') + @ =coalesce((SELECT value FROM tagxref + @ WHERE tagid=%d AND rid=plink.cid), 'trunk') ; - Stmt q; /* The prepared statement */ - int rc; /* Return code from stepping the prepared statement */ - - db_prepare(&q, zSql); - db_bind_int(&q, ":rid", rid); - rc = db_step(&q); - db_finalize(&q); - return rc==SQLITE_DONE; + rc = db_int(0, zSql, rid, TAG_BRANCH, TAG_BRANCH); + return rc==0; } /* ** COMMAND: ci ** COMMAND: commit
Modified src/db.c from [47c06ea3d7] to [c34a03c3db].
@@ -940,12 +940,12 @@ zDate[10]='T'; blob_appendf(&manifest, "D %s\n", zDate); blob_appendf(&manifest, "P\n"); md5sum_init(); blob_appendf(&manifest, "R %s\n", md5sum_finish(0)); - blob_appendf(&manifest, "T *sym-trunk *\n"); - blob_appendf(&manifest, "T +newbranch *\n"); + blob_appendf(&manifest, "T *branch * trunk\n"); + blob_appendf(&manifest, "T *sym-trunk *\n"); blob_appendf(&manifest, "U %F\n", g.zLogin); md5sum_blob(&manifest, &hash); blob_appendf(&manifest, "Z %b\n", &hash); blob_reset(&hash); rid = content_put(&manifest, 0, 0);
Modified src/descendants.c from [c48bc9acc2] to [8b62b08925].
@@ -33,21 +33,11 @@ ** Create a temporary table named "leaves" if it does not ** already exist. Load this table with the RID of all ** check-ins that are leaves which are decended from ** check-in iBase. ** -** A "leaf" is a check-in that has no children. For the purpose -** of finding leaves, children marked with the "newbranch" tag are -** not counted as children. For example: -** -** -** A -> B -> C -> D -** `-> E -** -** D and E are clearly leaves since they have no children. If -** D has the "newbranch" tag, then C is also a leaf since its only -** child is marked as a newbranch. +** A "leaf" is a check-in that has no children in the same branch. ** ** The closeMode flag determines behavior associated with the "closed" ** tag: ** ** closeMode==0 Show all leaves regardless of the "closed" tag. @@ -93,16 +83,17 @@ /* This query returns all non-merge children of check-in :rid */ db_prepare(&q1, "SELECT cid FROM plink WHERE pid=:rid AND isprim"); /* This query returns a single row if check-in :rid is the first - ** check-in of a new branch. In other words, it returns a row if - ** check-in :rid has the 'newbranch' tag. + ** check-in of a new branch. */ db_prepare(&isBr, - "SELECT 1 FROM tagxref WHERE rid=:rid AND tagid=%d AND tagtype=1", - TAG_NEWBRANCH + "SELECT 1 FROM tagxref" + " WHERE rid=:rid AND tagid=%d AND tagtype=2" + " AND srcid>0", + TAG_BRANCH ); /* This statement inserts check-in :rid into the LEAVES table. */ db_prepare(&ins, "INSERT OR IGNORE INTO leaves VALUES(:rid)");
Modified src/info.c from [e618e31047] to [24ba1fa9ee].
@@ -230,21 +230,22 @@ /* ** Show information about baselines mentioned in the "leaves" table. */ -static void showLeaves(void){ +static void showLeaves(int rid){ Stmt q; int cnt = 0; db_prepare(&q, "SELECT blob.uuid, datetime(event.mtime, 'localtime')," " coalesce(event.euser, event.user)," " coalesce(event.ecomment,event.comment)" " FROM leaves, blob, event" - " WHERE blob.rid=leaves.rid" + " WHERE blob.rid=leaves.rid AND blob.rid!=%d" " AND event.objid=leaves.rid" - " ORDER BY event.mtime DESC" + " ORDER BY event.mtime DESC", + rid ); while( db_step(&q)==SQLITE_ROW ){ const char *zUuid = db_column_text(&q, 0); const char *zDate = db_column_text(&q, 1); const char *zUser = db_column_text(&q, 2); @@ -477,11 +478,11 @@ } } @ </ul> compute_leaves(rid, 0); showDescendants(rid, 2, "Descendants"); - showLeaves(); + showLeaves(rid); showAncestors(rid, 2, "Ancestors"); style_footer(); } /* @@ -1165,13 +1166,16 @@ const char *zNewComment; const char *zUser; const char *zNewUser; const char *zColor; const char *zNewColor; + const char *zNewTag; + const char *zNewBranch; int fPropagateColor; char *zUuid; Blob comment; + Stmt q; static const struct SampleColors { const char *zCName; const char *zColor; } aColor[] = { { "(none)", "" }, @@ -1190,26 +1194,30 @@ int i; login_check_credentials(); if( !g.okWrite ){ login_needed(); return; } rid = atoi(PD("r","0")); + zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); zComment = db_text(0, "SELECT coalesce(ecomment,comment)" " FROM event WHERE objid=%d", rid); if( zComment==0 ) fossil_redirect_home(); + if( P("cancel") ){ + cgi_redirectf("vinfo?name=%d", rid); + } zNewComment = PD("c",zComment); zUser = db_text(0, "SELECT coalesce(euser,user)" " FROM event WHERE objid=%d", rid); if( zUser==0 ) fossil_redirect_home(); zNewUser = PD("u",zUser); zColor = db_text("", "SELECT bgcolor" " FROM event WHERE objid=%d", rid); zNewColor = PD("clr",zColor); fPropagateColor = P("pclr")!=0; - zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); - if( P("cancel") ){ - cgi_redirectf("vinfo?name=%d", rid); - } + zNewTag = P("newtag")!=0 ? P("tagname") : 0; + if( zNewTag && zNewTag[0]==0 ) zNewTag = 0; + zNewBranch = P("newbr")!=0 ? P("brname") : 0; + if( zNewBranch && zNewBranch[0]==0 ) zNewBranch = 0; if( P("apply") ){ Blob ctrl; char *zDate; int nChng = 0; @@ -1216,30 +1224,59 @@ login_verify_csrf_secret(); blob_zero(&ctrl); zDate = db_text(0, "SELECT datetime('now')"); zDate[10] = 'T'; blob_appendf(&ctrl, "D %s\n", zDate); + db_multi_exec("CREATE TEMP TABLE newtags(tag UNIQUE, prefix, value)"); if( zNewColor[0] && strcmp(zColor,zNewColor)!=0 ){ - nChng++; + char *zPrefix = "+"; if( fPropagateColor ){ - blob_appendf(&ctrl, "T *bgcolor %s %F\n", zUuid, zNewColor); - }else{ - blob_appendf(&ctrl, "T +bgcolor %s %F\n", zUuid, zNewColor); + zPrefix = "*"; } + db_multi_exec("REPLACE INTO newtags VALUES('bgcolor',%Q,%Q)", + zPrefix, zNewColor); + } + if( zNewColor[0]==0 && zColor[0]!=0 ){ + db_multi_exec("REPLACE INTO newtags VALUES('bgcolor','-',NULL)"); } if( strcmp(zComment,zNewComment)!=0 ){ - nChng++; - blob_appendf(&ctrl, "T +comment %s %F\n", zUuid, zNewComment); + db_multi_exec("REPLACE INTO newtags VALUES('comment','+',%Q)", + zNewComment); } if( strcmp(zUser,zNewUser)!=0 ){ - nChng++; - blob_appendf(&ctrl, "T +user %s %F\n", zUuid, zNewUser); + db_multi_exec("REPLACE INTO newtags VALUES('user','+',%Q)", zNewUser); + } + if( zNewTag ){ + db_multi_exec("REPLACE INTO newtags VALUES('sym-%q','+',NULL)", zNewTag); + } + if( zNewBranch ){ + db_multi_exec( + "REPLACE INTO newtags " + " SELECT tagname, '-', NULL FROM tagxref, tag" + " WHERE tagxref.rid=%d AND tagtype==2" + " AND tagname GLOB 'sym-*'" + " AND tag.tagid=tagxref.tagid", + rid + ); + db_multi_exec("REPLACE INTO newtags VALUES('branch','*',%Q)", zNewBranch); + db_multi_exec("REPLACE INTO newtags VALUES('sym-%q','*',NULL)", + zNewBranch); } - if( zNewColor[0]==0 && zColor[0]!=0 ){ + db_prepare(&q, "SELECT tag, prefix, value FROM newtags" + " ORDER BY prefix || tag"); + while( db_step(&q)==SQLITE_ROW ){ + const char *zTag = db_column_text(&q, 0); + const char *zPrefix = db_column_text(&q, 1); + const char *zValue = db_column_text(&q, 2); nChng++; - blob_appendf(&ctrl, "T -bgcolor %s\n", zUuid); + if( zValue ){ + blob_appendf(&ctrl, "T %s%F %s %F\n", zPrefix, zTag, zUuid, zValue); + }else{ + blob_appendf(&ctrl, "T %s%F %s\n", zPrefix, zTag, zUuid); + } } + db_finalize(&q); if( nChng>0 ){ int nrid; Blob cksum; blob_appendf(&ctrl, "U %F\n", g.zLogin); md5sum_blob(&ctrl, &cksum); @@ -1254,23 +1291,43 @@ blob_zero(&comment); blob_append(&comment, zNewComment, -1); zUuid[10] = 0; style_header("Edit Baseline [%s]", zUuid); if( P("preview") ){ + Blob suffix; + int nTag = 0; @ <b>Preview:</b> @ <blockquote> @ <table border=0> if( zNewColor && zNewColor[0] ){ @ <tr><td bgcolor="%h(zNewColor)"> }else{ @ <tr><td> } wiki_convert(&comment, 0, WIKI_INLINE); - @ (user: %h(zNewUser)) + blob_zero(&suffix); + blob_appendf(&suffix, "(user: %h", zNewUser); + db_prepare(&q, "SELECT substr(tagname,5) FROM tagxref, tag" + " WHERE tagname GLOB 'sym-*' AND tagxref.rid=%d" + " AND tagtype>1 AND tag.tagid=tagxref.tagid", + rid); + while( db_step(&q)==SQLITE_ROW ){ + const char *zTag = db_column_text(&q, 0); + if( nTag==0 ){ + blob_appendf(&suffix, ", tags: %h", zTag); + }else{ + blob_appendf(&suffix, ", %h", zTag); + } + nTag++; + } + db_finalize(&q); + blob_appendf(&suffix, ")"); + @ %s(blob_str(&suffix)) @ </td></tr></table> @ </blockquote> @ <hr> + blob_reset(&suffix); } @ <p>Make changes to attributes of check-in @ [<a href="vinfo?name=%d(rid)">%s(zUuid)</a>]:</p> @ <form action="%s(g.zBaseURL)/vedit" method="POST"> login_insert_csrf_secret(); @@ -1311,10 +1368,37 @@ @ <input type="checkbox" name="pclr"> } @ Propagate color to descendants</input></td></tr> @ </table> @ </td></tr> + + @ <tr><td align="right" valign="top"><b>Tags:</b></td> + @ <td valign="top"> + @ <input type="checkbox" name="newtag"> + @ Add the following new tag name to this check-in: + @ <input type="text" width="15" name="tagname"> + @ </td></tr> + + if( db_exists("SELECT 1 FROM tagxref WHERE rid=%d AND tagid=%d AND srcid>0", + rid, TAG_BRANCH)==0 ){ + @ <tr><td align="right" valign="top"><b>Branching:</b></td> + @ <td valign="top"> + @ <input type="checkbox" name="newbr"> + @ Make this check-in the start of a new branch named: + @ <input type="text" width="15" name="brname"> + @ </td></tr> + } + + if( is_a_leaf(rid) ){ + @ <tr><td align="right" valign="top"><b>Leaf Closure:</b></td> + @ <td valign="top"> + @ <input type="checkbox" name="close"> + @ Mark this leaf as "closed" so that it no longer appears on the + @ "leaves" page and is no longer labeled as a "<b>Leaf</b>". + @ </td></tr> + } + @ <tr><td colspan="2"> @ <input type="submit" name="preview" value="Preview"> @ <input type="submit" name="apply" value="Apply Changes"> @ <input type="submit" name="cancel" value="Cancel">
Modified src/rebuild.c from [194f1062f7] to [485e8e6098].
@@ -173,32 +173,21 @@ */ static void rebuild_tag_trunk(void){ int tagid = db_int(0, "SELECT 1 FROM tag WHERE tagname='sym-trunk'"); int rid; char *zUuid; - Stmt q; if( tagid>0 ) return; rid = db_int(0, "SELECT pid FROM plink AS x WHERE NOT EXISTS(" " SELECT 1 FROM plink WHERE cid=x.pid)"); if( rid==0 ) return; - db_prepare(&q, "SELECT uuid FROM tagxref, blob" - " WHERE tagid=%d AND tagtype>0 AND blob.rid=tagxref.rid", - TAG_NEWBRANCH); - - /* Block the trunk tag at all branches */ - while( db_step(&q)==SQLITE_ROW ){ - const char *z = db_column_text(&q, 0); - tag_add_artifact("sym-", "trunk", z, 0, 0); - } - db_finalize(&q); /* Add the trunk tag to the root of the whole tree */ zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); if( zUuid==0 ) return; tag_add_artifact("sym-", "trunk", zUuid, 0, 2); - tag_add_artifact("", "newbranch", zUuid, 0, 1); + tag_add_artifact("", "branch", zUuid, "trunk", 2); } /* ** Core function to rebuild the infomration in the derived tables of a ** fossil repository from the blobs. This function is shared between
Modified src/schema.c from [2bbbb93440] to [216bff41ba].
@@ -279,11 +279,11 @@ @ INSERT INTO tag VALUES(2, 'comment'); -- TAG_COMMENT @ INSERT INTO tag VALUES(3, 'user'); -- TAG_USER @ INSERT INTO tag VALUES(4, 'hidden'); -- TAG_HIDDEN @ INSERT INTO tag VALUES(5, 'private'); -- TAG_PRIVATE @ INSERT INTO tag VALUES(6, 'cluster'); -- TAG_CLUSTER -@ INSERT INTO tag VALUES(7, 'newbranch'); -- TAG_NEWBRANCH +@ INSERT INTO tag VALUES(7, 'branch'); -- TAG_BRANCH @ INSERT INTO tag VALUES(8, 'closed'); -- TAG_CLOSED @ @ -- Assignments of tags to baselines. Note that we allow tags to @ -- have values assigned to them. So we are not really dealing with @ -- tags here. These are really properties. But we are going to @@ -333,11 +333,11 @@ # define TAG_COMMENT 2 /* The check-in comment */ # define TAG_USER 3 /* User who made a checking */ # define TAG_HIDDEN 4 /* Do not display or sync */ # define TAG_PRIVATE 5 /* Display but do not sync */ # define TAG_CLUSTER 6 /* A cluster */ -# define TAG_NEWBRANCH 7 /* First check-in of a new named branch */ +# define TAG_BRANCH 7 /* Value is name of the current branch */ # define TAG_CLOSED 8 /* Do not display this check-in as a leaf */ #endif #if EXPORT_INTERFACE # define MAX_INT_TAG 8 /* The largest pre-assigned tag id */ #endif
Modified src/timeline.c from [59fa308491] to [4c13ae2995].
@@ -75,26 +75,28 @@ } } } /* -** Count the number of non-branch children for the given check-in. -** A non-branch child is a child that omits the "newbranch" tag. +** Count the number of primary non-branch children for the given check-in. +** +** A primary child is one where the parent is the primary parent, not +** a merge parent. +** +** A non-branch child is one which is on the same branch as the parent. */ int count_nonbranch_children(int pid){ int nNonBranch; - - nNonBranch = db_int(0, - "SELECT count(*) FROM plink" - " WHERE pid=%d AND isprim" - " AND NOT EXISTS(SELECT 1 FROM tagxref" - " WHERE tagid=%d" - " AND rid=cid" - " AND tagtype>0" - " )", - pid, TAG_NEWBRANCH - ); + static const char zSql[] = + @ SELECT count(*) FROM plink + @ WHERE pid=%d AND isprim + @ AND coalesce((SELECT value FROM tagxref + @ WHERE tagid=%d AND rid=plink.pid), 'trunk') + @ =coalesce((SELECT value FROM tagxref + @ WHERE tagid=%d AND rid=plink.cid), 'trunk') + ; + nNonBranch = db_int(0, zSql, pid, TAG_BRANCH, TAG_BRANCH); return nNonBranch; } /* ** Allowed flags for the tmFlags argument to www_print_timeline @@ -241,33 +243,38 @@ /* ** Return a pointer to a constant string that forms the basis ** for a timeline query for the WWW interface. */ const char *timeline_query_for_www(void){ + static char *zBase = 0; static const char zBaseSql[] = @ SELECT @ blob.rid, @ uuid, @ datetime(event.mtime,'localtime') AS timestamp, @ coalesce(ecomment, comment), @ coalesce(euser, user), @ (SELECT count(*) FROM plink WHERE pid=blob.rid AND isprim=1), @ (SELECT count(*) FROM plink WHERE cid=blob.rid), - @ 0==(SELECT count(*) FROM plink - @ WHERE pid=blob.rid AND isprim AND NOT EXISTS( - @ SELECT 1 FROM tagxref - @ WHERE tagid=(SELECT tagid FROM tag WHERE tagname='newbranch') - @ AND rid=plink.cid AND tagtype>0)), + @ NOT EXISTS(SELECT 1 FROM plink + @ WHERE pid=blob.rid + @ AND coalesce((SELECT value FROM tagxref + @ WHERE tagid=%d AND rid=plink.pid), 'trunk') + @ = coalesce((SELECT value FROM tagxref + @ WHERE tagid=%d AND rid=plink.cid), 'trunk')), @ bgcolor, @ event.type, @ (SELECT group_concat(substr(tagname,5), ', ') FROM tag, tagxref @ WHERE tagname GLOB 'sym-*' AND tag.tagid=tagxref.tagid @ AND tagxref.rid=blob.rid AND tagxref.tagtype>0) @ FROM event JOIN blob @ WHERE blob.rid=event.objid ; - return zBaseSql; + if( zBase==0 ){ + zBase = mprintf(zBaseSql, TAG_BRANCH, TAG_BRANCH); + } + return zBase; } /* ** Generate a submenu element with a single parameter change. */