I’ve been working on migrating teams, both externally and internally to Git, and wanted to write about the insight we gained from these experiences.  In particular, I wanted to frame it in terms of the questions that we most frequently receive from clients, and the responses I give.

Why Should I Switch to Git?

For a lot of people, Git is still relatively new, and I’m asked why Git – are people really using it? I believe this graphic says it all, showing how much Git adoption has increased over the past several years.  Source Control Popularity, as broken down by year.

Because this is from the Eclipse Community Survey, it isn’t the ‘bleeding edge’ of software development – it represents the typical corporate software development team.

How should we go about learning Git?
One thing you’ll find when you search for a Git tutorial is that there are quite a number out there (Atlassian has their own, GitHub has their own, Git-Scm has it’s own).  We’ve found that just doing one tutorial is rarely sufficient for an organization to fully embrace using Git.

When learning Git, here are a few recommendations that we’ve found useful:

  • Know the fundamentals of Distributed Version Control Systems (DVCS).  If you are coming from SVN, CVS or another centralized Version Control System, make sure you learn the usage concepts, and how it differs from the old centralized model.
  • Learn using a hands on tutorial, rather than just a webpage.  The trygit tutorial at Github is interactive, and simulates other users/committers – a key learning.  Much better than learning from static text!
  • When implementing, have a Centralized Repository Management tool.  This really enables beginners to self-check on their checkins, merges, as well as providing a friendly interface for frequently operations such as tagging + merging.   Examples of these tools are Atlassian Bitbucket / Stash, GitHub and GitLab.
  • Learn the command line.  Because the GUIs are really just a wrapper around the command line, it really is important to understand the command line interface – in particular for those times where you need to understand ‘why did Git do that?’  And keep a list of these commonly used commands on your wiki / Sharepoint – that will rapidly become one of your most visited sites internally :).
  • Provide coaching while starting out.  Providing support in those initial rampup days with Git minimizes frustration, cements new learnings, and is a faster road to productivity.

‘Stuff Git Says’

Like the William Shatner sitcom ($hi! My Dad Says), the things Git says can sometimes be baffling – and also like the show, it just isn’t very funny :).  (I kid, I kid.)  Here’s just a selection of some items that people have mentioned are particularly confusing, and what they mean in plain English.

  • ‘HEAD’ vs. head – both of these allude to a concept within any Distributed Version Control System (DVCS) – the tip of any branch.  However, ‘HEAD’ in Git has a specific meaning – it is a file that points at what your local working copy is referring to in the entire repository.  This is one of the many files that’s stored in the ‘.git’ directory for each repository.  See the examples below:

# NB: execute this commands from the root of your git repo
$  cat .git/HEAD
ref: refs/heads/master

This shows that the current workspace is pointing to the tip of your local ‘master’ branch – and any changes will be made children to the current tip of master.

  • ‘detached HEAD’ state – you will receive this message when Git doesn’t know where your next changeset should be placed.

You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example:
git checkout -b new_branch_name
HEAD is now at 3da9bc7... Mod line #1 via removal.

  • Why are you in this state?
    • You most commonly get in this state via checking out a tag or a specific changeset that already has a child.  Refer to the example illustrated below.
You have changeset C1 checked out, but C2 already has a child changeset on the same branch.  Changeset C1 should not have two children on the same branch.
  • What does this message mean?
    • You can make commits, and they will be persisted locally.
    • However, they won’t be persisted to the repository (a.k.a. shareable with other clones of the repo) until you create and place these changes against a new branch.  Refer to the diagram below:
You’ve just added changeset C3 in a new branch.  C1 now has two children, but as they are on separate branches, Git is happy :).
  • Bare vs. non-bare repositories
    • Non-bare – a non-bare repository is the standard repository that we all normally utilize, meant to be worked on, and directly changed – i.e. make a change, commit locally, create a new branch, etc.
    • Bare – a repository that does not contain the source files – it only contains the binary (non-human readable) .git representation of the source files. Bare repositories are meant to be used for centralized shared repositories, backup repositories – repositories to be shared, and only changed via pushing to.

For more on migrating to Git, see our i-Proving blog post, “Migrating Repositories from Subversion to Git.”