Jak grep (search) committed code w historii Gita?
Kiedyś w przeszłości usunąłem plik lub jakiś kod z pliku. Czy Mogę grep w treści (nie w wiadomościach commit)?
Bardzo słabym rozwiązaniem jest grep log:
git log -p | grep <pattern>
To jednak nie zwraca hash commit od razu. Grałem z git grep
bez skutku.
13 answers
Aby wyszukać treść commit (tj. rzeczywiste linie źródłowe, w przeciwieństwie do komunikatów commit i tym podobnych), musisz zrobić:
git grep <regexp> $(git rev-list --all)
Aktualizacje: git rev-list --all | xargs git grep expression
będzie działać, jeśli napotkasz błąd "lista argumentów za długa"
Jeśli chcesz ograniczyć wyszukiwanie do jakiegoś podzbioru (na przykład "lib / util"), musisz przekazać to do rev-list
oraz grep
:
git grep <regexp> $(git rev-list --all -- lib/util) -- lib/util
To przejrzy cały Twój tekst commit dla regexp.
Powodem przekazania ścieżki w obu komend jest to, że rev-list
zwróci listę revisions, w której zaszły wszystkie zmiany do lib/util
, ale musisz również przekazać ją do grep
, aby wyszukiwała tylko na lib/util
.
Wyobraź sobie następujący scenariusz: grep
może znaleźć ten sam <regexp>
w innych plikach, które są zawarte w tej samej rewizji zwracanej przez rev-list
(nawet jeśli nie było zmian w tym pliku w tej rewizji).
Oto kilka innych przydatnych sposoby wyszukiwania źródła:
Wyszukaj drzewo robocze dla tekstu pasującego do wyrażenia regularnego regexp:
git grep <regexp>
Wyszukaj w drzewie roboczym wiersze tekstu pasujące do wyrażenia regularnego regexp1 lub regexp2:
git grep -e <regexp1> [--or] -e <regexp2>
Przeszukanie drzewa roboczego dla wierszy tekstu pasujących do wyrażenia regularnego regexp1 i regexp2, raportowanie tylko ścieżek plików:
git grep -e <regexp1> --and -e <regexp2>
Wyszukiwanie w drzewie roboczym plików, które mają wiersze tekstu pasujące do wyrażenia regularnego regexp1 i wiersze tekstu pasujące do wyrażenia regularnego wyrażenie regexp2:
git grep -l --all-match -e <regexp1> -e <regexp2>
Wyszukaj drzewo robocze dla zmienionych linii tekstu pasującego do wzorca:
git diff --unified=0 | grep <pattern>
Przeszukaj wszystkie wersje dla tekstu pasującego do wyrażenia regularnego regexp:
git grep <regexp> $(git rev-list --all)
Przeszukaj wszystkie wersje między rev1 i rev2, aby znaleźć tekst pasujący do wyrażenia regularnego regexp:
git grep <regexp> $(git rev-list <rev1>..<rev2>)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-09 13:55:22
Powinieneś użyć kilofa (-S
) opcja git log
Aby wyszukać Foo
:
git log -SFoo -- path_containing_change
git log -SFoo --since=2009.1.1 --until=2010.1.1 -- path_containing_change
Zobacz Git history-znajdź zagubioną linię według słowa kluczowego aby dowiedzieć się więcej.
Jako Jakub Narębski skomentował (a):
Ten szuka różnic, które wprowadzają lub usuwają instancję
<string>
.
Zwykle oznacza "zmiany, w których dodano lub usunięto wiersz z 'Foo'".Opcja
--pickaxe-regex
pozwala na użyj rozszerzonego wyrażenia regularnego POSIX zamiast wyszukiwania ciągu znaków.
Jak skomentował Rob, wyszukiwanie uwzględnia wielkość liter - otworzył kolejne pytanie na temat tego, jak przeszukiwać wielkość liter.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-02 15:19:05
Moim ulubionym sposobem na to jest opcja git log
' S -G
(dodana w wersji 1.7.4).
-G<regex>
Look for differences whose added or removed line matches the given <regex>.
Istnieje subtelna różnica między sposobem, w jaki opcje -G
i -S
określają, czy commit pasuje:
- opcja
-S
zasadniczo liczy liczbę dopasowań wyszukiwania w pliku przed i po zatwierdzeniu. Commit jest pokazywany w dzienniku, jeśli licznik przed i po jest inny. Nie będzie to na przykład pokazywać commitów, w których linia pasująca do wyszukiwania został przeniesiony. - z opcją
-G
, zatwierdzenie jest wyświetlane w dzienniku, jeśli wyszukiwanie pasuje do dowolnej linii, która została dodana, usunięta lub zmieniona.
Weźmy ten commit jako przykład:
diff --git a/test b/test
index dddc242..60a8ba6 100644
--- a/test
+++ b/test
@@ -1 +1 @@
-hello hello
+hello goodbye hello
Ponieważ liczba wystąpień" hello " w pliku jest taka sama przed i po tym zatwierdzeniu, nie będzie pasować przy użyciu -Shello
. Jednakże, ponieważ nastąpiła zmiana dopasowania linii hello
, commit zostanie pokazany za pomocą -Ghello
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-20 16:43:21
Jeśli chcesz przeglądać zmiany w kodzie (zobacz co faktycznie zostało zmienione z podanym słowem w całej historii) przejdź do trybu patch
- znalazłem bardzo przydatną kombinację robienia:
git log -p
# hit '/' for search mode
# type in the word you are searching
# if the first search is not relevant hit 'n' for next (like in vim ;) )
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-17 08:17:38
Wziąłem @odpowiedź Jeeta i dodałem ją do Windows (dzięki Ta odpowiedź):
FOR /F %x IN ('"git rev-list --all"') DO @git grep <regex> %x > out.txt
Zauważ, że dla mnie, z jakiegoś powodu, rzeczywisty commit, który usunął ten regex, nie pojawił się na wyjściu polecenia, ale raczej jeden commit przed nim.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:03:04
git log
może być bardziej efektywnym sposobem wyszukiwania tekstu we wszystkich gałęziach, zwłaszcza jeśli jest wiele dopasowań i chcesz najpierw zobaczyć nowsze (istotne) zmiany.
git log -p --all -S 'search string'
git log -p --all -G 'match regular expression'
Te polecenia dziennika wypisują commity, które dodają lub usuwają dany ciąg wyszukiwania/regex, (ogólnie) nowszy jako pierwszy. Opcja -p
powoduje wyświetlenie odpowiedniego rozróżnienia, gdzie wzór został dodany lub usunięty, dzięki czemu można go zobaczyć w kontekście.
Po znalezieniu odpowiedniego commita, który dodaje tekst szukałeś (np. 8beeff00d), znajdź gałęzie zawierające commit:
git branch -a --contains 8beeff00d
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-23 00:38:58
Szukaj w dowolnej wersji, dowolnych plikach :
git rev-list --all | xargs git grep <regexp>
Wyszukiwanie tylko w niektórych podanych plikach, na przykład w plikach xml:
git rev-list --all | xargs -I{} git grep <regexp> {} -- "*.xml"
Linie wynikowe powinny wyglądać tak: 6988bec26b1503d45eb0b2e8a4364afb87dde7af:bla.xml: tekst znalezionej linii...
Możesz uzyskać więcej informacji takich jak autor, data, różnica używając git show:
git show 6988bec26b1503d45eb0b2e8a4364afb87dde7af
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-19 08:14:54
Dla każdego, kto próbuje to zrobić w SourceTree, nie ma bezpośredniego polecenia w interfejsie użytkownika (od wersji 1.6.21.0). Możesz jednak użyć poleceń podanych w zaakceptowanej odpowiedzi, otwierając okno Terminal (przycisk dostępny w głównym pasku narzędzi) i kopiując/wklejając je w nim.
Uwaga: widok SourceTree Search może częściowo przeszukiwać tekst. Naciśnij Ctrl + 3 aby przejść do widoku wyszukiwania (lub kliknąć zakładkę Szukaj dostępną w dno). Od prawej strony Ustaw typ Wyszukiwania na File Changes, a następnie wpisz szukany ciąg znaków. Ta metoda ma następujące ograniczenia w porównaniu z powyższym poleceniem:
- SourceTree pokazuje tylko commity , które zawierają wyszukiwane słowo w jednym ze zmienionych plików. Znalezienie dokładnego pliku zawierającego szukany tekst jest ponownie zadaniem ręcznym.
- RegEx nie jest obsługiwany.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-01 05:51:21
Dla uproszczenia, sugerowałbym użycie GUI: gitk-przeglądarka repozytorium Git , dość elastyczna
I możesz nawigować po wynikach za pomocą strzałki w górę / w dół
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-07 07:35:46
Więc próbujesz przejrzeć starsze wersje kodu, aby zobaczyć, gdzie coś ostatnio istnieje?
Gdybym to robił, prawdopodobnie użyłbym git bisect. Używając bisect, możesz określić znaną dobrą wersję, znaną złą wersję i prosty skrypt, który sprawdza, czy wersja jest dobra czy zła (w tym przypadku grep, aby sprawdzić, czy kod, którego szukasz, jest obecny). Uruchomienie tego spowoduje, że kod zostanie usunięty.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-28 11:52:32
Odpowiedź @ Jeet działa w PowerShell.
git grep -n <regex> $(git rev-list --all)
Poniżej wyświetlane są wszystkie pliki w zatwierdzeniu, które zawierają password
.
# store intermediate result
$result = git grep -n "password" $(git rev-list --all)
# display unique file names
$result | select -unique { $_ -replace "(^.*?:)|(:.*)", "" }
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-16 02:17:29
git rev-list --all | xargs -n 5 git grep EXPRESSION
Jest modyfikacją rozwiązania @Jeet, dzięki czemu wyświetla wyniki podczas wyszukiwania, a nie tylko na końcu (co może zająć dużo czasu w przypadku dużego repo).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-19 18:59:34
W moim przypadku musiałem wyszukać Krótki Commit i wymienione rozwiązania niestety nie działały.
Udało mi się to zrobić za pomocą: (zamieńregex token)
for commit in $(git rev-list --all --abbrev-commit)
do
if [[ $commit =~ __REGEX__ ]]; then
git --no-pager show -s --format='%h %an - %s' $commit
fi
done
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-31 22:44:08