Fossil SCM
Fix the describe_commit() routine so that it is faster and simpler and so that it ignores tags that are applied to more than one check-in.
Commit
41dc5fc000618313eaceae274ee4b1f5ac479f41b36961db7427d53b3176bbd7
Parent
36ca26647977e7e…
1 file changed
+43
-48
+43
-48
| --- src/info.c | ||
| +++ src/info.c | ||
| @@ -3705,12 +3705,15 @@ | ||
| 3705 | 3705 | ** 0: ok |
| 3706 | 3706 | ** -1: zName does not resolve to a commit |
| 3707 | 3707 | ** -2: zName resolves to more than a commit |
| 3708 | 3708 | ** -3: no ancestor commit with a fitting non-propagating tag found |
| 3709 | 3709 | */ |
| 3710 | -int describe_commit(const char *zName, const char *matchGlob, | |
| 3711 | - CommitDescr *descr){ | |
| 3710 | +int describe_commit( | |
| 3711 | + const char *zName, /* Name of the commit to be described */ | |
| 3712 | + const char *matchGlob, /* Glob pattern for the tag */ | |
| 3713 | + CommitDescr *descr /* Write the description here */ | |
| 3714 | +){ | |
| 3712 | 3715 | int rid; /* rid for zName */ |
| 3713 | 3716 | const char *zUuid; /* Hash of rid */ |
| 3714 | 3717 | int nRet = 0; /* Value to be returned */ |
| 3715 | 3718 | Stmt q; /* Query for tagged ancestors */ |
| 3716 | 3719 | |
| @@ -3728,63 +3731,55 @@ | ||
| 3728 | 3731 | zUuid = rid_to_uuid(rid); |
| 3729 | 3732 | descr->zCommitHash = mprintf("%s", zUuid); |
| 3730 | 3733 | descr->isDirty = unsaved_changes(0); |
| 3731 | 3734 | |
| 3732 | 3735 | db_multi_exec( |
| 3733 | - "DROP TABLE IF EXISTS singletonTaggedAncestors;" | |
| 3734 | - "CREATE TEMP TABLE singletonTaggedAncestors AS" | |
| 3735 | - " WITH RECURSIVE " | |
| 3736 | - " singletonTaggedCommits(rid,mtime,shorttag) AS (" | |
| 3737 | - " SELECT DISTINCT b.rid,e.mtime,substr(t.tagname,5) AS shorttag" | |
| 3738 | - " FROM blob b" | |
| 3739 | - " INNER JOIN event e ON e.objid=b.rid" | |
| 3740 | - " INNER JOIN tagxref tx ON tx.rid=b.rid" | |
| 3741 | - " INNER JOIN tag t ON t.tagid=tx.tagid" | |
| 3742 | - " WHERE e.type='ci'" | |
| 3743 | - " AND tx.tagtype=1" | |
| 3744 | - " AND t.tagname GLOB 'sym-%q'" | |
| 3745 | - " )," | |
| 3746 | - " parent(pid,cid,isCP,isPrim) AS (" | |
| 3747 | - " SELECT plink.pid, plink.cid, 0, isPrim FROM plink" | |
| 3748 | - " UNION ALL" | |
| 3749 | - " SELECT parentid, childid, 1, 0 FROM cherrypick WHERE NOT isExclude" | |
| 3750 | - " )," | |
| 3751 | - " ancestor(rid, mtime, isCP, isPrim) AS (" | |
| 3752 | - " SELECT objid, mtime, 0, 1 FROM event WHERE objid=%d" | |
| 3753 | - " UNION" | |
| 3754 | - " SELECT parent.pid, event.mtime, parent.isCP, parent.isPrim" | |
| 3755 | - " FROM ancestor, parent, event" | |
| 3756 | - " WHERE parent.cid=ancestor.rid" | |
| 3757 | - " AND event.objid=parent.pid" | |
| 3758 | - " AND NOT ancestor.isCP" | |
| 3759 | - " AND (event.mtime >= " | |
| 3760 | - " (SELECT max(mtime) FROM singletonTaggedCommits" | |
| 3761 | - " WHERE mtime<=(SELECT mtime FROM event WHERE objid=%d)))" | |
| 3762 | - " ORDER BY mtime DESC" | |
| 3763 | - " LIMIT 1000000" | |
| 3764 | - " ) " | |
| 3765 | - "SELECT rid, mtime, isCP, isPrim, ROW_NUMBER() OVER (ORDER BY mtime DESC) rn" | |
| 3766 | - " FROM ancestor", | |
| 3767 | - (matchGlob ? matchGlob : "*"), rid, rid | |
| 3736 | + "DROP TABLE IF EXISTS temp.singletonTag;" | |
| 3737 | + "CREATE TEMP TABLE singletonTag(" | |
| 3738 | + " rid INT," | |
| 3739 | + " tagname TEXT," | |
| 3740 | + " PRIMARY KEY (rid,tagname)" | |
| 3741 | + ") WITHOUT ROWID;" | |
| 3742 | + "INSERT OR IGNORE INTO singletonTag(rid, tagname)" | |
| 3743 | + " SELECT min(rid)," | |
| 3744 | + " substr(tagname,5)" | |
| 3745 | + " FROM tag, tagxref" | |
| 3746 | + " WHERE tag.tagid=tagxref.tagid" | |
| 3747 | + " AND tagxref.tagtype=1" | |
| 3748 | + " AND tagname GLOB 'sym-%q'" | |
| 3749 | + " GROUP BY tagname" | |
| 3750 | + " HAVING count(*)==1;", | |
| 3751 | + (matchGlob ? matchGlob : "*") | |
| 3768 | 3752 | ); |
| 3769 | 3753 | |
| 3770 | 3754 | db_prepare(&q, |
| 3771 | - "SELECT ta.rid, ta.mtime, ta.rn, b.uuid, substr(t.tagname, 5)" | |
| 3772 | - " FROM singletonTaggedAncestors ta" | |
| 3773 | - " INNER JOIN blob b ON b.rid=ta.rid" | |
| 3774 | - " INNER JOIN tagxref tx ON tx.rid=ta.rid" | |
| 3775 | - " INNER JOIN tag t ON tx.tagid=t.tagid" | |
| 3776 | - " WHERE tx.tagtype=1 AND t.tagname GLOB 'sym-%q' " | |
| 3777 | - " AND rn=(SELECT MAX(rn) FROM singletonTaggedAncestors)" | |
| 3778 | - " ORDER BY tx.mtime DESC, t.tagname DESC LIMIT 1", | |
| 3779 | - (matchGlob ? matchGlob : "*") | |
| 3755 | + "WITH RECURSIVE" | |
| 3756 | + " ancestor(rid,mtime,tagname,n) AS (" | |
| 3757 | + " SELECT %d, event.mtime, singletonTag.tagname, 0 " | |
| 3758 | + " FROM event" | |
| 3759 | + " LEFT JOIN singletonTag ON singletonTag.rid=event.objid" | |
| 3760 | + " WHERE event.objid=%d" | |
| 3761 | + " UNION ALL" | |
| 3762 | + " SELECT plink.pid, event.mtime, singletonTag.tagname, n+1" | |
| 3763 | + " FROM ancestor, plink, event" | |
| 3764 | + " LEFT JOIN singletonTag ON singletonTag.rid=plink.pid" | |
| 3765 | + " WHERE plink.cid=ancestor.rid" | |
| 3766 | + " AND event.objid=plink.pid" | |
| 3767 | + " AND ancestor.tagname IS NULL" | |
| 3768 | + " ORDER BY mtime DESC" | |
| 3769 | + " )" | |
| 3770 | + "SELECT tagname, n" | |
| 3771 | + " FROM ancestor" | |
| 3772 | + " WHERE tagname IS NOT NULL" | |
| 3773 | + " ORDER BY n LIMIT 1;", | |
| 3774 | + rid, rid | |
| 3780 | 3775 | ); |
| 3781 | 3776 | |
| 3782 | 3777 | if( db_step(&q)==SQLITE_ROW ){ |
| 3783 | - const char *lastTag = db_column_text(&q, 4); | |
| 3778 | + const char *lastTag = db_column_text(&q, 0); | |
| 3784 | 3779 | descr->zRelTagname = mprintf("%s", lastTag); |
| 3785 | - descr->nCommitsSince = db_column_int(&q, 2)-1; | |
| 3780 | + descr->nCommitsSince = db_column_int(&q, 1); | |
| 3786 | 3781 | nRet = 0; |
| 3787 | 3782 | }else{ |
| 3788 | 3783 | /* no ancestor commit with a fitting singleton tag found */ |
| 3789 | 3784 | descr->zRelTagname = mprintf(""); |
| 3790 | 3785 | descr->nCommitsSince = -1; |
| 3791 | 3786 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -3705,12 +3705,15 @@ | |
| 3705 | ** 0: ok |
| 3706 | ** -1: zName does not resolve to a commit |
| 3707 | ** -2: zName resolves to more than a commit |
| 3708 | ** -3: no ancestor commit with a fitting non-propagating tag found |
| 3709 | */ |
| 3710 | int describe_commit(const char *zName, const char *matchGlob, |
| 3711 | CommitDescr *descr){ |
| 3712 | int rid; /* rid for zName */ |
| 3713 | const char *zUuid; /* Hash of rid */ |
| 3714 | int nRet = 0; /* Value to be returned */ |
| 3715 | Stmt q; /* Query for tagged ancestors */ |
| 3716 | |
| @@ -3728,63 +3731,55 @@ | |
| 3728 | zUuid = rid_to_uuid(rid); |
| 3729 | descr->zCommitHash = mprintf("%s", zUuid); |
| 3730 | descr->isDirty = unsaved_changes(0); |
| 3731 | |
| 3732 | db_multi_exec( |
| 3733 | "DROP TABLE IF EXISTS singletonTaggedAncestors;" |
| 3734 | "CREATE TEMP TABLE singletonTaggedAncestors AS" |
| 3735 | " WITH RECURSIVE " |
| 3736 | " singletonTaggedCommits(rid,mtime,shorttag) AS (" |
| 3737 | " SELECT DISTINCT b.rid,e.mtime,substr(t.tagname,5) AS shorttag" |
| 3738 | " FROM blob b" |
| 3739 | " INNER JOIN event e ON e.objid=b.rid" |
| 3740 | " INNER JOIN tagxref tx ON tx.rid=b.rid" |
| 3741 | " INNER JOIN tag t ON t.tagid=tx.tagid" |
| 3742 | " WHERE e.type='ci'" |
| 3743 | " AND tx.tagtype=1" |
| 3744 | " AND t.tagname GLOB 'sym-%q'" |
| 3745 | " )," |
| 3746 | " parent(pid,cid,isCP,isPrim) AS (" |
| 3747 | " SELECT plink.pid, plink.cid, 0, isPrim FROM plink" |
| 3748 | " UNION ALL" |
| 3749 | " SELECT parentid, childid, 1, 0 FROM cherrypick WHERE NOT isExclude" |
| 3750 | " )," |
| 3751 | " ancestor(rid, mtime, isCP, isPrim) AS (" |
| 3752 | " SELECT objid, mtime, 0, 1 FROM event WHERE objid=%d" |
| 3753 | " UNION" |
| 3754 | " SELECT parent.pid, event.mtime, parent.isCP, parent.isPrim" |
| 3755 | " FROM ancestor, parent, event" |
| 3756 | " WHERE parent.cid=ancestor.rid" |
| 3757 | " AND event.objid=parent.pid" |
| 3758 | " AND NOT ancestor.isCP" |
| 3759 | " AND (event.mtime >= " |
| 3760 | " (SELECT max(mtime) FROM singletonTaggedCommits" |
| 3761 | " WHERE mtime<=(SELECT mtime FROM event WHERE objid=%d)))" |
| 3762 | " ORDER BY mtime DESC" |
| 3763 | " LIMIT 1000000" |
| 3764 | " ) " |
| 3765 | "SELECT rid, mtime, isCP, isPrim, ROW_NUMBER() OVER (ORDER BY mtime DESC) rn" |
| 3766 | " FROM ancestor", |
| 3767 | (matchGlob ? matchGlob : "*"), rid, rid |
| 3768 | ); |
| 3769 | |
| 3770 | db_prepare(&q, |
| 3771 | "SELECT ta.rid, ta.mtime, ta.rn, b.uuid, substr(t.tagname, 5)" |
| 3772 | " FROM singletonTaggedAncestors ta" |
| 3773 | " INNER JOIN blob b ON b.rid=ta.rid" |
| 3774 | " INNER JOIN tagxref tx ON tx.rid=ta.rid" |
| 3775 | " INNER JOIN tag t ON tx.tagid=t.tagid" |
| 3776 | " WHERE tx.tagtype=1 AND t.tagname GLOB 'sym-%q' " |
| 3777 | " AND rn=(SELECT MAX(rn) FROM singletonTaggedAncestors)" |
| 3778 | " ORDER BY tx.mtime DESC, t.tagname DESC LIMIT 1", |
| 3779 | (matchGlob ? matchGlob : "*") |
| 3780 | ); |
| 3781 | |
| 3782 | if( db_step(&q)==SQLITE_ROW ){ |
| 3783 | const char *lastTag = db_column_text(&q, 4); |
| 3784 | descr->zRelTagname = mprintf("%s", lastTag); |
| 3785 | descr->nCommitsSince = db_column_int(&q, 2)-1; |
| 3786 | nRet = 0; |
| 3787 | }else{ |
| 3788 | /* no ancestor commit with a fitting singleton tag found */ |
| 3789 | descr->zRelTagname = mprintf(""); |
| 3790 | descr->nCommitsSince = -1; |
| 3791 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -3705,12 +3705,15 @@ | |
| 3705 | ** 0: ok |
| 3706 | ** -1: zName does not resolve to a commit |
| 3707 | ** -2: zName resolves to more than a commit |
| 3708 | ** -3: no ancestor commit with a fitting non-propagating tag found |
| 3709 | */ |
| 3710 | int describe_commit( |
| 3711 | const char *zName, /* Name of the commit to be described */ |
| 3712 | const char *matchGlob, /* Glob pattern for the tag */ |
| 3713 | CommitDescr *descr /* Write the description here */ |
| 3714 | ){ |
| 3715 | int rid; /* rid for zName */ |
| 3716 | const char *zUuid; /* Hash of rid */ |
| 3717 | int nRet = 0; /* Value to be returned */ |
| 3718 | Stmt q; /* Query for tagged ancestors */ |
| 3719 | |
| @@ -3728,63 +3731,55 @@ | |
| 3731 | zUuid = rid_to_uuid(rid); |
| 3732 | descr->zCommitHash = mprintf("%s", zUuid); |
| 3733 | descr->isDirty = unsaved_changes(0); |
| 3734 | |
| 3735 | db_multi_exec( |
| 3736 | "DROP TABLE IF EXISTS temp.singletonTag;" |
| 3737 | "CREATE TEMP TABLE singletonTag(" |
| 3738 | " rid INT," |
| 3739 | " tagname TEXT," |
| 3740 | " PRIMARY KEY (rid,tagname)" |
| 3741 | ") WITHOUT ROWID;" |
| 3742 | "INSERT OR IGNORE INTO singletonTag(rid, tagname)" |
| 3743 | " SELECT min(rid)," |
| 3744 | " substr(tagname,5)" |
| 3745 | " FROM tag, tagxref" |
| 3746 | " WHERE tag.tagid=tagxref.tagid" |
| 3747 | " AND tagxref.tagtype=1" |
| 3748 | " AND tagname GLOB 'sym-%q'" |
| 3749 | " GROUP BY tagname" |
| 3750 | " HAVING count(*)==1;", |
| 3751 | (matchGlob ? matchGlob : "*") |
| 3752 | ); |
| 3753 | |
| 3754 | db_prepare(&q, |
| 3755 | "WITH RECURSIVE" |
| 3756 | " ancestor(rid,mtime,tagname,n) AS (" |
| 3757 | " SELECT %d, event.mtime, singletonTag.tagname, 0 " |
| 3758 | " FROM event" |
| 3759 | " LEFT JOIN singletonTag ON singletonTag.rid=event.objid" |
| 3760 | " WHERE event.objid=%d" |
| 3761 | " UNION ALL" |
| 3762 | " SELECT plink.pid, event.mtime, singletonTag.tagname, n+1" |
| 3763 | " FROM ancestor, plink, event" |
| 3764 | " LEFT JOIN singletonTag ON singletonTag.rid=plink.pid" |
| 3765 | " WHERE plink.cid=ancestor.rid" |
| 3766 | " AND event.objid=plink.pid" |
| 3767 | " AND ancestor.tagname IS NULL" |
| 3768 | " ORDER BY mtime DESC" |
| 3769 | " )" |
| 3770 | "SELECT tagname, n" |
| 3771 | " FROM ancestor" |
| 3772 | " WHERE tagname IS NOT NULL" |
| 3773 | " ORDER BY n LIMIT 1;", |
| 3774 | rid, rid |
| 3775 | ); |
| 3776 | |
| 3777 | if( db_step(&q)==SQLITE_ROW ){ |
| 3778 | const char *lastTag = db_column_text(&q, 0); |
| 3779 | descr->zRelTagname = mprintf("%s", lastTag); |
| 3780 | descr->nCommitsSince = db_column_int(&q, 1); |
| 3781 | nRet = 0; |
| 3782 | }else{ |
| 3783 | /* no ancestor commit with a fitting singleton tag found */ |
| 3784 | descr->zRelTagname = mprintf(""); |
| 3785 | descr->nCommitsSince = -1; |
| 3786 |