Ответ 1
Это невозможно, но недавно обсуждалось. Предлагаемый обходной путь в ссылке:
Вы можете поместить
*.dll
в файл .gitignore, затемgit grep --exclude-standard
.
РЕДАКТИРОВАТЬ увидеть только один ответ, так как git 1.9.0 это возможно.
Есть ли способ поиска репозитория git с помощью git grep
, но исключить из поиска определенные пути/каталоги/файлы? Как и опция --exclude
в обычной команде grep.
Если вам интересно: я не хочу использовать обычный grep, поскольку он намного медленнее, чем git grep
, когда размер репозитория git большой.
Это невозможно, но недавно обсуждалось. Предлагаемый обходной путь в ссылке:
Вы можете поместить
*.dll
в файл .gitignore, затемgit grep --exclude-standard
.
РЕДАКТИРОВАТЬ увидеть только один ответ, так как git 1.9.0 это возможно.
В git pathspec
exclude
"волшебного слова" было добавлено в pathspec
. Поэтому, если вы хотите искать foobar
в каждом файле, кроме тех, которые соответствуют *.java
вы можете сделать:
git grep foobar -- './*' ':(exclude)*.java'
Или используя !
"короткая форма" для исключения:
git grep foobar -- './*' ':!*.java'
Обратите внимание, что в версиях git до v2.12 при использовании pathspec
исключений pathspec
вас должен быть хотя бы один "включающий" pathspec
. В приведенных выше примерах это ./*
(рекурсивно включать все в текущем каталоге). В git v2.13 это ограничение было снято, и git grep foobar -- ':!*.java'
работает без ./*
.
Вы также можете использовать что-то вроде :(top)
(краткая форма :/
), чтобы включить все из верхней части репо. Но тогда вы, вероятно, также захотите настроить ваш исключающий pathspec
к pathspec
чтобы он начинался сверху:: :/!*.java
(иначе он будет исключать только файлы *.java
из вашего текущего каталога).
Есть хорошая ссылка на все "волшебные слова", разрешенные в pathspec
на git-scm.com (или просто git help glossary
). По какой-то причине документы на kernel.org действительно устарели, хотя они часто появляются первыми в поиске в Google.
Обновление: Для git >= 1.9 существует встроенная поддержка шаблонов исключений, см. только один ответ.
Это может показаться обратным, но вы можете передать список файлов, не соответствующих вашему шаблону исключения, в git grep
следующим образом:
git grep <pattern> -- `git ls-files | grep -v <exclude-pattern>`
grep -v
возвращает каждый путь, не соответствующий <exclude-pattern>
. Обратите внимание, что git ls-files
также принимает параметр --exclude
, но применяется только к файлам без следа.
В примере с помощью @kynan в качестве базы я сделал этот script и поместил его в свой путь (~/bin/
) как gg
. Он использует git grep
, но избегает определенных типов файлов.
В нашем репо было много изображений, поэтому я исключил файлы изображений, и это приведет к тому, что в течение всего времени репозитория будет отведено до 1/3 секунды. Но script можно легко изменить, чтобы исключить другие filestypes или geleralpatterns.
#!/bin/bash
#
# Wrapper of git-grep that excludes certain filetypes.
# NOTE: The filetypes to exclude is hardcoded for my specific needs.
#
# The basic setup of this script is from here:
# https://stackoverflow.com/a/14226610/42580
# But there is issues with giving extra path information to the script
# therefor I crafted the while-thing that moves path-parts to the other side
# of the '--'.
# Declare the filetypes to ignore here
EXCLUDES="png xcf jpg jpeg pdf ps"
# Rebuild the list of fileendings to a good regexp
EXCLUDES=`echo $EXCLUDES | sed -e 's/ /\\\|/g' -e 's/.*/\\\.\\\(\0\\\)/'`
# Store the stuff that is moved from the arguments.
moved=
# If git-grep returns this "fatal..." then move the last element of the
# arg-list to the list of files to search.
err="fatal: bad flag '--' used after filename"
while [ "$err" = "fatal: bad flag '--' used after filename" ]; do
{
err=$(git grep "[email protected]" -- `git ls-files $moved | grep -iv "$EXCLUDES"` \
2>&1 1>&3-)
} 3>&1
# The rest of the code in this loop is here to move the last argument in
# the arglist to a separate list $moved. I had issues with whitespace in
# the search-string, so this is loosely based on:
# http://www.linuxjournal.com/content/bash-preserving-whitespace-using-set-and-eval
x=1
items=
for i in "[email protected]"; do
if [ $x -lt $# ]; then
items="$items \"$i\""
else
moved="$i $moved"
fi
x=$(($x+1))
done
eval set -- $items
done
# Show the error if there was any
echo $err
Примечание 1
В соответствии с этим можно было бы назвать вещь git-gg
и иметь возможность называть ее обычной командой git, например:
$ git gg searchstring
Но я не могу заставить это работать. Я создал script в моем ~/bin/
и сделал символическую ссылку git-gg
в /usr/lib/git-core/
.
Примечание 2
Команда не может быть выполнена в обычный sh
git -alias, так как она будет вызываться в корне репо. И это не то, что я хочу!
Вы можете пометить файлы или каталоги как двоичные, создав файл атрибутов в вашем хранилище, например
$ cat .git/info/attributes
directory/to/ignore/*.* binary
directory/to/ignore/*/*.* binary
another_directory/to/also/ignore/*.* binary
Совпадения в двоичных файлах перечислены без включающей строки, например
$ git grep "bar"
Binary file directory/to/ignore/filename matches
other_directory/other_filename: foo << bar - bazz[:whatnot]