正規表現ベースの違い/パッチに関連ブロックのみを表示する

正規表現ベースの違い/パッチに関連ブロックのみを表示する

git log -G<regex> -p指定されたパターンに一致する変更のコードベースの履歴を取得するための素晴らしいツールです。しかし、ほとんど関係のないチャンクの海でdiff / patch出力で関連チャンクを見つけることは圧倒的かもしれません。

生の文字列/正規表現の出力を取得することは確かに可能ですgit logが、無関係な多くの変更による視覚的なノイズと干渉を減らすのにはほとんど役立ちません。

を読んで、私が望むものと正反対の人がgit logいることがわかりました。出力を(フルチェンジセットに)拡張しますが、私はそれを(特定のチャンクに)制限したいと思います。--pickaxe-all

本質的に、私はdiff / patchを別のチャンクに「インテリジェントに」解析し、各チャンクに対して検索を実行し(変更された行のみ)、一致しないチャンクを削除し、次のチャンクを出力する方法を探しますあります。それが。

私が説明するツールがありますか?一致または影響を受けたイケメンを得るためのより良い方法はありますか?

私がした事前調査は..

  • grep出力を比較/パッチし、コンテキストオプション値を動的に作成できる場合(たとえば、行数ではなく正規表現を介して)十分です。しかし、grepそれはまさにそのように構築されたものではありません(必須ではありません)。

  • 見つけました。パッチツールKitは最初は私のニーズに合ったようです。ただし、そのページを読んだ後、manこれらのツールは正規表現ベースの一致ブロックを処理できないようです。 (しかしハンサムな男のリストは受け入れられますが…)

  • ついに会いました分割 patch.rbstdinパッチの解析をうまく処理しているようですが、パッチを読み、必要なチャンクを一致させ、チャンクを出力して解析を処理するには大幅に改善する必要があります。

答え1

ここhttps://stackoverflow.com/a/35434714/5305907探しているタスクを実行する方法について説明します。効果的に:

git diff -U1 | grepdiff 'console' --output-matching=hunk

指定された文字列 "console"に一致する友達のみを表示します。

答え2

上記の@naguの回答と他のリンクからの回答に基づいて、関連しているgit log -G友達だけを表示することができました。

  1. 次の内容を含む$PATHのどこかにスクリプトを生成することから始めます。

    #!/bin/bash
    
    # pickaxe-diff : external diff driver for Git.
    #                To be used with the pickaxe options (git [log|show|diff[.*] [-S|-G])
    #                to only show hunks containing the searched string/regex.
    
    path=$1
    old_file=$2
    old_hex=$3
    old_mode=$4
    new_file=$5
    new_hex=$6
    new_mode=$7
    
    filtered_diff=$(diff -u -p $old_file $new_file | \
                    grepdiff "$GREPDIFF_REGEX" --output-matching=hunk | \
                    grep -v -e '+++ ' -e '--- ')
    
    a_path="a/$path"
    b_path="b/$path"
    
    echo "diff --git $a_path $b_path"
    echo "index $old_hex..$new_hex $old_mode"
    echo "--- $a_path"
    echo "+++ $b_path"
    echo "$filtered_diff"
    
  2. Gitを呼び出して、スクリプトを外部diffドライバとしてgit log -G使用するように指示します。pickaxe-diff

    export GREPDIFF_REGEX=<string>; 
    GIT_EXTERNAL_DIFF=pickaxe-diff git log -p --ext-diff -G $GREPDIFF_REGEX
    

    これはpickaxe-diffスクリプトを使用してdiffを生成するため、git log残りの出力(コミットハッシュ、メッセージなど)は変更されていません。

警告する
Gitのツルが動作する方法は、出力を次に制限することです。文書誰が友達が与えられた文字列/正規表現を変更しますか?これは、そのファイルの他のブロックにも検索文字列/正規表現が含まれていますが、それを変更しないと、まだ上記のスクリプトで表示されます。これはgrepdiffの制限です。 patchutilsプロジェクトには、--only-matchingこれらのチャンクを適切にフィルタリングするために必要な機能を提供するフラグをgrepdiffに追加するための公開プール要求があります。


私は私の解決策を書いたこの点

答え3

正確に要求されたものではありませんが、grepを実行する1つの方法はインタラクティブにパターンを追加することです。これを行うには、興味のあるパッチの後にコミットを確認する必要があります。

git checkout COMMIT_ID

その後、VCS で 1 つのステップに戻りますが、作業ディレクトリには戻りません。

git reset --soft HEAD^

(この時点でのインデックスと作業ディレクトリの違いは、関心のあるパッチに対応します。)

これで実行できます。これにより、一部の行が正規表現に一致するブロックを見つけるためのオプションを含むgit add -p対話型セッションが開始されます。/これは、パッチをさらに処理したい場合(例えば、部分的なチェリーの収穫の準備など)に特に便利です。

残念ながら、少なくともこの/コマンドはadd -p単一のファイルでのみ機能するため、関連していないいくつかのファイルをスキップする必要があるかもしれません。

関連情報