As a full stack developer with over 20 years of experience working in Git codebases, listing commits between commit hashes is a technique I utilize almost daily. When debugging issues, analyzing performance, reviewing pulls, and comprehending complex commit histories, being able to isolate changes between two points in the Git timeline has proven invaluable.
In this comprehensive guide, I will cover the many use cases for commit ranges, the Git commands available, how to customize the output, and expert best practices for leveraging commit listings as a seasoned developer.
Why List Commits Between Hashes as a Developer?
While simple commit histories have linear chains of updates, most real-world repos have intricate branch merges, resets, reverts, and rewrites that obfuscate the timeline. In these complex scenarios, here are some of the reasons listing commit SHAs can help:
Isolate Bug Introduction
When debugging an application bug, it helps immensely to identify the exact commit that introduced the regressive behavior. By listing changes between commits before and after the issue started occurring, developers can review the diffs for likely culprits.
git log --oneline --stat c5f411~..d77299
Running a command like this will print file diff stats for commits since and including c5f411
up through d77299
– perfect for honing in on bug origins.
Analyze Performance Regressions
In a similar vein, listing commit ranges helps uncover when performance regressions emerged. By keeping metrics on codebase performance, developers can pinpoint commits where speed degraded and view the diffs for optimization opportunities.
git log --grep="Improve perf" --patch c5f411..d77299
Adding --grep
and --patch
shows performance-related commits in the range with file diffs.
Revert Problematic Commits
When commits introduce issues, reverting them is an option. By listing commits between hashes, developers identify candidates for reversion.
git revert c5f411 d77299
The revert command allows specifying commit SHAs directly.
Review Pull Requests
On GitHub pull requests, the commits between the head and base branches depict the proposed changes. Being able to parse commit SHAs helps understand precisely what edits the pull entails.
Developers can also append hashes to the GitHub URL to view diffs up to a certain point, which facilitates reviewing incremental changes.
Compare Branches
Listing commit SHAs helps visualize how branches diverged. For example, showing commits on develop
since it forked from master
reveals new work.
git log --oneline master..develop
Cherry Pick Commits
Cherry picking copies commits from one branch to another. By listing commits, developers identify candidates to cherry pick elsewhere.
Analyze Code Churn
Counting commits between hashes can reveal code churn – how many times a file or line changed. This aids refactoring and quality efforts.
git log --oneline Xfile.py | wc -l
Git Commands to List Commit Ranges
Now that we‘ve covered use cases, what are the actual Git commands for printing commits between two SHAs? Primarily, git log
and git rev-list
facilitate commit listings.
Git Log
The git log
command shows the commit history. Appending two dots between SHAs prints a range:
git log --oneline c5f411..d77299
This will include d77299
but exclude c5f411
from the output.
Customize Log Output
Numerous flags allow customizing git log
:
--stat
: Print file change statistics per commit--patch
: Show full per-file diffs--grep
: Filter commits by search term--author
: Filter by commit author--since="1 week ago"
: Filter by relative date
For example, to print all commits by author Sara that touched XML files:
git log --author="Sara" -- c5f411..d77299 -- **/*.xml
This leverages commit ranges alongside other filters to hyper-focus the log.
Exclude End Commit
By default, the end commit SHA displays in git log
output. Add ~
after the hash to omit it:
git log --oneline c5f411..d77299~
Now d77299
will not appear.
Git Rev-List
The git rev-list
command also prints commits. It specializes in commit ancestry and graph reachability.
A common case is listing commits between two points with --ancestry-path
:
git rev-list --ancestry-path c5f411..d77299
This prints the full 40-character SHA hashes rather than abbreviated versions.
Count Commit Range
To count commits between SHAs rather than listing them:
git rev-list --ancestry-path c5f411..d77299 | wc -l
Piping to wc -l
prints the number of commits spanning the two hashes.
Compare Git Log and Git Rev-List
While git log
and git rev-list
both output commit histories, some key differences exist:
Feature | Git Log | Git Rev-List |
---|---|---|
Commit details | Shows author, date, message | Minimal output |
Display | Designed for humans | Built for tooling |
Ancestral commits | Only directly in branch | Complex reachability |
SHA length | Abbreviated | Full SHA |
In essence, git log
readably prints rich commit details for developers. git rev-list
enables commit analysis via streams of SHAs.
Expert Best Practices for Commit Ranges
Over decades of Git experience, I‘ve recognized patterns for efficiently leveraging commit ranges:
-
Bookend complex histories: Before hunting a bug or change, print commits on either side of timeline uncertainty with
git log --oneline
. This frames the investigative range. -
Bisect commit ranges: Rather than one huge range, iteratively divide the commit set in half to zero in on target commits.
-
Persist commit ranges: When debugging issues, save a commit range in source control comments to document affects.
-
Prefix commits: Tag commits with metadata like categories or ticket numbers. Then filter log output on the prefixes to associate by attribute.
-
Plot commit stats: Graph commit counts over time or by author to view project trends.
-
Attach ranges to metrics: Compare commit ranges to application monitoring and performance to connect code changes to production impact.
Conclusion
As a seasoned full stack developer, listing commits between Git SHAs provides invaluable visibility into code changes, bugs, authors, variants, ownership, and more. via powerful commands like git log
and git rev-list
, developers isolate commit ranges for targeted analysis. Paired with expert workflows, commit ranges unlock masterful app control.
I hope this guide has illuminated techniques every developer should know when working in complex Git repositories. Let me know if you have any other use cases for commit ranges I should cover!