-
Notifications
You must be signed in to change notification settings - Fork 0
/
clang_format_merge_driver.py
71 lines (57 loc) · 2.49 KB
/
clang_format_merge_driver.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#!/usr/bin/env python3
# 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.
"""
from __future__ import print_function
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)
# pylint: disable=unbalanced-tuple-unpacking
base, current, others, file_name_in_tree = sys.argv[1:5]
# pylint: enable=unbalanced-tuple-unpacking
if file_name_in_tree == '%P':
print(file=sys.stderr)
print('ERROR: clang-format merge driver needs git 2.5+', file=sys.stderr)
if sys.platform == 'darwin':
print('Upgrade to Xcode 7.2+', file=sys.stderr)
print(file=sys.stderr)
return 1
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 as 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())