Fix added_lines and deleted_lines dropping "++" and "--" content - #324
Merged
ishepard merged 1 commit intoSep 11, 2026
Merged
Conversation
ModifiedFile.added_lines skipped every diff line starting with "+++", and ModifiedFile.deleted_lines skipped every one starting with "---", to avoid counting the "+++ b/file" and "--- a/file" patch headers. GitPython's Diff.re_header already consumes both headers, so Diff.diff starts at the first "@@" hunk header and those guards could only match real content: an added line "++i;" appears as "+++i;" in the patch, and a deleted line "--i;" appears as "---i;". The counts therefore disagreed with ModifiedFile.diff_parsed and with Commit.insertions and Commit.deletions, which come from numstat. In test-repos/diff, commit 156111a deletes 9 lines from docs/reference.rst, one of them the reST underline "----------------", and deleted_lines returned 8. pydriller/domain/commit.py: drop both guards so every "+" and "-" line in the hunk body is counted.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #324 +/- ##
=======================================
Coverage 97.39% 97.39%
=======================================
Files 16 16
Lines 1150 1150
=======================================
Hits 1120 1120
Misses 30 30
🚀 New features to boost your workflow:
|
Owner
|
Amazing finding 😄 crazy that the bug has been there for all these years! thanks for fixing it! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ModifiedFile.added_linesskips every diff line starting with+++, andModifiedFile.deleted_linesskips every one starting with---, to avoid counting the+++ b/fileand--- a/filepatch headers. Those headers are never in the string being scanned: GitPython'sDiff.re_headermatches them as part of the header block and assignsDiff.diffonly the text that follows, soModifiedFile.diffalways starts at the first@@. The guards can therefore only match real content. An added line++i;appears as+++i;in the patch and a deleted line--i;appears as---i;, and both go uncounted.So the counts disagree with
Commit.insertionsandCommit.deletions, which come from numstat, and withModifiedFile.diff_parsed, which classifies the same lines with no header guard, as doesHunksCountatpydriller/metrics/process/hunks_count.py:45. There is already a case in the bundled repos: intest-repos/diff, commit156111a7deletes 9 lines fromdocs/reference.rst, one of them the reST underline----------------, anddeleted_linesreturns 8 whilegit diff --numstatanddiff_parsed["deleted"]both say 9. Everything built on these two properties inherits the undercount, includingCodeChurn,LinesCount,ContributorsCount,ContributorsExperienceandHistoryComplexity.The fix drops both guards in
pydriller/domain/commit.py, so every+and-line in the hunk body is counted.Two tests in
tests/test_commit.py: one overtest-repos/diffthat pins thereference.rstcount at 9 and checks the per-file sums now matchCommit.insertionsandCommit.deletions, and one that runs a small patch containing+++i;and---i;through a mockedDiff. On master they fail withassert 8 == 9andassert 0 == 1. With the change,mypy --ignore-missing-imports pydriller/ tests/,flake8andpytest tests/all pass locally on Python 3.11 on macOS.