Git is one of the most popular source code management systems available to developers. It was created by Linus Torvalds more than a decade ago. It is easy to get up and running with Git, but it takes time and a bit of learning to become familiar with its more subtle and more advanced features.

In this tutorial, I show you three tricks I find myself using on an almost daily basis. They are easy to pick up and they may save you a lot of time and frustration.

Stashing

A very useful, yet simple, Git command is stash. This command stashes the changes in the working directory and the staging area for later use, leaving you with a clean working directory and staging area. The stashed changes are pushed onto a stack. This means that you can create as many stashes as you want.

When should you use the stash command? Imagine the following scenario. You are in the middle of implementing a complex feature and your working directory is littered with changes in dozens of files and folders. Your boss walks in and asks you to create a build of the release branch you created the day before.

What do you do with the changes in your working directory? Do you make a dirty commit just to make sure you don't lose your work? You could create a new branch and commit your changes on that branch. There is a more elegant solution, though.

Enter git stash. To stash the changes in the working directory and the staging area, you execute the following command.

git stash

This is what the result looks like.

Saved working directory and index state WIP on feature/search: 5aa493e Update assets
HEAD is now at 5aa493e Update assets

The changes in the working directory and the staging area are safely stored for later use. You switch to the release branch, create a build, return to the branch you were working on, and apply the stash you created earlier. It is that simple. To apply a stash, you pop it from the stack of stashes.

git stash pop

If you frequently use stashes, it is recommended to name your stashes. This makes it easy to find stashes and apply or remove a stash by name.

git stash save "search feature"
Saved working directory and index state On feature/search: search feature
HEAD is now at 5aa493e Update assets

Patching

In a way, patching is similar to stashing. Both commands group a number of changes that you can apply later. A patch combines several commits or the changes in the working directory. The changes are stored in a file with a .diff extension.

Patches are useful for several reasons. It is easy to store patches to disk or share them with other developers. You can apply patches to branches no matter what the branching model looks like. They are also a good alternative to cherry picking.

I interact with Git using a combination of the command line interface and Fournova's Tower. Creating a patch is very easy in Tower. Select the commits you want to include in the patch, right-click, and choose Save Patch for X Revisions... from the contextual menu.

Creating a patch in Tower is easy.

Patches can be used in a wide range of scenarios. Imagine you are working with a teammate on a big, complex feature. You are both working on the same branch and firing on all cylinders, committing as if your life depended on it. You are about to push your changes to GitHub when you notice that your teammate already pushed her changes. It is time to pull and perform a nasty merge. I don't know about you, but I don't like these kinds of merges.

The solution is surprisingly simple. You create a patch, include the commits you are ahead of the remote branch, and reset your branch to HEAD of the remote branch. You then pull the changes of your teammate and apply the patch you created earlier. If you are both working on the same branch and modifying the same files, then it is still possible that you need to perform a manual merge.

Keep in mind that a reset is a potentially dangerous operation that can lead to data loss. Always bear this in mind when using the reset command.

Git Flow

A project with any degree of complexity needs a robust branching model. The branching model I have come to appreciate is the one outlined by Vincent Driessen. Vincent's model may look daunting at first, but it is easy to adopt in most software projects.

The idea is simple. A project adopting Vincent's branching model has a master and a develop branch. If you decide to work on a feature, you create a feature branch that branches off of develop. When a feature is ready to be released, the feature branch is merged back into develop.

When the time comes to schedule a release, a release branch is created that branches off of develop. The goal of the release branch is to prepare the release and fix critical bugs. A release branch is never used to implement features. After a successful release, the release branch is:

  • merged into master
  • merged into develop
  • merged into every downstream release branch

Merging into develop and every downstream release branch is important to guarantee that any work done on the release branch, such as bug fixes, are also included in feature and downstream release branches.

If you need to push a hotfix to the public, you create a hotfix branch that branches off of master. After releasing a hotfix, the same merge strategy is applied as for release branches.

This branching model has worked really well for me and the projects I have worked on. Make sure to prefix branch names with feature/, release/, and hotfix/ to avoid confusion.

What's Next?

Git is essential for my daily work. I really enjoy using it and appreciate its speed and flexibility. Getting up to speed with Git is easy once you understand the basic concepts. Questions? Leave them in the comments below or reach out to me on Twitter.