ortogonal created this revision. ortogonal added reviewers: klimek, Alexander-Shukaev, djasper. Herald added a project: clang. Herald added a subscriber: cfe-commits. ortogonal requested review of this revision.
When running git-clang-format in a pre-commit hook it's very useful to be able to tell git-clang-format to only look at the --staged/--cached files and not the working directory. Note this patch is a rebase/fork from D41147 <https://reviews.llvm.org/D41147> which is a fork of D15465 <https://reviews.llvm.org/D15465> This is tested with: mkdir /tmp/gcfs cd /tmp/gcfs git init cat <<EOF > foo.cc int main() { int x = 1; return 0; } EOF git add foo.cc git commit -m 'first commit' rm foo.cc cat <<EOF > foo.cc int main() { int x = 1; int y = 2; int z = 3; return 0; } EOF git add foo.cc git commit -m 'second commit' sed -i -e 's/1;/10;/' foo.cc git add foo.cc sed -i -e 's/10;/1;/' foo.cc sed -i -e 's/3;/30;/' foo.cc $ git-clang-format --diff diff --git a/foo.cc b/foo.cc index cb2dbc9..2e1b0e1 100644 --- a/foo.cc +++ b/foo.cc @@ -1,6 +1,6 @@ int main() { int x = 1; int y = 2; - int z = 30; + int z = 30; return 0; } $ git-clang-format --diff --staged diff --git a/foo.cc b/foo.cc index 3ea8c6c..7da0033 100644 --- a/foo.cc +++ b/foo.cc @@ -1,5 +1,5 @@ int main() { - int x = 10; + int x = 10; int y = 2; int z = 3; return 0; $ git-clang-format --diff HEAD~ HEAD diff --git a/foo.cc b/foo.cc index 7bfdb83..ce6f65e 100644 --- a/foo.cc +++ b/foo.cc @@ -1,6 +1,6 @@ int main() { int x = 1; - int y = 2; - int z = 3; + int y = 2; + int z = 3; return 0; } Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D90996 Files: clang/tools/clang-format/git-clang-format Index: clang/tools/clang-format/git-clang-format =================================================================== --- clang/tools/clang-format/git-clang-format +++ clang/tools/clang-format/git-clang-format @@ -32,12 +32,13 @@ import subprocess import sys -usage = 'git clang-format [OPTIONS] [<commit>] [<commit>] [--] [<file>...]' +usage = ('git clang-format [OPTIONS] [<commit>] [<commit>|--staged] ' + '[--] [<file>...]') desc = ''' If zero or one commits are given, run clang-format on all lines that differ between the working directory and <commit>, which defaults to HEAD. Changes are -only applied to the working directory. +only applied to the working directory, or in the stage/index. If two commits are given (requires --diff), run clang-format on all lines in the second <commit> that differ from the first <commit>. @@ -109,6 +110,8 @@ help='select hunks interactively') p.add_argument('-q', '--quiet', action='count', default=0, help='print less information') + p.add_argument('--staged', '--cached', action='store_true', + help='format lines in the stage instead of the working dir') p.add_argument('--style', default=config.get('clangformat.style', None), help='passed to clang-format'), @@ -128,12 +131,14 @@ commits, files = interpret_args(opts.args, dash_dash, opts.commit) if len(commits) > 1: + if opts.staged: + die('--staged is not allowed when two commits are given') if not opts.diff: die('--diff is required when two commits are given') else: if len(commits) > 2: die('at most two commits allowed; %d given' % len(commits)) - changed_lines = compute_diff_and_extract_lines(commits, files) + changed_lines = compute_diff_and_extract_lines(commits, files, opts.staged) if opts.verbose >= 1: ignored_files = set(changed_lines) filter_by_extension(changed_lines, opts.extensions.lower().split(',')) @@ -268,9 +273,9 @@ return convert_string(stdout.strip()) -def compute_diff_and_extract_lines(commits, files): +def compute_diff_and_extract_lines(commits, files, staged): """Calls compute_diff() followed by extract_lines().""" - diff_process = compute_diff(commits, files) + diff_process = compute_diff(commits, files, staged) changed_lines = extract_lines(diff_process.stdout) diff_process.stdout.close() diff_process.wait() @@ -280,17 +285,20 @@ return changed_lines -def compute_diff(commits, files): +def compute_diff(commits, files, staged): """Return a subprocess object producing the diff from `commits`. The return value's `stdin` file object will produce a patch with the - differences between the working directory and the first commit if a single + differences between the working/cached directory and the first commit if a single one was specified, or the difference between both specified commits, filtered on `files` (if non-empty). Zero context lines are used in the patch.""" git_tool = 'diff-index' + extra_args = [] if len(commits) > 1: git_tool = 'diff-tree' - cmd = ['git', git_tool, '-p', '-U0'] + commits + ['--'] + elif staged: + extra_args += ['--cached'] + cmd = ['git', git_tool, '-p', '-U0'] + extra_args + commits + ['--'] cmd.extend(files) p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE) p.stdin.close()
Index: clang/tools/clang-format/git-clang-format =================================================================== --- clang/tools/clang-format/git-clang-format +++ clang/tools/clang-format/git-clang-format @@ -32,12 +32,13 @@ import subprocess import sys -usage = 'git clang-format [OPTIONS] [<commit>] [<commit>] [--] [<file>...]' +usage = ('git clang-format [OPTIONS] [<commit>] [<commit>|--staged] ' + '[--] [<file>...]') desc = ''' If zero or one commits are given, run clang-format on all lines that differ between the working directory and <commit>, which defaults to HEAD. Changes are -only applied to the working directory. +only applied to the working directory, or in the stage/index. If two commits are given (requires --diff), run clang-format on all lines in the second <commit> that differ from the first <commit>. @@ -109,6 +110,8 @@ help='select hunks interactively') p.add_argument('-q', '--quiet', action='count', default=0, help='print less information') + p.add_argument('--staged', '--cached', action='store_true', + help='format lines in the stage instead of the working dir') p.add_argument('--style', default=config.get('clangformat.style', None), help='passed to clang-format'), @@ -128,12 +131,14 @@ commits, files = interpret_args(opts.args, dash_dash, opts.commit) if len(commits) > 1: + if opts.staged: + die('--staged is not allowed when two commits are given') if not opts.diff: die('--diff is required when two commits are given') else: if len(commits) > 2: die('at most two commits allowed; %d given' % len(commits)) - changed_lines = compute_diff_and_extract_lines(commits, files) + changed_lines = compute_diff_and_extract_lines(commits, files, opts.staged) if opts.verbose >= 1: ignored_files = set(changed_lines) filter_by_extension(changed_lines, opts.extensions.lower().split(',')) @@ -268,9 +273,9 @@ return convert_string(stdout.strip()) -def compute_diff_and_extract_lines(commits, files): +def compute_diff_and_extract_lines(commits, files, staged): """Calls compute_diff() followed by extract_lines().""" - diff_process = compute_diff(commits, files) + diff_process = compute_diff(commits, files, staged) changed_lines = extract_lines(diff_process.stdout) diff_process.stdout.close() diff_process.wait() @@ -280,17 +285,20 @@ return changed_lines -def compute_diff(commits, files): +def compute_diff(commits, files, staged): """Return a subprocess object producing the diff from `commits`. The return value's `stdin` file object will produce a patch with the - differences between the working directory and the first commit if a single + differences between the working/cached directory and the first commit if a single one was specified, or the difference between both specified commits, filtered on `files` (if non-empty). Zero context lines are used in the patch.""" git_tool = 'diff-index' + extra_args = [] if len(commits) > 1: git_tool = 'diff-tree' - cmd = ['git', git_tool, '-p', '-U0'] + commits + ['--'] + elif staged: + extra_args += ['--cached'] + cmd = ['git', git_tool, '-p', '-U0'] + extra_args + commits + ['--'] cmd.extend(files) p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE) p.stdin.close()
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits