Fossil SCM
Fix timeline displays of the form "/timeline?from=UUID&ft=TAG" (using from= and ft=) so that the first link out of UUID is allowed to be a cherrypick.
Commit
39efcebe0b280568a7226337167bec501f0f02f98d2550dd28928f319936ae35
Parent
db3c8e1e4963364…
2 files changed
+19
+19
-3
+19
| --- src/path.c | ||
| +++ src/path.c | ||
| @@ -168,10 +168,14 @@ | ||
| 168 | 168 | /* |
| 169 | 169 | ** Compute the shortest path from iFrom to iTo |
| 170 | 170 | ** |
| 171 | 171 | ** If directOnly is true, then use only the "primary" links from parent to |
| 172 | 172 | ** child. In other words, ignore merges. |
| 173 | +** | |
| 174 | +** If oneWayOnly is 1, then only follow edges from parent to child. | |
| 175 | +** If oneWayOnly is 2, that is like 1 except the first edge out of iFrom | |
| 176 | +** is allowed to be cherrypick edge. | |
| 173 | 177 | ** |
| 174 | 178 | ** Return a pointer to the beginning of the path (the iFrom node). |
| 175 | 179 | ** Elements of the path can be traversed by following the PathNode.u.pTo |
| 176 | 180 | ** pointer chain. |
| 177 | 181 | ** |
| @@ -217,10 +221,25 @@ | ||
| 217 | 221 | "UNION ALL " |
| 218 | 222 | "SELECT pid, 0 FROM plink WHERE :back AND cid=:pid" |
| 219 | 223 | ); |
| 220 | 224 | } |
| 221 | 225 | bag_init(&seen); |
| 226 | + if( oneWayOnly==2 ){ | |
| 227 | + Stmt s2; | |
| 228 | + db_prepare(&s2, | |
| 229 | + "SELECT childid FROM cherrypick WHERE parentid=%d AND NOT isExclude", | |
| 230 | + iFrom | |
| 231 | + ); | |
| 232 | + while( db_step(&s2)==SQLITE_ROW ){ | |
| 233 | + int cid = db_column_int(&s2,0); | |
| 234 | + PathNode *pNew; | |
| 235 | + if( bag_find(&seen, cid) ) continue; | |
| 236 | + pNew = path_new_node(cid, path.pStart, 1); | |
| 237 | + if( pHidden && bag_find(pHidden,cid) ) pNew->isHidden = 1; | |
| 238 | + } | |
| 239 | + db_finalize(&s2); | |
| 240 | + } | |
| 222 | 241 | while( (p = pqueuex_extract_ptr(&path.pending))!=0 ){ |
| 223 | 242 | if( path_debug ){ |
| 224 | 243 | printf("PULL %s %g\n", path_rid_desc(p->rid), p->u.rCost); |
| 225 | 244 | } |
| 226 | 245 | if( p->rid==iTo ){ |
| 227 | 246 |
| --- src/path.c | |
| +++ src/path.c | |
| @@ -168,10 +168,14 @@ | |
| 168 | /* |
| 169 | ** Compute the shortest path from iFrom to iTo |
| 170 | ** |
| 171 | ** If directOnly is true, then use only the "primary" links from parent to |
| 172 | ** child. In other words, ignore merges. |
| 173 | ** |
| 174 | ** Return a pointer to the beginning of the path (the iFrom node). |
| 175 | ** Elements of the path can be traversed by following the PathNode.u.pTo |
| 176 | ** pointer chain. |
| 177 | ** |
| @@ -217,10 +221,25 @@ | |
| 217 | "UNION ALL " |
| 218 | "SELECT pid, 0 FROM plink WHERE :back AND cid=:pid" |
| 219 | ); |
| 220 | } |
| 221 | bag_init(&seen); |
| 222 | while( (p = pqueuex_extract_ptr(&path.pending))!=0 ){ |
| 223 | if( path_debug ){ |
| 224 | printf("PULL %s %g\n", path_rid_desc(p->rid), p->u.rCost); |
| 225 | } |
| 226 | if( p->rid==iTo ){ |
| 227 |
| --- src/path.c | |
| +++ src/path.c | |
| @@ -168,10 +168,14 @@ | |
| 168 | /* |
| 169 | ** Compute the shortest path from iFrom to iTo |
| 170 | ** |
| 171 | ** If directOnly is true, then use only the "primary" links from parent to |
| 172 | ** child. In other words, ignore merges. |
| 173 | ** |
| 174 | ** If oneWayOnly is 1, then only follow edges from parent to child. |
| 175 | ** If oneWayOnly is 2, that is like 1 except the first edge out of iFrom |
| 176 | ** is allowed to be cherrypick edge. |
| 177 | ** |
| 178 | ** Return a pointer to the beginning of the path (the iFrom node). |
| 179 | ** Elements of the path can be traversed by following the PathNode.u.pTo |
| 180 | ** pointer chain. |
| 181 | ** |
| @@ -217,10 +221,25 @@ | |
| 221 | "UNION ALL " |
| 222 | "SELECT pid, 0 FROM plink WHERE :back AND cid=:pid" |
| 223 | ); |
| 224 | } |
| 225 | bag_init(&seen); |
| 226 | if( oneWayOnly==2 ){ |
| 227 | Stmt s2; |
| 228 | db_prepare(&s2, |
| 229 | "SELECT childid FROM cherrypick WHERE parentid=%d AND NOT isExclude", |
| 230 | iFrom |
| 231 | ); |
| 232 | while( db_step(&s2)==SQLITE_ROW ){ |
| 233 | int cid = db_column_int(&s2,0); |
| 234 | PathNode *pNew; |
| 235 | if( bag_find(&seen, cid) ) continue; |
| 236 | pNew = path_new_node(cid, path.pStart, 1); |
| 237 | if( pHidden && bag_find(pHidden,cid) ) pNew->isHidden = 1; |
| 238 | } |
| 239 | db_finalize(&s2); |
| 240 | } |
| 241 | while( (p = pqueuex_extract_ptr(&path.pending))!=0 ){ |
| 242 | if( path_debug ){ |
| 243 | printf("PULL %s %g\n", path_rid_desc(p->rid), p->u.rCost); |
| 244 | } |
| 245 | if( p->rid==iTo ){ |
| 246 |
+19
-3
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -1509,10 +1509,18 @@ | ||
| 1509 | 1509 | ** when moving either forwards are backwards in time from a |
| 1510 | 1510 | ** particular starting point (iFrom). Return the rid of that |
| 1511 | 1511 | ** first check-in. If there are no check-ins in the descendant |
| 1512 | 1512 | ** or ancestor set of check-in iFrom that match the tag, then |
| 1513 | 1513 | ** return 0. |
| 1514 | +** | |
| 1515 | +** If looking fowards (if bForward is true) then the first link | |
| 1516 | +** is allowed to be a cherrypick, but subsequent links must be | |
| 1517 | +** either full merges or normal check-ins. The idea is that we | |
| 1518 | +** are looking for the first use of the code in the iFrom check-in | |
| 1519 | +** that has the zEnd tag. The first link is allowed to be a cherrypick | |
| 1520 | +** because the code in question crosses that link, but the code does | |
| 1521 | +** not cross any subsequent cherrypick. | |
| 1514 | 1522 | */ |
| 1515 | 1523 | static int timeline_endpoint( |
| 1516 | 1524 | int iFrom, /* Starting point */ |
| 1517 | 1525 | const char *zEnd, /* Tag we are searching for */ |
| 1518 | 1526 | int bForward /* 1: forwards in time (descendants) 0: backwards */ |
| @@ -1532,10 +1540,14 @@ | ||
| 1532 | 1540 | if( tagId ){ |
| 1533 | 1541 | db_prepare(&q, |
| 1534 | 1542 | "WITH RECURSIVE dx(id,mtime) AS (" |
| 1535 | 1543 | " SELECT %d, event.mtime FROM event WHERE objid=%d" |
| 1536 | 1544 | " UNION" |
| 1545 | + " SELECT cp.childid, event.mtime FROM cherrypick AS cp, event" | |
| 1546 | + " WHERE cp.parentid=%d AND NOT cp.isExclude" | |
| 1547 | + " AND event.objid=cp.childid" | |
| 1548 | + " UNION" | |
| 1537 | 1549 | " SELECT plink.cid, plink.mtime" |
| 1538 | 1550 | " FROM dx, plink" |
| 1539 | 1551 | " WHERE plink.pid=dx.id" |
| 1540 | 1552 | " AND plink.mtime<=(SELECT max(event.mtime) FROM tagxref, event" |
| 1541 | 1553 | " WHERE tagxref.tagid=%d AND tagxref.tagtype>0" |
| @@ -1542,24 +1554,28 @@ | ||
| 1542 | 1554 | " AND event.objid=tagxref.rid)" |
| 1543 | 1555 | " ORDER BY plink.mtime)" |
| 1544 | 1556 | "SELECT id FROM dx, tagxref" |
| 1545 | 1557 | " WHERE tagid=%d AND tagtype>0 AND rid=id" |
| 1546 | 1558 | " ORDER BY dx.mtime LIMIT 1", |
| 1547 | - iFrom, iFrom, tagId, tagId | |
| 1559 | + iFrom, iFrom, iFrom, tagId, tagId | |
| 1548 | 1560 | ); |
| 1549 | 1561 | }else{ |
| 1550 | 1562 | db_prepare(&q, |
| 1551 | 1563 | "WITH RECURSIVE dx(id,mtime) AS (" |
| 1552 | 1564 | " SELECT %d, event.mtime FROM event WHERE objid=%d" |
| 1565 | + " UNION" | |
| 1566 | + " SELECT cp.childid, event.mtime FROM cherrypick AS cp, event" | |
| 1567 | + " WHERE cp.parentid=%d AND NOT cp.isExclude" | |
| 1568 | + " AND event.objid=cp.childid" | |
| 1553 | 1569 | " UNION" |
| 1554 | 1570 | " SELECT plink.cid, plink.mtime" |
| 1555 | 1571 | " FROM dx, plink" |
| 1556 | 1572 | " WHERE plink.pid=dx.id" |
| 1557 | 1573 | " AND plink.mtime<=(SELECT mtime FROM event WHERE objid=%d)" |
| 1558 | 1574 | " ORDER BY plink.mtime)" |
| 1559 | 1575 | "SELECT id FROM dx WHERE id=%d", |
| 1560 | - iFrom, iFrom, endId, endId | |
| 1576 | + iFrom, iFrom, iFrom, endId, endId | |
| 1561 | 1577 | ); |
| 1562 | 1578 | } |
| 1563 | 1579 | }else{ |
| 1564 | 1580 | if( tagId ){ |
| 1565 | 1581 | db_prepare(&q, |
| @@ -2221,11 +2237,11 @@ | ||
| 2221 | 2237 | |
| 2222 | 2238 | if( from_rid && to_rid ){ |
| 2223 | 2239 | if( from_to_mode==0 ){ |
| 2224 | 2240 | p = path_shortest(from_rid, to_rid, 0, 0, 0, cost); |
| 2225 | 2241 | }else if( from_to_mode==1 ){ |
| 2226 | - p = path_shortest(from_rid, to_rid, 0, 1, 0, cost); | |
| 2242 | + p = path_shortest(from_rid, to_rid, 0, 2, 0, cost); | |
| 2227 | 2243 | earlierRid = commonAncs = from_rid; |
| 2228 | 2244 | laterRid = to_rid; |
| 2229 | 2245 | }else{ |
| 2230 | 2246 | p = path_shortest(to_rid, from_rid, 0, 1, 0, cost); |
| 2231 | 2247 | earlierRid = commonAncs = to_rid; |
| 2232 | 2248 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -1509,10 +1509,18 @@ | |
| 1509 | ** when moving either forwards are backwards in time from a |
| 1510 | ** particular starting point (iFrom). Return the rid of that |
| 1511 | ** first check-in. If there are no check-ins in the descendant |
| 1512 | ** or ancestor set of check-in iFrom that match the tag, then |
| 1513 | ** return 0. |
| 1514 | */ |
| 1515 | static int timeline_endpoint( |
| 1516 | int iFrom, /* Starting point */ |
| 1517 | const char *zEnd, /* Tag we are searching for */ |
| 1518 | int bForward /* 1: forwards in time (descendants) 0: backwards */ |
| @@ -1532,10 +1540,14 @@ | |
| 1532 | if( tagId ){ |
| 1533 | db_prepare(&q, |
| 1534 | "WITH RECURSIVE dx(id,mtime) AS (" |
| 1535 | " SELECT %d, event.mtime FROM event WHERE objid=%d" |
| 1536 | " UNION" |
| 1537 | " SELECT plink.cid, plink.mtime" |
| 1538 | " FROM dx, plink" |
| 1539 | " WHERE plink.pid=dx.id" |
| 1540 | " AND plink.mtime<=(SELECT max(event.mtime) FROM tagxref, event" |
| 1541 | " WHERE tagxref.tagid=%d AND tagxref.tagtype>0" |
| @@ -1542,24 +1554,28 @@ | |
| 1542 | " AND event.objid=tagxref.rid)" |
| 1543 | " ORDER BY plink.mtime)" |
| 1544 | "SELECT id FROM dx, tagxref" |
| 1545 | " WHERE tagid=%d AND tagtype>0 AND rid=id" |
| 1546 | " ORDER BY dx.mtime LIMIT 1", |
| 1547 | iFrom, iFrom, tagId, tagId |
| 1548 | ); |
| 1549 | }else{ |
| 1550 | db_prepare(&q, |
| 1551 | "WITH RECURSIVE dx(id,mtime) AS (" |
| 1552 | " SELECT %d, event.mtime FROM event WHERE objid=%d" |
| 1553 | " UNION" |
| 1554 | " SELECT plink.cid, plink.mtime" |
| 1555 | " FROM dx, plink" |
| 1556 | " WHERE plink.pid=dx.id" |
| 1557 | " AND plink.mtime<=(SELECT mtime FROM event WHERE objid=%d)" |
| 1558 | " ORDER BY plink.mtime)" |
| 1559 | "SELECT id FROM dx WHERE id=%d", |
| 1560 | iFrom, iFrom, endId, endId |
| 1561 | ); |
| 1562 | } |
| 1563 | }else{ |
| 1564 | if( tagId ){ |
| 1565 | db_prepare(&q, |
| @@ -2221,11 +2237,11 @@ | |
| 2221 | |
| 2222 | if( from_rid && to_rid ){ |
| 2223 | if( from_to_mode==0 ){ |
| 2224 | p = path_shortest(from_rid, to_rid, 0, 0, 0, cost); |
| 2225 | }else if( from_to_mode==1 ){ |
| 2226 | p = path_shortest(from_rid, to_rid, 0, 1, 0, cost); |
| 2227 | earlierRid = commonAncs = from_rid; |
| 2228 | laterRid = to_rid; |
| 2229 | }else{ |
| 2230 | p = path_shortest(to_rid, from_rid, 0, 1, 0, cost); |
| 2231 | earlierRid = commonAncs = to_rid; |
| 2232 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -1509,10 +1509,18 @@ | |
| 1509 | ** when moving either forwards are backwards in time from a |
| 1510 | ** particular starting point (iFrom). Return the rid of that |
| 1511 | ** first check-in. If there are no check-ins in the descendant |
| 1512 | ** or ancestor set of check-in iFrom that match the tag, then |
| 1513 | ** return 0. |
| 1514 | ** |
| 1515 | ** If looking fowards (if bForward is true) then the first link |
| 1516 | ** is allowed to be a cherrypick, but subsequent links must be |
| 1517 | ** either full merges or normal check-ins. The idea is that we |
| 1518 | ** are looking for the first use of the code in the iFrom check-in |
| 1519 | ** that has the zEnd tag. The first link is allowed to be a cherrypick |
| 1520 | ** because the code in question crosses that link, but the code does |
| 1521 | ** not cross any subsequent cherrypick. |
| 1522 | */ |
| 1523 | static int timeline_endpoint( |
| 1524 | int iFrom, /* Starting point */ |
| 1525 | const char *zEnd, /* Tag we are searching for */ |
| 1526 | int bForward /* 1: forwards in time (descendants) 0: backwards */ |
| @@ -1532,10 +1540,14 @@ | |
| 1540 | if( tagId ){ |
| 1541 | db_prepare(&q, |
| 1542 | "WITH RECURSIVE dx(id,mtime) AS (" |
| 1543 | " SELECT %d, event.mtime FROM event WHERE objid=%d" |
| 1544 | " UNION" |
| 1545 | " SELECT cp.childid, event.mtime FROM cherrypick AS cp, event" |
| 1546 | " WHERE cp.parentid=%d AND NOT cp.isExclude" |
| 1547 | " AND event.objid=cp.childid" |
| 1548 | " UNION" |
| 1549 | " SELECT plink.cid, plink.mtime" |
| 1550 | " FROM dx, plink" |
| 1551 | " WHERE plink.pid=dx.id" |
| 1552 | " AND plink.mtime<=(SELECT max(event.mtime) FROM tagxref, event" |
| 1553 | " WHERE tagxref.tagid=%d AND tagxref.tagtype>0" |
| @@ -1542,24 +1554,28 @@ | |
| 1554 | " AND event.objid=tagxref.rid)" |
| 1555 | " ORDER BY plink.mtime)" |
| 1556 | "SELECT id FROM dx, tagxref" |
| 1557 | " WHERE tagid=%d AND tagtype>0 AND rid=id" |
| 1558 | " ORDER BY dx.mtime LIMIT 1", |
| 1559 | iFrom, iFrom, iFrom, tagId, tagId |
| 1560 | ); |
| 1561 | }else{ |
| 1562 | db_prepare(&q, |
| 1563 | "WITH RECURSIVE dx(id,mtime) AS (" |
| 1564 | " SELECT %d, event.mtime FROM event WHERE objid=%d" |
| 1565 | " UNION" |
| 1566 | " SELECT cp.childid, event.mtime FROM cherrypick AS cp, event" |
| 1567 | " WHERE cp.parentid=%d AND NOT cp.isExclude" |
| 1568 | " AND event.objid=cp.childid" |
| 1569 | " UNION" |
| 1570 | " SELECT plink.cid, plink.mtime" |
| 1571 | " FROM dx, plink" |
| 1572 | " WHERE plink.pid=dx.id" |
| 1573 | " AND plink.mtime<=(SELECT mtime FROM event WHERE objid=%d)" |
| 1574 | " ORDER BY plink.mtime)" |
| 1575 | "SELECT id FROM dx WHERE id=%d", |
| 1576 | iFrom, iFrom, iFrom, endId, endId |
| 1577 | ); |
| 1578 | } |
| 1579 | }else{ |
| 1580 | if( tagId ){ |
| 1581 | db_prepare(&q, |
| @@ -2221,11 +2237,11 @@ | |
| 2237 | |
| 2238 | if( from_rid && to_rid ){ |
| 2239 | if( from_to_mode==0 ){ |
| 2240 | p = path_shortest(from_rid, to_rid, 0, 0, 0, cost); |
| 2241 | }else if( from_to_mode==1 ){ |
| 2242 | p = path_shortest(from_rid, to_rid, 0, 2, 0, cost); |
| 2243 | earlierRid = commonAncs = from_rid; |
| 2244 | laterRid = to_rid; |
| 2245 | }else{ |
| 2246 | p = path_shortest(to_rid, from_rid, 0, 1, 0, cost); |
| 2247 | earlierRid = commonAncs = to_rid; |
| 2248 |