So, apparently this is the name of a hip hop group!

I thought I’d share some of my tips and shortcuts for working with git.

I collaborate on a lot of github repositories with a team of colleagues, and it’s important to make sure I have the latest changes before I start work, so that we don’t end up having to merge conflicting changes. So, I often found myself doing this kind of thing:

cd project-repository
git checkout main
git pull
git branch  # list whatever branches I was working on last time
git branch -d my-old-branch  # delete my local branch from the previous issue

Now I can start to get some work done.

This is tedious and repetitive, so of course I want to automate it.

The first part is easy:

git checkout main
git pull

Except that not every repository I work on has main as the default branch. Some of them still use master. If you git checkout a branch which doesn’t exist, the command will fail, so we can do this:

git checkout main || git checkout master

If we have a main branch, check it out. If we don’t have a main branch, try to checkout master instead.

Now I want to tidy up my local working copy by deleting any old branches I created the last time I worked on this project. This is a little bit trickier. Some local branches might be things I’m still working on, while others are things I finished already. How can my script know which local branches to keep, and which to delete?

We can use a side-effect of git branch -d here. If you try to delete a branch which has not yet been merged to the default branch the command will fail with a message like this:

git branch -d foo
error: The branch 'foo' is not fully merged.
If you are sure you want to delete it, run 'git branch -D foo'.

So, we can just try to delete all local branches, and any branches which shouldn’t be deleted (because they haven’t been merged into main yet), won’t be deleted. The only thing we need to be careful of is not to delete the main branch (or master if that’s the default branch).

So, here’s the full script:

#!/bin/bash

set -euo pipefail

git checkout main || git checkout master

git pull

git branch | grep -v master | grep -v main | xargs git branch -d

The set -euo pipefail is a good habit to put at the start of almost all shell scripts. It makes your script fail if you’re using any variables which are undefined (-u) or if any command fails (-e). The -o pipefail causes your script to die if any of the commands in a pipeline fails.

So, we’ve got our script. Now we need to put it on our path with a suitable name.

I put my ~/bin directory on my path by having a line like this in my ~/.bashrc file:

export PATH="$HOME/bin:$PATH"

So, I can put the script in there.

Git has a really neat trick to make it easy to create sub-commands. If you have an executable in your path with the filename git-whatever then you can invoke it by typing git whatever

So, I put my "start from a fresh working copy" script in the file ~/bin/git-fresh

Now, whenever I’m about to start work on a shared repository:

cd project-repository
git fresh

…and I can get to work.

What are your favourite tricks to smooth your git workflow?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s