[D365] Migrate from TFVC to GIT
Today I finally had time to move one of our projects in VSTS from TFVC to GIT source control!
Git has a lot of benefits like working offline (commit, revert, reset etc.), branching (even from WorkItems directly!) and others that I don't want to discuss here.
I want to share a quick step by step guide how to move from TFVC to GIT and what to take care of during the process.
You can move from TFVC to GIT in under 5 minutes!
This was the statement I got from Abel Wang (@AbelSquidHead) and Donovan Brown (@DonovanBrown) at the OOP 2018 in munich so I took the challenge.
What will be different?
Either the Projects folder will not be tracked by version control anymore or it needs to be relocated within the repo. We came to this conclusion as a GIT repository needs to be mapped completely to a local directory and we did not find a way to map parts of it like we used to with TFVC. For a solution, see the last point.
- Working offline
Developers will no longer need to be online to use the benefits of version control. They can commit, revert to it and reset their codebase totally local from now on!
Branches can now be created from work items directly with a right click action!
There is more comfort in reviewing changes with git support than TFVC had.
- Pull Requests
Another problem with changes being directly merged into a branch after a review will be solved due to gits ability to open pull requests which can be set up to need another confirmation and has an awesome cherry picking feature!
Lets get started
Create a git repository in VSTS
Navigate to the
Code Section in VSTS and create a new repository:
Choose a name and proceed without initializing README and gitigonore files:
Clone the new repo temporary
Since git can't clone a repository to an existing non-empty location, we use a little trick to get it working.
At first, we will clone the repo to any new path and then move the
.git directory to our existing
Using the Git Bash
cd c:/Users/USERNAME/Source/Repos git clone https://***.visualstudio.com/***/_git/***
Using Visual Studio
Connect to the new git repo:
Then click on the link in the message to clone it:
Choose any new destination path you like:
Close Visual Studio.
Moving the .git directory
.git directory to the destination path (PackagesLocalDirectory):
PS C:\> Move-Item -Path C:\Users\USERNAME\Source\Repos\REPO\.git -Destination C:\AOSService\PackagesLocalDirectory -Force
Delete the temoprary directory as we no longer need it:
PS C:\> Remove-Item -Recurse -Force C:\Users\USERNAME\Source\Repos\REPO
Add the current code initially
Use a Git Bash for the following commands and run it with elevated privileges.
Git now thinks all files are deleted and we need to reset the state to the one of the repository now:
$ git reset --hard
Now we add the folders of our models to git:
$ git add MyModel $ git add MyOtherModel
Synchronize Visual Studio
Open Visual Studio and add the local repo now:
Visual Studio needs a short sync and recognizes the changes then:
Exclude standard models
To exlcude the standard models (/their folders) we need to create a file called
You can find the syntax reference here.
We exclude everything by default and whitelist only our models:
# Ignore everything * # But descend into directories !*/ !/MyModel !/MyOtherModel # You can be specific with these rules #!/some/other/deep/path/** !.gitignore
Set access rights to the .git folder
Get-Acl -Path C:\AOSService\PackagesLocalDirectory | Set-Acl -Path C:\AOSService\PackageLocalDirectory\.git
If you don't set them, you will likely see the following error in the eventlog preventing the AOSService to start:
To keep VSProjects in version control, we need to relocate them to a path within the git repository.
C:\Users\USERNAME\Documents\Visual Studio 2015\Projects
Change the settings in Visual Studio under Tools>Options:
And add the following line to your .gitignore file to whitelist the folder:
Don't forget to check and tweak your build definitions to point to the git repo!
It took me exactly 4 minutes and 38 seconds to migrate from TFVC to git!
I need to mention that the codebase in this example was not very large.