How do we change from an existing TFVC repository to a Git repository, without affecting all the work already done, to all the code tracking, simply, and quickly, and most importantly, without affecting the team?
Disponible en español aquí
Faced with this problem, we find two solutions:
Manually create a Git repository and pass each of these changes and information that we would like to keep.
Use tools created by the community to, in a few steps, copy all the content from one repository to another and also get the advantages that Git bring to our project.
The obvious answer is the second option, and the reason for this document, using the git-tfs tool to achieve it. Let’s start.
To use the git-tfs tool I recommend the use of Chocolatey.
Chocolatey NuGet is a Machine Package Manager, that is, a package manager for our computer, capable of installing tools in a simple and well-managed way using Windows. To install Chocolatey, open a command console as administrator and enter the following command:
C:\> @powershell -NoProfile -ExecutionPolicy Bypass -Command "iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))" && SET PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin
Restart the command console.
Open a command prompt and run:
choco install gittfs
Once installed, you have to make sure that the git-tfs folder is included in the
PATH environment variable. You can include the folder temporarily using:
As usual, there is a help section in the tool itself, just use the following commands:
# All available commands git tfs help # Show a summary of use of one of the commands git tfs help <command>
Listing our projects and branches
Since more than one project can exist on our TFS server, we can use the
list-remote-branches to list all available projects and their branches.
# If we use Visual Studio Team Services (Visual Studio Online) git tfs list-remote-braches http://[ACCOUNT].visualstudio.com/tfs/DefaultCollection # If we use Visual Studio On-Premise git tfs list-remote-braches http://tfs:8080/tfs/DefaultCollection
From this point on, we assume that VSTS is being used so we will always use the address
http://[ACCOUNT].visualstudio.com/tfs/, to use VS On-Premise just change the addresses seen below by
What will give an output by command console like the following:
$/project/trunk [*] | +- $/project/branch1 | +- $/project/branch2 | +- $/project/branch3 | | | +- $/project/branche3-1 | +- $/project/git_central_repo $/other_project/trunk [*] | +- $/other_project/b1 | +- $/other_project/b2 Cloning root branches (marked by [*]) is recommended! PS:if your branch is not listed here, perhaps you should convert the containing folder to a branch in TFS
We may not find the project, or branch in the list, this is because our branch is surely a folder and not a branch itself.
Convert a folder to branch (optional)
In the case of not having the branch we need, it is very easy to convert a folder to a branch.
From Visual Studio, we access Source Control Explorer from our TFVC repository, in which we will see the different folders that make up the project. We just have to select the folder that we want to convert into a branch, right click on the mouse and select:
Branching and Merging > Convert to Branch.
Clone only the root
It is possible that we only need to clone the root for different reasons: that we are not interested in the rest of the branches, that we want to migrate our project to a free Git repository of dead branches… To do this, and continuing with the list of projects and branches mentioned above, we can use the following command to generate a Git repository from the TFS repository:
git tfs clone http://[ACCOUNT].VisualStudio.com/tfs/DefaultCollection $/project/trunk . --branches=none
This method is not appropriate if we have performed merges in our TFS repository. And we should use the following method.
Clone all history
If on the other hand, we want to clone the entire TFS repository and generate a new Git repository with all available branches and changes, we just have to use the following command:
git tfs clone http://[ACCOUNT].VisualStudio.com/tfs/DefaultCollection $/project/trunk . --branches=all
Both options are slow but safe, so take the opportunity to have a coffee.
Once our Git repository has been created, we need to be located in the folder created to continue with the operations.
Cleaning the commits (optional)
We can clean our new Git repository of any impurity created in the conversion and dragged from the TFS repository.
To clean all metadata created by git-tfs in commit messages:
git filter-branch -f --msg-filter "sed 's/^git-tfs-id:.*$//g'" -- --all
Once resolved, we verify that everything is correct in our Git repository and delete the
.git/refs/original folder, which will erase all the old or dead branches.
If we want to have some ids of changes in a more “human” way and not the one that generated TFS in its day, we will use the following command:
git filter-branch -f --msg-filter "sed 's/^git-tfs-id:.*;C\([0-9]*\)$/Changeset:\1/g'" -- --all
Uploading the changes to a remote repository
Add a remote repository to your local repository using the central Git repository of your choice:
git remote add origin https://github.com/user/project.git
Then, upload all the changes of all the branches created in the process:
git push --all origin
With these simple steps we will have converted our TFS repository to a Git repository keeping all the history of changes, all the branches, and all the information of our old repository.
NOTE: The WorkItems / Tasks associated with each checkin / commit can not be converted from TFS to Git, for this, you would have to manually modify each commit and add the information.
NOTE: At this time, Visual Studio Team Services works separately with the Git and TFS repositories, and requires at least one of them once created. That is, if at the time of converting our project from TFS to Git, we work on the same project and both repositories are uploaded to the same project, we would have two repositories in the same project, one from Git and another from TFS, by only existing one of each type, it would be impossible to delete the TFS repository and work only with the Git repository, having to somehow clean up or mark that the TFS repository has become obsolete.