Git History
Other than your Git repository storing your source code, the second most valuable source of information is your commits which chronicle the evolution of your codebase. Your commits are a treasure trove of information — when properly maintained — because they allow you to:
Achieve Second-Order Thinking by having the long tail of thought for understanding what took place, why decisions were made, and how those decisions were implemented.
Have well thought out Code Reviews. Even better, mentorship is built in by default because your code review’s Git history explains the what, why, and how so less experienced engineers have a chance to level up and learn …
Git History
Other than your Git repository storing your source code, the second most valuable source of information is your commits which chronicle the evolution of your codebase. Your commits are a treasure trove of information — when properly maintained — because they allow you to:
Achieve Second-Order Thinking by having the long tail of thought for understanding what took place, why decisions were made, and how those decisions were implemented.
Have well thought out Code Reviews. Even better, mentorship is built in by default because your code review’s Git history explains the what, why, and how so less experienced engineers have a chance to level up and learn from more experienced engineers.
Automate the generation of release notes and versions based on your curated commit history to produce Milestones for your team, stakeholders, and customers.
This all starts by using git log to view your commit history and team’s collective knowledge.
Table of Contents
Setup
To get started, copy and paste the following script in your console to setup a demo project you can play with:
mkdir demo
cd demo
git init
printf "%s\n" 'ARGV.then { |a, b| puts "#{a} plus #{b} equals #{a.to_i + b.to_i}." }' > calc.rb
git add --all .
git commit --message "Added calculator implementation" \
--message "Necessary for calculating the addition of two numbers."
printf "%s\n" "# License\n\nA license." > LICENSE.adoc
git add --all .
git commit --message "Added license" \
--message "Necessary to provide licensing information."
printf "%s\n" "# Demo\n\nA demonstration project." > README.adoc
git add --all .
git commit --message "Added documentation" \
--message "Necessary to explain what this project is and why it's important."
You’ll notice the above simulates actual work by using well written atomic commits. The fact that our implementation is extremely basic is because we only want to use git log to look at our commit history. In practice, you’d have a full implementation with specs.
Now, when you run git log from the root of your demo project, you should see the following output:
commit 72145f246d6b4ea593fdb40360ae9f34781764e1 (HEAD -> main)
Author: Brooke Kuhlmann <brooke@demo.io>
Date: Sun Nov 9 11:07:34 2025 -0700
Added documentation
Necessary to explain what this project is and why it's important.
commit 64ba0845908495d4d2fcb5ceb7c3e175a07991f0
Author: Brooke Kuhlmann <brooke@demo.io>
Date: Sun Nov 9 11:07:34 2025 -0700
Added license
Necessary to provide licensing information.
commit 39c7942cfe1ae6ad99429f569eff81294f1c9fbd
Author: Brooke Kuhlmann <brooke@demo.io>
Date: Sun Nov 9 11:07:33 2025 -0700
Added calculator implementation
Necessary for calculating the addition of two numbers.
The above is nice for getting started but only using git log gets old fast. We can do better!
Basics
As explained in Git Commit Anatomy, each Git commit you create needs to explain the following:
Who the person is that made the commit.
What the change is.
Why the change is important.
How the change was implemented.
We meet the criteria for the above. Granted, our commit message bodies could be more fleshed out with ASCII Doc syntax, Git Trailers, and more but this is fine for now.
A quick step up from using git log is to use git log --oneline. Example:
72145f246d6b (HEAD -> main) Added documentation
64ba08459084 Added license
39c7942cfe1a Added calculator implementation
Notice how concise this is. This is what you want but we’re missing information we had when using git log. So we need to combine both formats into something more powerful. Thankfully, Git has support for pretty formats which provides multiple ways to slice and dice commit details for logging purposes.
Advanced
With Git log pretty formats in mind, we can look at two useful ways to study your Git log history: concise and detailed.
Concise
One of the best ways to log commits, line by line, is as follows:
git log --graph \
--pretty=format:"%C(yellow)%h%C(reset) %G? %C(bold blue)%an%C(reset) %s%C(bold cyan)%d%C(reset) %C(green)%cr.%C(reset)"
The above will produce the following:

If you’ve never used pretty formatting before, here’s the full breakdown:
git log --graph: Logs your commit history in graph format which uses indentation to represent merge bubbles. In this case, we don’t have merge bubbles so only a single star (*) is shown in yellow color.
--pretty=format: Switches to pretty formatting.
%C(yellow)%h%C(reset): Prints our commit SHAs (%h) as yellow. Use of %C followed by parenthesis allows us to specify color — yellow in this case — followed by %C(reset) to reset the color.
%G?: Uses a single letter to indicate if our commit is signed and what status it’s in. In this case, all the commits are signed as indicated by G which is short for Good. No color is applied, in this case, so defaults to a white color.
%C(bold blue)%an%C(reset): Prints the author name (%an) in blue color.
%s: Informs Git to print our commit subject in white color (default color.
%C(bold cyan)%d%C(reset): Prints contextual information (i.e. branch, tag, HEAD) in cyan color. Extremely useful when on a branch, when a commit has been tagged, and so forth. This is why our last commit shows (HEAD -> main) in cyan color to let us know we are on the last commit of the main branch.
%C(green)%cr.%C(reset): Informs Git to show us the amount of time that has passed since we first created/updated the commit.
The above is so useful you might want to alias this as gl (short for git log) in your shell for faster typing.
Verbose
There are times where you might need more information such as viewing your commit message bodies, file details, and line change stats. This is where you can build upon pretty print formats by using the following:
git log --stat \
--pretty=format:"%C(yellow)%h%C(reset) %G? %C(bold blue)%an%C(reset) %s%C(bold cyan)%d%C(reset) %C(green)%cr.%C(reset) %n%n%b%n%N%-%n"
The above will yield the following output:

Now we get concise formatting, as shown before, along with commit message body, file, and line statistics. Here’s the break down of the modifications:
git log --stat: Prints statistical information about file changes with each file listed per line along with insert (plus) and deletion (minus) statistics.
%n%n%b%n%N: Print the commit body (%b) — including Git Trailers — followed by Git Notes (%N) if any.
%-%n: Prevents excessive blank lines when commits don’t have notes. Otherwise, you’d get extra whitespace which isn’t what you want.
Searching
The icing on the cake for well written commit messages — coupled with Git Rebase and excellent Git Commit Anatomy — is information retrieval. The following explains what this looks like and assumes you are using the concise pretty formats discussed earlier (swap out --graph for the option/command described below).
Grep
Grepping your Git commits allows you to search by commit messages only. This only means your subject and body including {git_trailers}. Keep in mind, this will not search through any files associated with your commit. Here’s a few examples (using short hand with no pretty formatting):
# Answer only added commits (will answer all three commits in our history).
git log --grep Added
# Answer only commits with this phrase (will answer our first commit).
git log --grep "calculating the addition"
# Answers commits based on trailers (will answer nothing since we didn't use trailers).
git log --grep "Milestone: patch"
Extremely powerful when you know you’ve written about a subject in the past and need a quick way to remember what your thought process was.
Pickaxe
Using -S is known as the pickaxe search which finds code that was added or removed in your commit history. Unlike grep, this does not search your commit messages, only the files associated with your commit. Here’s a few examples (using short hand with no pretty formatting):
# Answers only commits with this code snippet (i.e. our first commit).
git log -S "a.to_i + b.to_i"
# Answers only commits which use the `Demo::Logger` object (zero in this case).
git log -S Demo::Logger
# Answers only commits fail with the NoMatchingPatternError.
git log -S NoMatchingPatternError
Extremely powerful when you know the rough shape, or snippet, of the code you are looking for and need this for example purposes, need to revert the change, and so forth.
File
Sometimes you only need to look at the full history of a file. Example:
git log -- calc.rb
With the above, we only get a single commit answered back, our first commit, but when used on a larger repository, this gives you a nice way to review the evolution of specific file.
💡 Combine the above with --grep or -S for additional filtering.
Reflog
Git’s reflog is a powerful tool — and out of scope for a deeper dive here — but you can search your reflog via the following:
git log --reflog
While the above is worth knowing, the following is superior because you get relative time:
git reflog --relative-date
💡 Combine either of the above with --grep or -S for additional filtering.
All
This one is less useful but worth knowing about because this’ll allow you to search across all branches, tags, and remotes. Definitely a big hammer but can be handy in certain circumstances:
git log --all
💡 Combine the above with --grep or -S for additional filtering.
Conclusion
Tapping into Git pretty formats is one of the best ways to let Git do all of the heavy lifting for you when viewing your Git history. You’ve seen a few ways in which this can be accomplished but definitely take the time explore pretty formatting further so you can log commit message information in a format that is most productive for your own workflow. Even better, once you’ve got a killer Git history, you can tap into Git’s search tools for finding information quickly for making informed decisions.