Як я можу шукати у гілках Git файл або каталог?


323

Як я можу шукати файл чи каталог у Git через декілька гілок?

Я щось написав у гілці, але не пам'ятаю, яку. Тепер мені потрібно його знайти.

Пояснення : я шукаю файл, який я створив на одній із моїх гілок. Я хотів би знайти його шляхом, а не за його змістом, оскільки я не пам’ятаю, що це за вміст.


Мені незрозуміло питання. Чи був цей файл у гілці, яку зараз видалено? Файл видалено?
Абізерн

Відповіді:


444

git log+ git branchзнайде для вас:

% git log --all -- somefile

commit 55d2069a092e07c56a6b4d321509ba7620664c63
Author: Dustin Sallings <dustin@spy.net>
Date:   Tue Dec 16 14:16:22 2008 -0800

    added somefile


% git branch -a --contains 55d2069
  otherbranch

Також підтримується глобалізація:

% git log --all -- '**/my_file.png'

Одиночні лапки є необхідними (принаймні, якщо використовується оболонка Bash), тому оболонка передає шаблон шаблону, щоб він змінився незмінним, а не розширював його (як у Unix find).


2
Це спрацьовує, якщо ви знаєте точний шлях до somefile: якщо, наприклад, вам потрібен повторний пошук через шлях / ім’я файлу, тоді ви можете використовувати відповідь ididak.
ShreevatsaR

70
Підтримує також git log --all -- **/my_file.png
глобус

3
Я використав це для дещо іншої проблеми. Я намагався знайти всі * .sql файли, які я вчинив для певної гілки. Так я і використовував git log --grep='branch' --author='me' -- *.sql. Працював як шарм. версія git 1.7.11.1
thepriebe

1
Зауважте, що також gitkпідтримується глобалізація. Це відмінна відповідь @webmat! Якщо ви хочете побачити, де це було видалено / створено / тощо, ви можете використовувати git log --all --stat -- **/my_file.png, таким чином вам не доведеться здогадуватися, чи перевіряєте ви це з комітету, який видалив його.
eacousineau

1
@webmat: Я сміливо додав у відповідь вашу інформацію про глобалізацію. Дякуємо, що згадали про це!
sleske

65

git ls-дерево може допомогти. Для пошуку в усіх існуючих галузях:

for branch in `git for-each-ref --format="%(refname)" refs/heads`; do
  echo $branch :; git ls-tree -r --name-only $branch | grep '<foo>'
done

Перевага цього в тому, що ви також можете шукати за допомогою регулярних виразів по імені файлу.


3
Кілька сподіваються корисних коментарів: (а) Ви, мабуть, хочете додати "-r" до "git ls-tree", щоб він знайшов файл, навіть якщо він знаходиться у підкаталозі. (b) Можливо, більш приємною альтернативою першому рядку буде використання "git for-кожного ref", наприклад "для гілки в git for-each-ref --format="%(refname)" refs/heads; do" (c) "git ls-tree - name-only" зробить висновок акуратнішим (г) можливо у вашій відповіді варто зазначити, що в цьому є перевага перед рішенням Дастіна, а саме те, що вам не потрібно точно знати назву файлу - ви можете шукати шляхом регулярного вираження, що відповідає будь-якій частині шляху
Марк Лонгейр

9
Я завершив це в сценарій, щоб ви могли запустити "gitfind.sh <regex>"; the gist is gist.github.com/62d981890eccb48a99dc
Різноробочий5

3
Зауважте, що це буде шукати лише в місцевих відділеннях. Для пошуку відділень дистанційного відстеження використовуйте refs/remotesзамість refs/heads. Для пошуку всього (локальні гілки, гілки дистанційного відстеження та теги) просто використовуйте refs/.
sleske

19

Хоча відповідь ідідака досить класна, і Handyman5 надає сценарій для її використання, я вважав, що цей підхід трохи обмежений.

Іноді потрібно шукати щось, що може з’являтися / зникати з часом, то чому б не шукати проти всіх домовленостей? Крім того, іноді вам потрібна багатослівна відповідь, а інший раз лише фіксування відповідностей. Ось дві версії цих варіантів. Покладіть ці сценарії на свій шлях:

git-find-файл

for branch in $(git rev-list --all)
do
  if (git ls-tree -r --name-only $branch | grep --quiet "$1")
  then
     echo $branch
  fi
done

git-find-file-verbose

for branch in $(git rev-list --all)
do
  git ls-tree -r --name-only $branch | grep "$1" | sed 's/^/'$branch': /'
done

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

$ git find-file <regex>
sha1
sha2

$ git find-file-verbose <regex>
sha1: path/to/<regex>/searched
sha1: path/to/another/<regex>/in/same/sha
sha2: path/to/other/<regex>/in/other/sha

Дивіться, що за допомогою getopt ви можете змінювати цей скрипт, щоб чергувати пошук усіх комісій, refs, refs / heads, багатослівний тощо.

$ git find-file <regex>
$ git find-file --verbose <regex>
$ git find-file --verbose --decorated --color <regex>

Отримайте замовлення https://github.com/albfan/git-find-file для можливої ​​реалізації.


Ви мали на увазі "Тепер ви можете зробити git-find-file <regex>"? У мене це працює, дякую!
Ілля Лінн

1
Особисто мені здається, що набагато корисніше використовувати $ (git гілка | cut -c 3-) замість $ (git rev-list --all). Мені не цікаво знайти купу комісій, я дбаю про названі гілки.
Campadrenalin

Я також змінив сценарії, щоб використовувати $ (git гілка | cut -c 3-), оскільки цикл для всіх комітетів був занадто повільним.
i4h

Побачена вся суєта, яку я річ, варто створити для цього репо. github.com/albfan/git-find-file . Я відкрив деякі питання, не соромтесь запропонувати більше або надіслати піар на це.
albfan

1
Встановлення сценарію @lumbric на шляху працює з поля, його функція git
albfan

10

Ви можете використовувати gitk --allта шукати комісії "дотикові шляхи" та ім'я, яке вас цікавить.


3
Як зазначено, використовуйте gitk --all, а потім у View | Новий вигляд, увімкніть Усі відділення. Потім встановіть критерії пошуку: назви файлів (з підказками) в передостанньому полі. Нарешті: гаразд.
MikeW

8

Скопіюйте та вставте це для використання git find-file SEARCHPATTERN

Друк усіх пошукових гілок:

git config --global alias.find-file '!for branch in `git for-each-ref --format="%(refname)" refs/heads`; do echo "${branch}:"; git ls-tree -r --name-only $branch | nl -bn -w3 | grep "$1"; done; :'

Друкувати лише гілки з результатами:

git config --global alias.find-file '!for branch in $(git for-each-ref --format="%(refname)" refs/heads); do if git ls-tree -r --name-only $branch | grep "$1" > /dev/null; then  echo "${branch}:"; git ls-tree -r --name-only $branch | nl -bn -w3 | grep "$1"; fi; done; :'

Ці команди додадуть деякі мінімальні скрипти прямо в ~/.gitconfigякості глобального мерзотника псевдоніма .


це лише пошук у
головній

Він шукає у всіх місцевих відділеннях
Леонардо Еррера

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