How do you migrate from TFVC to Git in Azure DevOps, and what history is preserved?
Quick Answer
Azure DevOps provides a built-in import tool that converts TFVC repositories to Git, preserving up to 180 days of history. For full history migration, use the git-tfs tool which converts all changesets to Git commits while preserving author information and timestamps.
Detailed Answer
Think of converting a paper filing cabinet into a digital document management system. You can scan the most recent 6 months of documents quickly (built-in import), or you can scan every document back to day one (git-tfs) — the second approach takes longer but gives you the complete historical record.
TFVC (Team Foundation Version Control) is a centralized version control system where all history lives on the server. Git is distributed — every clone has the full history. Migration from TFVC to Git is a one-way conversion that transforms TFVC changesets into Git commits. Azure DevOps provides a built-in import feature under Repos > Import Repository that handles simple migrations with up to 180 days of history.
The built-in import works by selecting TFVC as the source type, specifying the TFVC path (e.g., $/ProjectName/Main), and choosing how much history to import (up to 180 days or just the latest version). It creates a new Git repository with the converted history. For full history beyond 180 days, the git-tfs open-source tool performs a complete conversion — it replays every TFVC changeset as a Git commit, preserving authors, dates, and commit messages. The command is: git tfs clone https://dev.azure.com/org $/Project/Path --branches=all.
At production scale, large TFVC repositories with thousands of changesets and multiple branches can take hours to convert with git-tfs. Teams should plan the migration during a quiet period, freeze TFVC commits during conversion, verify the Git history matches TFVC changeset counts, and update all CI/CD pipelines to point to the new Git repository. Branch mappings need careful planning — TFVC branches are directories, while Git branches are lightweight pointers.
The non-obvious gotcha is that TFVC and Git handle large binary files very differently. TFVC stores binaries efficiently server-side, but Git clones include all binary history in every clone, bloating repository size. Teams should set up Git LFS (Large File Storage) before migration and configure .gitattributes to track binary file types. Also, TFVC workspace mappings (cloaking, mapping specific paths) have no Git equivalent — the entire repository is cloned.