Converting an assembla subversion repository to a Jira / Stash hosted git repository

Converting an assembla subversion repository to a Jira / Stash hosted git repository

We were tasked by our client to move several subversion repositories,  hosted at Assembla,  to Stash GIT on dedicated Windows 2008 servers with SQL Server 2008.

First install windows git (http://git-scm.com/download/win)

So,   first I had to download an install Jira (https://www.atlassian.com/software/jira/download),  and Stash (https://www.atlassian.com/software/stash/download) from atlassian.   This was very straight forward,  just create an account at Atlassian download on the Webserver and install using the evaluation key.
I installed the apps using their default options with the default ports and then when prompted I just changed ‘localhost’ to the IP of the server I was working on.

Once they were installed I accessed them at

http://serverip:8080/    – Jira
http://serverip:7990/    – Stash

Each one of the programs takes you through a setup wizard.  Where it prompts you to connect to a database server.  This was straight forward you just have to make sure you setup separate databases for each of them.  I used the same database server and username.   The only gotcha comes with setting up the Stash database.  here you will want to just use SQL to set up the DB.

CREATE DATABASE stash
USE stash
ALTER DATABASE stash SET ALLOW_SNAPSHOT_ISOLATION ON
ALTER DATABASE stash SET READ_COMMITTED_SNAPSHOT ON
ALTER DATABASE pm_stash COLLATE SQL_Latin1_General_CP1_CS_AS
SET NOCOUNT OFF

This setup is a requirement of stash so the db is case sensitive.  After both databases are setup you can setup your user with create drop insert and select privileges (i just gave it db_owner).

Setup Jira first and then when setting up Stash,   you can just answer some basic questions about where your Jira installation is and you can combine the user accounts so you only manage one set of users.

Now that the default is setup,  add a project and repository to stash,  this is basic and the repository is empty and on the resulting screen it shows you how to push an existing repository into stash.

 

You will see in the Stash repository screen commands that you will use to push the desired repository to Stash take note of where to find it,  we are going to first convert our repository from SVN to git

Log into a ‘working’ linux installation,  I have a Ubuntu server.

Delete the temporary folder and download your svn repository into a temporary directory (I had seen some odd errors when I tried to clone again to a partially cloned git repo,  so I decided I will always delete the git repo first ,  and start from scratch if there is an error to make sure it is 100% clean)

  • rm -rf /tmp/temp.git
  • git svn clone <svnurl>  –no-metadata -A users.txt –stdlayout /tmp/temp.git

This clone command may take a while depending on how large the repository is as well as your bandwidth to pull down all of the code.
While it is difficult to be able to tell WHERE in the process you are in order to find out how long the process may take,  I did find a couple of indicators which may help if it is a very lengthy  process.

find out some information on your existing repository 1) the current revision and 2) what the total size of your repository is on the server (http://stackoverflow.com/questions/1740543/determine-total-size-of-svn-directory-trunk)

  1. svn info <svn repository url>
  2. svn list -vR <svn repository url>|awk ‘{if ($3 !=””) sum+=$3; i++} END {print “ntotal size= ” sum/1024000″ MB” “nnumber of files= ” i/1000 ” K”}’

You can use the information above in a couple of ways

  1. watch the output from your command,  depending on the size of the commits to your repository,  you will frequently see what revision number is currently being worked on. (r17 is revision 17)  you can compare this against the most recent revision on the server to determine how far you are in the import
  2. Even though you git repository will be smaller than the SVN repository(between 0 and 30%),  you may be able to compare the size to indicate how far along in the process it is.  so cd /tmp/temp.git and ‘du –max-depth=0’

Ignore the errors about using –prefix,  these just caused me headaches and so by NOT using their recommendations to set prefix=origin/  this will work.
If you receive an error which says I need to have ‘usera’  I would add usera to users.txt and run the  rm and git svn clone command again

  • echo “usera = User A <usera@com.com>” >> users.txt

This method works if you only have a couple of users,   but for some of my repositories I had LOTS of users,  so I used the following command and then edited the user file by hand to make sure it worked.

  • svn log -q <svnurl> | awk -F ‘|’ ‘/^r/ {sub(“^ “, “”, $2); sub(” $”, “”, $2); print $2″ = “$2” <“$2″>”}’ | sort -u > users.txt

If you receive the error “Unexpected HTTP status 405 ‘Method Not Allowed’ on ‘/svn/wssus.admindash’” this means that you have some protected directories setup in your Assembla.  Open the project within Assembla > Settings > Protected branch and remove the directories and run the  rm and git svn clone command again

If dont have any ignore files in svn i fake one so I have at least one commit

  • cd/tmp/temp.git
  • touch .gitignore #if I dont have any ignore files
  • git svn show-ignore > .gitignore  #if I do have ignore files i svn,  this will return an error if there are no ignore files
  • git add .gitignore
  • git commit -m ‘Converting Properties from SVN  to GIT’ .gitignore

create another bare repo and create a symbolic link for the ‘trunk’ coming from SVN

  • mkdir /tmp/bare.git
  • cd /tmp/tmpbare.git
  • git init –bare
  • git symbolic-ref HEAD refs/heads/trunk

Go back to the temp git repo and push it to the new bare repo and rename the ‘trunk’ to ‘master’

  • cd /tmp/temp.git
  • git remote add bare /tmp/bare.git
  • git config remote.bare.push ‘refs/remotes/*:refs/heads/*’
  • git push bare
  • cd /tmp/bare.git
  • git branch -m trunk  master

Clean up branches and tags (thanks to http://john.albin.net/git/convert-subversion-to-git for most of this)

  • git for-each-ref –format=’%(refname)’ refs/heads/tags |
    cut -d / -f 4 |
    while read ref
    do
      git tag “$ref” “refs/heads/tags/$ref”;
      git branch -D “tags/$ref”;
    done

Now you have a correctly formatted repo at /git/bare.git.    you can push it to your stash git repository

  • cd /tmp/bare.git
  • git config remote-url <your git repository url from stash>
  • git push origin master

This may take a bit of time depending on how much code you have.  But once it is complete you can browse you repository in stash.

 

Next step,  setting up Git work flows to implement a required SDLC.