Skip to content

Instantly share code, notes, and snippets.

@leftclickben
Last active June 7, 2023 10:58
Show Gist options
  • Save leftclickben/322b7a3042cbe97ed2af to your computer and use it in GitHub Desktop.
Save leftclickben/322b7a3042cbe97ed2af to your computer and use it in GitHub Desktop.
Steps to migrate from SVN to GitLab

Steps to migrate from SVN to GitLab

This process worked for me. I take no responsibility for any damage or loss incurred as a result of following or not following these steps or, for that matter, anything else you might do or not do.

Setup

  • SVN is hosted at svn.domain.com.au.
  • SVN is accessible via http (other protocols should work).
  • GitLab is hosted at git.domain.com.au and:
    • A group is created with the namespace dev-team.
    • At least one user account is created, added to the group, and has an SSH key for the account being used for the migration (test using ssh [email protected]).
    • The project favourite-project is created in the dev-team namespace.
  • The file users.txt contains the relevant user details, one user per line, of the form username = First Last <[email protected]>, where username is the username given in SVN logs. (See first link in References section for details, in particular answer by user Casey).

Versions

  • subversion version 1.6.17 (r1128011)
  • git version 1.9.1
  • GitLab version 7.2.1 ff1633f
  • Ubuntu server 14.04

Commands

git svn clone --stdlayout --no-metadata -A users.txt http://svn.domain.com.au/svn/repository/favourite-project
cd favourite-project
git remote add gitlab [email protected]:dev-team/favourite-project.git
git push --set-upstream gitlab master

That's it! Reload the project page in GitLab web UI and you will see all commits and files now listed.

Notes

  • If there are unknown users, the git svn clone command will stop, in which case, update users.txt, cd favourite-project and git svn fetch will continue from where it stopped.
  • The standard trunk-tags-branches layout for SVN repository is required.
  • The SVN URL given to the git svn clone command stops at the level immediately above trunk/, tags/ and branches/.
  • The git svn clone command produces a lot of output, including some warnings at the top; I ignored the warnings.

References

@leftclickben
Copy link
Author

@cbscd @adinthyank Yes, this will migrate the repository with the full history, commit comments, etc, as opposed to just the current state of the repository.

@leftclickben
Copy link
Author

@cbscd The users.txt file should contain an entry for all of the users mentioned in the SVN history. It doesn't matter whether the user is currently able to access the repository, all that matters is that they are listed in the history. If there is a user in the SVN history that isn't represented in the users.txt file, the process will fail, but you can update the users.txt file with the missing user and start again.

@leftclickben
Copy link
Author

@weismannweb Thanks for that, it certainly beats the trial-and-error method that I used. In my case, I had less than a dozen users all up, but your method would be excellent especially for repos with a lot more users.

Copy link

ghost commented Feb 23, 2015

How can I push tags from the svn repository? I can see them created in the new repository under \refs\remotes\tags\ but there isn't any tag shown in gitlab.

@michabbb
Copy link

michabbb commented Apr 4, 2015

Here's another well documented Tutorial

@ChristianLutz
Copy link

Also, there is an official migration documentation for gitlab.

@docdawning
Copy link

docdawning commented Sep 2, 2016

Props. Thanks a lot for this. I've used it with fairly satisfying success. Muchas mcfrickken gracias! (specifically, I followed the gitlab docs for svn -> git -> gitlab first, then I used this to get my tickets & milestones

@nissaba
Copy link

nissaba commented Sep 22, 2016

I got a empty repo after a very long list of files printed to the screen ending with this

Found possible branch point: svn://xxx.xxx.xxx.xxx/ios/MobileUniversal/trunk => svn://xxx.xxx.xxx.xxx/ios/MobileUniversal/branches/mantis681_jfwork, 3246
Use of uninitialized value $u in substitution (s///) at /Applications/Xcode.app/Contents/Developer/usr/share/git-core/perl/Git/SVN.pm line 101.
Use of uninitialized value $u in concatenation (.) or string at /Applications/Xcode.app/Contents/Developer/usr/share/git-core/perl/Git/SVN.pm line 101.
refs/remotes/origin/trunk: 'svn://xxx.xxx.xxx.xxx/ios' not found in ''

@vs
Copy link

vs commented Dec 1, 2016

It is also possible to create GitLab mirror of existing SVN project via SubGit, see instructions.

@ynotna87
Copy link

I am a noobie on this.

I get 'Can't create session' error when i want to access the svn that using https. What should i do ?

Thanks in advance.

@swanandmehta
Copy link

maybe I am too late here but I created script maybe it would help anyone in need

#!/usr/bin/env sh

echo Please provide svn project repo :
read svnRepo

echo Please provide git project repo :
read gitRepo

echo Please provide svn project name :
read projectName

root="${projectName}_root"
svnDir="${projectName}_svn"
gitDir="${projectName}_git"

mkdir -p $root
cd $root

mkdir -p $svnDir
cd $svnDir

svn checkout $svnRepo

cd $projectName

svn log -q | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > ../../users.txt

cd ../../

read -p "Press [Enter] key to confirm the users.txt file is updated with valid accounts which are present in git."

mkdir -p $gitDir
cd $gitDir

git svn clone --stdlayout --no-metadata -A ../users.txt $svnRepo

cd $projectName

for t in $(git for-each-ref --format='%(refname:short)' refs/remotes/tags); do git tag ${t/tags//} $t && git branch -D -r $t; done

for b in $(git for-each-ref --format='%(refname:short)' refs/remotes); do git branch $b refs/remotes/$b && git branch -D -r $b; done

git remote add origin $gitRepo

read -p "Press [Enter] key to confirm force push branches, tags into git."

git push -f --all

read -p "Press [Enter] key to quit the program."

@Hackbard
Copy link

@swanandmehta you are just in time ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment