1. ホーム
  2. git

[解決済み] git logで特定のパスの変更を無視するようにする

2022-04-27 20:25:05

質問

を作るにはどうしたらいいのでしょうか? git log は、私が指定したファイル以外を変更したコミットのみを表示しますか?

git log 私は、指定されたパスの集合に触れたコミットを表示するようフィルタリングすることができます。このフィルタを反転させて、指定したパス以外のパスに触れたコミットだけを表示させたいと思います。

を使えば、望みのものが手に入ります。

git log --format="%n/%n%H" --name-only | ~/filter-log.pl | git log --stdin --no-walk

ここで filter-log.pl があります。

#!/usr/bin/perl
use strict;
use warnings;

$/ = "\n/\n";
<>;

while (<>) {
    my ($commit, @files) = split /\n/, $_;

    if (grep { $_ && $_ !~ m[^(/$|.etckeeper$|lvm/(archive|backup)/)] } @files) {
        print "$commit\n";
    }
}

ただし、それよりもいくらかエレガントなものが欲しい。

なお、私は ではなく は、そのファイルを git に無視させる方法を尋ねています。これらのファイル べきである 追跡され、コミットされます。ただ、たいていの場合、私はそれらを見ることに興味がないのです。

関連する質問 git log --grep=<pattern>` またはパターンにマッチしない git logs を表示する方法を反転させる方法 パスではなくコミットメッセージを除いては、同じ質問です。

2008年のフォーラムでの議論です。 Re: git-diff からファイルを除外する これは期待できそうでしたが、スレッドが枯渇してしまったようです。

解決方法は?

現在(git 1.9/2.0、2014年第1四半期)、導入されています。 パススペックマジック :(exclude) とその短縮形である :! コミット ef79b1f コミット 1649612 によるものです。 Nguyễn Thái Ngọc Duy ( pclouds ) ドキュメントを見ることができます。 こちら .

これで、サブフォルダの内容以外をログに残すことができるようになりました。

git log -- . ':(exclude)sub'
git log -- . ':!sub'

または、そのサブフォルダ内の特定の要素を除外することができます。

  • 特定のファイル

      git log -- . ':(exclude)sub/sub/file'
      git log -- . ':!sub/sub/file'
    
    
  • 内の任意のファイル sub :

      git log -- . ':(exclude)sub/*file'
      git log -- . ':!sub/*file'
      git log -- . ':(exclude,glob)sub/*/file'
    
    

その除外は大文字と小文字を区別しないようにすることができます!

git log -- . ':(exclude,icase)SUB'

として ケニー・エヴィット注目

を実行する場合は、シングルクォートを使用するか、ダブルクォートで適切にエスケープすることを忘れないでください。 git の中に bash シェル、例えば ':!sub' または ":\!sub" . そうでない場合は、次のようになります。 bash: ... event not found エラー


注:Git 2.13(2017年第2四半期)では、シノニムが追加されます。 ^ から !

参照 コミット 859b7f1 , コミット 42ebeb9 (2017年02月08日)によるものです。 リーナス・トーバルズ ( torvalds ) .

(によって統合されました。 ジュニオ・C・ハマノ--。 gitster -- コミット 015fba3 , 2017年2月27日)

<ブロッククオート

pathspec magic: ' を追加します。 ^ のエイリアスとして、' ! '

<ブロッククオート

の選択は、' ! は、負のパス仕様にマッチしないだけでなく リビジョンのために行うものであり、また、シェルで使うには恐ろしい文字です。 はクオートを必要とするため、展開されます。

そこで、' ^ は、パス仕様のエントリを除外するための代替エイリアスとして使用します。


なお、Git 2.28 (Q3 2020) 以前では、作業ツリーに未追跡のものを含むパスを収集しながら、負のpathspecを使用することは、壊れていました。

参照 コミット f1f061e (2020年06月05日)によるものです。 イライジャ・ニューレン( newren ) .

(によって統合されました。 ジュニオ・C・ハマノ--。 gitster -- コミット64efa11 , 2020年6月18日)

<ブロッククオート

dir : 否定されたパス仕様の扱いを修正

<上 報告者: John Millikin

サインオフ-by: イライジャ・ニューレン

<ブロッククオート

do_match_pathspec() としてスタートしました。 match_pathspec_depth_1() からしか呼び出されないことになっており、正しさのために match_pathspec_depth() . match_pathspec_depth() に改名されました。 match_pathspec() という不変量があります。 do_match_pathspec() の外側に直接の呼び出し元がない。 match_pathspec() .

残念ながら、この意図は2つの関数の名前を変更したことで失われ、さらに do_match_pathspec() は、コミット 75a6315f74 (" ls-files : add pathspec matching for submodules", 2016-10-07, Git v2.11.0-rc0 --。 マージ に掲載されています。 一括#11 ) と 89a1f4aaf7 (" dir : もし我々のpathspecがdir以下のファイルにマッチするかもしれないなら、それに再帰する", 2019-09-17, Git v2.24.0-rc0).

もちろんです。 do_match_pathspec() に対して重要なアドバンテージがありました。 match_pathspec() -- match_pathspec() はflagsを2つの値のうちの1つにハードコードしており、これらの新しい呼び出し元はflagsに他の値を渡す必要がありました。

また do_match_pathspec() を直接指定するのは間違っていましたが、観測可能な最終出力には何の違いもなかったと思われます。 fill_diretory() は不要なディレクトリに再帰してしまいます。

その後、ディレクトリ下の個々のパスに対して does-this-path-match チェックを行えば、それらの余分なパスはフィルタリングされるため、間違った関数を使用した場合と異なるのは、不必要な計算だけです。

その2つ目の悪い呼び出しは do_match_pathspec() は、直接移動するか、コピーと編集を経て、後の多くのリファクタリングに関わりました。

コミットを見る 777b420347 (" dir : 同期 treat_leading_path()read_directory_recursive() ", 2019-12-19, Git v2.25.0-rc0 --。 マージ ), 8d92fb2927 (" dir : replace exponential algorithm with linear one", 2020-04-01, Git v2.27.0-rc0 --。 マージ に記載されている バッチ5号 )、および 95c11ecc73 ("エラーが発生しやすい fill_directory() API; make it return only matches", 2020-04-01, Git v2.27.0-rc0 --。 マージ に記載されている バッチ5号 ).

このうち、最後に紹介したのは do_match_pathspec() を個々のファイルで使用するため、本来は返されないはずの個々のパスが返される結果となりました。

を呼び出した場合の問題点は do_match_pathspec() の代わりに match_pathspec() は、'`:!unwanted_path`` のような否定されたパターンが無視されることです。 .

新しい match_pathspec_with_flags() 関数は、否定されたパターンを正しくチェックしながら特別なフラグを指定するニーズを満たすために、大きなコメントを上に追加します。 do_match_pathspec() の現在の呼び出し元を修正し、他の人が誤用しないようにします。 do_match_pathspec() のどちらかを使用するようにします。 match_pathspec() または match_pathspec_with_flags() .

最後の注意点は DO_MATCH_LEADING_PATHSPEC を使用する場合は、特別な配慮が必要です。 DO_MATCH_EXCLUDE .

のポイントは DO_MATCH_LEADING_PATHSPEC のようなパス仕様がある場合

*/Makefile

のようなディレクトリパスをチェックしています。

src/module/component

というのは、そのディレクトリに再帰的に移動するために、マッチしたと見なしたいからです。 _might という名前のファイルを持っています。 Makefile を下のどこかに書いてください。

しかし、除外パターンを使っている場合、つまり、以下のようなpathspecがある場合は、除外パターンを使っていることになります。

:(exclude)*/Makefile

のようなディレクトリパスがある場合、このようなことは言いたくありません。

src/module/component

は(負の)マッチです。

がある一方で かもしれない そのディレクトリの下のどこかに 'Makefile' という名前のファイルがあるかもしれませんが、他のファイルもある可能性があります。

を調整します。 DO_MATCH_LEADING_PATHSPEC ロジックは、正のパススペックに対してのみアクティブになるようにします。