314d1a9a41231220ae79fc971758da141c21f233 markd Fri Oct 2 21:36:10 2026 -0700 Revert the superTrack nesting fix on master; it lives on superTrackNesting. refs #38460 Taken off master with its only consumer, the TSS trackDb change reverted in the previous commit. It is a library change every CGI links, in trackDbCustom.c, hdb.c, hubConnect.c and hgTracks.c, and nothing on master needs it until the TSS tracks nest again. Kept on the superTrackNesting branch with its regression evidence. Note for whoever lands 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/trackDbCustom.c src/hg/lib/trackDbCustom.c index a0e6a842070..4fddeb2ca84 100644 --- src/hg/lib/trackDbCustom.c +++ src/hg/lib/trackDbCustom.c @@ -613,34 +613,30 @@ } char *maybeSkipHubPrefix(char *track) { if (!startsWith("hub_", track)) return track; char *nextUnderBar = strchr(track + sizeof "hub_", '_'); if (nextUnderBar) return nextUnderBar + 1; return track; } -#define maxSuperTrackDepth 10 -// No real trackDb nests supertracks anywhere near this deep; the limit is only -// here so a malformed parent chain cannot spin forever. - void trackDbSuperMarkup(struct trackDb *tdbList) /* Set trackDb from superTrack setting */ { struct trackDb *tdb; struct hash *superHash = hashNew(0); char *setting = NULL; char *words[3]; int wordCt = 0; /* find supertracks, setup their settings */ for (tdb = tdbList; tdb != NULL; tdb = tdb->next) { setting = trackDbLocalSetting(tdb, "superTrack"); if (!setting) continue; @@ -649,82 +645,55 @@ { if (!hashLookup(superHash, tdb->track)) { hashAdd(superHash, maybeSkipHubPrefix(tdb->track), tdb); tdbMarkAsSuperTrack(tdb); if ((wordCt > 1) && sameString("show", words[1])) tdb->isShow = TRUE; } } freeMem(words[0]); } /* adjust settings on supertrack members after verifying they have * a supertrack configured in this trackDb */ for (tdb = tdbList; tdb != NULL; tdb = tdb->next) { - if (tdb->parent != NULL) + if (tdbIsSuperTrack(tdb) || tdb->parent != NULL) continue; setting = trackDbLocalSetting(tdb, "parent"); - // A superTrack may name a parent superTrack, which nests it one level deeper. - // Its own "superTrack on" is not a parent reference, so only a non-super may - // fall back to the old style, where the setting holds the parent's name. - if (!setting && !tdbIsSuperTrack(tdb)) + if (!setting) setting = trackDbLocalSetting(tdb, "superTrack"); // Old style if (!setting) continue; wordCt = chopLine(cloneString(setting), words); assert(differentString("on", words[0])); // already weeded out "superTrack on" char *parentName = maybeSkipHubPrefix(words[0]); tdb->parent = hashFindVal(superHash, parentName); if (tdb->parent == tdb) { warn("Track %s lists itself as its own parent, ignoring.", tdb->track); tdb->parent = NULL; } if (tdb->parent) { tdbMarkAsSuperTrackChild(tdb); tdb->parentName = cloneString(parentName); if (wordCt > 1) tdb->visibility = max(0, hTvFromStringNoAbort(words[1])); } freeMem(words[0]); } - -/* Now that every link is set, make sure the supertracks form a tree. Nesting - * means the parent chain is walked rather than looked at one level, so a loop - * would hang every walker instead of being harmless. Only a supertrack can - * close a loop here, since nothing else is given a parent by this routine, so - * breaking it at a supertrack names the track whose setting is wrong and leaves - * the members attached to their folder. */ -for (tdb = tdbList; tdb != NULL; tdb = tdb->next) - { - if (!tdbIsSuperTrack(tdb) || tdb->parent == NULL) - continue; - struct trackDb *ancestor; - int depth = 0; - for (ancestor = tdb->parent; ancestor != NULL; ancestor = ancestor->parent) - { - if (ancestor == tdb || ++depth > maxSuperTrackDepth) - { - warn("Supertrack %s is its own ancestor through its parent setting, " - "ignoring that setting.", tdb->track); - tdb->parent = NULL; - break; - } - } - } hashFree(&superHash); } char *trackDbOrigAssembly(struct trackDb *tdb) /* return setting from trackDb, if any */ { return (trackDbSetting(tdb, "origAssembly")); } void trackDbPrintOrigAssembly(struct trackDb *tdb, char *database) /* Print lift information from trackDb, if any */ { char *origAssembly = trackDbOrigAssembly(tdb); if (origAssembly) {