Làm thế nào để grep khác biệt git?


81

Có cách nào để hiển thị git-diff được lọc theo một mẫu nhất định không.

Cái gì đó như

git grepdiff pattern

changed file
+++ some sentence with pattern
changed file 2
--- some other pattern

Thật không may, giải pháp đơn giản nhất không đủ tốt

git diff | grep pattern 

+++ some sentence with pattern
--- some other pattern
# not an option as doesn't put the filename close to the match

Tôi đến với một giải pháp thay thế bằng awk

git diff | awk "/\+\+\+/{f = \$2}; /PATTERN/ {print f \$0} "

Nhưng rất muốn biết rằng có một lệnh cho việc này.


3
Rõ ràng dự án github có tên git-diff-grep thực hiện một điều hoàn toàn khác.
Kuba

Câu trả lời:


98

Không chắc chắn nhưng không git diff -G <regex>gắn cờ OK?

-G <regex>

Look for differences whose added or removed line matches the given <regex>.

15
rằng không phải chính xác những gì tôi đang tìm kiếm, như tôi muốn nhìn thấy chỉ có đường nét, phù hợp với mô hình - không phải là toàn bộ diff của một tác phẩm, bao gồm sự thay đổi với các mô hình
Kuba

sau đó tôi đoán có giải pháp không đơn giản như bạn
CharlesB

Ít nhất git diff -G là bước đầu tiên tốt hơn so với git diff đầy đủ.
Kuba

1
Phiên bản của tôi không có cờ -G. Nó đã bị loại bỏ?
RedX

3
Cũng hữu ích để xem những tệp nào bị ảnh hưởng bởi regex:git diff -G <regex> --raw
Raman


11

Một khả năng khác là xem toàn bộ sự khác biệt và tìm kiếm đầu ra bằng các lesslệnh bình thường (nhập /và sau đó là mẫu).

Khi bạn đã lesscấu hình để hiển thị một số dòng trước trận đấu bằng cách sử dụng --jump-target=N, điều này khá hữu ích. Hãy thử nó như thế này:

PAGER="/usr/bin/less --jump-target=10" git diff

Điều này có nghĩa là kết quả khớp phải được hiển thị trên dòng 10 (hiển thị 9 dòng ngữ cảnh ở trên), điều này có thể đủ để xem tên tệp.

Bạn cũng có thể sử dụng ví dụ --jump-target=.5để đặt khớp ở giữa màn hình.


3

Tôi sử dụng git log -p, mở ít hơn (mặc dù có thể định cấu hình), do đó có thể được tìm kiếm với /. Còn git log -S <searchword>nữa.


Tôi quen thuộc với những điều đó - bởi tôi không nhìn vào lịch sử, mà là những thay đổi trong công việc hiện tại.
Kuba

Được rồi, sau đó có thể sử dụng cùng một phương pháp (như robinst đã trích dẫn). Nếu bạn muốn đầu ra, bạn có thể sử dụng bất kỳ thư viện nào bằng libgit2 hoặc gitgui / gitk.
chelmertz

1

Điều này đã làm công việc cho tôi, tôi hy vọng nó sẽ giúp ai đó:

git diff | grep  -P '^\+|^\-'

1

Tôi nghĩ rằng cách tiếp cận của bạn đối với diffđầu ra "grep" là giải pháp tốt nhất.

Bạn có thể cải thiện tập lệnh awk của mình bằng cách sử dụng sed:

colored="(^[\[[0-9;]*[a-zA-Z])"
marker="^$colored+diff"
pattern="^$colored+.*(\+|\-).*PATTERN"
git diff --color | sed -rn -e "/$marker/! H; /$marker/ ba; $ ba; b; :a; x; /$pattern/ p"
  • colored: regex để khớp với các đường màu đầu cuối
  • marker: điểm đánh dấu để khớp sự phân chia từ các khối khác nhau diff, các đường bắt đầu bằng "diff" được tô màu
  • pattern: mẫu cần tìm kiếm, các dòng bắt đầu bằng màu "+" hoặc "-" và chứa "MẪU"

Thao tác này sẽ in các phần khác nhau đầy đủ, với MẪU được thêm hoặc bớt, cũng duy trì đầu ra màu hữu ích.

Lưu ý rằng ^[trong coloredphải là thực tế, theo nghĩa đen ^[. Bạn có thể nhập chúng trong bash bằng cách nhấn Ctrl+ V, Ctrl+[


thông minh!! cho bất cứ ai cố gắng để kiểu này ở một nơi nào khác hơn là một vỏ bash (ví dụ như chỉnh sửa sh tập tin trong IDE), bạn cần phải thay thế ^[như colored=$'(\e\[[0-9;]*[a-zA-Z])'và trên hệ điều hành MacOS bạn cũng cần phải brew install gnu-sedvà thay thếsed --> gsed
Anentropic

0

Đây là một công cụ khác biệt tùy chỉnh cho phép chuyển đổi các thay đổi bên trong (nhưng không phải ngữ cảnh):

Sử dụng

GIT_EXTERNAL_DIFF="mydiff --grep foo" git diff

Thao tác này sẽ xuất ra các dòng chứa các thay đổi của bạn foo(bao gồm các dòng đã foobiến mất do các thay đổi của bạn). Có thể sử dụng bất kỳ mẫu grep nào để thay thế foo.

Mỗi dòng đầu ra bắt đầu bằng tiền tố sau:

filename: oldlinenum: newlinenum|

Tập lệnh cũng có thể được sử dụng mà không có --greptùy chọn, trong trường hợp đó, nó chỉ đơn giản là định dạng sự khác biệt đầy đủ (tức là cung cấp ngữ cảnh đầy đủ) như được mô tả ở trên.

mydiff

#!/bin/bash

my_diff()
{
    diff --old-line-format="$1"':%6dn:      |-%L'     \
         --new-line-format="$1"':      :%6dn|+%L'     \
         --unchanged-line-format="$1"':%6dn:%6dn| %L' \
         $2 $3
}

if [[ $1 == '--grep' ]]
then
    pattern="$2"
    shift 2
    my_diff "$1" "$2" "$5"|grep --color=never '^[^|]\+|[-+].\+'"$pattern"'.*'
else
    my_diff "$1" "$2" "$5"
fi

exit 0

0

Trên Windows, một giải pháp đơn giản là:

git diff -U0 | findstr string

Nếu bạn muốn nhóm theo tên tệp, hãy sử dụng

FOR /F "usebackq delims==" %i IN (`git diff --name-only`) do git diff -U0 %~fi | findstr string

0

Tôi đã sử dụng cái này với sự hài lòng tuyệt vời :)

grep -ri <MY_PATTERN> $(git diff 790e26393d --name-only) 
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.