Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | When doing "fossil export" make sure the output is in strict topological orders, since Git hates timewarps. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
c0a3e9ff6fbe3b48bf3c3a31173b7f16 |
User & Date: | drh 2018-05-04 15:39:25 |
Context
2018-05-05
| ||
11:30 | Update the built-in SQLite to the latest 3.24.0 alpha. ... (check-in: 58a64102 user: drh tags: trunk) | |
2018-05-04
| ||
15:39 | When doing "fossil export" make sure the output is in strict topological orders, since Git hates timewarps. ... (check-in: c0a3e9ff user: drh tags: trunk) | |
13:52 | Fix a harmless compiler warning in timeline.c. ... (check-in: 8d1cb59f user: drh tags: trunk) | |
Changes
Changes to src/export.c.
︙ | ︙ | |||
598 599 600 601 602 603 604 605 606 607 608 | } db_finalize(&q); db_finalize(&q2); db_finalize(&q3); /* Output the commit records. */ db_prepare(&q, "SELECT strftime('%%s',mtime), objid, coalesce(ecomment,comment)," " coalesce(euser,user)," " (SELECT value FROM tagxref WHERE rid=objid AND tagid=%d)" | > | > > | | | > > | 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 | } db_finalize(&q); db_finalize(&q2); db_finalize(&q3); /* Output the commit records. */ topological_sort_checkins(0); db_prepare(&q, "SELECT strftime('%%s',mtime), objid, coalesce(ecomment,comment)," " coalesce(euser,user)," " (SELECT value FROM tagxref WHERE rid=objid AND tagid=%d)" " FROM toponode, event" " WHERE toponode.tid=event.objid" " AND event.type='ci'" " AND NOT EXISTS (SELECT 1 FROM oldcommit WHERE toponode.tid=rid)" " ORDER BY toponode.tseq ASC", TAG_BRANCH ); db_prepare(&q2, "INSERT INTO oldcommit VALUES (:rid)"); while( db_step(&q)==SQLITE_ROW ){ Stmt q4; const char *zSecondsSince1970 = db_column_text(&q, 0); int ckinId = db_column_int(&q, 1); const char *zComment = db_column_text(&q, 2); const char *zUser = db_column_text(&q, 3); const char *zBranch = db_column_text(&q, 4); char *zMark; bag_insert(&vers, ckinId); db_bind_int(&q2, ":rid", ckinId); db_step(&q2); db_reset(&q2); if( zBranch==0 || fossil_strcmp(zBranch, "trunk")==0 ){ zBranch = gexport.zTrunkName; } zMark = mark_name_from_rid(ckinId, &unused_mark); printf("commit refs/heads/"); print_ref(zBranch); printf("\nmark %s\n", zMark); free(zMark); printf("committer"); print_person(zUser); |
︙ | ︙ | |||
735 736 737 738 739 740 741 | if( ferror(f)!=0 || fclose(f)!=0 ){ fossil_fatal("error while writing %s", markfile_out); } } bag_clear(&blobs); bag_clear(&vers); } | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 | if( ferror(f)!=0 || fclose(f)!=0 ){ fossil_fatal("error while writing %s", markfile_out); } } bag_clear(&blobs); bag_clear(&vers); } /* ** Construct the temporary table toposort as follows: ** ** CREATE TEMP TABLE toponode( ** tid INTEGER PRIMARY KEY, -- Check-in id ** tseq INT -- integer total order on check-ins. ** ); ** ** This table contains all check-ins of the repository in topological ** order. "Topological order" means that every parent check-in comes ** before all of its children. Topological order is *almost* the same ** thing as "ORDER BY event.mtime". Differences only arrise when there ** are timewarps. In as much as Git hates timewarps, we have to compute ** a correct topological order when doing an export. ** ** Since mtime is a usually already nearly in topological order, the ** algorithm is to start with mtime, then make adjustments as necessary ** for timewarps. This is not a great algorithm for the general case, ** but it is very fast for the overwhelmingly common case where there ** are few timewarps. */ int topological_sort_checkins(int bVerbose){ int nChange = 0; Stmt q1; Stmt chng; db_multi_exec( "CREATE TEMP TABLE toponode(\n" " tid INTEGER PRIMARY KEY,\n" " tseq INT\n" ");\n" "INSERT INTO toponode(tid,tseq) " " SELECT objid, CAST(mtime*8640000 AS int) FROM event WHERE type='ci';\n" "CREATE TEMP TABLE topolink(\n" " tparent INT,\n" " tchild INT,\n" " PRIMARY KEY(tparent,tchild)\n" ") WITHOUT ROWID;" "INSERT INTO topolink(tparent,tchild)" " SELECT pid, cid FROM plink;\n" "CREATE INDEX topolink_child ON topolink(tchild);\n" ); /* Find a timewarp instance */ db_prepare(&q1, "SELECT P.tid, P.tseq, C.tid, C.tseq\n" " FROM toponode P, toponode C, topolink X\n" " WHERE X.tparent=P.tid\n" " AND X.tchild=C.tid\n" " AND P.tseq>=C.tseq;" ); /* Update the timestamp on :tid to have value :tseq */ db_prepare(&chng, "UPDATE toponode SET tseq=:tseq WHERE tid=:tid" ); while( db_step(&q1)==SQLITE_ROW ){ int iParent = db_column_int(&q1, 0); i64 iParentTime = db_column_int64(&q1, 1); int iChild = db_column_int(&q1, 2); i64 iChildTime = db_column_int64(&q1, 3); nChange++; if( nChange>10000 ){ fossil_fatal("failed to fix all timewarps after 100000 attempts"); } db_reset(&q1); db_bind_int64(&chng, ":tid", iChild); db_bind_int64(&chng, ":tseq", iParentTime+1); db_step(&chng); db_reset(&chng); if( bVerbose ){ fossil_print("moving %d from %lld to %lld\n", iChild, iChildTime, iParentTime+1); } } db_finalize(&q1); db_finalize(&chng); return nChange; } /* ** COMMAND: test-topological-sort ** ** Invoke the topological_sort_checkins() interface for testing ** purposes. */ void test_topological_sort(void){ int n; db_find_and_open_repository(0, 0); n = topological_sort_checkins(1); fossil_print("%d reorderings required\n", n); } |