Moving to Git

Moving to Git

Git, the distributed source control system is fast becoming the de facto standard, at least in the open source arena. Although it comes with a bit of a learning curve, the advantages of using Git over more traditional SCMs like Subversion and TFS far outweighs the investment of time unnecessary to learn it.

TL;DR

A quick introduction to Git, with a basic command reference. If you are familiar with Git, you probably won’t learn anything new. If not, please continue reading.

The Pros and cons

Why switch to Git?

  • It’s fast. Repository history is stored locally, so we can diff and traverse history at a whim without having to involve the server.
  • Cheap local branches. Ever wanted to branch per feature? Git is your friend.
  • Merges are almost magical. Git does a much better job of merging than any other SCM I’ve seen.
  • Since commits are done locally, you can commit as often as you like. Because history for your local repository can be rewritten, commits become more of a checkpoint than something permanent.
  • Awesome command line flow. Although Git has plenty of commands available, you only need a couple to get the job done on a daily basis. Git smoothly integrates with several command line and GUI tools, and you can easily jump to the GUI for more complex operations like merging.

The only downside to Git is with binary assets - if you store and change binary assets in your repository, it will quickly grow to a unwieldy size. An alternative way to manage binary files with git is using git-annex. See this Stack Overflow question for details.

Getting started

On Linux operating systems, use your favourite package manager to install the git client. On Windows, the easiest way to get Git is to install GitExtensions, which installs msysgit, kdiff and Putty or openssh. GitExtensions also includes Visual Studio integration which is useful every now and then.

Git on Windows runs in Git bash, which is just bash ported to Windows. For something that feels more native to the Windows platform, PoshGit allows for functional usage of Git inside a PowerShell shell. TortoiseGit (based on the popular TortoiseSvn) integrates Git functions into Windows Explorer, allowing you to drive Git in a more graphical way. For browsing the history of a repository, gitk on Windows (should come installed with Git Extensions), and tig on Debian based systems can provide a graphical way of performing this task.

However, avoiding the command line and relying on the GUI for driving Git makes you miss out on the cross-platform experience, and means that you will need to drop down to an uncomfortable place for some of the more advanced operations, so I highly recommend starting out at the command line and using the GUI pieces for convenience where it makes sense.

Where to get help

Git has an awesome built-in help system, which can be triggered by calling

git –help

You can get help on specific commands by adding the –help parameter after the command :

git add –help

Basic commands

At it’s most basic Git can be used just like more traditional SCMs :

git pull

Pulls down the latest version of the source code from the remote repository, and merges it into the current working set.

git push

Pushes (commits) the locally performed commits to the remote repository. After it’s been pushed, other team members can pull your changes.

git add -A git commit -m “My detailed commit message.”

Git has the concept of a staging area, which is a holding area for the changes that you would like to commit. The add command adds either a specific file to the staging area, or all detected changes with the -A parameter.

The commit command performs a local commit, while the -m parameter specifies a message for the commit. If the -m parameter is not provided, Git will open up a text editor for you to edit the commit message.

Should a pull or a push result in merge conflicts, you can start a manual merge process by running the following command :

git mergetool

To view the history of the repository, you can query the log via

git log

The commands above is all you need to get started with Git - once you get those under your belt, the true power of this distributed source control provider can kick in with some more advanced commands.

More advanced usage

One of the things I like the most about Git is it’s cheap, local branches. With these, there is no reason not to branch for even the simplest change. To create a new branch and switch to it, run the following :

git checkout -b “newbranch”

The -b parameter lets Git know to create a new branch, with name newbranch. Change and commit as normal, and when you are ready to merge back into the master (trunk in traditional terms), you can do the following to merge the changes in :

git checkout master git merge newbranch

The branch can then be discarded if not needed any more:

git branch -d newbranch

Because the repository is local, switching branches is fast and painless - unlike more traditional SCM’s that need to talk to the server to achieve this.

Git does not like having uncommitted changes lying around between operations like branching and merging. Git provides a “stashing” mechanism where it temporarily stores away changes that can be reapplied later :

git stash save “stashname”

Saves the current changes into a stash with the specified name, and check outs the most recent commit on that branch. You can run

git stash apply

To apply these changes to the file set again.

Rebase is worthy of its own post - there is just so much power in being able to rewrite history.

Using Git With Other Source Control Systems

If for some reason, you can’t use Git on the server, you might still be able to use it on the client. Git works well with other other source control systems like TFS, and Subversion through the use of plugins. Git integrates with these SCM’s by “cloning” the remote repository locally, and then pushing local changes back to the remote servers when it is requested.

For TFS support, after installing git-tfs, you’ll have access to the following commands :

git tfs clone http://tfs:8080/tfs/collection $/project_name

Clones the project with the specified name contained in that collection.

git tfs checkintool

Brings up the check in tool with the changes available to commit to TFS.

git tfs shelve name

Creates a shelve set with the changes since the last commit to TFS.

Integrating with Subversion works in a similar way - with the git-svn package you can perform the following operations :

git svn clone [repositoryurl]

Creates a “cloned” local Git repository based of the remote Subversion repository. In the local repository, Subversion commits become Git commits.

git svn rebase

Performs an update, and rebases your change sets on top of it.

git svn dcommit

Takes your Git commits and streams your changes to the Subversion server.

Tips and tricks

When I started out with Git, it took me a while to realize that some of the situations I ran into into with it was caused by me not adhering to the git workflow. Reading up on it is highly recommended before you do any serious work with it.

If you have a complex release strategy, it will be worth your time to familiarize yourself with git-flow, and the successful branching model behind it.

Also learn what git pull actually does, and read up about why git fetch should be preferred.

Making learning fun

Git, being a power tool, is very feature rich. For encouragement on exploring all it’s features, and just to make the learning process fun I strongly recommend these two tools :

  • git-achievements tracks your usage of features, and unlocks “achievements”, much like Stack Overflow badges.
  • githug (Linux and macOS) provides a game like environment where you are asked to perform specific operations in order to get to the next level. Levels are of varying difficulty, so this is a great way of exercising your Git chops.

Further reading

  • Git ready provides excellent explanations of git features, and some more advanced tweaks.
  • The git book is the official, community driven reference for Git.

Photo by Caleb Jones on Unsplash


See also