James Zern | 9097dcf | 2022-05-15 15:39:54 -0700 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
John Koleszar | a3ff625 | 2012-08-08 09:28:01 -0700 | [diff] [blame] | 2 | ## |
Yaowu Xu | 9c01aa1 | 2016-09-01 14:32:49 -0700 | [diff] [blame] | 3 | ## Copyright (c) 2016, Alliance for Open Media. All rights reserved |
| 4 | ## |
| 5 | ## This source code is subject to the terms of the BSD 2 Clause License and |
| 6 | ## the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License |
| 7 | ## was not distributed with this source code in the LICENSE file, you can |
| 8 | ## obtain it at www.aomedia.org/license/software. If the Alliance for Open |
| 9 | ## Media Patent License 1.0 was not distributed with this source code in the |
| 10 | ## PATENTS file, you can obtain it at www.aomedia.org/license/patent. |
John Koleszar | a3ff625 | 2012-08-08 09:28:01 -0700 | [diff] [blame] | 11 | ## |
| 12 | """Calculates the "intersection" of two unified diffs. |
| 13 | |
| 14 | Given two diffs, A and B, it finds all hunks in B that had non-context lines |
| 15 | in A and prints them to stdout. This is useful to determine the hunks in B that |
| 16 | are relevant to A. The resulting file can be applied with patch(1) on top of A. |
| 17 | """ |
| 18 | |
| 19 | __author__ = "jkoleszar@google.com" |
| 20 | |
John Koleszar | a3ff625 | 2012-08-08 09:28:01 -0700 | [diff] [blame] | 21 | import sys |
| 22 | |
John Koleszar | a7be7c8 | 2012-07-13 13:01:40 -0700 | [diff] [blame] | 23 | import diff |
John Koleszar | a3ff625 | 2012-08-08 09:28:01 -0700 | [diff] [blame] | 24 | |
| 25 | |
| 26 | def FormatDiffHunks(hunks): |
| 27 | """Re-serialize a list of DiffHunks.""" |
| 28 | r = [] |
| 29 | last_header = None |
| 30 | for hunk in hunks: |
| 31 | this_header = hunk.header[0:2] |
| 32 | if last_header != this_header: |
| 33 | r.extend(hunk.header) |
| 34 | last_header = this_header |
| 35 | else: |
| 36 | r.extend(hunk.header[2]) |
| 37 | r.extend(hunk.lines) |
| 38 | r.append("\n") |
| 39 | return "".join(r) |
| 40 | |
| 41 | |
| 42 | def ZipHunks(rhs_hunks, lhs_hunks): |
| 43 | """Join two hunk lists on filename.""" |
| 44 | for rhs_hunk in rhs_hunks: |
| 45 | rhs_file = rhs_hunk.right.filename.split("/")[1:] |
| 46 | |
| 47 | for lhs_hunk in lhs_hunks: |
| 48 | lhs_file = lhs_hunk.left.filename.split("/")[1:] |
| 49 | if lhs_file != rhs_file: |
| 50 | continue |
| 51 | yield (rhs_hunk, lhs_hunk) |
| 52 | |
| 53 | |
| 54 | def main(): |
John Koleszar | a7be7c8 | 2012-07-13 13:01:40 -0700 | [diff] [blame] | 55 | old_hunks = [x for x in diff.ParseDiffHunks(open(sys.argv[1], "r"))] |
| 56 | new_hunks = [x for x in diff.ParseDiffHunks(open(sys.argv[2], "r"))] |
John Koleszar | a3ff625 | 2012-08-08 09:28:01 -0700 | [diff] [blame] | 57 | out_hunks = [] |
| 58 | |
| 59 | # Join the right hand side of the older diff with the left hand side of the |
| 60 | # newer diff. |
| 61 | for old_hunk, new_hunk in ZipHunks(old_hunks, new_hunks): |
| 62 | if new_hunk in out_hunks: |
| 63 | continue |
| 64 | old_lines = old_hunk.right |
| 65 | new_lines = new_hunk.left |
| 66 | |
| 67 | # Determine if this hunk overlaps any non-context line from the other |
| 68 | for i in old_lines.delta_line_nums: |
| 69 | if i in new_lines: |
| 70 | out_hunks.append(new_hunk) |
| 71 | break |
| 72 | |
| 73 | if out_hunks: |
James Zern | 9097dcf | 2022-05-15 15:39:54 -0700 | [diff] [blame] | 74 | print(FormatDiffHunks(out_hunks)) |
John Koleszar | a3ff625 | 2012-08-08 09:28:01 -0700 | [diff] [blame] | 75 | sys.exit(1) |
| 76 | |
| 77 | if __name__ == "__main__": |
| 78 | main() |