There are a couple of FreeBSD git repositories that have been converted with various programs and various parameters. This page describes the "official" git-branches of the FreeBSD project that should be used as common repositories to base other work on.
The repositories are provided as a read-only mirror of the state of the Subversion src, doc and, ports repositories at http://svn.FreeBSD.org/base, http://svn.FreeBSD.org/doc, and http://svn.FreeBSD.org/ports respectively. Using git to commit changes to these repositories is not officially supported (but doable), instead it is supposed to serve as a collaboration point by using additional tools like Github, Gitorious, or Gerrit, etc.
Bear in mind that git will not replace Subversion for use in FreeBSD and the repository is only offered on a best-effort basis. The steps to redo the conversion are outlined below, so that people can move the process in-house should they see the need for it.
CAVEAT EMPTOR: It is possible (but highly unlikely) that the repositories might need to be re-done due to bugs in the converter. This would result in changed commit IDs for the impacted branches. As the actual tree objects for a certain SVN revision will remain identical, it will always be possible to rebase or merge your work on these new branches and not run into any merge conflicts. Advance notice will be provided if this proves necessary, along with advice on the required git commands.
The beta repository-mirrors are updated at least hourly, should they lag the svn repository by more than a day, please contact <uqs@FreeBSD.org> (monitoring still needs to be put into place, help wanted btw).
https://github.com/freebsd/freebsd-ports.git (the preferred sources)
- git://git-beta.freebsd.org/freebsd-ports.git (the canonical sources)
- SVN merges for single revisions (that span only parts of the tree then), are not really representable as merges in git and instead are called cherry-picks there. The converter tries to be smart about whole tree merges however -- this heuristic is only activated for the head/, user/, and projects/ branches. A whole-tree merge of project/foo into head/ should thus be correctly represented in git. Merges from head/ to stable/ or from contrib/ to head/ will be plain commits, i.e. "cherry-picks".
$ git clone --config remote.origin.fetch='+refs/notes/*:refs/notes/*' git://github.com/freebsd/freebsd.git $ cd freebsd && git pull # For some reason, the notes will not be fetched during the clone operation ... $ hack, hack, hack $ git commit
Advanced, useful examples to show the diff between a subdir of a branch, or the commits that introduced these diffs. It is basically what svn mergeinfo --show-revs=eligible does. See git-log(1) for more info.
$ git diff origin/stable/9 master -- usr.sbin/acpi $ git log --graph --format=oneline --right-only --cherry-pick --no-merges origin/stable/9...origin/master -- usr.sbin/acpi
See any other git howto or documentation if you're stuck on the basics. A useful reference for the issue with notes is http://git-scm.com/2010/08/25/notes.html.
Adding SVN Revision Notes to an Existing Clone
The git notes in the Github repositories contain useful information, and show up in git-log if present. git-clone without the --config ... line from above will default to not cloning refs/notes. You can configure the local git repo to fetch notes like so:
$ cd freebsd $ git config --add remote.origin.fetch '+refs/notes/*:refs/notes/*' $ git fetch # It's many MB for src, will take some time
It will add lines to your git log output like this:
Notes: svn path=/head/; revision=277815
Merging pull requests from github using git-svn (FreeBSD committers only)
Experimental git-svn bootstrap
There is an experimental git-svn bootstrap for quickly getting a complete git-svn enabled repository of your own.
Visit https://github.com/idaemons/freebsd and follow the instructions described in the README file.
- I want authornames!
Good for you, and this has been done but abandoned again for various reasons: There's no authoritative, complete and stable mapping of svn users to "Name <email>" pairs. Especially for people without access to freefall. Random contributors are more likely to have a conversion using the current parameters.
- Why the full history and not only since day X
- It would make the history incompatible with other people's repository and the space savings are simply not worth the hassle. As of Oct/2012, all revisions make up about 933MB.
Everything done is so that everybody can verify the integrity of the conversion using the tools mentioned in this article. Hence the focus on repeat-ability of the process.
Verifying that the git export is identical to the SVN tree (in content), can be done like this:
$ svn export --ignore-keywords svn://svn.freebsd.org/base/head freebsd.svn ... Exported revision 243246. $ git clone --config remote.origin.fetch='+refs/notes/*:refs/notes/*' git://github.com/freebsd/freebsd.git freebsd.git $ cd freebsd.git && git pull $ git log <We see that revision 243246 is git commit f9ebae3> $ git checkout f9ebae3 $ cd ../freebsd.svn $ git --git-dir ../freebsd.git/.git diff <There should be no output, i.e. no diff>
To verify the history and integrity of the conversion, you are advised to run such a conversion yourself and compare (and report) any discrepancies that you find.
Install the ports devel/subversion, devel/git, devel/qt4-corelib, devel/qmake4
- Get an svnsync clone of the repository you want to verify, the converter can only run against a local copy
Get the converter and rules: svn co http://svn.freebsd.org/base/user/uqs/git_conv && cd git_conv
Remove conflicting git configs, these are not for you: rm -rf doc-head.git freebsd-doc.git freebsd-ports.git freebsd-base.git ports-head.git src-head.git
Build svn2git: cd svn2git/src && make && cd ../..
Either tweak and run the git_conv script, or do it manually: svn2git/svn-all-fast-export --add-metadata-notes --identity-domain FreeBSD.org --rules freebsd-base.rules /path/to/freebsd-base.svn
Fetch upstream commits into your repo: cd freebsd-base.git && git remote add origin git://github.com/freebsd/freebsd.git && git fetch origin
Find out where/if their history diverges: git merge-base master origin/master
To redo this at a later stage, you simply need to
svnsync sync file:///path/to/freebsd-base.svn
svn2git/svn-all-fast-export --add-metadata-notes --identity-domain FreeBSD.org --rules freebsd-base.rules /path/to/freebsd-base.svn
cd freebsd-base.git && git fetch origin
git merge-base master origin/master
It really helps to understand the data structure of a git commit, because then you know how merging/rebasing works and can fix snafus easily.
A good visual git reference can be found at A Visual Git Reference.
This is a decent book on getting started with Git ($16 USD for ebook) Pragmatic Guide to Git
The software used for the conversion is a slightly modified fork of svn2git, as used by the KDE project. It can be found at https://gitorious.org/~uqs/svn2git/uqs-svn2git
It requires a rules file to map svn trees and/or revisions to git branches or tags. The current rules don't make use of tags but simply store them as branches.
See the project branch at http://svn.freebsd.org/base/user/uqs/git_conv/ for extra patches, rules and the scripts used to do these conversions.