After working for the last three years with TFS’s classic source control TFVC, I recently moved to a new company and with that, to Git.
Before working with Git, I loved working with TFVC. I thought it was great and pretty much the most I can expect from a source control.
Git, however, changed the way I work with source control and even the way I think about source control.
This post is a small taste of what Git does and how my workflow changed accordingly. It is not a Git tutorial, but rather my impressions from it. I do link at the end to some additional resources.
Git is HARD to start with
Git has a pretty steep learning curve. Crazy steep when comparing to TFVC (Original TFS) or Subversion (SVN).
Things are not intuitive in Git when starting. At least they weren’t for me after working for so long with TFVC and SVN. And the reason is that there is a core difference between them.
To work with Git, we have to understand how Git thinks. And at the core, we have to understand DVCS.
DVCS vs CVCS
Git is a Distributed Version Control System – DVCS. Whereas TFVC is Centralized Version Control System – CVCS.
DVCS means each developer has the entire repository, including the entire change history on his/her local machine. So the developer can see changeset history offline or commit (check-in) changes offline to his local repository.
In CVCS, the developer has a copy of the repository file system on his machine. So offline actions like commits (check-ins) and seeing history are impossible since the local repository can’t save “changes”.
So what are the implications of this?
— Donovan Brown (@DonovanBrown) 5 February 2015
In Git, everything is done locally
Since the entire repository is local, we do everything locally. This includes, but not limited to:
- Committing changes (Check-in)
- Viewing commit history
- Creating a new branch
- Merging branches
- Moving to a different branch
- Deleting branches
- Reverting older commits
Of course, at some point, we have to sync our changes to the remote repository (“Push”).
“Check-in” in Git is divided into 2 parts: Commit and Push.
This is actually a big deal. It allows a much better workflow for us developers. I can now commit locally whatever I want – Ugly code, comments, and work in progress. The other developers won’t get those changes. And when my code is nice and clean, I can Push all my commits to the remote repository.
[su_box class=”jetpack_subscription_inline”][jetpack_subscription_form subscribe_text=”Join the mailing list and get updates on new interesting articles” title=”SUBSCRIBE VIA EMAIL” subscribe_button=”GO”] [/su_box]
Another concept in Git is Staging. This is a bit like Included / Excluded changes in TFS. Only staged files will be committed. Which is convenient since I usually have modified configuration files that I don’t want to be committed.
Git is fast, really fast!
Committing (Which is like check-in to the local repository) takes less than a second on my PC. Blame (Annotate) , viewing history or filtering by commits is incredibly fast. This is partly because in Git everything is done locally. But also, because of Git’s unique way to save the repository. Git works with snapshots instead of with changes.
Branches and Merges are really where the power of Git over TFVC shines.
Branches in Git
In TFVC, Branch will create a new directory with a copy of all files and directories of the parent Branch. For a developer to work on that new branch, he will have to copy that directory to his hard disk, essentially having another folder with the source code.
In Git, each branch is not a copy of the files from the parent branch. Instead, it’s simply a pointer to the Commit in the parent Branch from where we created our new branch.
So when we want to work on a different branch, we tell Git “Move to another branch” (Checkout command) and Git will change our working area to match the desired branch. This is very fast since it’s done locally. Git already contains all the branches on the local machine.
Merging is a lightweight operation. We can merge any branch to any branch. We can merge the entire difference or a specific Commit. Git will find the “Base” Commit where the branches split and allow us to resolve conflicts (This is the same as in TFS)
A good practice with Git is to create a new branch to work on a big feature. Eventually, merging that branch to the master branch and discarding the new branch entirely.
Here’s a good tutorial on branches in Git.
Tooling and Git command line
Git is a command line based tool. You can do everything with the command line, and I know there are a lot of Git users that advocate that. However, nowadays there are some excellent tools that provide a nice GUI to work with Git. One such tool is Git Extensions.
Also, there’s integration with Git in Visual Studio, but I find Git Extensions to be more convenient.
Git Extensions actually gives you a Console window where you can use Git command line with several Linux commands like Grep. This is very useful. Especially when seeing answers in StackOverflow, I can just copy-paste them to my console window.
I don’t see why anyone would choose to use Git with the command line when there are such great free tools like Git Extensions.
But then again, be careful taking advice from the internet 🙂
My transition to Git
Once I got over the initial Git shock, my working flow became faster. There are a number of reasons for that. First of all, Git itself is really fast. Second, with Git I do local commits which saves me time. I can commit my work in progress code without worrying it’s buggy and will disrupt another developer’s work. So I don’t have to save my pending changes for a long time until I’m sure whatever I’m doing is good enough.
This is one of those things that I never realized I needed until I started working this way.
The third reason Git made my life better is branches. Creating merges and working on a side branch become a part of my workflow.
I am definitely falling in love with Git.
Full disclosure: I also fell in love with TFVC and TFS when I started working with those.
Git is faster and more powerful than TFVC or SVN. It rapidly becomes the world standard to source control system.
Git is also pretty hard and I’m sure many a developer spent a lot of hours trying to decipher why Git does what it does. TFVC is definitely easier to start with and more intuitive.
I don’t think moving to Git is necessarily the right choice for everyone.
Here’s my very opinionated advice about organizations considering moving to Git:
- When starting a new project with no developers yet, use Git.
- If you have a small team with at least one strong developer experienced with Git, move to Git.
- If you have a big team working with TFVC and not enough people experienced with Git, moving to Git will be costly. But maybe it will pay in the long run.
- In the end, it’s all about the quality of people. Git is more powerful but harder. If you have superstar developers on your team, they will figure it out. Move to Git.