| #!/usr/bin/env python3 |
| # Copyright 2012 The Chromium Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """ |
| Invokes git diff [args...] and inserts file:line in front of each line of diff |
| output where possible. |
| |
| This is useful from an IDE that allows you to double-click lines that begin |
| with file:line to open and jump to that point in the file. |
| |
| Synopsis: |
| %prog [git diff args...] |
| |
| Examples: |
| %prog |
| %prog HEAD |
| """ |
| |
| import subprocess |
| import sys |
| |
| |
| def GitShell(args, ignore_return=False): |
| """A shell invocation suitable for communicating with git. Returns |
| output as list of lines, raises exception on error. |
| """ |
| job = subprocess.Popen(args, |
| shell=True, |
| stdout=subprocess.PIPE, |
| stderr=subprocess.STDOUT) |
| (out, err) = job.communicate() |
| if job.returncode != 0 and not ignore_return: |
| print(out) |
| raise Exception("Error %d running command %s" % ( |
| job.returncode, args)) |
| return out.split('\n') |
| |
| |
| def PrintGitDiff(extra_args): |
| """Outputs git diff extra_args with file:line inserted into relevant lines.""" |
| current_file = ''; |
| line_num = 0; |
| lines = GitShell('git diff %s' % ' '.join(extra_args)) |
| for line in lines: |
| # Pass-through lines: |
| # diff --git a/file.c b/file.c |
| # index 0e38c2d..8cd69ae 100644 |
| # --- a/file.c |
| if (line.startswith('diff ') or |
| line.startswith('index ') or |
| line.startswith('--- ')): |
| print(line) |
| continue |
| |
| # Get the filename from the +++ line: |
| # +++ b/file.c |
| if line.startswith('+++ '): |
| # Filename might be /dev/null or a/file or b/file. |
| # Skip the first two characters unless it starts with /. |
| current_file = line[4:] if line[4] == '/' else line[6:] |
| print(line) |
| continue |
| |
| # Update line number from the @@ lines: |
| # @@ -41,9 +41,9 @@ def MyFunc(): |
| # ^^ |
| if line.startswith('@@ '): |
| _, old_nr, new_nr, _ = line.split(' ', 3) |
| line_num = int(new_nr.split(',')[0]) |
| print(line) |
| continue |
| print(current_file + ':' + repr(line_num) + ':' + line) |
| |
| # Increment line number for lines that start with ' ' or '+': |
| # @@ -41,4 +41,4 @@ def MyFunc(): |
| # file.c:41: // existing code |
| # file.c:42: // existing code |
| # file.c:43:-// deleted code |
| # file.c:43:-// deleted code |
| # file.c:43:+// inserted code |
| # file.c:44:+// inserted code |
| if line.startswith(' ') or line.startswith('+'): |
| line_num += 1 |
| |
| |
| def main(): |
| PrintGitDiff(sys.argv[1:]) |
| |
| |
| if __name__ == '__main__': |
| main() |