:!: of historical interest only. This page describes the %%FreeBSD%% Subversion to CVS exporter AKA svn2cvs. The exporter runs on repoman.%%FreeBSD%%.org (mostly) in the directory ''%%/r/svn2cvs/%%''. Currently the page is **work in progress** and should not be relied on to be accurate! ====== svn2cvs overview ====== The basic purpose of the %%FreeBSD%% svn2cvs system is to replicate commits in the %%FreeBSD%% Subversion repository to the old CVS repository. svn2cvs preserves full commit information (as much as CVS allows) by exporting: * commit actually change content * commit comment * commit date / time * commit author * svn revision number (in the CVS commit comment) svn2cvs exporter basically works by examining each subversion commit and then replicating it as good as possible into CVS. Due to the way CVS works $%%FreeBSD%%$ is changed by CVS so the original $%%FreeBSD%%$ set by Subversion is overwritten by CVS. To find out which Subversion revision a file in CVS is based on, one has to see the commit log which includes the revision ID. ====== svn2cvs parts ====== svn2cvs consists of the following parts: * The main svn2cvs python script ''%%export.py%%'' * A counter stored as a SVN property telling the exporter the last SVN revision exported * A mapping table (called ''%%maptable%%'' and stored in ''%%export.py%%'') which maps from SVN to CVS branches (IE, stable/7 -> RELENG_7) * Modified version of cvs * Local %%FreeBSD%% svn mirror updated every 5 seconds * Checked out version of each active CVS branch ===== Python 'export.py' script ===== TODO - Location (repo stored in, public access, etc...) and dependancies ===== Last exported revision property ===== The counter with the last exported revision is stored as a revision property stored on revision 0 and is called ''%%fbsd:lastexp%%''. Note that the property is stored on the mirrored repository used by the exporter, not the main %%FreeBSD%% repository. The current value for ''%%/r/svnmirror/base%%'' can be retrieved using: svn pg fbsd:lastexp --revprop -r 0 file:///r/svnmirror/base ===== maptable ===== TODO ===== Modified CVS ===== The modified version of CVS is changed from stock CVS as follows: * If the environment variable ''%%CVS_TIMESTAMP%%'' is set, use that as the commit time-stamp instead of the current 'wall clock'. * If the environment variable ''%%CVS_AUTHOR%%'' is set, use that to set author in CVS commit instead if the actual user which are performing the commit action (svn2cvs) * Do not allow 'cvs imports' to be run on the 'ncvs' repository. All the changes to the CVS repository is done with the modified cvs binary so there is no "magic" manipulation of the CVS repository. ===== Local FreeBSD svn mirror ===== TODO - setup, why needed, etc... ====== Create branch checklist ====== XXX **This may _very_ well miss required steps!** * Make sure ''%%maptable%%'' contains the new branch. * Create the branch in CVS e.g. using ''%%cvs tag -b RELENG_9%%'' - XXX svn2cvs should actually handle it by itself * Perform the branch in svn. ====== How svn2cvs works, per commit ====== TODO ====== Caveats ====== ===== Manual CVS work ===== If the CVS repository is every updated directly for whatever reason, the checkouts used by svn2cvs must also manually be updated. Otherwise, on the first export to the directory containing the manually modified files, the export will fail with an CVS up-to-date-check. To recover from this situation, simply manually (as user svn2cvs) run ''%%cvs update%%'' in the affected directory, and revert the changes made for the export which fails. Now the exporter can be restarted. ====== Current problems ====== It doesn't like when a file is 'replaced' in Subversion. As of this writing no files are out of sync. ====== Tips ====== The following command can be used to get all commits to a branch e.g. for hand exporting: svn log --xml --stop-on-copy file:%%//%%/r/svnmirror/base/releng/9.1 | xmllint --format /dev/stdin | awk -F\" '/%%<%%logentry revision="/ { print $2 }' | sort -n | awk '{ printf "echo \"Press enter to export r%s\"\nread line\npython export.py -r %s\n", $1, $1 }' Simon's original suggestion: svn log --xml --stop-on-copy file:%%//%%/r/svnmirror/base/releng/9.1 | xmllint --format /dev/stdin | grep 'logentry revision' | sed -Ee 's/.*revision="(.*)">.*/\1/' | sort ---- {{tag>Historical}}