How to compute diff stats (insertions, deletions) in Python
Parses a git diff text and counts the number of added and removed lines to produce insertion and deletion stats.
Python code
39 linesimport re
from collections import Counter
def parse_diff(diff_text):
insertions = 0
deletions = 0
for line in diff_text.splitlines():
if line.startswith("+") and not line.startswith("+++"):
insertions += 1
elif line.startswith("-") and not line.startswith("---"):
deletions += 1
return insertions, deletions
def diff_stats(diff_text):
ins, dels = parse_diff(diff_text)
return {
"insertions": ins,
"deletions": dels,
"total_changes": ins + dels,
}
if __name__ == "__main__":
sample_diff = """diff --git a/example.txt b/example.txt
--- a/example.txt
+++ b/example.txt
@@ -1,4 +1,4 @@
Hello world
-old line removed
+new line added
+another insertion
unchanged line
"""
stats = diff_stats(sample_diff)
print(f"Insertions: {stats['insertions']}")
print(f"Deletions: {stats['deletions']}")
print(f"Total changes: {stats['total_changes']}")
Output
Insertions: 2
Deletions: 1
Total changes: 3
How it works
This function reads a diff string line by line. Lines starting with + are counted as insertions, - as deletions. The not line.startswith("+++") guard skips the diff header lines like +++ b/example.txt. The --- guard similarly skips the original file header. Splitting by splitlines() handles both \n and \r\n line endings, making it robust across platforms. Counting raw lines gives a quick approximation of the git diff --stat output, though it doesn't account for moved or context lines.
Common mistakes
- Not skipping the `+++` and `---` header lines, which corrupts the counts
- Forgetting that blank lines in the diff start with a space and should not be counted
- Ignoring binary file diffs where `Binary files differ` appears instead of `+`/`-` lines
Variations
- Use `subprocess.run` with `git diff --stat` or `git diff --numstat` to let Git compute stats
- Parse `git diff --numstat` output which gives tab-separated counts per file
Real-world use cases
- Build a CI bot that comments merge-request size (insertions vs deletions) on every pull request.
- Write a pre-commit hook that blocks changes touching more than N lines in critical files.
- Summarize weekly developer activity by aggregating diff stats across a repo's commit history.
Sponsored
More from Git + Python
- Amend Last Commit Message in Python easy
- Bisect Good Bad Automation Script in Python easy
- Build a Simple Log Graph in Python easy
- Bump Semantic Version Git Tag in Python easy
- Count Unique Contributors from Git Shortlog in Python easy
- Create a Mock GitHub Release API in Python for Testing gh CLI easy
Keep learning
Related tutorials and quizzes for this topic.