Migrate from TFVC to Git
By Robert Outlaw
Bring over the code in your TFVC main branch into a new Git repo, but avoid bringing over your TFVC checkin history with it. Keep your existing TFVC in the same team project as your new Git repo so you have easy access to your development history before the migration.
Key advantages to not migrating history include:
- Easy removal of any large binary files stored in TFVC. Git has difficultly with large binary files and you should avoid adding them to your Git repo.
- The process to perform and verify the migration is much easier and far less error-prone.
- Your TFVC repo in the same team project preserves your history up to the migration of your code to Git. This history retains its full fidelity in TFVC.
Avoid trouble: Don’t try to maintain two separate versions of your code at the same time in both Git and TFVC repos while you migrate. Switch over each repo to Git cleanly.
Prepare the migration
Install Git for Windows if you haven’t done so already. Make sure to Enable Git Credential Manager during the installation so you can easily connect to Team Services or TFS.
Create and clone your Git repo
Create a Git repo in Team Services or TFS to push your code to when the migration is complete. Make sure to copy the Clone URL for this repo to a convenient place. This repo should be in the same Team Project as your existing TFVC repo so that existing users and groups can be used to manage your new Git repo.
Populate your Git repo
Copy your code
Copy the code from the folder where the TFVC workspace for your main branch is mapped to the folder containing your new Git repo. Don’t stage or commit your migrated code in Git yet.
Separate large binaries
When working with large binary files in TFVC, you kept one copy of the file on your system at a time. Other versions of these files are downloaded from the server as needed. Git is decentralized, so it must keep all versions of a file in your local repo, including large binaries. Git is optimized for text-based source code-files that are easily diffable and compressible. Binary files don’t share these properties, and they can cause performance issues for your local repo over time as versions of these files add up.
Address this problem with large binary files through a two-step process:
- Identify which files need to be excluded. A good rule of thumb is that if a binary is large and frequently updated, it should not be stored directly in Git. Learn more about storing large files in Git.
- Create a mechanism to manage these files. Incorporate these external packages into your build to run and test your code.
Exclude tools and libraries
Create a .gitignore in the root folder of your repo and set it up to ignore any large binary tools and libraries that were part of your TFVC repo. Carefully consider what to do with the large files you need to keep-each new version will increase the size of your repo and can impact performance over time.
You can find the largest files in your repo by running the following PowerShell command from the folder containing your code:
gci . -r | sort Length -desc | select fullname -f 25
This returns the 25 largest files in your repo. You can tweak this command and filter the output on other criteria as needed. Add each file or file pattern you don’t want to save in Git to the .gitignore file in the folder where you created your Git repo.
Package the excluded files
Excluding these files mean that they are no longer under version control. If your build relies on removed files, you need to make them available so that your code builds from a fresh copy of your repo. Adopt a packaging solution with versioning support, such as NuGet , to manage and incorporate these files into your build.
Manage asset files
Look at the TFVC check in history of the asset files in your repo, such as images and other data in binary file formats. If your source has a large number of these files and they are frequently updated, consider a solution like Git LFS to help you manage these assets. If the source binary files are small and infrequently updated, consider just adding them into Git. If you decide to use Git LFS, make sure to follow the instructions and add and commit the files to your local repo before continuing.
Push your changes to your remote repo
Commit your code to your local repo. The .gitignore created in the previous step excludes the large binaries identified in the commit.
git commit --all -m "Initial commit of TFVC code"
Then push the code to the master branch in your Git repo in Team Services or TFS:
git push -u origin master
The main branch of your code is now in a Git repository in TFS or Team Services. If you don’t need to migrate any TFVC branches, your migration is complete.
Once you’ve committed and pushed your code, migrate your TFVC branches to Git by creating a new branch off the
master branch in your new Git repo for each migrated branch and switching to the new branch. In this example, we are using a branch name
git checkout -b releases/20
Only migrate TFVC branches that make sense in your team’s Git branching strategy.
Copy over the most recent version of code in your TFVC branch into your Git repo. Perform the same steps as before to filter out any large files included in the branch, then stage and commit your changes. If you updated the .gitignore in your main branch, it will filter out the same files in new branch as well.
git commit --all -m "Initial commit of TFVC release 2.0 branch"
Push your branch to Team Services/TFS:
git push -u origin releases/20
Switch back to the
master branch and repeat this process for any other branches you need to migrate.
Update your workflow
Moving from TFVC to Git takes more than just migrating code. Your team needs understand how Git is different from TFVC and how these differences affect day-to-day work. Learn more.
Get started with unlimited free private Git repos in Visual Studio Team Services.