Git tips and tricks

In a few short years Git became one of the most popular source control management system, especially for newly started and open source projects. If you’re a developer, you’ll eventually cross paths with Git. Here is a list of a few Git tips and tricks, starting from beginner and progressing to more advanced levels.

These tips assume you’re using Git from a terminal. Even if you’re using GUI every day, it’s a good practice to introduce yourself to CLI because it’s ubiquitous and consistent across all major platforms. Many GUI tools have simplified terminology and support only a subset of functionality, so if you encounter a big problem and need to resolve it from a terminal, it’s better to be familiar with it.

1) Supercharge your terminal

I find many people using Git from a terminal, but they don’t use the full power that is available. First of all, enable color output with:

$ git config --global color.ui true

It will add a line to your global .gitconfig file and will result in log, branch, diff and other commands much more understandable.

Most common shells allow expanding expressions or arguments with the Tab key. The same can work for Git commands if you have git completion set up. Just search install git completion for your chosen platform and follow the instructions.

Someone said that developers working in Git can be recognized by not knowing which branch they’re working on. That is true in some cases but can be completely avoided by having a branch name in your prompt. Just search for git branch in bash/zsh prompt; it’s very easy to set up.

If you`re using Git Bash on Windows, everything should already be set up.

2) Visualize your history

One of the greatest benefits of GUI tools is history visualization. Similar output can be achieved in a terminal with:

$ git log --oneline --graph --decorate

It will print out a one line description, tags and branches and draw development tracks in ASCII art. Not as beautiful as GUI, but the “hacker factor” just went through the roof, right? It’s very useful if you don’t want to leave the terminal or if you’re connected to another machine via SSH and are trying to make sense of the remote repository.

The command is very long to type every time, so it’s best to add it to your .gitconfig as an alias.

[alias]
    l = log --oneline --graph --decorate

This way you can quickly invoke visual log with only git l. The output can be customized even further with the --pretty=format:<string> argument. Check out git help log for more information about formatting.

3) Stash – handling your work in progress

One very handy command is git stash. Its help page says: “The command saves your local modifications away and reverts the working directory to match the HEAD commit.” It becomes very useful if you have some unfinished work in progress, but need to store it away for a while and come back to it later. Interrupts like that are very common during development so it’s good to have a tool to help you with that. Just have in mind that all stashes are local to the repository.

git stash will save your changes and clean up your working directory. This command can be invoked multiple times and will push all changes onto a stack. git stash list prints out the list of all changes and git stash pop will apply the latest one and remove it from the stack. If you want to apply some change in the middle of the list and preserve it, use git stash apply <stash-reference>.

4) Empty commits

Empty commits have no real value and Git won’t allow you to create them unless you force it. You can do it with --allow-empty argument to the git commit command. But why would you want to do it? Demos and workshops are great use cases because it allows you to quickly build a set of commits, maybe in different branches, you can work on.

$ git commit --allow-empty

5) Find the common ancestor

Sometimes it’s necessary to find the place where two branches diverged. It can be accomplished in a terminal by visually following the second tip in this article or with a git merge-base command. It also very convenient when used in a script or as a subshell command. If we take the same example from the second image, here is the command and its output.

$ git merge-base master bugs
487cfb555dec2cbe2086e92c40f6dc5a7b3bacee

Often you’ll want to find which changesets are in one branch and not in other. Finding a merge base and then printing out the log from that branch to merge base will give you expected results, but the same thing can be done much simpler:

$ git log --oneline master..bugs
97b9479 Fix issue #2
27be1af Fix issue #1

6) Remote tracking branch shortcut

Working on one branch in a cloned repository is the most simple workflow. You have “master” and “origin/master” available as references. But if you’re tracking many repositories and have multiple tracking branches locally, remembering which branch corresponds to which remote repository and which remote branch can become tricky.

You can use @{u} to reference a remote tracking branch of the one that is currently checked out locally. The two commands below will accomplish the same thing.

(master)$ git rebase origin/master
(master)$ git rebase @{u}