87

clang-formatファイルが指定された形式を満たしているかどうかを報告するモードで実行できる方法はありますか? 変更が必要かどうかを報告するが、変更を行わない一種の予行演習モード。理想的には、ファイルに変更が必要な場合に、clang-format がゼロ以外の終了コードを返すようにしたいと考えています。または、さらに理想的には、ゼロ以外の終了コードと、変更が必要なファイルのリストが標準出力に表示されます。

より多くの人が回答できるように、質問を一般的なものにしようとしていますが、私がやろうとしているのは、予想される .clang-format に一致しないコミットを拒否する git pre-commit フックを作成することです。インデックス内のファイルのリストに対して clang-format を実行するのは簡単です。しかし、clang-format が実際に何かを変更したかどうかを知ることは困難です。

(回答として投稿する)に基づく潜在的な解決策が1つ-output-replacements-xmlありますが、それはハックであり、これはもっと簡単であるべきだと思います。コメント/提案、編集、さまざまな回答/アプローチはすべて大歓迎です。

4

9 に答える 9

48

-output-replacements-xml は本質的に私が望む答えを私に与えるので、これはそれよりも簡単であるべきだと私が感じる理由の1つです。ただし、置換が不要な場合の出力は非常に予測可能であるため、出力の解析はそれほど難しくありません。

私が今持っているのは

clang-format -style=file -output-replacements-xml | grep -c "<replacement " >/dev/null

grep は、何かが一致する場合は 0 を返し、何も一致しない場合は 1 を返すため、これは実際には必要な終了コードの逆を返します。しかし、それは対処するのに十分簡単です。

したがって、私の git pre-commit フックの関連ビットは次のようになります

git diff --cached --name-only --diff-filter=ACMRT |
  grep "\.[cmh]$" |
  xargs -n1 clang-format -style=file -output-replacements-xml |
  grep "<replacement " >/dev/null
if [ $? -ne 1 ]; then 
    echo "Commit did not match clang-format"
    exit 1
fi
  1. インデックス内のファイルの完全なファイル名を取得します (削除されているファイルや、ファイルを処理したくないその他の異常なケースを除く)
  2. フォーマットを確認したいもののファイル名のみを保持します(私の場合はc、m、およびhファイルのみ)
  3. xargs を介して結果を実行し、次のコマンドを基本的に「それぞれに」実行します
  4. すべてのファイルで -output-replacements-xml オプションを指定して clang-format を実行します。
  5. clang-format が作成したい置換を見つけたことを示す (置換ではなく) 置換を検索します。(すべての出力を XML として破棄しても、ユーザーにとって意味がありません。)
  6. 最後のコマンドは 1 を終了します (grep は、何も見つからなかったと言います) これで問題はありません。
  7. そうでない場合は、メッセージを表示して 1 を終了します。これにより、コミットがキャンセルされます。残念ながら、どのファイルが問題であるかをユーザーに伝える簡単な方法はありませんが、clang-format を自分で実行して確認することはできます。
于 2014-04-04T15:13:45.067 に答える
1

git-clang-formatMike Rhodes のブログの pre-commit スクリプトを使用します。

#!/bin/python

import subprocess
output = subprocess.check_output(["git", "clang-format", "--diff"])

if output not in ['no modified files to format\n', 'clang-format did not modify any files\n']:
    print "Run git clang-format, then commit.\n"
    exit(1)
else:
    exit(0)

スクリプトには、コミットがない場合は機能しないという小さなエラーがあります (まだ存在しない HEAD に対してチェックしようとしています)。これを回避するには、-nまたは--no-verifyオプションを使用します。

プリコミット スクリプトをスキップするために使用-nすると、コードベースが大きいと時間がかかる可能性があるため、チェックをバイパスするときにも役立ちます。

元の投稿はこちら: http://www.dx13.co.uk/articles/2015/4/3/Setting-up-git-clang-format.html

于 2016-10-06T20:24:33.037 に答える