Làm thế nào để tìm ra cam kết Git đã giới thiệu một chuỗi trong bất kỳ nhánh nào?


396

Tôi muốn có thể tìm thấy một chuỗi nhất định được giới thiệu trong bất kỳ cam kết nào trong bất kỳ chi nhánh nào, làm thế nào tôi có thể làm điều đó? Tôi đã tìm thấy một cái gì đó (mà tôi đã sửa đổi cho Win32), nhưng git whatchangeddường như không nhìn vào các nhánh khác nhau (bỏ qua đoạn py3k, nó chỉ là một sửa lỗi nguồn cấp dữ liệu msys / win)

git whatchanged -- <file> | \
grep "^commit " | \
python -c "exec(\"import sys,msvcrt,os\nmsvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)\nfor l in sys.stdin: print(l.split()[1])\")" | \
xargs -i% git show origin % -- <file>

Nó không thực sự quan trọng nếu giải pháp của bạn chậm.


Câu trả lời:


685

Bạn có thể làm:

git log -S <whatever> --source --all

Để tìm tất cả các xác nhận đã thêm hoặc xóa chuỗi cố định whatever . Các --allphương tiện thông số bắt đầu từ mỗi chi nhánh và --sourcephương tiện để thể hiện mà những chi nhánh dẫn đến phát hiện rằng cam kết. Nó thường hữu ích để thêm -pvào để hiển thị các bản vá mà mỗi cam kết đó cũng sẽ giới thiệu.

Các phiên bản của git kể từ 1.7.4 cũng có một -Gtùy chọn tương tự , có biểu thức chính quy . Điều này thực sự có ngữ nghĩa khác nhau (và khá rõ ràng hơn), được giải thích trong bài đăng trên blog này từ Junio ​​Hamano .

Như thameera chỉ ra trong các bình luận, bạn cần đặt dấu ngoặc kép quanh cụm từ tìm kiếm nếu nó chứa khoảng trắng hoặc các ký tự đặc biệt khác, ví dụ:

git log -S 'hello world' --source --all
git log -S "dude, where's my car?" --source --all

Đây là một ví dụ sử dụng -G để tìm sự xuất hiện của function foo() {:

git log -G "^(\s)*function foo[(][)](\s)*{$" --source --all

19
+1 cho sự xuất sắc. Chỉ vào -S là một điều, giải thích mọi thứ, tốt hơn. Ngoài ra, tôi thích sử dụng - phân tích để xem những thứ mà nhánh đến từ
sehe

7
@sehe: Cảm ơn bình luận tốt đẹp của bạn. Tôi đoán rằng đáng chú ý là --decoratechỉ thêm tên chi nhánh vào cam kết ở đầu mỗi chi nhánh. Trong thực tế, tôi không thực sự sử dụng --sourcehoặc --decoratethay vào đó sử dụng git branch -a --contains <commit-hash>để tìm ra nhánh nào chứa cam kết mà tôi quan tâm.
Mark Longair

3
thêm -p để xem khác biệt nội tuyến, FWIW
rogerdpack

1
@MarkLongair nó không hiển thị các thay đổi được thực hiện trong hợp nhất. Bất kỳ đề nghị để hiển thị những người là tốt?
Pahlevi Fikri Auliya

2
Đối với tôi, điều này chỉ hoạt động nếu tôi loại bỏ khoảng trắng giữa -S và cụm từ tìm kiếm, nghĩa là , git log -S"dude, where's my car?" --source --all. @ribamar cũng đã viết rằng trong một câu trả lời dưới đây, nhưng nó có thể dễ dàng bị bỏ qua bên cạnh câu trả lời hàng đầu này.
lỗi13

69

--reverse cũng hữu ích vì bạn muốn cam kết đầu tiên thực hiện thay đổi:

git log --all -p --reverse --source -S 'needle'

Bằng cách này, các cam kết cũ hơn sẽ xuất hiện đầu tiên.


20

Câu trả lời của Mark Longair là tuyệt vời, nhưng tôi đã tìm thấy phiên bản đơn giản hơn này để làm việc cho tôi.

git log -S whatever

24
Chỉ cần làm rõ, điều đó hoạt động tốt nếu cam kết bạn đang tìm kiếm HEAD, nhưng câu hỏi cụ thể này được hỏi cụ thể về việc tìm kiếm trên tất cả các chi nhánh trong kho lưu trữ.
Đánh dấu Longair

18

Loay hoay với cùng một câu trả lời:

$ git config --global alias.find '!git log --color -p -S '
  • ! là cần thiết bởi vì cách khác, git không chuyển đối số chính xác cho -S. Xem phản hồi này
  • --color-p giúp hiển thị chính xác "whatchanged"

Bây giờ bạn có thể làm

$ git find <whatever>

hoặc là

$ git find <whatever> --all
$ git find <whatever> master develop

6
git log -S"string_to_search" # options like --source --reverse --all etc

Chú ý không sử dụng khoảng trắng giữa S và "string_to_search". Trong một số thiết lập (git 1.7.1), bạn sẽ gặp lỗi như:

fatal: ambiguous argument 'string_to_search': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions

2

Mặc dù điều này không trả lời trực tiếp câu hỏi của bạn, tôi nghĩ nó có thể là một giải pháp tốt cho bạn trong tương lai. Tôi thấy một phần mã của tôi, đó là xấu. Không biết ai đã viết nó hoặc khi nào. Tôi có thể thấy tất cả các thay đổi từ tệp, nhưng rõ ràng mã đã được chuyển từ một số tệp khác sang tệp này. Tôi muốn tìm người thực sự đã thêm nó ở nơi đầu tiên.

Để làm điều này, tôi đã sử dụng Git bisect , nó nhanh chóng cho tôi tìm tội nhân.

Tôi đã chạy git bisect startvà sau đó git bisect bad, vì bản sửa đổi kiểm tra có vấn đề. Vì tôi không biết khi nào sự cố xảy ra, tôi đã nhắm mục tiêu cam kết đầu tiên cho "tốt" , git bisect good <initial sha>.

Sau đó, tôi tiếp tục tìm kiếm repo cho mã xấu. Khi tôi tìm thấy nó, tôi đã chạy git bisect badvà khi nó không ở đó : git bisect good.

Trong ~ 11 bước, tôi đã bao gồm ~ 1000 cam kết và tìm thấy cam kết chính xác, nơi vấn đề được đưa ra. Khá tuyệt.


2

Không chắc chắn tại sao câu trả lời được chấp nhận không hoạt động trong môi trường của tôi, cuối cùng tôi chạy lệnh bên dưới để có được thứ tôi cần

git log --pretty=format:"%h - %an, %ar : %s"|grep "STRING"
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.