Index: clang_format_merge_driver.py |
diff --git a/clang_format_merge_driver.py b/clang_format_merge_driver.py |
new file mode 100755 |
index 0000000000000000000000000000000000000000..5f0449a28b10ebc65757b70f7b8591a28a9cdb4a |
--- /dev/null |
+++ b/clang_format_merge_driver.py |
@@ -0,0 +1,58 @@ |
+#!/usr/bin/env python |
+# Copyright 2016 The Chromium Authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+"""clang-format 3-way merge driver. |
+ |
+This is a custom merge driver for git that helps automatically resolves |
+conflicts caused by clang-format changes. The conflict resolution |
+strategy is extremely simple: it simply clang-formats the current, |
+ancestor branch's, and other branch's version of the file and delegates |
+the remaining work to git merge-file. |
+ |
+See https://git-scm.com/docs/gitattributes ("Defining a custom merge |
+driver") for more details. |
+""" |
+ |
+import subprocess |
+import sys |
+ |
+import clang_format |
+ |
+ |
+def main(): |
+ if len(sys.argv) < 5: |
+ print('usage: %s <base> <current> <others> <path in the tree>' % |
+ sys.argv[0]) |
+ sys.exit(1) |
+ |
+ base, current, others, file_name_in_tree = sys.argv[1:5] |
+ print 'Running clang-format 3-way merge driver on ' + file_name_in_tree |
+ |
+ try: |
+ tool = clang_format.FindClangFormatToolInChromiumTree() |
+ for fpath in base, current, others: |
+ # Typically, clang-format is used with the -i option to rewrite files |
+ # in-place. However, merge files live in the repo root, so --style=file |
+ # will always pick up the root .clang-format. |
+ # |
+ # Instead, this tool uses --assume-filename so clang-format will pick up |
+ # the appropriate .clang-format. Unfortunately, --assume-filename only |
+ # works when the input is from stdin, so the file I/O portions are lifted |
+ # up into the script as well. |
+ with open(fpath, 'rb') as input_file: |
+ output = subprocess.check_output( |
+ [tool, '--assume-filename=%s' % file_name_in_tree, '--style=file'], |
+ stdin=input_file) |
+ with open(fpath, 'wb') as output_file: |
+ output_file.write(output) |
+ except clang_format.NotFoundError, e: |
+ print e |
+ print 'Failed to find clang-format. Falling-back on standard 3-way merge' |
+ |
+ return subprocess.call(['git', 'merge-file', '-Lcurrent', '-Lbase', '-Lother', |
+ current, base, others]) |
+ |
+ |
+if __name__ == '__main__': |
+ sys.exit(main()) |