This is the second post in a series of notes on version control with Git. The first article is about undoing or fixing the most recent commit in a Git repository. We will take a step back for the second article and cover various flavors of two basic commands that help us inspect the current state of a repository: log and diff. All of the presented commands only read and present Git data without making any changes to the repository and can therefore be safely played around with.

Logs: Inspecting history

A Git repository stores history of a project by creating a sequence of snapshots called commits. It also allows for multiple concurrent tracks of different histories called branches. Branches can share history, diverge and join at different points. As a whole, the history of a repository is a graph of commits. But sometimes we get lost and need a map. With git log we can get a list of the commits on the current branch and see where we currently are. The list is in reverse chronological order showing the most recent commit on top going down all the way to the oldest. There are a couple of helpful arguments and options to this command. Just like with any other Git command, there are many more options but these are the ones that have helped me the most so far. They can all be combined to create precisely tailored logs.

  • git log: The default behavior is to list all commits on the current branch in reverse chronological order including details such as author, time and message.

  • git log *<start>*: Given a branch, tag or commit as first argument start the log will start at this point instead of the current branch.

  • git log *<start>*..*<end>*: It is also possible to log commits of a certain range by providing a start and an end branch, tag or commit.

  • git log *-<n>*: Passing a number n as option will limit the number of shown commits to this amount.

  • git log -p: This option will add a diff with the introduced changes to each commit in the log.

  • git log --stat: This flavor will show number of added and deleted lines for changed files in each commit.

  • git log --oneline: This format shows less information about each commit making them one line each.

Diffs: Viewing changes

  • git diff: The default behavior is to list all changes that are not staged for the next commit. These are the ones that are red when running git status.

  • git diff --staged : This is the counterpart to the default behavior as it lists all staged changes. These are the ones that are green when running git status.

  • git diff <path>: The path argument will limit the diff to the given directory or file. This one is very powerful since glob patterns can be used to match a subset of all files.

Logging examples using the semver project

In order to run a few examples we need a Git repository. It does not matter which one as long as there is enough history in it, so I chose semver, the semantic versioning specification1. You should not be able to break anything by running any of these commands, so I recommend you use a repository of your own. Let’s go:

Git logs and diffs

This is a screenshot of my terminal so please excuse the ugly styling. This example combines three options to get an overview of what files were changed in the last five commits.

Git logs and diffs

Here the form with a start and end commit is used. Instead of specifying the range with SHA hashes it uses tag names which point to a certain commit. Therefore this log shows all commits that happened between release candidate 1 and the actual release of version 1.0.0.