git log --follow, the gitpython way
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
If you want the equivalent of git log --follow in Python, the simplest practical answer is that GitPython does not expose a high-level rename-following history API that fully replaces the CLI behavior. The reliable approach is usually to call the underlying Git command through GitPython's command wrapper and let Git itself handle rename tracking.
Why --follow Is Special
git log --follow -- path/to/file is not the same as a plain history walk filtered by path. Git uses rename detection heuristics to keep tracing history when the file name changes.
A normal GitPython history call like this:
can show commits for the current path, but it does not guarantee the same rename-follow behavior as git log --follow. That is the gap most people run into.
Use the Wrapped Git Command Directly
GitPython gives you access to the raw Git executable through repo.git. That means you can run the exact log command you would trust in the shell.
This is usually the right answer because it preserves Git's own path-follow and rename-detection logic instead of trying to reconstruct it manually in Python.
If you want a custom output format for parsing:
That gives you structured data without having to scrape the default human-readable log format.
When iter_commits Is Still Fine
If the file was never renamed, or if rename following is not important, iter_commits(paths=...) is still a perfectly good solution.
This is cleaner when you only need straightforward path filtering. The problem appears only when you need the semantic behavior of --follow.
Avoid Reimplementing Rename Tracking Yourself
It is technically possible to walk commits manually, inspect diffs, detect renames, and keep updating the tracked path in Python. In practice, that is almost always the wrong level of abstraction unless you are building a specialized Git analysis tool.
Git already has nontrivial rename heuristics. Reimplementing that logic yourself usually means more code, more edge cases, and behavior that still does not quite match the CLI command people already trust.
If the requirement is "do what git log --follow does," the cleanest solution is to call that command through GitPython.
Parse Output Deliberately
When you wrap raw Git commands, think about output format up front. Using --format makes parsing predictable and avoids brittle string handling.
For example, a small helper can return structured records:
This keeps the Python side small and lets Git stay responsible for history semantics.
Common Pitfalls
- Expecting
iter_commits(paths=...)to behave exactly likegit log --followleads to confusion because rename following is the missing piece. - Parsing the default
git logtext output is brittle. Use--formatso each record is machine-friendly. - Trying to reimplement rename tracking in Python usually creates edge cases and still may not match Git's heuristics.
- Forgetting the
--separator before the file path can cause Git to interpret the path as another revision argument. - Assuming
--followworks for arbitrary combinations of paths and complex history filters can still lead to surprises because the Git CLI has its own limitations and heuristics.
Summary
- GitPython does not provide a perfect high-level replacement for
git log --follow. - The practical solution is to call
repo.git.log("--follow", "--", path)and let Git do the heavy lifting. - Use
iter_commitsonly when plain path filtering is enough and rename history does not matter. - Prefer
--formatwhen you need to parse the result programmatically. - If the goal is CLI-equivalent rename tracking, invoking the underlying Git command is the cleanest and most reliable approach.
Related reading
- Git log to get commits only for a specific branch
- git log to return only the commits made to the master branch?
- Git merge branch into master
- Git merge errors
- Git merge from someone else's fork
- Git merge hotfix branch into feature branch
- Git merge hotfix branch into feature branch
- Git Merge in only one commit
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.