Как я могу искать ветки Git для файла или каталога?

В Git, как я могу искать файл или каталог по пути по нескольким ветвям?

Я написал что-то в ветке, но я не помню, какой из них. Теперь мне нужно его найти.

Уточнение. Я ищу файл, который я создал на одном из моих ветвей. Я хотел бы найти его по пути, а не по его содержимому, поскольку я не помню, что такое содержимое.

Ответ 1

git журнал найдет его для вас:

% git log --all -- somefile

commit 55d2069a092e07c56a6b4d321509ba7620664c63
Author: Dustin Sallings <[email protected]>
Date:   Tue Dec 16 14:16:22 2008 -0800

    added somefile
% git branch -a --contains 55d2069
  otherbranch

Поддерживает также подглаживание:

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

Одинаковые кавычки необходимы (по крайней мере, если используется оболочка bash), поэтому оболочка передает шаблон glob на git без изменений, вместо того, чтобы расширять его (как и Unix find).

Ответ 2

git ls-tree может помочь. Для поиска по всем существующим ветвям:

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

Хотя отклик ididak довольно крутой, и Handyman5 предоставляет скрипт для его использования, я нашел его немного ограниченным в использовании этого подхода.

Иногда вам нужно искать что-то, что может появиться/исчезнуть со временем, так почему бы не выполнить поиск по всем коммитам? Кроме того, иногда вам нужен подробный ответ, а в других случаях фиксируются только совпадения. Вот две версии этих опций. Поместите эти сценарии на свой путь:

ГИТ-находка файл

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

ГИТ-найти файлы многословных

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 вы можете изменить этот скрипт, чтобы чередовать поиск по всем коммитам, ссылкам, ссылкам/заголовкам, многословности и т.д.

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

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

Ответ 4

Вы можете использовать gitk --all и искать коммиты "трогательные пути" и интересующий вас путь.

Ответ 5

Скопируйте и вставьте это, чтобы использовать 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 как глобальный псевдоним git.

Ответ 6

Достаточно приличную реализацию команды find для репозиториев Git можно найти здесь:

https://github.com/mirabilos/git-find