🚀 Executive Summary

TL;DR: Migrating legacy SVN repositories to Git can significantly boost team productivity by enabling modern CI/CD workflows. This guide details a refined `git-svn` process to ensure a complete and accurate transition, preserving all commit history, branches, and tags.

🎯 Key Takeaways

  • Creating an `authors.txt` mapping file is crucial for accurately translating SVN usernames to Git’s name and email format, preventing ‘no author’ commits.
  • The `git svn clone –stdlayout –authors-file=authors.txt` command is central to initiating the migration, converting SVN revisions into Git commits while respecting standard repository structures.
  • Post-clone, specific scripts are required to convert SVN remote branches and tags into native Git branches and lightweight tags, ensuring full history and structure preservation.

Migrate Subversion (SVN) Repo to Git with History Preserved

Migrate Subversion (SVN) Repo to Git with History Preserved

Hey there, Darian Vance here. Let’s talk about SVN. It was a workhorse, but modern CI/CD pipelines and developer workflows are built around Git for a reason. For a long time, one of our key legacy projects was stuck on an old SVN server. The migration felt daunting, and we kept putting it off. But once we finally bit the bullet and moved it to Git, our team’s productivity shot up. No more clunky branching or disconnected commit history. This guide is the exact, no-fluff process I’ve refined to get it done right, preserving every last bit of that valuable history.

Prerequisites

Before we dive in, let’s make sure your workstation is ready. You don’t want to get halfway through and realize a tool is missing. You’ll need:

  • Git: The core version control system.
  • Subversion Client: The command-line tools for SVN.
  • git-svn: This is a utility that’s usually included with a standard Git installation. It’s the magic wand for this entire operation.

I’m assuming you have a standard development environment set up. I’ll skip the basics of creating a working directory, as you’ve likely got your own preferred workflow for that. Let’s jump straight into the migration commands.


The Step-by-Step Guide

Step 1: Create the Authors File

This is the most critical step for preserving history accurately. SVN just logs a username for each commit (e.g., “dvance”). Git, however, needs a name and an email (e.g., “Darian Vance <d.vance@techresolve.com>”). We need to create a mapping file.

First, get a list of all commit authors from your SVN repo. You can do this by running a command against your SVN repository to extract the author names from the logs. Once you have the list of unique usernames, create a file named authors.txt with the following format:

sv_username1 = First Last <email@example.com>
sv_username2 = Another Name <another@example.com>
dvance = Darian Vance <d.vance@techresolve.com>

Pro Tip: Don’t skip this. If you do, your Git history will be filled with commits from “(no author)”, which makes `git blame` and history tracking practically useless. Take the ten minutes to get this right; your future self will thank you.

Step 2: The Initial Clone with `git svn`

Now we’ll perform the main cloning operation. This command tells Git to connect to the SVN remote, pull down all the revisions, and convert them into Git commits, using our authors file for mapping.

Navigate to your empty working directory and run the following command. Be patient; for a large repository, this can take hours.

git svn clone --stdlayout --authors-file=authors.txt https://svn.example.com/path/to/repo/ my_new_git_repo

Let’s break down those flags:

  • --stdlayout: This is a shortcut that tells git-svn your repository follows the standard /trunk, /branches, /tags structure. If your repo is non-standard, you’ll need to specify the paths manually with -T, -b, and -t flags.
  • --authors-file=authors.txt: Points to the mapping file we just created.
  • https://svn.example.com/...: The URL to your SVN repository.
  • my_new_git_repo: The name of the local directory where the new Git repo will be created.

Step 3: Convert SVN Branches and Tags

After the clone finishes, you’ll notice something odd. If you run `git branch -a`, you’ll see your SVN branches listed as remote branches (e.g., `remotes/origin/feature-branch`). Tags are treated the same way. We need to convert these into proper, native Git branches and tags.

First, convert the branches:

for branch in $(git branch -r | grep -v 'tags/' | grep -v 'trunk'); do
    git branch "$(echo $branch | sed 's/origin\///')" "$branch"
done

This script iterates over all remote branches (excluding tags and the trunk, which is already our `main` branch) and creates a local Git branch for each one.

Next, convert the tags:

for tag in $(git branch -r | grep 'tags/'); do
    git tag "$(echo $tag | sed 's/origin\/tags\///')" "$(git rev-parse "$tag")"
done

This does something similar, but it creates lightweight Git tags from the SVN tag branches. This is how Git expects tags to exist.

Step 4: Clean Up and Finalize

Our repository is now a proper Git repo, but it still has some SVN metadata hanging around. We don’t need that anymore. In my production setups, I like to run a quick cleanup to sever the connection to the old SVN remote.

You can do this by removing the SVN-related configuration from your local .git/config file. It’s also a good idea to remove the now-redundant remote branches that `git-svn` created.

Step 5: Push to Your New Git Remote

The final step is to push your shiny new Git repository to its new home (like GitHub, GitLab, or Bitbucket).

First, create a new, empty repository on your platform of choice. Grab the remote URL it gives you.

git remote add origin git@github.com:your-org/my_new_git_repo.git
git push --all origin
git push --tags origin

And that’s it! Your entire repository, with all its branches, tags, and commit history intact, is now living in a native Git environment.


Common Pitfalls (Where I Usually Mess Up)

  • Non-Standard SVN Layout: The --stdlayout flag is a lifesaver, but I’ve been burned by repos that had a non-standard structure (e.g., `Trunk` with a capital ‘T’ or no branches folder). The clone will fail or give you a weird history. Always double-check the SVN structure and use manual flags (--trunk=..., --branches=...) if needed.
  • Forgetting an Author: If you miss a username in authors.txt, the clone process will pause and ask you for the mapping. In a long, unattended script, this will cause it to hang indefinitely. Be thorough with that file.
  • Huge Repositories: For truly massive SVN repositories (many gigabytes and hundreds of thousands of revisions), the initial `git svn clone` can be fragile. It might fail due to network hiccups. In these rare cases, you might need to look into more advanced tools or incremental cloning strategies.

Conclusion

Migrating from SVN to Git might seem like a complex chore, but it’s an investment that pays dividends almost immediately. Your team gets access to a more powerful branching model, better tooling, and a workflow that aligns with modern DevOps practices. By following these steps, you can ensure a clean, complete, and painless transition. Happy coding!

Darian Vance - Lead Cloud Architect

Darian Vance

Lead Cloud Architect & DevOps Strategist

With over 12 years in system architecture and automation, Darian specializes in simplifying complex cloud infrastructures. An advocate for open-source solutions, he founded TechResolve to provide engineers with actionable, battle-tested troubleshooting guides and robust software alternatives.


🤖 Frequently Asked Questions

âť“ How do I migrate an SVN repository to Git while preserving its full history?

Utilize `git-svn` with an `authors.txt` file to map SVN usernames to Git’s name and email format, then use `git svn clone –stdlayout` to pull all revisions and convert them into Git commits, followed by converting SVN branches and tags to native Git objects.

âť“ How does the `git-svn` method compare to other approaches for SVN to Git migration?

The `git-svn` method is highly effective for preserving complete commit history, including authors, branches, and tags, ensuring a faithful conversion to a native Git repository. Simpler methods might lose critical metadata or require manual reconstruction of history.

âť“ What happens if my SVN repository doesn’t follow the standard `/trunk`, `/branches`, `/tags` layout during migration?

If the SVN repository has a non-standard layout, the `git svn clone` command with the `–stdlayout` flag will fail or produce an incorrect history. You must manually specify the trunk, branches, and tags paths using `–trunk=…`, `–branches=…`, and `–tags=…` flags instead.

Leave a Reply

Discover more from TechResolve - SaaS Troubleshooting & Software Alternatives

Subscribe now to keep reading and get access to the full archive.

Continue reading