Някога в миналото съм изтривал файл или някакъв код в него. Мога ли да използвам grep в съдържанието (а не в съобщенията за извършени операции)?
Много лошо решение е да използвате grep в дневника:
git log -p | grep <pattern>
Това обаче не връща веднага хеша на извършената операция. Играх си с git grep
без резултат.
За да търсите съдържание на предаването (т.е. действителни редове от изходния код, за разлика от съобщенията за предаването и други подобни), трябва да направите:
git grep <regexp> $(git rev-list --all)
git rev-list --all | xargs git grep <expression>
ще работи, ако се сблъскате с грешка "Списъкът с аргументи е твърде дълъг".
Ако искате да ограничите търсенето до някое поддърво (например "lib/util"), ще трябва да го предадете и на подкомандата rev-list
и на grep
:
git grep <regexp> $(git rev-list --all -- lib/util) -- lib/util
Това ще прегледа целия ви текст на поправките за regexp
.
Причината за подаване на пътя и в двете команди е, че rev-list
ще върне списъка с ревизиите, в които са станали всички промени в lib/util
, но също така трябва да го подадете на grep
, така че да търси само в lib/util
.
Представете си следния сценарий: grep
може да намери същия <regexp>
в други файлове, които се съдържат в същата ревизия, върната от rev-list
(дори и да не е имало промяна в този файл в тази ревизия).
Ето и някои други полезни начини за търсене в изходния код:
Търсене в работното дърво за текст, отговарящ на регулярния израз regexp:
git grep <regexp>
Търсене в работното дърво за редове от текст, отговарящи на регулярен израз regexp1 или regexp2:
git grep -e <regexp1> [--or] -e <regexp2>
Търсене в работното дърво за редове от текст, отговарящи на регулярни изрази regexp1 и regexp2, като се отчитат само пътищата до файловете:
git grep -e <regexp1> --and -e <regexp2>
Търсене в работното дърво за файлове, в които има редове от текст, отговарящи на регулярен израз regexp1, и редове от текст, отговарящи на регулярен израз regexp2:
git grep -l --all-match -e <regexp1> -e <regexp2>
Търсене в работното дърво за променени редове от текст, отговарящи на шаблона:
git diff --unified=0 | grep <pattern>
Търсене на всички ревизии за текст, отговарящ на регулярния израз regexp:
git grep <regexp> $(git rev-list --all)
Търсене на всички ревизии между rev1 и rev2 за текст, отговарящ на регулярния израз regexp:
git grep <regexp> $(git rev-list <rev1>..<rev2>)
Трябва да използвате опцията pickaxe (-S
) на git log
За да търсите Foo
:
git log -SFoo -- path_containing_change
git log -SFoo --since=2009.1.1 --until=2010.1.1 -- path_containing_change
Вижте История на Git - намиране на изгубен ред по ключова дума за повече информация.
Както коментира Jakub Narębski:
това търси разлики, които въвеждат или премахват инстанция на <string>
.
Обикновено това означава "ревизии, в които сте добавили или премахнали ред с 'Foo'".
опцията --pickaxe-regex
ви позволява да използвате разширен POSIX regex вместо да търсите низ.
Както коментира Rob, това търсене е чувствително към големи и малки букви - той отвори допълнителен въпрос за това как да се търси без чувствителност към големи и малки букви.
Опитвате ли се да прегледате по-стари версии на кода, за да видите къде нещо е съществувало последно?
Ако аз правех това, вероятно щях да използвам git bisect. Използвайки bisect, можете да посочите известна добра версия, известна лоша версия и прост скрипт, който прави проверка дали версията е добра или лоша (в този случай grep, за да се види дали кодът, който търсите, присъства). Изпълнението на този скрипт ще установи кога е бил премахнат кодът.