A few months ago, Dmitry Marakasov asked for a new feature: a link to diff.
The problem I had was figuring out the previous revision. The code always has the current revision. That is stored in the table:
freshports.org=# \d commit_log_elements Table "public.commit_log_elements" Column | Type | Modifiers ---------------+--------------+------------------------------------------------------------------ id | integer | not null default nextval('commit_log_elements_id_seq'::regclass) commit_log_id | integer | not null element_id | integer | not null revision_name | text | change_type | character(1) | not null Indexes: "commit_log_elements_pkey" PRIMARY KEY, btree (id) "commit_log_elements_clid" btree (commit_log_id) "commit_log_elements_ei" btree (element_id) Check constraints: "commit_log_elements_change_type" CHECK (change_type = 'A'::bpchar OR change_type = 'M'::bpchar OR change_type = 'R'::bpchar) Foreign-key constraints: "$1" FOREIGN KEY (commit_log_id) REFERENCES commit_log(id) ON UPDATE CASCADE ON DELETE CASCADE "$2" FOREIGN KEY (element_id, revision_name) REFERENCES element_revision(element_id, revision_name) ON UPDATE CASCADE ON DELETE CASCADE Referenced by: TABLE "commit_log_port_elements" CONSTRAINT "$2" FOREIGN KEY (commit_log_element_id) REFERENCES commit_log_elements(id) ON UPDATE CASCADE ON DELETE CASCADE Triggers: element_delete_check BEFORE INSERT OR UPDATE ON commit_log_elements FOR EACH ROW EXECUTE PROCEDURE element_delete_check()
There is it, right there, in revision_name. It contains stuff like this:
freshports.org=# select * from commit_log_elements order by id desc limit 60; id | commit_log_id | element_id | revision_name | change_type ---------+---------------+------------+---------------+------------- 1534684 | 379870 | 354019 | 1.2 | M 1534683 | 379870 | 354014 | 1.2 | M 1534682 | 379869 | 221937 | 1.2 | M 1534681 | 379869 | 221935 | 1.8 | M 1534680 | 379868 | 240127 | 1.30 | M 1534679 | 379867 | 102768 | 1.22 | M 1534678 | 379866 | 354111 | 1.3 | M 1534677 | 379865 | 136152 | 1.244 | M 1534676 | 379865 | 284011 | 1.15 | M 1534675 | 379865 | 136112 | 1.85 | M 1534674 | 379865 | 311651 | 1.20 | M 1534673 | 379865 | 216772 | 1.127 | M 1534672 | 379864 | 259820 | 1.13 | M 1534671 | 379864 | 236271 | 1.9 | M 1534670 | 379864 | 284164 | 1.41 | M 1534669 | 379864 | 253791 | 1.55 | M 1534668 | 379864 | 56333 | 1.93 | M 1534667 | 379863 | 214941 | 1.6.2.2 | M 1534666 | 379862 | 214941 | 1.8.2.2 | M 1534665 | 379861 | 304100 | 1.92 | M 1534664 | 379860 | 219241 | 1.1.10.4 | M 1534663 | 379859 | 234097 | 1.2.2.1 | M 1534662 | 379859 | 226441 | 1.5.2.1 | M 1534661 | 379859 | 226438 | 1.5.2.1 | M 1534660 | 379859 | 297415 | 1.3.2.2 | A 1534659 | 379859 | 294597 | 1.2.4.2 | A 1534658 | 379859 | 294596 | 1.7.2.2 | A 1534657 | 379859 | 295929 | 1.5.2.2 | A 1534656 | 379859 | 295928 | 1.3.2.2 | A 1534655 | 379859 | 339174 | 1.1.4.2 | A 1534654 | 379859 | 339173 | 1.1.4.2 | A 1534653 | 379859 | 339172 | 1.1.4.2 | A
Over in svn.freshports.org, we have similar:
svn.freshports.org=# select * from commit_log_elements order by id desc limit 30; id | commit_log_id | element_id | revision_name | change_type ---------+---------------+------------+---------------+------------- 1755850 | 402089 | 457016 | 1.21 | M 1755849 | 402088 | 456648 | 1.2 | M 1755848 | 402088 | 456643 | 1.2 | M 1755847 | 402087 | 221937 | 1.2 | M 1755846 | 402087 | 221935 | 1.8 | M 1755845 | 402086 | 240127 | 1.30 | M 1755844 | 402085 | 102768 | 1.22 | M 1755843 | 402084 | 456871 | 1.3 | M 1755842 | 402083 | 136152 | 1.244 | M 1755841 | 402083 | 284011 | 1.15 | M 1755840 | 402083 | 136112 | 1.85 | M 1755839 | 402083 | 311555 | 1.20 | M 1755838 | 402083 | 216772 | 1.127 | M 1755837 | 402082 | 259820 | 1.13 | M 1755836 | 402082 | 236271 | 1.9 | M 1755835 | 402082 | 284164 | 1.41 | M 1755834 | 402082 | 253791 | 1.55 | M 1755833 | 402082 | 56333 | 1.93 | M 1755832 | 402081 | 214941 | 1.6.2.2 | M 1755831 | 402080 | 453211 | 213754 | M 1755830 | 402080 | 412765 | 213754 | M 1755829 | 402080 | 311620 | 213754 | M 1755828 | 402079 | 214941 | 1.8.2.2 | M 1755827 | 402078 | 453211 | 213753 | M 1755826 | 402078 | 412765 | 213753 | M 1755825 | 402078 | 311620 | 213753 | M 1755824 | 402077 | 304100 | 1.92 | M 1755823 | 402076 | 313721 | 213752 | M 1755822 | 402075 | 219241 | 1.1.10.4 | M 1755821 | 402074 | 317668 | 213751 | M (30 rows) svn.freshports.org=#
Thus, we must cater for both svn and cvs. FreshPorts records data for all FreeBSD commits, not just the ports tree; it also covers the source tree, which is in svn.
Here is the PHP code I came up with:
function GetPreviousRevision( $revision ) { // if we find a dot, decrement the bit after the last dot // hence, a cvs revision // if no dot, treat it as an svn revision $dotPos = strrpos( $revision, '.' ); if ( $dotPos === false ) { $prev = intval ( $revision ) - 1; } else { $beforeLastDot = substr( $revision, 0, $dotPos + 1 ); $afterDot = substr( $revision, $dotPos + 1 ); if ( $afterDot === false ) { syslog( LOG_ERR, 'decimal not found in ' . $revision); $prev = $revision; } else { // previous revision is before dot || (after dot - 1) $prev = $beforeLastDot . ( intval( $afterDot ) - 1 ); } } return $prev; }
The output is available on the beta website and will soon move to the production site..