Cloning the SVN repository
Cloning the SVN repository can be done via this command:
Most of the conversions can be done with three parameters to the ‘git svn clone’ command:
$ git svn clone --stdlayout --authors-file=authorinfo.txt file:///Users/username/Documents/subversion/theproject/
The clone command does the combination of init and fetch. The very first logging statement from the above command tells that an empty git repository is being made.
Initialized empty Git repository in /Users/username/projectdir/projectname/.git/
And then it (the clone) goes on to fetch the content.
The ‘git svn clone’ command has the following three main parameters:
- The Layout
- Author information
- SVN repository location
You can use the flag --stdlayout to tell git svn that standard Subversion directory structure is used --- meaning, in Subversion, you used three directories called trunk, branches, and tags.
With the --stdlayout the final migrated git code will be in just one directory. If you don’t use the above flag, then git will migrate the code into three separate directories (you don’t want that).
When the original SVN repository was not set up with standard names trunk, branches, and tags, you can actually specify these names using the flags --trunk, --tags, and --branches (or, -T, -t, and -b).
Finding the Subversion Repository Layout
By using the ‘svn list’ command, you can find out how the repository has been laid out.
$ svn list file:///users/username/Documents/repositorydirectory/application
The ‘file:/// …’ in the above command is the path to your Subversion repository.
If you want more information about the layout, you can use the flag -v (for verbose)
$ svn list -v file:///Users/username/Documents/repositorydirectory/application
498 user Feb 25 2011 ./
464 user Apr 20 2010 branches/
465 user Apr 20 2010 tags/
498 user Feb 25 2011 trunk/
The verbose listing gives the details on when was the last time a particular subdirectory was changed. The date on the tags directory will tell the last time you created a tag (most likely you haven’t changed the source that was copied as a part of a tag creation). Date next to trunk is the date when the trunk was last changed. And the number at the beginning of the listing (e.g. 498) is the last revision that has been made in that particular directory. These revisions in Subversion will become commits in git.
In the above repository, the standard layout of branches, tags, and trunk is used. So, in this case, the flag --stdlayout can be used with the ‘git svn’ command.
If you don’t provide git svn command, the author information, the user information will be a little bit messed up (or, rather generic).
As you can see, each SVN revision is converted into a commit in git. But the author email address is not correct.
Author: authername <authorname@50abe658-1f70-4458-b33a-5e60236458cc>
Date: <original revision date>
In order to fix the, you would need to use an authors-file.
This file will be in the following format:
authorname = Author Name <firstname.lastname@example.org>
And that authors file can be provided as a parameter to the git svn command:
$ git svn clone --stdlayout --authors-file=authors-info.txt <svn repository name>
After the migration, you will see the proper email address attached to the author (for the commits):
Author: Author Name <email@example.com>
Date: <original revision date>
Author from svn log
The author info can be obtained from the svn log command:
$ svn log -q
r498 | authorname | 2011-02-25 20:20:32 -0800 (Fri, 25 Feb 2011)
r497 | authorname | 2011-02-25 20:17:31 -0800 (Fri, 25 Feb 2011)
The flag -q (for quiet) provides a one line listing for each revision. This listing includes just the revision number, author name and the date. For most projects, the individual authors can be extracted from this listing manually. Otherwise, a simple script can extract individual authors.
You can also get the above log information in xml format and obtain the author information from there.
$ svn log -q --xml > svnlog.xml
Gives info in this format:
Author in svn and git blame
This author name is important, as it gets used all over in both Subversion and git. For example, this name is used in the source attribution commands like svn blame or git blame.
$ svn blame -v Info.plist
1 author 2009-04-04 12:27:31 -0700 (Sat, 04 Apr 2009) <?xml version="1.0" encoding="UTF-8"?>
1 author 2009-04-04 12:27:31 -0700 (Sat, 04 Apr 2009) <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
1 author 2009-04-04 12:27:31 -0700 (Sat, 04 Apr 2009) <plist version="1.0">
1 author 2009-04-04 12:27:31 -0700 (Sat, 04 Apr 2009) <dict>
1 author 2009-04-04 12:27:31 -0700 (Sat, 04 Apr 2009) <key>CFBundleDevelopmentRegion</key>
1 author 2009-04-04 12:27:31 -0700 (Sat, 04 Apr 2009) <string>English</string>
In Subversion, the blame command on particular file shows the revision number, followed by the author. With the -v (for version) flag, you will also get the date information.
In git, you will get very similar information with git blame command. As you can see below, the commit hash, name of the author, and date when the change has been made are displayed with git blame.
$ git blame Info.plist
^fc8d376 (author 2009-04-04 19:27:31 +0000 1) <?xml version="1.0" encoding="UTF-8"?>
^fc8d376 (author 2009-04-04 19:27:31 +0000 2) <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://w
^fc8d376 (author 2009-04-04 19:27:31 +0000 3) <plist version="1.0">
^fc8d376 (author 2009-04-04 19:27:31 +0000 4) <dict>
^fc8d376 (author 2009-04-04 19:27:31 +0000 5) <key>CFBundleDevelopmentRegion</key>
^fc8d376 (author 2009-04-04 19:27:31 +0000 6) <string>English</string>
In SVN, the revision numbers go from 1, 2, … etc. Where as the commits in git have unique hashes. Once the migration is completed, you can see the 1:1 relationship between revision numbers and commit hashes.
SVN repository location
And, finally, the SVN repository location needs to be provided to the git svn command:
$ git svn clone --stdlayout --authors-file=authors.txt file:///Users/username/documents/subversion/theproject/
If the subversion repository is there locally, then file:/// can be used. Otherwise, the url of the svn repository can be used.
One-way migration from SVN to Git
You can find out more about the one-way migration from SVN to Git from this article (It also includes notes and thoughts on cleaning up the local git repository before pushing it to the server):
One-way migration from SVN to Git
Pushing to the new repository to server
And the notes on pushing the finalized repository to the server are detailed in the following article:
Pushing the New Git Repository to Server