web-dev-qa-db-ja.com

gitdiffにコメントを無視させる方法

特定のコミットで変更されたファイルのリストを作成しようとしています。問題は、すべてのファイルのコメントにバージョン番号が含まれていることです。このコミットにより新しいバージョンが導入されるため、すべてのファイルが変更されました

変更されたコメントは気にしないので、これらはすべてコメント(/ * * /の一部)であるため、gitdiffに^\s*\*.*$に一致するすべての行を無視させたいと思います。

特定の行を無視するようにgitdiffに指示する方法が見つかりません。

私はすでにtextconv属性を設定して、ファイルをdiffする前にgitがファイルをsedに渡すようにしようとしました。これにより、sedは問題のある行を取り除くことができます。これに関する問題は、git diff--name-statusが実際にはdiffしないことです。ファイルは、ハッシュを比較するだけで、もちろんすべてのハッシュが変更されています。

これを行う方法はありますか?

25
Benubird
git diff -G <regex>

また、バージョン番号の行と一致しない正規表現を指定してください。

7
riezebosch

これが私にとってうまく機能している解決策です。 git (log|diff) -G<regex>オプションに関するソリューションといくつかの追加の不足しているドキュメントを作成しました。

基本的に上記と同じソリューションを使用しますが、特に*または#で始まるコメント、場合によっては*の前のスペースを使用します...ただし、#ifdef#includeなどの変更を許可する必要があります。

先を見越して後ろを振り返るのは-Gオプションではサポートされていないようで、?は一般的にサポートされておらず、*の使用にも問題があります。ただし、+はうまく機能しているようです。

(注、Git v2.7.0でテスト済み)

複数行コメントバージョン

git diff -w -G'(^[^\*# /])|(^#\w)|(^\s+[^\*#/])'
  • -w空白を無視する
  • -Gは、次の正規表現に一致する差分行のみを表示します
  • (^[^\*# /])スター、ハッシュ、またはスペースで始まらない行
  • (^#\w)#で始まり、その後に文字が続く行
  • (^\s+[^\*#/])空白で始まり、その後にコメント文字が続く行

基本的に、svnフックは現在すべてのファイルを変更し、すべてのファイルの複数行コメントブロックを変更します。これで、svnがコメントにドロップするfyi情報なしで、svnに対して変更を比較できます。

技術的には、これによりpythonおよび#TODOのようなbashコメントをdiffに表示でき、除算演算子がc ++の改行で開始された場合は無視できます。

a = b
    / c;

また、gitの-Gに関するドキュメントがかなり不足しているように見えたので、ここの情報が役立つはずです:

git diff -G<regex>

-G<regex>

パッチテキストに<regex>に一致する追加/削除された行が含まれている違いを探します。

-S<regex> --pickaxe-regex-G<regex>の違いを説明するために、
同じファイル内で次のdiffを使用したコミットを検討してください。

+    return !regexec(regexp, two->ptr, 1, &regmatch, 0);
...
-    hit = !regexec(regexp, mf2.ptr, 1, &regmatch, 0);

git log -G"regexec\(regexp"はこのコミットを表示しますが、
git log -S"regexec\(regexp" --pickaxe-regexはしません
(その文字列の出現回数は変更されなかったため)。

詳細については、 gitdiffcore(7)pickaxeエントリを参照してください。

(注、Git v2.7.0でテスト済み)

  • -Gは基本的な正規表現を使用します。
  • ?*!{}regex構文はサポートされていません。
  • ()およびOR-ingグループを使用したグループ化は、|で機能します。
  • \s\Wなどのワイルドカード文字がサポートされています。
  • 先読みと後読みはサポートされていません
  • 開始行と終了行のアンカーは^$動作します。
  • この機能はGit1.7.4から利用できます。

除外されたファイルv除外された差分

-Gオプションは、差分されるファイルをフィルタリングすることに注意してください。

ただし、ファイルが「差分」されると、以前に「除外/含まれた」行がすべて差分に表示されます。

fooに言及している少なくとも1行のファイルの違いのみを表示します。

git diff -G'foo'

#で始まる行を除くすべてのファイルの違いを表示する

git diff -G'^[^#]'

FIXMEまたはTODOに言及している違いのあるファイルを表示する

git diff -G`(FIXME)|(TODO)`

git log -Ggit grepgit log -S--pickaxe-regex--pickaxe-allも参照してください。

更新:-Gオプションで使用されている正規表現ツールはどれですか?

https://github.com/git/git/search?utf8=%E2%9C%93&q=regcomp&type=

https://github.com/git/git/blob/master/diffcore-pickaxe.c

if (opts & (DIFF_PICKAXE_REGEX | DIFF_PICKAXE_KIND_G)) {
    int cflags = REG_EXTENDED | REG_NEWLINE;
    if (DIFF_OPT_TST(o, PICKAXE_IGNORE_CASE))
        cflags |= REG_ICASE;
    regcomp_or_die(&regex, needle, cflags);
    regexp = &regex;

// and in the regcom_or_die function
regcomp(regex, needle, cflags);

http://man7.org/linux/man-pages/man3/regexec.3.html

   REG_EXTENDED
          Use POSIX Extended Regular Expression syntax when interpreting
          regex.  If not set, POSIX Basic Regular Expression syntax is
          used.

//.。

   REG_NEWLINE
          Match-any-character operators don't match a newline.

          A nonmatching list ([^...])  not containing a newline does not
          match a newline.

          Match-beginning-of-line operator (^) matches the empty string
          immediately after a newline, regardless of whether eflags, the
          execution flags of regexec(), contains REG_NOTBOL.

          Match-end-of-line operator ($) matches the empty string
          immediately before a newline, regardless of whether eflags
          contains REG_NOTEOL.

それが皆を助けることを願っています。

15
phyatt

git difftoolを使用して外部差分を起動するのが最も簡単であることがわかりました。

git difftool -y -x "diff -I '<regex>'"
8
richvdh

解決策を見つけました。このコマンドを使用できます:

git diff --numstat --minimal <commit> <commit> | sed '/^[1-]\s\+[1-]\s\+.*/d'

コミット間で複数行が変更されたファイルを表示します。これにより、コメントのバージョン番号のみが変更されたファイルが削除されます。

3
Benubird

「gitdiff」出力で「grep」を使用:

git diff -w | grep -c -E "(^[+-]\s*(\/)?\*)|(^[+-]\s*\/\/)"

コメント行の変更のみを計算できます。 (A)

'git diff --stat'出力を使用:

git diff -w --stat

すべてのライン変更を計算できます。 (B)

コメント以外のソース行の変更(NCSL)カウントを取得するには、(B)から(A)を引きます。

説明: 'git diff'出力(空白の変更は無視されます)では、

  • '+'または '-'で始まる行を探します。これは、変更された行を意味します。
  • これに続いて、オプションの空白文字を含めることができます。 '\ s *'
  • 次に、コメント行パターン '/ *'(または)だけ '*'(または) '//'を探します。
  • '-c'オプションはgrepで指定されているため、カウントを出力するだけです。 '-c'オプションを削除して、diffにコメントのみを表示します。

注:以下の仮定により、コメント行数に軽微なエラーが発生する可能性があり、その結果を球場の数値と見なす必要があります。

  • 1.)ソースファイルはC言語に基づいています。 Makefile、シェルスクリプトファイルには、コメント行を示すために異なる規則「#」があり、それらがdiffsetの一部である場合、コメント行はカウントされません。

  • 2.)行変更のGIT規則:行が変更された場合、GITはその特定の行が削除され、そこに新しい行が挿入されたと見なし、実際には1行が変更されているのに対し、2行が変更されたように見える場合があります。

    以下の例では、「FOO」の新しい定義は2行の変更のように見えます。

    $ git diff --stat -w abc.h
    .。
    -#defineFOO 7
    +#define FOO 105
    .。
    1つのファイルが変更され、1つの挿入(+)、1つの削除(-)
    $

  • 3.)パターンに一致しない有効なコメント行(または)パターンに一致する有効なソースコード行は、計算でエラーを引き起こす可能性があります。

    以下の例では、「*」で始まらない「+ blahblah」行はコメント行として検出されません。

           + /*   
           +  blah blah  
           + *   
           + */
    

    以下の例では、「+ * ptr」行は、有効なソースコード行ですが、*で始まるコメント行としてカウントされます。

            + printf("\n %p",  
            +         *ptr);  
    

おそらくこのようなbashスクリプト(コードをテストしていません。動作させることができるかどうか教えてください)

#!/bin/bash
git diff --name-only "$@" | while read FPATH ; do
    LINES_COUNT=`git diff --textconv "$FPATH" "$@" | sed '/^[1-]\s\+[1-]\s\+.*/d' | wc -l`
    if [ $LINES_COUNT -gt 0 ] ; then
        echo -e "$LINES_COUNT\t$FPATH"
    fi
done | sort -n
0
saeedgnu