TFVC to Git Migration: Step-by-Step Guide for Modern DevOps Teams
Migrating from TFVC to Git modernizes the development workflow, enabling distributed version control, better branching, and DevOps automation.
Join the DZone community and get the full member experience.
Join For FreeThe Challenge
Our organization has maintained a large monolithic codebase in Team Foundation Version Control (TFVC) for over a decade. As development velocity has increased and teams have moved toward agile methodologies, microservices, and cloud-native architectures, the limitations of TFVC have become increasingly apparent. The centralized version control model hinders collaboration, branching, and automation, and our existing classic build and release pipelines in TFS are tightly coupled with legacy tooling that no longer aligns with modern DevOps practices.
We have observed significant bottlenecks in:
- Managing concurrent feature development across teams
- Implementing flexible CI/CD workflows
- Integrating with cloud-based infrastructure and tools
- Adopting containerized, microservice-oriented deployments
To enable a scalable, collaborative, and DevOps-friendly environment, we must migrate our TFVC repositories to Git, which is better suited for distributed development, supports lightweight branching, and integrates seamlessly with modern CI/CD pipelines and platforms like Azure DevOps, GitHub, and Kubernetes.
Overview
While TFVC has served enterprises for years, its centralized nature and complex branching model make it less suitable for modern development paradigms. In contrast, Git, a distributed version control system, empowers teams to move faster, collaborate more effectively, and align with industry-standard CI/CD practices.
In this blog, we will walk through
- Why should we migrate from TFVC to Git
- Key challenges during migration
- Step-by-step guide using Azure DevOps
- An example use case
- Post-migration best practices
Why Migrate from TFVC to Git?
1. Align With Modern Tooling
Git integrates seamlessly with tools like GitHub, GitLab, Bitbucket, Azure DevOps Repos, Kubernetes, Docker, and more. TFVC is limited mostly to older Visual Studio versions and TFS
2. Distributed Workflows
Git allows every developer to work independently with a local copy of the entire codebase, enabling offline work, faster operations, and streamlined collaboration.
3. Agile and DevOps Support
Git's branching and merging strategies suit agile development and trunk-based development better than TFVC’s heavyweight model.
4. Cloud-Native and Microservices Ready
Microservices require isolated, independently deployable repositories. Git supports this easily with its lightweight branching, tagging, and submodule capabilities.
Challenges We May Face
While Git offers substantial benefits, the migration is not trivial, especially in large enterprises
Challenge | Description |
---|---|
Repository Size | TFVC projects can be large with extensive history |
History Preservation | We may want to retain commit history, comments and metadata |
User Mapping | Mapping historical TFVC users to Git commit authors |
Tool Familiarity | Developers may need Git training |
Pipeline Dependencies | Existing TFS build/release pipelines may break post-migration |
Step-by-Step Migration from TFVC to Git (Using Azure DevOps)
Azure DevOps provides native tools to facilitate TFVC-to-Git migrations. Let’s walk through a real-world example:
Scenario
A legacy monolithic application is stored in a TFVC repository in Azure DevOps Server 2019. The organization wants to modernize development by migrating this codebase to Git and starting to use YAML pipelines.
Step 1: Prepare the Environment
Step 2: Install Git-TFS
Git-TFS is a .NET tool that allows you to clone a TFVC repository and convert it into a Git repository.
choco install gittfs
Or manually download from this link.
Step 3: Clone the TFVC Repository With Git History
Now we will create a Git repository by fetching history from TFVC:
git tfs clone http://your-tfs-url:8080/tfs/DefaultCollection $/YourProject/MainBranch --branches=all
Notes:
--branches=all
will attempt to migrate TFVC branches to Git branches.$
is the root symbol for TFVC paths.
We can also limit the history to a certain number of changesets for performance:
git tfs clone http://your-tfs-url:8080/tfs/DefaultCollection $/YourProject/MainBranch --changeset=10000
Step 4: Push to Git Repository in Azure DevOps
Create a new Git Repo in Azure DevOps:
- Go to Project > Repos > New Repository.
- Select Git, name it appropriately.
Then, push your migrated Git repo.
cd <<YOUR-GIT-REPO>>
git remote add origin https://dev.azure.com/your-org/YourProject/_git/YourProject-Git
git push -u origin --all
Step 5: Validate and Set Up CI/CD
- Ensure all branches and tags are present.
- Recreate pipelines using Azure Pipelines (YAML) or any Git-based CI/CD system.
- Define branch policies, pull request templates, and protection rules.
Example Use Case
Let's assume we are migrating a health care management system developed in the .NET framework and hosted in TFVC.
Before Migration
- Single monolithic TFVC repository.
- Classic release pipelines in TFS.
- Developers struggle with branching and rollback.
After Migration
- Git repository with
main
,feature/*
, andrelease/*
branches. - Developers create pull requests for features and hotfixes.
- Azure YAML pipelines automate builds and deployments
Sample Git Branching Strategy
main
│
├── feature/add-enrollment-integration
├── feature/optimize-db-calls
├── release/v1.0
Sample Azure DevOps (YAML) CI/CD Pipeline
trigger:
branches:
include:
- main
- release/*
pool:
vmImage: 'windows-latest'
steps:
- task: UseDotNet@2
inputs:
packageType: 'sdk'
version: '6.x'
- script: dotnet build
- script: dotnet test
- script: dotnet publish -c Release
Best Practices Post-Migration
- Train the team on Git commands and workflows.
- Automate branching policies and PR reviews.
- Archive or decommission TFVC repositories to avoid confusion.
- Use semantic versioning, tagging, and GitHub flow based on team size.
- Monitor Git performance with tools like Git Large File Storage (LFS) if needed.
Understanding Branch Migration With Git-TFS
- When we run a basic
git tfs clone
command, Git-TFS only clones the main branch (trunk) and its history. - To migrate all branches, we must add
--branches=all
option:
git tfs clone http://tfs-url:8080/tfs/Collection $/YourProject/MainBranch --branches=all
This:
- Identifies TFVC branches as defined in the TFS repository
- Attempts to map them into Git branches
- Tries to preserve the merge relationships, if any
Migrate Selective TFVC Branches to Git
1. Identify TFVC Branch Paths
Find the full TFVC paths for the branches we care about:
$/YourProject/Main
$/YourProject/Dev
$/YourProject/Release/1.0
$/YourProject/Release/2.0
We can use Visual Studio or the tf branches command to list these
2. Clone the Main Branch First
git tfs clone http://tfs-server:8080/tfs/DefaultCollection $/YourProject/Main --with-branches --branches=none --debug
- This creates a Git repository tracking the Main TFVC branch and avoids pulling in unwanted branches.
--branches=none
ensures only this branch is cloned (avoids automatic detection of others).--with-branches
initializes Git-TFS to track additional branches later.
3. Add Additional Branches
Add additional desired branches using:
cd YourProject
git tfs branch -i $/YourProject/Dev
git tfs branch -i $/YourProject/Release/1.0
4. Fetch All the Branches
Now download the full changeset history for all the added branches:
git tfs fetch
5. Verify Git Branches
List the available branches in the local Git repo:
git branch -a
Expected output:
* main
remotes/tfs/Dev
remotes/tfs/Release-1.0
6. Create Local Branches (Optional)
If we want to work locally on these branches:
git checkout -b dev remotes/tfs/Dev
git checkout -b release/1.0 remotes/tfs/Release-1.0
7. Commit (Only If Modifications Are Made Locally)
If any manual changes are done to the working directory, don’t forget to commit:
git add .
git commit -m "Post-migration cleanup or updates"
8. Push to Git Remote (e.g., Azure DevOps or GitHub)
First, add your remote Git repository:
git remote add origin https://dev.azure.com/your-org/YourProject/_git/YourProject-Git
Then push your branches:
git push -u origin main
git push -u origin dev
git push -u origin release/1.0
Other Methods
While Git-TFS is one common approach, there are multiple methods to migrate from TFVC to Git, each with trade-offs depending on your goals: whether you need full history, multiple branches, scalability for large repos, or simplicity for new development. Below are the main options:
1. Shallow Migration (No History, Clean Slate)
This is best for:
- Teams that want a fresh start in Git
- Rewriting architecture to microservices
- Repositories with bloated or irrelevant TFVC history
Steps
- Create a Git repo.
- Export the latest code snapshot from TFVC (e.g, using
tf get
). - Add, commit, and push to Git.
tf get $/YourProject/Main
git init
git add .
git commit -m "Initial commit from TFVC snapshot"
git remote add origin <GitRepoURL>
git push -u origin main
Challenges
- We lose historical commit history.
- Can't track file-level changes pre-migration.
2. Manual Branch-by-Branch Migration
This is best for:
- Large monoliths broken down into microservices
- Controlled, phased migration
Steps
- Identify key branches (e.g., main, dev, release).
- Export them one by one using
git-tfs clone
. - Push each to separate Git repos or branches.
Challenges
- Requires effort to maintain consistency across branches
- Risk of missing context between branches
Conclusion
Migrating from TFVC to Git is not just a source control update — it's a strategic step toward modernization. Git enables speed, agility, and scalability in software development that centralized systems like TFVC cannot match.
By adopting Git, you not only align with current development trends but also lay the foundation for DevOps, microservices, and scalable delivery pipelines.
Whether you’re handling a single project or thousands of TFVC branches, start small, validate your process, and iterate. With the right tooling and planning, the transition to Git can be smooth and incredibly rewarding.
Opinions expressed by DZone contributors are their own.
Comments