| | @@ -1474,11 +1474,17 @@ |
| 1474 | 1474 | |
| 1475 | 1475 | /* |
| 1476 | 1476 | ** The input query q selects various records. Print a human-readable |
| 1477 | 1477 | ** summary of those records. |
| 1478 | 1478 | ** |
| 1479 | | -** Limit number of entries printed to N. |
| 1479 | +** Limit number of lines or entries printed to nLimit. If nLimit is zero |
| 1480 | +** there is no limit. If nLimit is greater than zero, limit the number of |
| 1481 | +** complete entries printed. If nLimit is less than zero, attempt to limit |
| 1482 | +** the number of lines printed (this is basically the legacy behavior). |
| 1483 | +** The line limit, if used, is approximate because it is only checked on a |
| 1484 | +** per-entry basis. If verbose mode, the file name details are considered |
| 1485 | +** to be part of the entry. |
| 1480 | 1486 | ** |
| 1481 | 1487 | ** The query should return these columns: |
| 1482 | 1488 | ** |
| 1483 | 1489 | ** 0. rid |
| 1484 | 1490 | ** 1. uuid |
| | @@ -1487,11 +1493,13 @@ |
| 1487 | 1493 | ** 4. Number of non-merge children |
| 1488 | 1494 | ** 5. Number of parents |
| 1489 | 1495 | ** 6. mtime |
| 1490 | 1496 | ** 7. branch |
| 1491 | 1497 | */ |
| 1492 | | -void print_timeline(Stmt *q, int N, int verboseFlag){ |
| 1498 | +void print_timeline(Stmt *q, int nLimit, int verboseFlag){ |
| 1499 | + int nAbsLimit = (nLimit >= 0) ? nLimit : -nLimit; |
| 1500 | + int nLine = 0; |
| 1493 | 1501 | int nEntry = 0; |
| 1494 | 1502 | char zPrevDate[20]; |
| 1495 | 1503 | const char *zCurrentUuid=0; |
| 1496 | 1504 | int fchngQueryInit = 0; /* True if fchngQuery is initialized */ |
| 1497 | 1505 | Stmt fchngQuery; /* Query for file changes on check-ins */ |
| | @@ -1500,11 +1508,11 @@ |
| 1500 | 1508 | if( g.localOpen ){ |
| 1501 | 1509 | int rid = db_lget_int("checkout", 0); |
| 1502 | 1510 | zCurrentUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1503 | 1511 | } |
| 1504 | 1512 | |
| 1505 | | - while( db_step(q)==SQLITE_ROW && nEntry<N){ |
| 1513 | + while( db_step(q)==SQLITE_ROW ){ |
| 1506 | 1514 | int rid = db_column_int(q, 0); |
| 1507 | 1515 | const char *zId = db_column_text(q, 1); |
| 1508 | 1516 | const char *zDate = db_column_text(q, 2); |
| 1509 | 1517 | const char *zCom = db_column_text(q, 3); |
| 1510 | 1518 | int nChild = db_column_int(q, 4); |
| | @@ -1516,10 +1524,11 @@ |
| 1516 | 1524 | |
| 1517 | 1525 | sqlite3_snprintf(sizeof(zUuid), zUuid, "%.10s", zId); |
| 1518 | 1526 | if( memcmp(zDate, zPrevDate, 10) ){ |
| 1519 | 1527 | fossil_print("=== %.10s ===\n", zDate); |
| 1520 | 1528 | memcpy(zPrevDate, zDate, 10); |
| 1529 | + nLine++; /* record another line */ |
| 1521 | 1530 | } |
| 1522 | 1531 | if( zCom==0 ) zCom = ""; |
| 1523 | 1532 | fossil_print("%.8s ", &zDate[11]); |
| 1524 | 1533 | zPrefix[0] = 0; |
| 1525 | 1534 | if( nParent>1 ){ |
| | @@ -1538,13 +1547,12 @@ |
| 1538 | 1547 | } |
| 1539 | 1548 | if( fossil_strcmp(zCurrentUuid,zId)==0 ){ |
| 1540 | 1549 | sqlite3_snprintf(sizeof(zPrefix)-n, &zPrefix[n], "*CURRENT* "); |
| 1541 | 1550 | n += strlen(zPrefix); |
| 1542 | 1551 | } |
| 1543 | | - nEntry++; |
| 1544 | 1552 | zFree = sqlite3_mprintf("[%.10s] %s%s", zUuid, zPrefix, zCom); |
| 1545 | | - comment_print(zFree, 9, 79); |
| 1553 | + nLine += comment_print(zFree, 9, 79); /* record another X lines */ |
| 1546 | 1554 | sqlite3_free(zFree); |
| 1547 | 1555 | |
| 1548 | 1556 | if(verboseFlag){ |
| 1549 | 1557 | if( !fchngQueryInit ){ |
| 1550 | 1558 | db_prepare(&fchngQuery, |
| | @@ -1564,17 +1572,27 @@ |
| 1564 | 1572 | const char *zFilename = db_column_text(&fchngQuery, 2); |
| 1565 | 1573 | int isNew = db_column_int(&fchngQuery, 0); |
| 1566 | 1574 | int isDel = db_column_int(&fchngQuery, 1); |
| 1567 | 1575 | if( isNew ){ |
| 1568 | 1576 | fossil_print(" ADDED %s\n",zFilename); |
| 1577 | + nLine++; /* record another line */ |
| 1569 | 1578 | }else if( isDel ){ |
| 1570 | 1579 | fossil_print(" DELETED %s\n",zFilename); |
| 1580 | + nLine++; /* record another line */ |
| 1571 | 1581 | }else{ |
| 1572 | 1582 | fossil_print(" EDITED %s\n", zFilename); |
| 1583 | + nLine++; /* record another line */ |
| 1573 | 1584 | } |
| 1574 | 1585 | } |
| 1575 | 1586 | db_reset(&fchngQuery); |
| 1587 | + } |
| 1588 | + nEntry++; /* record another complete entry */ |
| 1589 | + if( !nAbsLimit ) continue; /* no limit, continue */ |
| 1590 | + if( nLimit<0 && nLine>=nAbsLimit ){ |
| 1591 | + break; /* line count limit hit, stop. */ |
| 1592 | + }else if( nEntry>=nAbsLimit ){ |
| 1593 | + break; /* entry count limit hit, stop. */ |
| 1576 | 1594 | } |
| 1577 | 1595 | } |
| 1578 | 1596 | if( fchngQueryInit ) db_finalize(&fchngQuery); |
| 1579 | 1597 | } |
| 1580 | 1598 | |
| | @@ -1677,11 +1695,11 @@ |
| 1677 | 1695 | zLimit = find_option("count",0,1); |
| 1678 | 1696 | } |
| 1679 | 1697 | if( zLimit ){ |
| 1680 | 1698 | n = atoi(zLimit); |
| 1681 | 1699 | }else{ |
| 1682 | | - n = 20; |
| 1700 | + n = -20; |
| 1683 | 1701 | } |
| 1684 | 1702 | if( g.argc>=4 ){ |
| 1685 | 1703 | k = strlen(g.argv[2]); |
| 1686 | 1704 | if( strncmp(g.argv[2],"before",k)==0 ){ |
| 1687 | 1705 | mode = 1; |
| 1688 | 1706 | |