Maybe you've found yourself stuck with a codebase in the TFS Version Control System and would like to move it, along with its entire history, into Git. If so, this article explains how to do it. Even if you don't plan to move, you might want to check out git-tfs - a bridge between TFS and Git, that allows you to work with your codebase in TFS as if it were a Git repository. I'd been using git-tfs for multiple projects, and since now the TFS server itself directly supports Git, it's about time to migrate it.
If you want to do the migration, you will need to have git-tfs (and git itself) installed. There are various ways to do this, but I prefer using Chocolatey - just run
choco install gittfs -y as admin.
Clone the TFS repository. This step might take a while - since git-tfs is fetching every checkin in your project's history and making it into a git commit. Just run
git tfs clone https://your-tfs/collection/$/Migrated-project-name
Clone the (still empty) target repo of your new Git project.
git clone https://url/to/target-git-repo
If you try just pushing the source repo into the target (as I naively did), you will get an error that goes like this:
remote: error: refusing to update checked out branch: refs/heads/master remote: error: By default, updating the current branch in a non-bare repository remote: error: is denied, because it will make the index and work tree inconsistent remote: error: with what you pushed, and will require 'git reset --hard' to match remote: error: the work tree to HEAD.
That's basically Git trying to prevent you from shooting yourself in the foot - because hey, you're clearly pushing into a completely unrelated repository.
You can override this behaviour. Go to the target Git repo and set "denyCurrentBranch" to "warn".
cd target-git-repo git config --local receive.denyCurrentBranch warn
You should be ready now. Just use your favourite client to
git push from the
Migrated-project-name (the repository created by git-tfs) into your
target-git-repo (the new git repository).
Reminder: you're pushing into the newly created repository you made on your local file system - not the central repository (like TFS) it will eventually reside in.
You might want to check out the master branch in your new repo. Run
git checkout master
At this point, you should see the most up-to-date version of the files in your old TFS workspace in
target-git-repo. You're ready to push into your git repository's origin. (I.e. into TFS or GitHub.)
And that's it.
A word of warning: while I like the visually pleasing GitKraken client, I've had many issues with it. Sometimes it outright doesn't do what it should and displays an error (or gets itself into a state where it can't even start), sometimes it's more subtle.
When I'd tried to do this process with GitKraken, I got confusing errors (not to mention it refuses to even open a repo that doesn't have any commits yet). When I tried the same steps with TortoiseGit, everything went smoothly.
At this point, you might want to reset/remove the
denyCurrentBranch that's still left in your
Please note that this assumes you will make a new TFS project for your new Git codebase. I haven't tried finding out whether you can switch it 'in place', or anything. ↩︎