Migrating Projects from SVN to Git with Full History


Subversion was the backbone of version control for enterprise projects for many years. But the industry has moved on. Git has become the standard, and the demand for migration from SVN to Git keeps growing. This post walks through the steps I followed to move an SVN project to Git without losing history, tags, or branches.

You can read this post in Turkish.

Prerequisites

Three tools are needed for this migration:

  • git and git-svn (the bridge between Git and Subversion)
  • subversion (SVN client)
  • A text editor (vim or nano)

If git-svn is not available on your system, jump to Step 0 below for a Docker-based workaround.

Step 0: Use Docker When git-svn Is Missing

Some systems do not ship git-svn by default. Instead of hunting down packages, you can spin up a container:

docker run -it --network=host ubuntu bash

Once inside the container, install the required packages:

apt update && apt install git git-svn subversion vim -y

The --network=host flag ensures the container can reach your SVN server. After the migration is complete, you can discard the container.

Step 1: Checkout the SVN Repository

Start by checking out the project from SVN. Use a full checkout so all branches and tags are available locally.

svn checkout http://svn-adresi/svn/proje proje-svn

Replace the URL with your actual SVN repository address.

Step 2: Extract the List of Committers

Git commits require proper author information (name and email). SVN only stores usernames. You need to extract every unique committer from the SVN log and build a mapping file.

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

This command parses the SVN log and outputs lines in the format:

username = username <username>

Step 3: Map SVN Usernames to Git Authors

Edit the users.txt file and replace the placeholder entries with real names and email addresses:

jdoe = John Doe <jdoe@example.com>
asmith = Alice Smith <asmith@example.com>

If your SVN server uses a consistent pattern (for example, usernames are also email prefixes), you can automate the mapping:

sed -i 's/>/@example.com>/g' users.txt

This appends @example.com to each username, turning jdoe = jdoe <jdoe> into jdoe = jdoe <jdoe@example.com>. You still need to fill in full names manually.

Step 4: Clone the SVN Repository with git-svn

With the author mapping ready, clone the repository using git svn clone. The --stdlayout flag tells git-svn that the repository follows the standard SVN layout (trunk, branches, tags).

git svn clone http://svn-adresi/svn/proje --authors-file=users.txt --stdlayout --no-metadata --prefix "" proje-git

Key flags explained:

FlagPurpose
--authors-file=users.txtMap SVN usernames to Git authors
--stdlayoutUse standard trunk/branches/tags layout
--no-metadataOmit SVN metadata from commit messages
--prefix ""Keep remote reference names clean

This step takes time depending on the repository size. Every commit from SVN history is replayed as a Git commit with proper author information.

Step 5: Convert SVN Branches and Tags to Git

After the clone completes, branches and tags are stored as remote references. They need to be converted to native Git objects.

Convert Tags

SVN tags appear under refs/remotes/tags/. Move them to proper Git tags:

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

Convert Branches

Regular branches live under refs/remotes/. Promote them to local branches:

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

Clean Up

Some references may contain @ symbols (git-svn artifacts). Remove them:

for p in $(git for-each-ref --format='%(refname:short)' | grep @); do
  git branch -D $p
done

The trunk branch is no longer needed since Git uses main or master as the default branch. Remove it:

git branch -d trunk

Step 6: Push to a New Git Remote

The local Git repository is now ready. Add a remote and push everything:

git remote add origin http://git-adresi/yeni/git-projesi.git
git push origin --all
git push origin --tags

--all pushes all branches. --tags pushes all tags. The new repository now contains the full history, every branch, and every tag from the original SVN project.

Wrapping Up

Migrating from SVN to Git with full history is a straightforward process when you follow the right steps. The key is preparing the author mapping file correctly and using git-svn with the right flags. Branches and tags need a small conversion step after the clone, but the entire process is scriptable and repeatable.

The Docker workaround solves the environment problem cleanly when git-svn is not available. Once the migration is done, the team can start using Git with all the history intact and no lost context.

Originally published in Turkish on Medium