93a3129444064c4d19b4cb49e24b6de4bd0e06a6 markd Fri Oct 2 21:41:15 2026 -0700 Restore the superTrack nesting fix. refs #38460 Taking this off master was over-cautious. It is wanted on its own: #38460 is a real bug, a superTrack given a parent passes tdbQuery -check -strict and is then silently dropped at load, and the fix should get into a release rather than wait on a trackDb change that uses it. Nothing on master nests yet, and the fix is behaviour-identical where nothing does: trackDb built with it and with the released hgTrackDb is byte-identical on hg38, hs1 and mm39, and hgTracks renders the same rows and supertrack controls as dev. The TSS trackDb change that uses this stays reverted, on superTrackNesting, until this ships. Whoever releases it: trackDbToTxt has to be rebuilt too, or the curated hub it writes names a parent stanza it did not emit. diff --git src/hg/lib/hubConnect.c src/hg/lib/hubConnect.c index 219ffc10a3a..af9b83a9a9f 100644 --- src/hg/lib/hubConnect.c +++ src/hg/lib/hubConnect.c @@ -480,35 +480,44 @@ } static struct trackDb *findSuperTrack(struct trackDb *tdbList, char *trackName) /* discover any supertracks, and if there are some add them * to the subtrack list of the supertrack */ { struct trackDb *tdb; struct trackDb *p = NULL; struct trackDb *next; for(tdb = tdbList; tdb; tdb = next) { /* save away the next pointer becuase we may detach this node and * add it to its supertrack parent */ next = tdb->next; - if (tdb->parent != NULL && sameString(trackName, tdb->parent->track)) + /* Walk up the chain: a supertrack may sit inside another supertrack, and + * neither is in tdbList, so an outer one is only named by an ancestor of a + * track that is. Only an immediate child is added as a subtrack. */ + struct trackDb *ancestor; + for (ancestor = tdb->parent; ancestor != NULL; ancestor = ancestor->parent) { - /* found a supertrack with the right name, add this child */ - p = tdb->parent; + if (sameString(trackName, ancestor->track)) + { + /* found a supertrack with the right name */ + p = ancestor; + if (ancestor == tdb->parent) slAddHead(&p->subtracks, tdb); + break; + } } } return p; } void hubConnectAddDescription(char *database, struct trackDb *tdb) /* Fetch tdb->track's html description (or nearest ancestor's non-empty description) * and store in tdb->html. */ { unsigned hubId = hubIdFromTrackName(tdb->track); struct hubConnectStatus *hub = hubFromId(hubId); struct trackHubGenome *hubGenome = trackHubFindGenome(hub->trackHub, database); trackHubPolishTrackNames(hub->trackHub, tdb);