diff options
author | Jan Holthuis <jan.holthuis@ruhr-uni-bochum.de> | 2020-08-03 21:08:37 +0200 |
---|---|---|
committer | Jan Holthuis <jan.holthuis@ruhr-uni-bochum.de> | 2020-08-03 21:08:37 +0200 |
commit | 1e7698d781179b4c0a05ee40d8245e7fd4896bd6 (patch) | |
tree | 72c4710a6411772a01758cbf9f6b1235a4e9fff3 /tools/githelper.py | |
parent | 5589ce8cac60eab8886efa5e234bfcd7a1565b9e (diff) |
tools: Add various improvements for clang_format.py/githelper.py
Diffstat (limited to 'tools/githelper.py')
-rw-r--r-- | tools/githelper.py | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/tools/githelper.py b/tools/githelper.py index b7eb1656b1..29e9ee0a4e 100644 --- a/tools/githelper.py +++ b/tools/githelper.py @@ -26,41 +26,52 @@ def get_toplevel_path() -> str: def get_changed_lines( from_ref=None, filter_lines=None, include_files=None ) -> typing.Iterable[Line]: - """Inspect `git diff` output, yields changed lines.""" + """Inspect `git diff-index` output, yields changed lines.""" logger = logging.getLogger(__name__) - cmd = ["git", "diff", "--unified=0", from_ref if from_ref else "HEAD"] + cmd = [ + "git", + "diff-index", + "--patch", + "--unified=0", + from_ref if from_ref else "HEAD", + ] if include_files: cmd.extend(["--", *include_files]) logger.debug("Executing: %r", cmd) proc = subprocess.run(cmd, capture_output=True) proc.check_returncode() current_file = None - lines_left = 0 + hunk_lines_left = 0 for line in proc.stdout.decode(errors="replace").splitlines(): match_file = re.match(r"^\+\+\+ b/(.*)$", line) if match_file: + # Current line contains a diff filename + assert hunk_lines_left == 0 current_file = match_file.group(1) - lines_left = 0 continue match_lineno = re.match( r"^@@ -(\d+(?:,\d+)?) \+([0-9]+(?:,[0-9]+)?) @@", line ) if match_lineno: + # Current line contains a hunk header + assert current_file is not None + assert hunk_lines_left == 0 start_removed, _, length_removed = match_lineno.group(1).partition( "," ) start_added, _, length_added = match_lineno.group(2).partition(",") lineno_removed = int(start_removed) lineno_added = int(start_added) - lines_left = int(length_removed) if length_removed else 1 - lines_left += int(length_added) if length_added else 1 + hunk_lines_left = int(length_removed) if length_removed else 1 + hunk_lines_left += int(length_added) if length_added else 1 continue - if lines_left and line: - lines_left -= 1 + if hunk_lines_left and line: + # Current line contains an added/removed line + hunk_lines_left -= 1 assert line[0] in ("+", "-") if line.startswith("+"): @@ -80,11 +91,18 @@ def get_changed_lines( if filter_lines is None or filter_lines(lineobj): yield lineobj + # If we reach this part, the line does not contain a diff filename or a + # hunk header and does not belog to a hunk. This means that this line + # will be ignored implicitly. + + # Make sure we really parsed all lines from the last hunk + assert hunk_lines_left == 0 + def get_changed_lines_grouped( from_ref=None, filter_lines=None, include_files=None ) -> typing.Iterable[FileLines]: - """Inspect `git diff` output, yields changed lines grouped by file.""" + """Inspect `git diff-index` output, yields lines grouped by file.""" lines = get_changed_lines(from_ref, filter_lines, include_files) for filename, file_lines in itertools.groupby( |