Saturday, May 18, 2013

Migrating from Subversion to a simple self-hosted Git server

I recently migrated a Sourceforge-hosted Subversion repository to a Git repository for one of my open-source projects. I also have a number of private projects holed up on an old Linux server at home and decided that it's nigh time to git them over to Git as well. Now that I have a Mac Mini, I figured that I could take advantage of its Unix backbone to set up a simple SSH-based, self-hosted Git server.

My code will get an upgrade in hardware and version control protocol in one fell swoop. And given the number of minor tricks I had to find along the way, especially with the help of this tutorial, I figured that I'd document them here for posterity's sake.

Exporting the Subversion repository
I again used svn2git to export the Subversion repository to a local Git repository. In my case, I had a multi-project Subversion repo and wanted to export only one sub-project, so I used the "--no-minimize-url" flag. It also happened to be in slightly non-standard layout ("TxtflMobile" instead of "trunk"), which required me to explicitly set the trunk name. The authors flag was as outlined previously.

[on local machine:]
$ mkdir prjdir
$ cd prjdir
$ svn2git http://path/to/repo/subproject --trunk TxtflMobile --tags tags --branches branches --no-minimize-url --username name --authors ~/authors-txtfl.txt --verbose

As the repo was private, I had to specify the username to access the repo. Strangely, the execution hung, and I realized that I was supposed to provide my password even though it didn't prompt me--that is, until after  I provided my password and hit Enter.

To check the export, I ran the "git branch" and "git tag" commands to see the listing of all branches and tags.

Setting up the simple Git server
Looking through Git server options, I initially thought that I would need to download a variety of third-party server packages to set it up. A great many server packages do exist, including 8 outlined here and seemingly several popular packages that have since arisen. Fortunately, one of the easiest of these options is also one recommended in the Git book itself, the SSH-based server that allows access through basic SSH login.

To set up the remote repository on the server, I logged into the server (which happened to be the same computer to which I had exported the Subversion repo). In the System Preferences, I made sure that "Remote login" was enabled, which turns on sshd to allow SSH connections. I also wanted to change the sshd port, which involved editing the /System/Library/LaunchDaemons/ssh.plist file and making sure that my router forwarded this port to my server.

Now that the server was accessible (was, in fact, a "server"), I created a "bare" repository in the location from which I would host the Git repo and into which I would push my local Git repo.

[on server:]
$ mkdir /path/to/hosted/repo
$ cd /path/to/hosted/repo
$ git init --bare

Pushing the local repo to the server
Back on the local machine, I prepared the repo for pushing onto the server. I added the remote location to the repo to indicate where to push up the local repo.

[on local machine:]
$ git remote add origin ssh://name@

In my case, I used my username and customized port (eg "123") for login. Note that the "ssh://" protocol is necessary to specify the alternate port. In the process of learning this trick, I had to edit the URL for "origin" by using the "set-url" parameter in place of "add". In this case, I used "" as the IP because I would be pushing the local repo from same machine as the server.

Once I had set the remote URL, it was just a matter of pushing up the master branch, each additional branch, and all the tags to the server.

$ git push origin master
$ git push origin branch1
$ git push origin branch2
$ git push --tags

Accessing the repo from abroad
Of course, one of the main benefits of hosting the hosting the repo remotely is that one can access it from abroad. Using the "git clone" command to the server's URL allowed me to download it onto another machine.

[on another local machine:]
$ git clone ssh://

Another benefit of hosting the repo remotely is for backups. The cloned copies each serve as backups, and the remote repo itself can be backed up from the server. As one still getting used to Git, I immediately made an erroneous commit that I had already pushed to the remote server. While reverting this change can be difficult once on the remote server, in this case I merely had to enter the Time Machine backup software and restore the folder on the remote machine from a preceding backup. This simple solution is of course much more feasible given the simplicity of the project on such a simple server.
Post a Comment