What’s a technical skill that will increase your effectiveness, but isn’t programming? How about: being efficient your source control system’s command-line interface? Even though I’ve used Git for a while, there are some things I’ve picked only recently that have made me more efficient.
Achieving Flow State
Did you ever have a time when you were using a hammer, slowly driving in one nail at a time? Then along comes someone with a nail gun and BAM BAM BAM, they’re done! …That’s what comes with using a more powerful tool. We use source control systems every day, yet many of us slowly click on things in a graphical UI, or slowly type out commands in their entirety.

Improve your test writing “Flow.”
Sign up to get my test-oriented code snippets.
The more you equip yourself with good tools and learn to use them well, the better you’ll be able to stay “in the flow” of development. For example, time spent learning keyboard shortcuts for Xcode quickly pays off. In the same way, the better you can use Git (or whatever you use for source control), the more it gets out of your way, letting you concentrate on the actual coding.
So I want to show you 6 simple things you can use to improve your Git workflow—a set of Git power tools. These tools generally involve one-time setup (except for one that is a fun, game-like tutorial). Put these tools to use, and you’ll find you can get more done, more quickly.
The more you equip yourself with good tools, the better you'll be able to stay "in the flow"
1. Git Auto-Completion
Why type more in the command-line than you have to? By installing the Git completion script, you’ll be able auto-complete Git commands. Not just commands, but also the options. And not just commands and options, but also the names of your branches and tags!
The script is available for various shells: Bash, tcsh, and zsh. Get the latest version here. If you already installed the script some time ago, check to see if you have the latest version.
You can copy the script to your home directory, but I don’t want it sitting there cluttering things up. So I rename the file, adding a dot prefix to hide it. Then I add it to my shell startup. Since I use Bash, I edit .bash_profile
and add
source ~/.git-completion.bash
Install it yourself, then open a new Terminal window. Now try using the Tab key to auto-complete a command, or hit Tab twice to show a list of options. For example, from a Git repository, type “git che” Tab Tab, and you’ll see a list of the Git commands starting with “che”. Add a “c” to make it “git chec”, then Tab. It will auto-complete it to “git checkout”. Now hit Tab Tab, and you’ll see your list of branches.
Less typing means you can move faster.
2. Git Prompt
Branching is one of Git’s key strengths. But it also makes it easy to lose track of which branch you’re in at the moment. You can type “git branch” to check, but wouldn’t it be great if you could just see where you are? Well, you can!
Install the Git prompt script somewhere in your home directory. Again, I like to rename mine with a dot prefix so that it doesn’t clutter things up. Then include it in your .bash_profile
start-up script like this:
source ~/.git-prompt.sh
This defines a function to show the name of your current branch. I like to use that function to define my command-line prompt, like this:
export PS1='$(__git_ps1 "[%s] ")\$ '
Whenever I’m in a Git repo, the prompt now shows the current branch:
[master] $
And if I’m not in a get repo, it shows a simple no-frills prompt:
$
Most templates for command-line prompts have a lot more information. You may prefer that. But I like mine short and simple, to show me just what I need without taking up too much space.
There are popular templates for the Git prompt that show colorized information. I recommend against using these. Terminal text colors are helpful for output text, but not when mixed with input text. The control characters for switching colors still count as characters, so the display gets quite confused if your command goes across two lines—which happens often if the prompt is long. It also happens when you try to edit a command. So avoid colors in your prompt.
3. Learn Git Branching
In Git, commits aren’t necessarily linear. Instead, they form a directed acyclic graph, or DAG. And Git provides powerful commands to let you rearrange that graph in any number of ways—including massaging it back into a linear sequence. But how do you learn all these complicated commands?
The best way is through an online game. Learn Git Branching is a remarkable visual tutorial. It'll teach you a command with animated illustrations, then ask you to transform a graph from one shape to another. It’s really well made, and even quite fun.
4. Visualize Git Branches
Now you’re a Git command-line pro. But there’s one problem: the command line is great for a lot of things—but not for showing you the topology of your commit graph. To see a graph, it’s still good to have a graphical interface.
You can use any Git GUI you prefer. But I like GitX. It’s simple and free, and focuses on the graph. I find it handy for visualizing commits and branches.
5. Alias to Git Repository
One last, ultra-simple trick: When you create a new Git repository that you’ll be using often, make a command that will take you there in just a few keystrokes. I do this with Bash aliases. For example, here’s the example that motivated me to write this entire post:
alias mb="cd ~/Development/MarvelBrowser"
Now I can type “mb”, and I’m in the Marvel Browser project I’m creating for the TDD Case Study. I have aliases set up for the other repositories I work in the most, such as OCHamcrest (“och”) and OCMockito (“ocm”).
For being so simple, this tool is surprisingly effective at helping me stay “in the flow.”
6. Generate Your .gitignore
Here’s another Git power tool I came across while starting the Marvel Browser project. When you create a new Xcode project, you don’t want to check in everything to source control. User-specific files within the project should be excluded. macOS keeps Finder information in hidden files named .DS_Store. And I plan to use AppCode, which caches project information in a .idea directory.
Now you can certainly discover which files to exclude from Git, and build up your .gitignore item by item. But why spend the time, when someone else has already figured out what to exclude? Go to gitignore.io. There, I specified Xcode, macOS, and AppCode, then hit the Generate button. Out popped a fully-formed .gitignore file! This made it super-easy to create my first commit. I’m confident that my new repository doesn’t accidentally contain files that shouldn’t be there, and I didn’t have to spend any time on it.
Simple Tools Work Together
These tools are lightweight, mostly involving one-time setup. But they also complement each other! From the Terminal, I type “mb” to jump over to the Marvel Browser project. The prompt switches to show the name of the current branch, keeping me grounded as I quickly switch branches using auto-completion.
If you’ve shied away from using Git from the command line, I hope this inspires you to give it a try. If you’ve been using the command line but have been typing too much, these tools will let you fly. Most developers can type faster than they can manipulate a GUI. And by moving faster with less effort, you will be less distracted by source control management. Your brain will be able to stay more focused on actually writing code.
What are some other Git tools that improve your workflow? Share your recommendations in the comments below.
The Git Prompt is awesome – I run
git status
all the time, and this will save me from running it so often. Thanks a ton, Jon!I would also recommend to setup some common aliases so you can type `git st` instead of `git status`, `git co` instead of `git checkout`, `git ci` instead of `git commit`:
git config --global alias.st status
git config --global alias.ci commit
git config --global alias.co checkout
I really recommend changing bash to some more modern shell. Zsh or fish provide some excellent and helpful tools for command line – git prompt is there, autocompletion is there and many, many more (all easily installable/configurable from …. git repos of those tools). With Zsh, oh-my-zsh is great, fish has a lot of extensions out-of-the-box.
+1 on using zsh. I use oh-my-zsh as well :)
Recommendations from two people I respect… I gave it a try, and it’s great! zsh doesn’t have the same problem bash does with colorizing the prompt, so the default oh-my-zsh theme is really nice.
Colorized git output helps you quickly understand the output from git. Also, using git bisect is a very powerful tool for tracking down the source of bugs. You can automate ‘git bisect’ using ‘git bisect run’ and combine it with, say, unit tests to track down the source of a unit test failure.
At Lyst we use git hooks.
Those are: stuff that happens before/after git commands.
EG: pre-commit (we use this one to check and delete the .orig files that git generates on merges).
Check on .git/hooks the available hooks: commit-msg, post-update, pre-commit, pre-push, pre-rebase … etc.
Create a script file and name it like the existing .sample that you’ll find on that folder (make sure that git can execute the script). Make sure that it does not have extension.
Git will do it automatically every time before you (commit, rebase… etc) or after :).
This example .orig file removal script was written by Michael May:
echo "Looking for .orig files to remove"
pwd=$(pwd)
find . -type f -name \*.orig -exec rm {} \;
echo "Done removing .orig files"
In addition to the mentioned tips I recommend tig [http://jonas.nitro.dk/tig/]. It’s an ncurses text based interface for git. If you love the command line and vim you’ll love it.
It’s much faster and visual than autocompletion + aliases for any daily task: commit, diff, log, blame, cherry pick…and especially for staging/unstaging hunks of code.
That said, I have a bunch of git and shell aliases. This is the last one I added to change directory to the git root:
alias gr='cd $(git rev-parse --show-toplevel)'
I use Magit. It has the highest learning curve (need to know your way around Emacs), but is also the most powerful git tool. Most if not all of the available git command line options in a simple menu of single key strokes.