Fossil SCM
Merge lines descending to the bottom of the timeline that refer to the same commit
Commit
8ae790623c14ac5cee1b3638b875f159f112b8f7
Parent
a4bb89ba081e29c…
2 files changed
+19
-4
+1
-1
+19
-4
| --- src/graph.c | ||
| +++ src/graph.c | ||
| @@ -258,11 +258,10 @@ | ||
| 258 | 258 | int iRail = pBottom->iRail; |
| 259 | 259 | GraphRow *pCurrent; |
| 260 | 260 | GraphRow *pPrior; |
| 261 | 261 | u64 mask = ((u64)1)<<iRail; |
| 262 | 262 | |
| 263 | - pBottom->iRail = iRail; | |
| 264 | 263 | pBottom->railInUse |= mask; |
| 265 | 264 | pPrior = pBottom; |
| 266 | 265 | for(pCurrent=pBottom->pChild; pCurrent; pCurrent=pCurrent->pChild){ |
| 267 | 266 | assert( pPrior->idx > pCurrent->idx ); |
| 268 | 267 | assert( pCurrent->iRail<0 ); |
| @@ -344,14 +343,16 @@ | ||
| 344 | 343 | /* |
| 345 | 344 | ** Compute the complete graph |
| 346 | 345 | */ |
| 347 | 346 | void graph_finish(GraphContext *p, int omitDescenders){ |
| 348 | 347 | GraphRow *pRow, *pDesc, *pDup, *pLoop, *pParent; |
| 349 | - int i; | |
| 348 | + int i, j; | |
| 350 | 349 | u64 mask; |
| 351 | 350 | int hasDup = 0; /* True if one or more isDup entries */ |
| 352 | 351 | const char *zTrunk; |
| 352 | + int railRid[GR_MAX_RAIL]; /* Maps rails to rids for lines | |
| 353 | + that enter from bottom of screen */ | |
| 353 | 354 | |
| 354 | 355 | if( p==0 || p->pFirst==0 || p->nErr ) return; |
| 355 | 356 | p->nErr = 1; /* Assume an error until proven otherwise */ |
| 356 | 357 | |
| 357 | 358 | /* Initialize all rows */ |
| @@ -366,10 +367,11 @@ | ||
| 366 | 367 | pDup->isDup = 1; |
| 367 | 368 | } |
| 368 | 369 | hashInsert(p, pRow, 1); |
| 369 | 370 | } |
| 370 | 371 | p->mxRail = -1; |
| 372 | + memset(railRid, 0, sizeof(railRid)); | |
| 371 | 373 | |
| 372 | 374 | /* Purge merge-parents that are out-of-graph if descenders are not |
| 373 | 375 | ** drawn. |
| 374 | 376 | ** |
| 375 | 377 | ** Each node has one primary parent and zero or more "merge" parents. |
| @@ -458,10 +460,13 @@ | ||
| 458 | 460 | } |
| 459 | 461 | if( p->mxRail>=GR_MAX_RAIL ) return; |
| 460 | 462 | mask = BIT(pRow->iRail); |
| 461 | 463 | if( !omitDescenders ){ |
| 462 | 464 | pRow->bDescender = pRow->nParent>0; |
| 465 | + if( pRow->bDescender ){ | |
| 466 | + railRid[pRow->iRail] = pRow->aParent[0]; | |
| 467 | + } | |
| 463 | 468 | for(pLoop=pRow; pLoop; pLoop=pLoop->pNext){ |
| 464 | 469 | pLoop->railInUse |= mask; |
| 465 | 470 | } |
| 466 | 471 | } |
| 467 | 472 | assignChildrenToRail(pRow); |
| @@ -536,12 +541,22 @@ | ||
| 536 | 541 | for(i=1; i<pRow->nParent; i++){ |
| 537 | 542 | int parentRid = pRow->aParent[i]; |
| 538 | 543 | pDesc = hashFind(p, parentRid); |
| 539 | 544 | if( pDesc==0 ){ |
| 540 | 545 | /* Merge from a node that is off-screen */ |
| 541 | - int iMrail = findFreeRail(p, pRow->idx, p->nRow, 0); | |
| 542 | - if( p->mxRail>=GR_MAX_RAIL ) return; | |
| 546 | + int iMrail = -1; | |
| 547 | + for(j=0; j<GR_MAX_RAIL; j++){ | |
| 548 | + if( railRid[j]==parentRid ){ | |
| 549 | + iMrail = j; | |
| 550 | + break; | |
| 551 | + } | |
| 552 | + } | |
| 553 | + if( iMrail==-1 ){ | |
| 554 | + iMrail = findFreeRail(p, pRow->idx, p->nRow, 0); | |
| 555 | + if( p->mxRail>=GR_MAX_RAIL ) return; | |
| 556 | + railRid[iMrail] = parentRid; | |
| 557 | + } | |
| 543 | 558 | mask = BIT(iMrail); |
| 544 | 559 | pRow->mergeIn[iMrail] = 1; |
| 545 | 560 | pRow->mergeDown |= mask; |
| 546 | 561 | for(pLoop=pRow->pNext; pLoop; pLoop=pLoop->pNext){ |
| 547 | 562 | pLoop->railInUse |= mask; |
| 548 | 563 |
| --- src/graph.c | |
| +++ src/graph.c | |
| @@ -258,11 +258,10 @@ | |
| 258 | int iRail = pBottom->iRail; |
| 259 | GraphRow *pCurrent; |
| 260 | GraphRow *pPrior; |
| 261 | u64 mask = ((u64)1)<<iRail; |
| 262 | |
| 263 | pBottom->iRail = iRail; |
| 264 | pBottom->railInUse |= mask; |
| 265 | pPrior = pBottom; |
| 266 | for(pCurrent=pBottom->pChild; pCurrent; pCurrent=pCurrent->pChild){ |
| 267 | assert( pPrior->idx > pCurrent->idx ); |
| 268 | assert( pCurrent->iRail<0 ); |
| @@ -344,14 +343,16 @@ | |
| 344 | /* |
| 345 | ** Compute the complete graph |
| 346 | */ |
| 347 | void graph_finish(GraphContext *p, int omitDescenders){ |
| 348 | GraphRow *pRow, *pDesc, *pDup, *pLoop, *pParent; |
| 349 | int i; |
| 350 | u64 mask; |
| 351 | int hasDup = 0; /* True if one or more isDup entries */ |
| 352 | const char *zTrunk; |
| 353 | |
| 354 | if( p==0 || p->pFirst==0 || p->nErr ) return; |
| 355 | p->nErr = 1; /* Assume an error until proven otherwise */ |
| 356 | |
| 357 | /* Initialize all rows */ |
| @@ -366,10 +367,11 @@ | |
| 366 | pDup->isDup = 1; |
| 367 | } |
| 368 | hashInsert(p, pRow, 1); |
| 369 | } |
| 370 | p->mxRail = -1; |
| 371 | |
| 372 | /* Purge merge-parents that are out-of-graph if descenders are not |
| 373 | ** drawn. |
| 374 | ** |
| 375 | ** Each node has one primary parent and zero or more "merge" parents. |
| @@ -458,10 +460,13 @@ | |
| 458 | } |
| 459 | if( p->mxRail>=GR_MAX_RAIL ) return; |
| 460 | mask = BIT(pRow->iRail); |
| 461 | if( !omitDescenders ){ |
| 462 | pRow->bDescender = pRow->nParent>0; |
| 463 | for(pLoop=pRow; pLoop; pLoop=pLoop->pNext){ |
| 464 | pLoop->railInUse |= mask; |
| 465 | } |
| 466 | } |
| 467 | assignChildrenToRail(pRow); |
| @@ -536,12 +541,22 @@ | |
| 536 | for(i=1; i<pRow->nParent; i++){ |
| 537 | int parentRid = pRow->aParent[i]; |
| 538 | pDesc = hashFind(p, parentRid); |
| 539 | if( pDesc==0 ){ |
| 540 | /* Merge from a node that is off-screen */ |
| 541 | int iMrail = findFreeRail(p, pRow->idx, p->nRow, 0); |
| 542 | if( p->mxRail>=GR_MAX_RAIL ) return; |
| 543 | mask = BIT(iMrail); |
| 544 | pRow->mergeIn[iMrail] = 1; |
| 545 | pRow->mergeDown |= mask; |
| 546 | for(pLoop=pRow->pNext; pLoop; pLoop=pLoop->pNext){ |
| 547 | pLoop->railInUse |= mask; |
| 548 |
| --- src/graph.c | |
| +++ src/graph.c | |
| @@ -258,11 +258,10 @@ | |
| 258 | int iRail = pBottom->iRail; |
| 259 | GraphRow *pCurrent; |
| 260 | GraphRow *pPrior; |
| 261 | u64 mask = ((u64)1)<<iRail; |
| 262 | |
| 263 | pBottom->railInUse |= mask; |
| 264 | pPrior = pBottom; |
| 265 | for(pCurrent=pBottom->pChild; pCurrent; pCurrent=pCurrent->pChild){ |
| 266 | assert( pPrior->idx > pCurrent->idx ); |
| 267 | assert( pCurrent->iRail<0 ); |
| @@ -344,14 +343,16 @@ | |
| 343 | /* |
| 344 | ** Compute the complete graph |
| 345 | */ |
| 346 | void graph_finish(GraphContext *p, int omitDescenders){ |
| 347 | GraphRow *pRow, *pDesc, *pDup, *pLoop, *pParent; |
| 348 | int i, j; |
| 349 | u64 mask; |
| 350 | int hasDup = 0; /* True if one or more isDup entries */ |
| 351 | const char *zTrunk; |
| 352 | int railRid[GR_MAX_RAIL]; /* Maps rails to rids for lines |
| 353 | that enter from bottom of screen */ |
| 354 | |
| 355 | if( p==0 || p->pFirst==0 || p->nErr ) return; |
| 356 | p->nErr = 1; /* Assume an error until proven otherwise */ |
| 357 | |
| 358 | /* Initialize all rows */ |
| @@ -366,10 +367,11 @@ | |
| 367 | pDup->isDup = 1; |
| 368 | } |
| 369 | hashInsert(p, pRow, 1); |
| 370 | } |
| 371 | p->mxRail = -1; |
| 372 | memset(railRid, 0, sizeof(railRid)); |
| 373 | |
| 374 | /* Purge merge-parents that are out-of-graph if descenders are not |
| 375 | ** drawn. |
| 376 | ** |
| 377 | ** Each node has one primary parent and zero or more "merge" parents. |
| @@ -458,10 +460,13 @@ | |
| 460 | } |
| 461 | if( p->mxRail>=GR_MAX_RAIL ) return; |
| 462 | mask = BIT(pRow->iRail); |
| 463 | if( !omitDescenders ){ |
| 464 | pRow->bDescender = pRow->nParent>0; |
| 465 | if( pRow->bDescender ){ |
| 466 | railRid[pRow->iRail] = pRow->aParent[0]; |
| 467 | } |
| 468 | for(pLoop=pRow; pLoop; pLoop=pLoop->pNext){ |
| 469 | pLoop->railInUse |= mask; |
| 470 | } |
| 471 | } |
| 472 | assignChildrenToRail(pRow); |
| @@ -536,12 +541,22 @@ | |
| 541 | for(i=1; i<pRow->nParent; i++){ |
| 542 | int parentRid = pRow->aParent[i]; |
| 543 | pDesc = hashFind(p, parentRid); |
| 544 | if( pDesc==0 ){ |
| 545 | /* Merge from a node that is off-screen */ |
| 546 | int iMrail = -1; |
| 547 | for(j=0; j<GR_MAX_RAIL; j++){ |
| 548 | if( railRid[j]==parentRid ){ |
| 549 | iMrail = j; |
| 550 | break; |
| 551 | } |
| 552 | } |
| 553 | if( iMrail==-1 ){ |
| 554 | iMrail = findFreeRail(p, pRow->idx, p->nRow, 0); |
| 555 | if( p->mxRail>=GR_MAX_RAIL ) return; |
| 556 | railRid[iMrail] = parentRid; |
| 557 | } |
| 558 | mask = BIT(iMrail); |
| 559 | pRow->mergeIn[iMrail] = 1; |
| 560 | pRow->mergeDown |= mask; |
| 561 | for(pLoop=pRow->pNext; pLoop; pLoop=pLoop->pNext){ |
| 562 | pLoop->railInUse |= mask; |
| 563 |
+1
-1
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -737,11 +737,11 @@ | ||
| 737 | 737 | pRow->mergeOut, /* mo */ |
| 738 | 738 | pRow->mergeUpto, /* mu */ |
| 739 | 739 | pRow->aiRiser[pRow->iRail], /* u */ |
| 740 | 740 | pRow->isLeaf ? 1 : 0 /* f */ |
| 741 | 741 | ); |
| 742 | - /* u */ | |
| 742 | + /* au */ | |
| 743 | 743 | cSep = '['; |
| 744 | 744 | for(i=0; i<GR_MAX_RAIL; i++){ |
| 745 | 745 | if( i==pRow->iRail ) continue; |
| 746 | 746 | if( pRow->aiRiser[i]>0 ){ |
| 747 | 747 | cgi_printf("%c%d,%d", cSep, i, pRow->aiRiser[i]); |
| 748 | 748 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -737,11 +737,11 @@ | |
| 737 | pRow->mergeOut, /* mo */ |
| 738 | pRow->mergeUpto, /* mu */ |
| 739 | pRow->aiRiser[pRow->iRail], /* u */ |
| 740 | pRow->isLeaf ? 1 : 0 /* f */ |
| 741 | ); |
| 742 | /* u */ |
| 743 | cSep = '['; |
| 744 | for(i=0; i<GR_MAX_RAIL; i++){ |
| 745 | if( i==pRow->iRail ) continue; |
| 746 | if( pRow->aiRiser[i]>0 ){ |
| 747 | cgi_printf("%c%d,%d", cSep, i, pRow->aiRiser[i]); |
| 748 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -737,11 +737,11 @@ | |
| 737 | pRow->mergeOut, /* mo */ |
| 738 | pRow->mergeUpto, /* mu */ |
| 739 | pRow->aiRiser[pRow->iRail], /* u */ |
| 740 | pRow->isLeaf ? 1 : 0 /* f */ |
| 741 | ); |
| 742 | /* au */ |
| 743 | cSep = '['; |
| 744 | for(i=0; i<GR_MAX_RAIL; i++){ |
| 745 | if( i==pRow->iRail ) continue; |
| 746 | if( pRow->aiRiser[i]>0 ){ |
| 747 | cgi_printf("%c%d,%d", cSep, i, pRow->aiRiser[i]); |
| 748 |