intersect-diffs.py 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. #!/usr/bin/env python
  2. ## Copyright (c) 2012 The WebM project authors. All Rights Reserved.
  3. ##
  4. ## Use of this source code is governed by a BSD-style license
  5. ## that can be found in the LICENSE file in the root of the source
  6. ## tree. An additional intellectual property rights grant can be found
  7. ## in the file PATENTS. All contributing project authors may
  8. ## be found in the AUTHORS file in the root of the source tree.
  9. ##
  10. """Calculates the "intersection" of two unified diffs.
  11. Given two diffs, A and B, it finds all hunks in B that had non-context lines
  12. in A and prints them to stdout. This is useful to determine the hunks in B that
  13. are relevant to A. The resulting file can be applied with patch(1) on top of A.
  14. """
  15. __author__ = "jkoleszar@google.com"
  16. import sys
  17. import diff
  18. def FormatDiffHunks(hunks):
  19. """Re-serialize a list of DiffHunks."""
  20. r = []
  21. last_header = None
  22. for hunk in hunks:
  23. this_header = hunk.header[0:2]
  24. if last_header != this_header:
  25. r.extend(hunk.header)
  26. last_header = this_header
  27. else:
  28. r.extend(hunk.header[2])
  29. r.extend(hunk.lines)
  30. r.append("\n")
  31. return "".join(r)
  32. def ZipHunks(rhs_hunks, lhs_hunks):
  33. """Join two hunk lists on filename."""
  34. for rhs_hunk in rhs_hunks:
  35. rhs_file = rhs_hunk.right.filename.split("/")[1:]
  36. for lhs_hunk in lhs_hunks:
  37. lhs_file = lhs_hunk.left.filename.split("/")[1:]
  38. if lhs_file != rhs_file:
  39. continue
  40. yield (rhs_hunk, lhs_hunk)
  41. def main():
  42. old_hunks = [x for x in diff.ParseDiffHunks(open(sys.argv[1], "r"))]
  43. new_hunks = [x for x in diff.ParseDiffHunks(open(sys.argv[2], "r"))]
  44. out_hunks = []
  45. # Join the right hand side of the older diff with the left hand side of the
  46. # newer diff.
  47. for old_hunk, new_hunk in ZipHunks(old_hunks, new_hunks):
  48. if new_hunk in out_hunks:
  49. continue
  50. old_lines = old_hunk.right
  51. new_lines = new_hunk.left
  52. # Determine if this hunk overlaps any non-context line from the other
  53. for i in old_lines.delta_line_nums:
  54. if i in new_lines:
  55. out_hunks.append(new_hunk)
  56. break
  57. if out_hunks:
  58. print FormatDiffHunks(out_hunks)
  59. sys.exit(1)
  60. if __name__ == "__main__":
  61. main()