Git is a Distributed Version Control System that was developed initially as part of the Linux development initiative, and later on as an independent open source project. Microsoft Team Foundation Server embraced Git from its version TFS 2012.2. While creating a team project either on 'on-premise' TFS or Visual Studio Online Now, Git is one of the options available along with traditional Team Foundation Version Control (TFVC).
This article is published from the DotNetCurry .NET Magazine – A Free High Quality Digital Magazine for .NET professionals published once every two months. Subscribe to this eMagazine for Free and get access to hundreds of free .NET tutorials from experts

TFVC is a centralized version control system. It stores all the versions of software at a central repository; the database of TFS. Whenever a request comes in, either the latest version or a specific version of files is given to the user by transferring over the network from TFS. All the other versions remain on the central repository only. Behavior of Git is a little different from that of TFVC. Whenever the user wants to work on a software and has permission to do so, Git forces the user to clone the server repository on the user’s machine. In this way, the user gets all the versions of all the files of that software in a local repository. The User now can work on all the versions of that software locally, which of course is much faster than working with versions that are located on a central server somewhere in the network or the internet. So far, this model is excellent as far as an individual developer is concerned, but modern nontrivial software development is a team work. How will the developer share his / her work with team members in this model? This is where TFS or Visual Studio Online (VSO) comes in. When a team project is created with the option of Git selected, a server side empty Git repository is created. Developers are suggested to clone that empty repository using Visual Studio or a command line tool (Third party tools are available for free download). The image shows the page that is shown to the user when he / she clicks the CODE menu on the TFS Web Interface.

Whenever the developer needs to share work with others, he / she pushes that part of the software (files) on the central Git repository that is kept on the TFS or VSO. For this to work, all those team members have to be member of the contributors group of that Team Project.

If a new user joins the team, he / she will start by cloning the remote repository that exists on VSO for that project. Files shared by all earlier developers with all the versions of those files will be then available to that developer in the local repository.

Before we dive deep into the concepts of Git as implemented on TFS / VSO, a few words about VSO itself. VSO is an implementation of TFS on the cloud maintained by Microsoft. The benefits of VSO that I can think comparing it to on premise TFS, are numerous:
1. You need not implement and maintain TFS itself. It is maintained by Microsoft. This reduces your infrastructure cost as well as efforts to back-up database for failovers.
2. Latest features of TFS are always available on VSO much earlier than same features being made available on on premise TFS.
3. VSO is location transparent. Since VSO is in the cloud, it does not matter from where the team members are accessing the services of VSO.
For a free trial of VSO, Microsoft offers a free account that can have a team of upto 5 users who do not have MSDN subscription. Any team members having MSDN Subscription are considered in addition to these 5 accounts.
When a repository is cloned it creates a folder on the user's machine that contains the files and a hidden folder named .git.

This .git folder contains all the settings, logs, hooks and the source objects on which you are locally working.

.git has a subfolder named "refs" that contains the named references to the branches in a subfolder "heads" and references to the remote branches that you have "fetched" in the subfolder "remotes".
We came across an operation of git in the earlier statement named “fetch”. "fetch" is an operation that brings the latest updates from remote branches that you are tracking. These remote branches are shared by other developers on VSO. Fetching a branch from remote repository does not mean you can still work on it and edit code in it. If you too want to participate in contributing in the same branch, then you need to create a local branch that clones the remote branch. Once that cloned local branch is created, you can work on that branch, create new code in it or edit existing code. After doing these edits, you can “commit” them. “Commit” operation is very similar to Check-in of TFVC but committed code does not go to the server as the checked in code does in TFVC. It remains in the local repository only, i.e. in the branch that you are working right now. That branch’s last commit is called "HEAD", note the difference in the case. "head" is a named reference of any branch whereas "HEAD" is the variable that stores the latest commit of the branch that is active.
Before you commit the edited code, as a best practice you should fetch and merge the remote commits in your code. Merge is an operation that merges the code from one branch into the other.

We came across an operation of git in the earlier statement named “fetch”. "fetch" is an operation that brings the latest updates from remote branches that you are tracking. These remote branches are shared by other developers on VSO. Fetching a branch from remote repository does not mean you can still work on it and edit code in it. If you too want to participate in contributing in the same branch, then you need to create a local branch that clones the remote branch. Once that cloned local branch is created, you can work on that branch, create new code in it or edit existing code. After doing these edits, you can “commit” them. “Commit” operation is very similar to Check-in of TFVC but committed code does not go to the server as the checked in code does in TFVC. It remains in the local repository only, i.e. in the branch that you are working right now. That branch’s last commit is called "HEAD", note the difference in the case. "head" is a named reference of any branch whereas "HEAD" is the variable that stores the latest commit of the branch that is active.
Before you commit the edited code, as a best practice you should fetch and merge the remote commits in your code. Merge is an operation that merges the code from one branch into the other.

VSO provides another option that combines the "fetch" and "merge" operations and that is called "pull". Pull operation does an automatic merge immediately after fetch operation on a remote branch. Many experts still prefer the two separate operations to be done manually since it provides a degree of control on what is merged and how the conflicts are resolved. It is the same as TFVC which can do automated conflict resolution but does also provide a manual option to do so. I do also recommend doing manual merge unless you are in too much hurry and there are too many changes to merge (and you have a nature that accepts inherent risks of automated conflict resolution!).
You may commit code many number of times. Each time it will move the tip of the branch to the latest commit so that it will become the HEAD for the time being. After you have committed the code that you are editing and are sure that you may now share the code with others, you can "push" the code to the VSO server repository that is shared by the entire team.

The Sync button that you see in the image is an operation specific to VSO (& TFS) that is a combination of "pull" which of course includes "fetch" with "merge" and "push" operations. It synchronizes the local branch with the corresponding remote branch.
After "push" operation, VSO will reflect that on the CODE option of the team project and will also show the details of that operation - like when was the last change (commit) made, what was the comment given by developer while committing that and the name of the developer who committed.
When the Git repository is created by VSO for a team project and the team starts working on it, there is only one branch that is created by VSO. By default it is named as Master. Whenever you want to work on some code that needs special attention, at that time you can create another branch from Master. If and when other branches exist, you may also branch out from them. For example, a team member wants to try out some code before it can become part of the release. She creates a branch called SimpleCode for this purpose.

The check-box for "Checkout branch" that you see in the image is not the Checkout operation that is commonly known to the developers who are using TFVC. In git "Checkout" operation is to make that branch as the active branch, so that HEAD becomes the tip of that branch.
After the branch is created, VSO keeps it as a sort of private branch, unpublished to the other team members. To share that branch with the team members, you need to publish that branch which you can do by using the context menu (right click) of the unpublished branch.

Now that branch is shown on VSO under the Branches item under CODE section of the team project. It also shows the commits done in that branch.

Over the time many branches will get created in the repository. VSO does not yet have a hierarchical visualizer for git branches that we are accustomed to in TFVC. It makes up for that by providing the relative status of branches in comparison to a specific branch. For example in the image shown here, branch ComplexCode is selected by a user. Commits that are done in other branches as well as the ones that those do not have, are shown.

The branch SimpleCode is "Behind" ComplexCode branch by 2 commits which means there are 2 commits in ComplexCode that are not merged in SimpleCode and at the same time it is "Ahead" of ComplexCode branch by 1 commit. It has one commit that is not merged with ComplexCode branch. Status of each branch is shown in this way. If you change the selected branch, then the status also changes to show relative commits.
You may also compare two branches to check the differences in those branches. It not only shows which files are different, but VSO also shows the code that is different in two branches.

These features that are under the Branches tab of CODE section of VSO are not available when you use TFVC. I found these features to be excellent and worth making available in TFVC also.
TFS allows some settings to be done on Git by individual developers. They can provide their name, email and default location of repository.

Ignore File (.gitignore) is a generic Git setting that allows the specified file types to be ignored in commits by Git. When this file is created using Visual Studio, it adds by default the extensions for Solution Files, Built Assemblies, Test Results etc. Similarly another file (.gitattributes) can be added that stores the attributes required by Git commands.
There are certain unique features in TFS Version Control unique (with TFVC) that are found to be missing in Git with VSO / TFS. First and foremost is a glaring absence of Check-in policies. Although hooks can be developed for client side checks, it does not replace the server side hook that can be a shared rule to be observed when developers push their code. I did not find any documentation to develop these hooks. Another noticeable absence is that of Gated Check-in. Such unique features provide better value to TFS / VSO in comparison to other tools and I hope that Microsoft provides these as features in the near future.
Summary:
For a developer who has always used centralized version control system, the concepts of distributed version control system like Git are very different. Git is becoming popular due to the speed that it provides to developers to do version control operations. TFS and VSO have embraced Git as one of the default options for version control while creating a new team project. In this article, I have tried to put the concepts of Git as implemented by TFS / VSO in perspective for a developer who is accustomed to TFVC.
This article has been editorially reviewed by Suprotim Agarwal.
C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.
We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).
Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.
Click here to Explore the Table of Contents or Download Sample Chapters!
Was this article worth reading? Share it with fellow developers too. Thanks!
Subodh is a Trainer and consultant on Azure DevOps and Scrum. He has an experience of over 33 years in team management, training, consulting, sales, production, software development and deployment. He is an engineer from Pune University and has done his post-graduation from IIT, Madras. He is a Microsoft Most Valuable Professional (MVP) - Developer Technologies (Azure DevOps), Microsoft Certified Trainer (MCT), Microsoft Certified Azure DevOps Engineer Expert, Professional Scrum Developer and Professional Scrum Master (II). He has conducted more than 300 corporate trainings on Microsoft technologies in India, USA, Malaysia, Australia, New Zealand, Singapore, UAE, Philippines and Sri Lanka. He has also completed over 50 consulting assignments - some of which included entire Azure DevOps implementation for the organizations.
He has authored more than 85 tutorials on Azure DevOps, Scrum, TFS and VS ALM which are published on
www.dotnetcurry.com.Subodh is a regular speaker at Microsoft events including Partner Leadership Conclave.You can connect with him on
LinkedIn .