Post

Migrating Repos to GitHub

Overview

There are several options for migrating repos to GitHub, depending on what Source Control Management (SCM) tool you are coming from, and what you want to migrate. Just the Git repo with all of its history? Because it’s Git to Git, it’s easy Only care about the latest changes and want to start fresh? Perhaps even easier, pull or get latest, create a new Git repo, add in the changes, and push. If it’s not Git, you must determine if you want to use a specialized tool to migrate or start fresh. This post will cover all of the different options, when you should use them, and any known gotchas.

Often, simply migrating your entire Git repository (with history) is sufficient and the most recommended approach. If you need to persist the metadata of your issues and pull requests comments for audit purposes, one option is to leave around the old system in a read-only state until it can be retired.

Note on Commit Authors

The way that GitHub attributes commits to an author is via the email address in the git config. In GitHub, you can add multiple email addresses, and if you want to see your GitHub avatar show up next to your commits, make sure to add your email address to your GitHub account.

Look at the example below. The first edit I made in GitHub.com, so it shows up as me. The second edit I made on my local machine, and since my git config was set up without using an email address linked to my GitHub account, the commit does not show up as from me:

Git commits, email addresses, and how GitHub renders the commit author Since the email in my Git config isn’t added to my GitHub account, the commit doesn’t link to my profile

To summarize, use git config --global --edit to view/update your local Git config and make sure the email address listed here is also added in GitHub.

Option 1: Using GitHub Importer

I often forget about this one, and if your repo is on a SAAS service (like Azure DevOps, BitBucket Cloud, etc.), this is going to be the way to go. The GitHub Importer works with Git, SVN, and Mercurial. This tool will import the contents of the repository, including history. For repos that require authentication, the wizard walks you through providing that information (typically a personal access token or API key). I’ve personally used this for migrating Azure DevOps Git repos as well as BitBucket Cloud Git repos to GitHub.

The downside is that it won’t work for those who have self-hosted instances of your source control system (such as Azure DevOps Server or BitBucket Server) since these are likely not internet-facing. It also won’t migrate any pull request or issue metadata information.

If using SVN or Mercurial, you will have the ability to update commit author attribution during the process. For Git, see the note above on commit authors.

Note: The docs say that this tool supports TFVC, but I’ve never been able to get it to work, so if you’re looking for TFVC, keep reading!

No source repositories were detected at <url>/_versionControl. Please check the URL and try again.

Option 2: Git Clone Mirror

This is usually what I do when migrating Git repos to GitHub, since it’s fast, efficient, and scriptable 😀. This migrates the entire repository, including all history, branches, and tags. The steps are as follows:

1
2
3
4
5
6
7
8
# Pre-requisite: Create repo in GitHub and grab the URL

# migrate the repository
git clone --mirror <source-repo-url>
cd <source-repo-name>
git push --mirror  <github-repo-url>
cd ..
rm -rf <source-repo-name>

The --mirror clones a bare copy of the repository that contains all refs (branches, tags, notes, etc.). With the bare copy of the repository, the files in the directory aren’t human readable, that’s why we clean up with the rm -rf at the end. Run a git clone <github-repo-url> to get a local copy of the repository and begin working with the repository in GitHub.

This of course works for transferring Git repos between any Git SCM.

A nice script that can do mass migrations is available here.

Option 3: Transfer a Repo in GitHub

If your repository is already in GitHub, and you just need to move it to another user or organization, did you know you can simply transfer the repo?

Option 4: Get Latest and Start Fresh

Starting fresh might be best for repositories with very old history, and/or repositories with a lot of binaries committed. Here’s how this process might look:

  1. Create a new EMPTY repo in GitHub - don’t initialize with a README or .gitignore
  2. Get your latest changes in existing SCM; e.g.: git pull or tf get to get latest changes
  3. Create a new folder and copy in the files from your existing repo - make sure to to NOT copy over the .git or $tf folder
  4. Initialize a new Git repo: git init
  5. Important: Add in a gitignore file - for .NET developers, you can run dotnet new gitignore, alternatively see github/gitignore repo for other templates
  6. Delete any binaries or other files you don’t want committed to the new repo, and/or modify gitignore as needed
  7. Add the origin: git remote add origin <github-repo-url>
  8. Push: git push -u origin main

Entirely scripted out, it would look something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
cd old-repo
# grab latest changes
git pull
# copy files to new folder and cd into it
mkdir ./../new-repo && cp -r ./* ./../new-repo && cd ./../new-repo
# initialize new git repo
git init
# add in and populate gitignore - either yourself or use `dotnet new gitignore`
touch .gitignore
# add in files, commit, and make sure we're using the main branch
git add .
git commit -m "Initial commit"
git branch -M main
# add remote and push
git remote add origin <github-repo-url>
git push -u origin main

Option 5: SVN to Git

  1. See my blog post!
  2. Otherwise, if your SVN repo is internet-accessible, see: GitHub Importer

Option 6: TFVC to Git

  1. Perhaps the simplest is to use the Azure Repos Git repo importer to convert from TFVC to Git, and then migrate that repo to GitHub using Option 1 or Option 2 above
    • If self-hosted, requires TFS 2017.2 or later
    • Note that it can only migrate 180 days of history and only supports 1 branch
  2. For more advanced migrations, use the Git-TFS tool
    • See this page for more information on the git-tfs clone command
    • There are various blog posts here, here, and here if you need additional guidance

See Microsoft’s documentation for more information on this topic.

Option 7: Other Third-Party Tools

Search GitHub and see what else is out there!

Summary

There is no shortage of options for migrating repositories, and while Git is certainly the easiest, there are still options for SVN, Mercurial, and TFVC out there.

I hope this post helps you find the right tool for your migration needs! 🥳

This post is licensed under CC BY 4.0 by the author.