Git

僅顯示基於正則表達式的差異/更新檔的相關大塊

  • November 10, 2019

git log -G<regex> -p是搜尋程式碼庫歷史以查找與指定模式匹配的更改的絕佳工具。然而,在大多數不相關的大塊海洋中找到差異/更新檔輸出中的相關大塊可能會讓人不知所措。

當然可以搜尋git log原始字元串/正則表達式的輸出,但這並不能減少視覺噪音和許多不相關更改的干擾。

繼續閱讀git log,我看到有--pickaxe-all,這與我想要的完全相反:它擴大了輸出(到整個變更集),而我想限制它(到特定的大塊)。

本質上,我正在尋找一種方法來“智能”地將差異/更新檔解析為單獨的塊,然後對每個塊執行搜尋(僅針對更改的行),丟棄不匹配的塊,並輸出那些塊這樣做。

我描述的工具是否存在?有沒有更好的方法來獲得匹配/受影響的帥哥?

我做過的一些初步研究…

  • 如果可以grep通過 diff/patch 輸出並使上下文選項值動態化(例如,通過正則表達式而不是行數),那可能就足夠了。但grep並非完全以這種方式建構(我也不一定要求該功能)。
  • 我找到了patchutils套件,最初聽起來它可能適合我的需要。但是在閱讀了它的man頁面之後,這些工具似乎並沒有處理基於正則表達式的匹配塊。(他們可以接受一個帥哥列表,不過……)
  • 我終於遇到了splitpatch.rb,它似乎可以很好地處理更新檔的解析,但是需要顯著增強它來處理通過讀取更新檔stdin,匹配所需的大塊,然後輸出大塊。

這裡https://stackoverflow.com/a/35434714/5305907描述了一種方法來做你正在尋找的東西。有效地:

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

它僅顯示與給定字元串“console”匹配的帥哥。

在@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"
  1. 呼叫git log -G並告訴 Git 將該pickaxe-diff腳本用作外部差異驅動程序:
export GREPDIFF_REGEX=<string>; 
GIT_EXTERNAL_DIFF=pickaxe-diff git log -p --ext-diff -G $GREPDIFF_REGEX

這將使用 pickaxe-diff 腳本來生成差異,因此git log輸出的其餘部分(送出雜湊、消息等)將保持不變。

警告

Git 鎬的工作方式是將輸出限制為那些大塊更改給定字元串/正則表達式的*文件。*這意味著如果這些文件中的另一個塊也包含搜尋字元串/正則表達式,但不更改它,它仍將與上述腳本一起顯示。這是 grepdiff 的限制。在 patchutils 項目中有一個開放的拉取請求,--only-matching向 grepdiff 添加一個標誌,這將提供正確過濾掉這些大塊所需的功能。


我在這個 gist中寫了我的解決方案。

引用自:https://unix.stackexchange.com/questions/216066