Check-in [42c2a18e73]
Not logged in
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
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.
 */