Skip to content

Commit ae4097b

Browse files
[clang-format] Add "three dot" diff option to git-clang-format
This patch adds in the ability to do a "three dot" git-clang-format between two commits. This looks at the diff between the second commit and the common merge base rather than comparing at the point of the specified commits. This is needed to improve the reliability of the LLVM code formatting CI action which currently breaks in some cases where files have been modified in the upstream tree and when the person created their branch, leaving phantom formatting diffs that weren't touched by the PR author. Part of a fix for llvm#73873
1 parent e315bf2 commit ae4097b

File tree

1 file changed

+15
-4
lines changed

1 file changed

+15
-4
lines changed

clang/tools/clang-format/git-clang-format

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,10 @@ def main():
132132
help='passed to clang-format'),
133133
p.add_argument('-v', '--verbose', action='count', default=0,
134134
help='print extra information')
135+
p.add_argument('--diff_from_common_commit', action='store_true',
136+
help=('diff from the last common commit for commits in '
137+
'separate branches rather than the exact point of the '
138+
'commits'))
135139
# We gather all the remaining positional arguments into 'args' since we need
136140
# to use some heuristics to determine whether or not <commit> was present.
137141
# However, to print pretty messages, we make use of metavar and help.
@@ -154,7 +158,10 @@ def main():
154158
if len(commits) > 2:
155159
die('at most two commits allowed; %d given' % len(commits))
156160
opts.binary=os.path.abspath(opts.binary)
157-
changed_lines = compute_diff_and_extract_lines(commits, files, opts.staged)
161+
changed_lines = compute_diff_and_extract_lines(commits,
162+
files,
163+
opts.staged,
164+
opts.diff_from_common_commit)
158165
if opts.verbose >= 1:
159166
ignored_files = set(changed_lines)
160167
filter_by_extension(changed_lines, opts.extensions.lower().split(','))
@@ -302,9 +309,9 @@ def get_object_type(value):
302309
return convert_string(stdout.strip())
303310

304311

305-
def compute_diff_and_extract_lines(commits, files, staged):
312+
def compute_diff_and_extract_lines(commits, files, staged, diff_common_commit):
306313
"""Calls compute_diff() followed by extract_lines()."""
307-
diff_process = compute_diff(commits, files, staged)
314+
diff_process = compute_diff(commits, files, staged, diff_common_commit)
308315
changed_lines = extract_lines(diff_process.stdout)
309316
diff_process.stdout.close()
310317
diff_process.wait()
@@ -314,7 +321,7 @@ def compute_diff_and_extract_lines(commits, files, staged):
314321
return changed_lines
315322

316323

317-
def compute_diff(commits, files, staged):
324+
def compute_diff(commits, files, staged, diff_common_commit):
318325
"""Return a subprocess object producing the diff from `commits`.
319326
320327
The return value's `stdin` file object will produce a patch with the
@@ -328,6 +335,10 @@ def compute_diff(commits, files, staged):
328335
git_tool = 'diff-tree'
329336
elif staged:
330337
extra_args += ['--cached']
338+
339+
if len(commits) > 1 and diff_common_commit:
340+
commits = [f'{commits[0]}...{commits[1]}']
341+
331342
cmd = ['git', git_tool, '-p', '-U0'] + extra_args + commits + ['--']
332343
cmd.extend(files)
333344
p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)

0 commit comments

Comments
 (0)