Lines Matching +full:commit +full:- +full:message
3 #===- git-clang-format - ClangFormat Git Integration ---------*- python -*--===#
10 #===------------------------------------------------------------------------===#
13 clang-format git integration
16 This file provides a clang-format integration for git. Put it somewhere in your
17 path and ensure that it is executable. Then, "git clang-format" will invoke
18 clang-format on the changes in current files or a specific commit.
21 git clang-format -h
35 usage = 'git clang-format [OPTIONS] [<commit>] [--] [<file>...]'
38 Run clang-format on all lines that differ between the working directory
39 and <commit>, which defaults to HEAD. Changes are only applied to the working
42 The following git-config settings set the default of the corresponding option:
44 clangFormat.commit
49 # Name of the temporary index file in which save the output of clang-format.
51 temp_index_basename = 'clang-format-index'
60 # In order to keep '--' yet allow options after positionals, we need to
61 # check for '--' ourselves. (Setting nargs='*' throws away the '--', while
65 idx = argv.index('--')
78 # Other languages that clang-format supports
86 p.add_argument('--binary',
87 default=config.get('clangformat.binary', 'clang-format'),
88 help='path to clang-format'),
89 p.add_argument('--commit',
90 default=config.get('clangformat.commit', 'HEAD'),
91 help='default commit to use if none is specified'),
92 p.add_argument('--diff', action='store_true',
94 p.add_argument('--extensions',
97 help=('comma-separated list of file extensions to format, '
98 'excluding the period and case-insensitive')),
99 p.add_argument('-f', '--force', action='store_true',
101 p.add_argument('-p', '--patch', action='store_true',
103 p.add_argument('-q', '--quiet', action='count', default=0,
105 p.add_argument('--style',
107 help='passed to clang-format'),
108 p.add_argument('-v', '--verbose', action='count', default=0,
111 # to use some heuristics to determine whether or not <commit> was present.
113 p.add_argument('args', nargs='*', metavar='<commit>',
119 opts.verbose -= opts.quiet
122 commit, files = interpret_args(opts.args, dash_dash, opts.commit)
123 changed_lines = compute_diff_and_extract_lines(commit, files)
134 print 'Running clang-format on the following files:'
152 print 'clang-format did not modify any files'
168 is a dictionary mapping option name (in lower case) to either "--bool" or
169 "--int"."""
173 for entry in run('git', 'config', '--list', '--null').split('\0'):
183 """Interpret `args` as "[commit] [--] [files...]" and return (commit, files).
185 It is assumed that "--" and everything that follows has been removed from
188 If "--" is present (i.e., `dash_dash` is non-empty), the argument to its
189 left (if present) is taken as commit. Otherwise, the first argument is
190 checked if it is a commit or a file. If commit is not given,
194 commit = default_commit
196 die('at most one commit allowed; %d given' % len(args))
198 commit = args[0]
199 object_type = get_object_type(commit)
200 if object_type not in ('commit', 'tag'):
202 die("'%s' is not a commit" % commit)
204 die("'%s' is a %s, but a commit was expected" % (commit, object_type))
208 commit = args[0]
211 commit = default_commit
214 commit = default_commit
216 return commit, files
221 # If `value` is ambiguous (neither a commit nor a file), the following
222 # command will die with an appropriate error message.
223 run('git', 'rev-parse', value, verbose=False)
227 if object_type in ('commit', 'tag'):
229 die('`%s` is a %s, but a commit or filename was expected' %
236 cmd = ['git', 'cat-file', '-t', value]
244 def compute_diff_and_extract_lines(commit, files): argument
246 diff_process = compute_diff(commit, files)
256 def compute_diff(commit, files): argument
257 """Return a subprocess object producing the diff from `commit`.
260 differences between the working directory and `commit`, filtered on `files`
261 (if non-empty). Zero context lines are used in the patch."""
262 cmd = ['git', 'diff-index', '-p', '-U0', commit, '--']
275 The input must have been produced with ``-U0``, meaning unidiff format with
283 match = re.search(r'^@@ -[0-9,]+ \+(\d+)(,(\d+))?', line)
308 toplevel = run('git', 'rev-parse', '--show-toplevel')
315 Returns the object ID (SHA-1) of the created tree."""
316 return create_tree(filenames, '--stdin')
319 def run_clang_format_and_save_to_tree(changed_lines, binary='clang-format',
321 """Run clang-format on each file and save the result to a git tree.
323 Returns the object ID (SHA-1) of the created tree."""
330 return create_tree(index_info_generator(), '--index-info')
336 If mode is '--stdin', it must be a list of filenames. If mode is
337 '--index-info' is must be a list of values suitable for "git update-index
338 --index-info", such as "<mode> <SP> <sha1> <TAB> <filename>". Any other mode
340 assert mode in ('--stdin', '--index-info')
341 cmd = ['git', 'update-index', '--add', '-z', mode]
349 tree_id = run('git', 'write-tree')
353 def clang_format_to_blob(filename, line_ranges, binary='clang-format',
355 """Run clang-format on the given file and save the result to a git blob.
357 Returns the object ID (SHA-1) of the created blob."""
360 clang_format_cmd.extend(['-style='+style])
362 '-lines=%s:%s' % (start_line, start_line+line_count-1)
373 hash_object_cmd = ['git', 'hash-object', '-w', '--path='+filename, '--stdin']
407 gitdir = run('git', 'rev-parse', '--git-dir')
410 tree = '--empty'
411 run('git', 'read-tree', '--index-output='+path, tree)
417 # We use the porcelain 'diff' and not plumbing 'diff-tree' because the output
420 subprocess.check_call(['git', 'diff', old_tree, new_tree, '--'])
427 `patch_mode`, runs `git checkout --patch` to select hunks interactively."""
428 changed_files = run('git', 'diff-tree', '-r', '-z', '--name-only', old_tree,
431 unstaged_files = run('git', 'diff-files', '--name-status', *changed_files)
436 print >>sys.stderr, 'Please commit, stage, or stash them first.'
441 # message saying "Discard ... from worktree". Instead, we use the old
443 # better message, "Apply ... to index and worktree". This is not quite
446 subprocess.check_call(['git', 'checkout', '--patch', new_tree])
450 run('git', 'checkout-index', '-a', '-f')
478 def die(message): argument
479 print >>sys.stderr, 'error:', message