Monday 17 February 2014

Git For TFVC Users

One of the biggest features of Team Foundation Server 2013 is it’s support for Git. Git is popular source code repository specially in the open source community. However, unlike Team Foundation Version Control (TFVC), Git is a distributed version control system. This means that for regular users of TFVC, there are some conceptual differences to consider when working with Git. In this post, I will explain some of these differences and also illustrate the equivalent operations in Git for most common TFVC operations.


Centralized Vs Distributed Version Control Systems

TFVC is a centralized version control system while Git is a distributed. That is to say that at any point of time, the server in TFVC contains the “true” version of any file. Anyone making a change is expected to fetch this version, make the change and then check-in against this version. For this to happen, the client must be connected to the server. 

Git, meanwhile, is a Distributed Version Control system where each client machines keeps a local copy of the repository. Any user working with the client can keep working on local version of the file without talking to the server. It is only when the client tries to “push” the changes that a contact to the server is made. Since multiple people can work on the same file in their local repositories, there might be some conflicts. Git addresses this requiring the users to resolve all conflicts with the remote repository before they “push” their changes.


Here, I am “disregarding” local workspaces, which is a feature that was introduced in TFS 2012. Local workspaces has some similarities with Git in that it propones “Change –> Merge –> Push” way of working rather than “Checkout –> Change –> CheckIn”. However, the fact remains that TFVC is a centralised  system.


Changesets Vs Commits

All changes in TFS are checked in as changesets. A changeset is a single unit of change that can be checked in and constitutes the list files which are changed. A changeset can be reverted back and merged to different branches.

The equivalent in Git are commits. They are essentially the same as changesets except that they exist on local repositories. Once pushed to remote repository, they are essentially same as changesets in TFVC.


Until commits are pushed, they reside only on the local repositories and are not visible to other users who clones or fetches the remote repository. You can event amend your commits.


Branching

Branching in TFVC is a very different concept that branching in Git. In TFVC, branching is essentially a “deep copy” of the original branch. . The branching operation is time consuming and is always executed on the server. Once a new branch is created, users can work on it completely independently without needing to even get a local copy its parent. Each branch has its own version history.

In Git, a branch is light weight. In actual, it is merely creating a new head pointer to the version pointed by the parent branch. Once the new branch is created, the new head pointer is moved as new changes are committed. In essence, all branches exists within the same file path. The only difference between an active branch and inactive branches is the head pointer selected at the moment.


Merging

It can be safely stated that merging is one of the strongest feature in Git. TFVC perform merging using the 3-way merge algorithm, in which it attempts to merge the changes from baseline to the newer version and also the changes from the baseline with the version of the file in the current workspace. If it can’t resolve any conflicts it asks the users to resolve conflicts.
Git supports 3-way merge as well as a host of other merging algorithms such as recursive, octopus, etc. While it uses the optimum algorithm for the situation, user has the option to select the merge algorithm through the command line parameter as well.


Security


TFVC is fully integrated with Active Directory and uses it for security. Online version of TFS can use an authentication service such as windows live service to authenticate users. Moreover, there are options of set permissions for individual files, folders and branches.
Git does not have such an extensive security mechanism. Users can be restricted permission such as make them read-only on a repository but there is no support for setting permission for files and branches.


Common Operations

Since the working practices are quite different between Git and TFS version control, there isn’t a simple one to one mapping for quite a few operations but I will make an attempt with the following table.



Get Latest Version

· Fetches the latest version of files from the TFS server to the client.
· Operation can be performed for an entire team project and any folder beneath it.
· There must be a local workspace present with mapping from server folder paths to local directory paths.


There can be three commands corresponding to the Get Latest Version in TFVC.

clone

· Creates a copy of the remote repository locally.
· To be used when you need to get the contents of the remote repository for the first time.
· Note the difference in terminology. It is a copy and not a fetch. In fact, if disk on the server gets corrupted, this can be copied to the server.
· Repository has to be cloned in entirety. Cannot clone parts of the repository.

Fetch
· Used to get the contents of the remote repository.
· To be used when there is already a local repository.
· Doesn’t attempt to merge the changes from the remote repository to the local repository.

Pull
· Similar to “Fetch” except that it also attempts to merge the changes from remote repository on to the local repository.



Add To Source Control
· Allow one or more files or folders to TFS server. The files are only marked for addition and will not be added until the changes are checked-in.
init and add
· Initialize a new repository using the existing directory.
· Once the directory is initialized, the files must be added using the add command.
· Changes are not made permanent in the repository until there is a commit and are not sent to the server until there is a push.




Check Out
· Enable user to change files locally.
· TFS doesn’t fetch the latest version of the file but users should work with the latest version or they will get merge conflicts when they attempt to check-in.
· The changes stay local on end user’s machine until the changes are checked-in.


branch and checkout
· The checkout command in Git switches to the given branch in the local repository.
· Occasionally, the user will require to create a branch before the checkout.
· The branch command in in Git creates a new head to track the version. Creating a branch means that user can keep on working a completely separate version with the option to revert back to the version from which the branch was taken. (More on this later).


Check-In
· Enable users to publish the changes made locally to the server.
· The check-in command checks the version of the file that was taken as a baseline before changes were made locally. If there is a modified version available on the serve, user is required to merge.

commit and push
· The commit command publishes the changes made by the user to local repository. Since, the change is only published to local repository, there is no equivalence in TFVC.
· The push command publishes the changes made locally to the remote repository.
· Like TFVC, if there are subsequent changes made on the remote repository, Git requires to merge the changes.


Shelve Changes
· “Parks” the changes made locally on the server so that they can be fetched either by the same or another user.


· There is no equivalence of shelvesets in Git. The closest is the stash command which publish changes to the local repository. However, unlike shelvesets, these changes are not visible to server.
History
· Displays the history of changes made to a particular branch, folder or file.
· Some of the features such as annotation is supported by TFS Power tools.

log
· Displays the list of commits for the currently active branch.

Blame
· Displays the revisions and the author of each revision for each line of the given file.

Annotate
· Annotates the given file.





Delete / Destroy
· Deletes the given file or folder.
· The destroy command permanent delete files and folders.
· The deletion / destruction is only performed on the server after the deleted files are checked in.


rm and push
· Removes the file from local repository.
· Removal is published to the remote repository after the push operation.
· There isn’t an equivalent of destroy command in Git. However, the reset HEAD command can be used to remove history of older version.