Як знайти команду Git, яка ввела рядок у будь-яку гілку?


396

Я хочу, щоб я міг знайти певний рядок, який був введений в будь-який комітет у будь-якій галузі, як це зробити? Я знайшов щось (що я змінив для Win32), але git whatchanged, схоже, не розглядає різні гілки (ігноруйте фрагмент py3k, це лише виправлення каналу msys / win line)

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>

Не важливо, чи ваше рішення повільне.


Відповіді:


685

Ви можете зробити:

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

Щоб знайти всі коміти, які додавали або видаляли фіксовану рядок whatever . В --allозначає параметр , щоб почати з кожної гілки і --sourceзасобів , щоб показати , які з цих гілок привели до виявлення того, що фіксації. Часто корисно додати, -pщоб показати патчі, які також вводить кожен із цих комісій.

Версії git з 1.7.4 також мають подібний -Gваріант, який приймає регулярне вираження . Це насправді має іншу (і досить очевидну) семантику, пояснювану в цій публікації в блозі Хуніо Хамано .

Як зазначає thameera в коментарях, вам потрібно поставити лапки навколо пошукового терміну, якщо він містить пробіли або інші спеціальні символи, наприклад:

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

Ось приклад використання -Gдля пошуку подій function foo() {:

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

19
+1 для досконалості. Вказівка ​​на -S - це одне, краще пояснити речі. Також я люблю використовувати --decorate, щоб побачити, з яких гілок
діють

7
@sehe: Дякую за ваш приємний коментар. Я думаю, що варто відзначити, що --decorateлише додавання назви гілки до комірок на кінчику кожної гілки. На практиці я не використовую --sourceабо --decorate, а натомість використовую, git branch -a --contains <commit-hash>щоб знайти, які гілки містять
комітет, який

3
add -p, щоб побачити вбудовану
різницю

1
@MarkLongair не відображає змін, зроблених у злитті. Будь-яка пропозиція показати їх також?
Пахлеві Фікрі Аулія

2
Для мене це працює лише в тому випадку, якщо я видалю пробіл між -S та пошуковим терміном, тобто git log -S"dude, where's my car?" --source --all. @ribamar також написав, що у відповіді нижче, але вона може легко не помітити поруч із цією верхньою відповіддю.
помилка313

69

- зворотний варіант також корисний, оскільки ви хочете, щоб перша комісія, яка внесла зміни

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

Таким чином, перші повідомлення з’являться першими.


20

Відповідь Марка Лонгайра - відмінна, але я знайшов, що ця простіша версія працює для мене.

git log -S whatever

24
Просто для уточнення, це добре працює, якщо ви шукаєте комісію HEAD, але саме це питання задається спеціально щодо перегляду всіх гілок у сховищі.
Марк Лонгейр

18

Возитися з тими ж відповідями:

$ git config --global alias.find '!git log --color -p -S '
  • ! потрібен, оскільки інший спосіб, git не передає аргумент правильно -S. Дивіться цю відповідь
  • --color and -p допомагає точно показати "що змінилося"

Тепер ви можете зробити

$ git find <whatever>

або

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

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

Зверніть увагу, щоб не використовувати пробіли між S та "string_to_search". У деяких налаштуваннях (git 1.7.1) ви отримаєте помилку типу:

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

2

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

Для цього я використав Git bisect , який швидко дозволив мені знайти грішника.

Я побіг, git bisect startа потім git bisect bad, оскільки перевірка була перевірена, мала проблему. Оскільки я не знав, коли виникла проблема, я націлився на перше зобов'язання щодо "добра" git bisect good <initial sha>.

Тоді я просто продовжував шукати репо для поганого коду. Коли я знайшов його, я побіг git bisect bad, і коли він не був там: git bisect good.

За ~ 11 кроків я покрив ~ 1000 комісій і знайшов точну фіксацію, де було введено проблему. Досить чудово.


2

Не впевнений, чому прийнята відповідь не працює в моєму середовищі, нарешті, я запускаю команду нижче, щоб отримати те, що мені потрібно

git log --pretty=format:"%h - %an, %ar : %s"|grep "STRING"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.