Як присвоїти Git набуття різниці або вмісту для певного слова?


622

У сховищі коду Git я хочу перерахувати всі коміти, які містять певне слово. Я спробував це

git log -p | grep --context=4 "word"

але це не обов'язково повертає мені ім'я файлу (якщо тільки це не менше 5 рядків від слова, яке я шукав. Я також намагався

git grep "word"

але це дає мені лише наявні файли, а не історію.

Як шукати всю історію, щоб я міг слідкувати за змінами на певному слові? Я маю намір шукати в своїй кодовій базі даних щодо появи слів для відстеження змін (пошук у історії файлів).


Відповіді:


904

Якщо ви хочете знайти всі коміти, у яких повідомлення про фіксацію містить задане слово, використовуйте

$ git log --grep=word

Якщо ви хочете знайти всі коміти, де "слово" було додано або видалено у вмісті файлу (точніше: там, де кількість випадків "слова" змінилося), тобто пошук вмісту комірок , використовуйте так званий пошук "pickaxe" з

$ git log -Sword

У сучасному git також є

$ git log -Gword

шукати відмінності , доданий чи видалений рядок відповідає "слову" (також виконувати вміст ).

Зауважте, що -Gза замовчуванням приймає регулярний вираз, тоді як -Sприймає рядок, але може бути змінено, щоб прийняти регулярні вирази за допомогою --pickaxe-regex.

Щоб проілюструвати різницю між -S<regex> --pickaxe-regexі -G<regex>, розгляньте команду із наступним розбігом у тому ж файлі:

+    return !regexec(regexp, two->ptr, 1, &regmatch, 0);
...
-    hit = !regexec(regexp, mf2.ptr, 1, &regmatch, 0);

Хоча git log -G"regexec\(regexp"покаже це зобов’язання, git log -S"regexec\(regexp" --pickaxe-regexне буде (тому що кількість зустрічей цього рядка не змінилося).


З Git 2.25.1 (лютий 2020 р.) Документація з’ясовується навколо цих виразів.

Див. Комітет 9299f84 (06 лютого 2020 р.) Мартіна Агрена (``) .
(Об'єднано Хуніо С Хамано - gitster- у комітеті 0d11410 , 12 лютого 2020 року)

diff-options.txt: уникайте перевантаження "регулярного вираження"

Повідомив: Адам Дінвуді
Підписався: Мартін Агрен Оглянув
: Тейлор Блау

Коли ми демонструємо різницю між -Gта -S(використовуючи --pickaxe-regex), ми робимо це, використовуючи приклад diff та git diffвиклик, що включає "regexec", "regexp", "regmatch", ...

Приклад правильний, але ми можемо полегшити розплутування, уникаючи написання "регулярного вираження".

Використовуйте замість цього кілька складених нерегексивних слів.

git diffДокументація тепер включає в себе:

Щоб проілюструвати різницю між -S<regex> --pickaxe-regexі -G<regex>, розгляньте команду із наступним розбігом у тому ж файлі:

+    return frotz(nitfol, two->ptr, 1, 0);
...
-    hit = frotz(nitfol, mf2.ptr, 1, 0);

Хоча git log -G"frotz\(nitfol"покаже це зобов’язання, git log -S"frotz\(nitfol" --pickaxe-regexне буде (тому що кількість зустрічей цього рядка не змінилося).


3
@TankorSmash -S<string>Шукайте відмінності, які впроваджують або видаляють екземпляр <string>. -G<string>Шукайте відмінності, доданий чи видалений рядок відповідає заданому <regex>.
m-ric

1
@ m-ric О, бачу, єдиний екземпляр рядка проти цілого рядка! Спасибі
TankorSmash

3
@ m-ric, @TankorSmash: Різниця в тому, що -S<string>вона швидша, тому що вона перевіряє лише те, чи <string>змінилося число подій , а -G<string>рядки пошуку додаються та видаляються у кожному комітеті.
Якуб Нарбський

3
Якщо вам потрібно шукати слова з пробілом між ними git log --grep="my words",.
MEM

4
@MEM, --grepвідрізняється від -Sта -G. Ви можете цитувати рядок до кожного з цих аргументів.
Acumenus

255

git logpickaxe знайде коміти зі змінами, включаючи слово "с" git log -Sword


60
Це не зовсім точно. -S <string> Шукайте відмінності, які вводять або видаляють екземпляр <string>. Зауважте, що це відрізняється від рядка, що просто відображається у різному виході;
tymtam

4
Хоча це, як правило, правильна відповідь, я намагаюся лише заохотити інших прочитати цю відповідь ( stackoverflow.com/a/1340245/586983 ), яка має три різні способи та пояснює їх тонкощі.
jakeonrails

18
огонь! Я не думаю, що це вагома причина спростувати правильну відповідь ... ви не були впевнені, що включення посилання в коментар буде достатнім заохоченням?
Дебора

@jakeonrails. Ця відповідь повинна була бути редакцією цього (старшого) варіанта, тому у нас немає таких дратівливих копій. Але люди хочуть лише репутації, а не чистої сторінки відповідей.
Юліан Онофрей

22

Після багатьох експериментів я можу порекомендувати наступне, що показує комісії, що вводять або видаляють рядки, що містять заданий регулярний вираз, і відображає зміни тексту в кожному, кольори показують слова, додані та видалені.

git log --pickaxe-regex -p --color-words -S "<regexp to search for>"

Хоча трохи пробігти, хоча ... ;-)


2
Це одне з найкращих досі подяк. Підказка: просто перелічити всі результати без підкачки, або додайте команду до GIT_PAGER=catабо додайте її| cat
Zack Morris,

Вказати шлях або файл буде набагато швидшеgit log --pickaxe-regex -p --color-words -S "<regexp to search for>" <file or fiepath>
fangxing

10

Ви можете спробувати наступну команду:

git log --patch --color=always | less +/searching_string

або використовуючи grepнаступний спосіб:

git rev-list --all | GIT_PAGER=cat xargs git grep 'search_string'

Запустіть цю команду в батьківському каталозі, де ви хочете здійснити пошук.


2
Мені подобається цей метод, тому що в комісіях, на які я переглядаю, є сотні рядків непов'язаних змін, і мене цікавлять лише фактичні виправлення, що стосуються слова, яке я шукаю. Щоб отримати кольорове використання git log --patch --color=always | less +/searching_string.
Радон Росборо

9

Ще один спосіб / синтаксис - це: наприклад, git log -S "word"
ви можете шукати, наприкладgit log -S "with whitespaces and stuff @/#ü !"


1

vim-втікач універсальний для такого виду експертизи у Vim.

Використовуйте :Ggrepдля цього. Для отримання додаткової інформації ви можете встановити vim-fugitive та шукати turorial by :help Grep. І цей епізод: дослідження-історія-сховища-git-сховище допоможе вам зробити все це.


1

Для використання булевого з'єднувача у регулярному вираженні:

git log --grep '[0-9]*\|[a-z]*'

Цей регулярний вираз пошуку регулярного виразу [0-9] * або [az] * у повідомленнях фіксації.


-1

Якщо ви хочете шукати конфіденційні дані, щоб вилучити їх із своєї історії git (через що я приземлився тут), для цього є інструменти. Github як спеціальна сторінка довідки з цього питання .

Ось суть статті:

BFG Repo-очищувач є більш швидким, простий альтернативою мерзотника фільтра-гілка для видалення непотрібних даних. Наприклад, щоб видалити файл із конфіденційними даними та залишити останню фіксацію недоторканою), запустіть:

bfg --delete-files YOUR-FILE-WITH-SENSITIVE-DATA

Щоб замінити весь текст, вказаний у passwords.txt, де б його не було знайдено в історії вашого сховища, запустіть:

bfg --replace-text passwords.txt

Дивіться документацію BFG Repo-Cleaner для повного використання та інструкцій щодо завантаження.


Ви можете хочете додати цю відповідь на stackoverflow.com/questions/872565/… замість цього
lacostenycoder
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.