Git: Показати всі різні зміни в одному рядку у вказаному файлі протягом усієї історії git


112

Я озирнувся, і не впевнений, чи це можливо, але ось:

У мене є (javascript) файл (скажімо /lib/client.js), у якому я маю унікальний ідентифікатор, призначений змінній, як-от так: var identifier = "SOME_IDENTIFIER";

Ви можете думати про ідентифікатор як номер версії: Періодично цю змінну ми будемо змінювати на новий ідентифікатор.

Що я хотів би зробити, це знайти всі унікальні ідентифікатори, які ми коли-небудь використовували. Як я можу це зробити при git?

Я думаю, може існувати спосіб пошуку історії git та друкування відповідності рядків "var identifier =". Я міг би зняти цей список вручну.

У будь-якому разі, я би вдячний за будь-яке розуміння тут. Дякую.


Відповіді:


106

Оскільки git 1.8.4 , існує більш прямий спосіб відповісти на ваше запитання.

Припустимо, що у цьому рядку 110є рядковий вислів var identifier = "SOME_IDENTIFIER";, тоді зробіть це:

git log -L110,110:/lib/client.js

Це поверне кожну комісію, яка торкнулася цього рядка коду.

[ Документація Git (див. Параметр командного рядка "-L")]


49

Дивіться сторінку людини для git-logта gitdiffcore. Я вірю, що ця команда зробила б це, але це може бути не зовсім правильно:

git log -G "var identifier =" file.js

EDIT: Ось приблизний початок для скрипту bash, щоб показати фактичні рядки. Це може бути більше того, що ви шукаєте.

for c in $(git log -G "something" --format=%H -- file.js); do
    git --no-pager grep -e "something" $c -- file.js
done

Він використовує git log -Gдля пошуку цікавих комітетів, використовуючи --format=%Hдля складання списку хеш-файлів. Потім він повторює кожну цікаву git grepкоманду , запитуючи показати рядки з цього коміту та файлу, що містять регулярний вираз, попередній хеш комітів.


EDIT: Змінено для використання -Gзамість -Sзапропонованого в коментарях.


@Rob - спасибі за це - невелике редагування вашого сценарію, хоча - якщо розміщувати лише ім'я файлу, відображаються файли, які впливають лише на цей файл - якщо комісія посилається на інші файли, вона не вказана
Адріан Корніш

@AdrianCornish - Радий, що це було корисно. Я думаю, що ОП хотів просто переглянути один файл, але ви цілком вірні, що видалення імені файлу, ймовірно, є більш загальним сценарієм.
пограбувати

У мене складніша ситуація. Розглянутий файл перемістився з paht_a / файл у path_b / файл. Тепер, коли я роблю це у path_b, він відображає зміни лише до того, коли файл переміщується з path_a в path_b. Якщо я це роблю в path_a, він повідомляє мені фатальний: неоднозначний аргумент 'file': невідома редакція або шлях не в робочому дереві.
Енді Пісень

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

Для мене було зручніше - розміщуйте порожній рядок після кожного вчинення, перераховуйте рядки:sfile=path/to/some_file; sfind='string_to_find'; for c in $(git log -G $sfind --format=%H -- $sfile); do git --no-pager grep -e $sfind -n $c -- $sfile; echo; done
John_West

14

Ви також можете це зробити за допомогою gitk:

gitk file.js

У спадному меню "фіксувати" виберіть "додавання / видалення рядка:" та в текстовому полі поруч із ним введіть "var identifier =", і будь-які коміти, які додають або видаляють рядки, що містять цей рядок, будуть виділені.


Це допомогло точно визначити коміту, при якій додано рядок, що містить "var identifier =", але в ньому не відображаються наступні коміти, що модифікували цей рядок.
findchris

2
Ви пробували git blame file.jsчи git gui blame file.js?
Етан Браун

1
Я знаю, що робить винна гіта; Я шукаю повну історію змін, ані одну різницю.
findchris

1
git gui blame file.jsзроби це ... він покаже вам всі версії файлу та хто його змінив; ви можете просто натиснути назад через історію.
Етан Браун

Я в кінцевому підсумку переступив візуально з gitk. Я думаю, що для цього є якась елегантна техніка git, але gitk був досить гарним. Дякую.
findchris

9

Якщо ви трохи адаптуєте відповідь @ rob, це в git logосновному зробить це за вас, якщо все, що вам потрібно, це візуальне порівняння:

git log -U0 -S "var identifier =" path/to/file

-U0означає вихід у режимі патча ( -p) та показує нульові рядки контексту навколо патчу.

Ви навіть можете це зробити в різних галузях:

git log -U0 -S "var identifier =" branchname1 branchname2 -- path/to/file

Можливо, є спосіб придушити заголовок diff, але я не знаю жодного.


Працювали для мене! Дякую.
Роберто Боніні

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.