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.
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 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 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:
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.
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.