git log – the Good Parts

news image

If you’re managing a complex git codebase with multiple developers, then you may well be using a tool like GitHub or BitBucket to delve into the history and figure out branch and merge issues.

These GUIs are great for providing a nice user interface for managing pull requests and simple histories and the like, but when the workflow SHTF there’s no substitute for using git log and its relatively little-known flags to really dig into the situation.

You’re going to run through this with me so that I know you’ve got it. Type the commands in bold to follow.

This is based on material from my book Learn Git the Hard Way, a free sample available here.

An Example Git Repository

Run this to download a fairly typical git repository that I work on:

NB this is a copy of the original repo, ‘frozen’ here to provide stable output. 

 

git log

git log is the vanilla log command you are probably already familiar with:

It outputs 5+ lines per commit, with date, author commit message and id. It goes in reverse time order, which makes sense for most cases, as you are mostly interested in what happened recently.

NOTE: output can vary depending on version, aliases,
and whether you are outputting to a terminal!
My version here was 2.7.4.

--oneline

Most of the time I don’t care about the author or the date, so in order that I can see more per screen, I use --oneline to only show the commit id and comment per-commit.

--decorate

You might want more information than that, though, like which branch was that commit on? Where are the tags?

The --decorate flag provides this.

 

--all

I use this so much it’s in my muscle memory.

Can you see what it does? If you can’t, compare it to --oneline above and dig around to figure it out. (Remember that your version might do --all by default when output goes to the terminal instead of a file).

More recent versions of git put this in the terminal by default, so things are improving for my fingers.

That’s great, but what would be great is a visual representation of all those branches…

--graph

--graph gives you that visual representation, but in the terminal. While it might not look as slick as some git GUIs, it does have the benefit of being consistently viewed anywhere, and much more configurable to your specific needs.

And when you’re trying to piece together what happened on a 15-team project that doesn’t rebase, it can be essential…

DON’T PANIC!

The above can be hard for the newcomer to parse, and there is little out there to guide you, but a few tips here can make it much easier to read.

The * indicates that there is a commit on the line, and the details of the commit (here the commit id, and first line of the comment) are on the right hand side.

The lines and position of the * indicate the lineage (or parentage) of each change. So, to take these three lines for example:

The green pipes indicate that while the two changes listed here were going on, another branch had a gap between its two changes (9816651 and d21351c).

The blue line takes you to one parent of the bf36cf5 merge (what’s the commit id of the blue parent?), and the pink one goes to the other parent commit (313c03a).

It’s worth taking a bit of time to figure out what’s going on here, as it will pay dividends in a crisis later…


If you like this post, you’ll like my book Learn Git the Hard Way

It covers all this and much more in a similar style.

learngitthehardway


--simplify-by-decoration

If you’re looking at the whole history of a project and want to get a feel for its shape before diving in, you may want to see only the significant points of change (ie the lines affected by -–decorate above).

These remove any commit that wasn’t tagged, branched (ie there’s no reference). The root commit is always there too.

Try tagging a specific commit not listed above, and then re-run the command.

File Info

Using --oneline can be a bit sparse, so --stat can give you useful information about what changed.

The number indicates the numbers of lines that were changed, with insertions represented by a + sign, and deletions by a -. There’s no concept of a ‘change’ to a line as such: the old line is deleted, and then the new one added even if only one character changed.

If you find --stat hard to remember, then an alternative is to use --name-only, but with that you lose the information about numbers of changes to files.

Regex on Commits

This one’s also really handy. The -G flag allows you to search for all commits and only return commits and their files whose changes include that regexp.

This one, for example, looks for changes that contain the text chef-client

If you’ve ever spent ages searching through git log --patch output looking for a specific change this is a godsend…

The eccentrically-named --pickaxe-all gives you information about all files that changed in the commit, rather than just the ones that matched the regexp in the commit.

Try it out!

 


If you like this post, you’ll like my book Learn Git the Hard Way

It covers all this and much more in a similar style.

learngitthehardway


If you liked this post, check out:

Five Key Git Concepts Explained the Hard Way

Create Your Own Git Diagrams

Ten Things I Wish I’d Known About bash

A Non-Cloud Serverless Application Pattern Using Git and Docker

Read More

Leave a Reply

Your email address will not be published. Required fields are marked *