Проверьте, является ли текущий каталог репозиторием Git
212
Я пишу серию скриптов для управления Git на zsh.
Как проверить, является ли текущий каталог репозиторием Git? (Когда я не использую репозиторий Git, я не хочу выполнять кучу команд и получать кучу fatal: Not a git repositoryответов).
Вы для вдохновения смотрели файл завершения bash (в contrib / Завершение / git-Completion.bash)? Я использую команду __git_ps1 как часть моей командной строки bash. Фактически, большая часть его будет исходить из zsh. Возможно, вам нужна функция __gitdir.
Примечание: ни один из текущих ответов не учитывать $GIT_DIRили $GIT_WORK_TREEпеременные окружения, или как они взаимодействуют.
o11c
Ответы:
161
Скопировано из файла завершения bash, вот наивный способ сделать это
# Copyright (C) 2006,2007 Shawn O. Pearce <spearce@spearce.org>
# Conceptually based on gitcompletion (http://gitweb.hawaga.org.uk/).
# Distributed under the GNU General Public License, version 2.0.
if [ -d .git ]; then
echo .git;
else
git rev-parse --git-dir 2> /dev/null;
fi;
Вы можете заключить это в функцию или использовать в скрипте.
Сконцентрировано в однострочное условие, подходящее для bash и zsh
@William Pursell Зачем форк, если он вам не нужен? В основном для скорости в тривиальном случае.
jabbie
19
Для использования ответ необходимо обновить git rev-parse --is-inside-git-dir. Я лично использую git rev-parse --is-inside-work-treeперед установкой PS1.
juliohm
14
@juliohm --is-inside-git-dirвернет true только в том случае, если вы действительно находитесь в .gitкаталоге репозитория. Я не думаю, что OP этого ищет.
Это не учитывает подкаталог. Мне нужно проверить, git rev-parse --show-toplevelсоответствует ли подпапка, которую я проверяю,
Альпер,
Выбранный ответ даже ничего не распечатал. Этот сработал.
ScottyBlades
50
Используйте git rev-parse --git-dir
если git rev-parse --git-dir> / dev / null 2> & 1; тогда
: # Это действующий репозиторий git (но текущий рабочий
# каталог не может быть верхнего уровня.
# Проверьте вывод команды git rev-parse, если вам интересно)
еще
: # это не репозиторий git
фи
inside_git_repo="$(git rev-parse --is-inside-work-tree 2>/dev/null)"
if [ "$inside_git_repo" ]; then
echo "inside git repo"
else
echo "not in git repo"
fi
не содержит лишних операций и работает в -eрежиме.
Как отметил @ go2null , это не будет работать в чистом репо. Если по какой-то причине вы хотите работать с голым репо, вы можете просто проверить его git rev-parseуспешность, игнорируя его вывод.
Я не считаю это недостатком, потому что строка выше имеет отступ для сценариев, и практически все gitкоманды действительны только внутри рабочего дерева. Таким образом, для написания сценариев вам, скорее всего, будет интересно находиться не просто внутри «репозитория git», а внутри рабочего дерева.
Вместо проверки вывода лучше проверять возвращаемое значение. Ни в коем случае не призывайте [. Просто делайте if git rev-parse --is-inside-work-tree; then ...(с перенаправлением по желанию)
@Ivan_pozdeev Зависит от вашего определения слова «работа». В этом случае я бы сказал, что проверка возвращаемого значения работает, а проверка вывода - нет. В любом случае, с точки зрения передовой практики написания кода в оболочке, более целесообразно проверить возвращаемое значение.
Уильям Перселл
@WilliamPursell, если вы прочитаете связанный комментарий, вы поймете, что я имел в виду под словом «не работает» здесь.
ivan_pozdeev 07
8
Не уверен, есть ли общедоступный / документированный способ сделать это (есть некоторые внутренние функции git, которые вы можете использовать / злоупотреблять в самом источнике git)
Вы могли бы сделать что-то вроде:
if ! git ls-files >& /dev/null; then
echo "not in git"
fi
gitвозвращает errorlevel, 0если он находится внутри репозитория git, иначе он возвращает errorlevel 128. (Он также возвращается trueили falseнаходится в репозитории git.)
Пример использования
for repo in *; do
# skip files
[ -d "$repo" ] || continue
# run commands in subshell so each loop starts in the current dir
(
cd "$repo"
# skip plain directories
is_inside_git_repo || continue
printf '== %s ==\n' "$repo"
git remote update --prune 'origin' # example command
# other commands here
)
done
Не достаточно. Внутри .gitполучится, но распечатать false.
ivan_pozdeev
@ivan_pozdeev: Если git rev-parse --is-inside-work-treeвозвращается, trueили falseтогда он находится внутри репозитория git, и это то, что возвращает функция. то есть функция правильная
go2null
Чтобы развернуть, см. описание в ответе, значение, возвращаемое из git, игнорируется, используется уровень ошибки.
go2null
2
это работает для меня. Вы по-прежнему получаете ошибки, но их достаточно легко подавить. он также работает из подпапок!
Возможно, достаточно для многих случаев, но не работает на голом репозитории git.
Wildcard
3
git statusможет быть очень медленным на большом / старом репо. Я бы не стал использовать его для этой цели.
henrebotha
2
# проверяем, есть ли git repo
if [ $(git rev-parse --is-inside-work-tree) = true ]; then
echo "yes, is a git repo"
git pull
else
echo "no, is not a git repo"
git clone url --depth 1
fi
Это не лучшая практика. При запуске вне рабочего каталога вы получите «fatal: not a git repository (или любой из родительских каталогов): .git», написанное на stderr, и «no, is not a git repo» на stdout. Здесь вообще нет необходимости призывать [. Просто сделайте:if git rev-parse --is-inside-work-tree > /dev/null 2>&1; then ....
Уильям Перселл
В моем случае меня это устраивает, и я хочу отслеживать этот сбой в своих журналах. Ура!
Паскаль Энди
1
Почему бы не использовать коды выхода? Если мерзавец хранилище существует в текущем каталоге, а затем git branchи git tagкоманды возвращают код выхода на 0; в противном случае будет возвращен ненулевой код выхода. Таким образом, вы можете определить, существует ли репозиторий git или нет. Просто вы можете запустить:
git tag > /dev/null 2>&1 && [ $? -eq 0 ]
Преимущество : Flexibe. Он работает как с голыми, так и с обычными репозиториями, а также с sh, zsh и bash.
Объяснение
git tag: Получение тегов репозитория, чтобы определить, существует он или нет.
> /dev/null 2>&1: Предотвращение печати чего-либо, включая нормальный вывод и вывод ошибок.
[ $? -eq 0 ]: Проверить, вернула ли предыдущая команда код выхода 0 или нет. Как вы, наверное, знаете, каждый ненулевой выход означает, что произошло что-то плохое. $?получает код выхода предыдущей команды, и [, -eqи ]выполняет сравнение.
Например, вы можете создать файл check-git-repoсо следующим содержимым, сделать его исполняемым и запустить:
#!/bin/shif git tag > /dev/null 2>&1 && [ $? -eq 0 ]; thenecho"Repository exists!";
elseecho"No repository here.";
fi
if ! [[ $(pwd) = *.git/* || $(pwd) = *.git ]]; then
if type -P git >/dev/null; then
! git rev-parse --is-inside-work-tree >/dev/null 2>&1 || {
printf '\n%s\n\n' "GIT repository detected." && git status
}
fi
fi
Спасибо ivan_pozdeev , теперь у меня есть тест, если внутри каталога .git код не запускается, поэтому ошибки не распечатываются или статус ложного выхода.
Команда " ! [[$ (Pwd) = .git / || $ (pwd) = * .git]] " проверяет, не находитесь ли вы внутри репозитория .git, тогда он выполнит команду git. Команда встроенного типа используется для проверки того, установлен ли у вас git или он находится в вашем PATH. см. тип помощи
Вы можете добавить или заменить свой $ PS1 в zshrc с помощью тех или иных инструментов git-prompt. Таким образом, вы можете удобно узнать, находитесь ли вы в репозитории git и находится ли оно в состоянии.
Весь вопрос OP заключался в том, как это сделать из сценария
Эндрю Си
и как можно не использовать __git_ps1 из сценария? Вся суть git-prompt заключается в проверке статуса git текущего каталога, о чем и просили.
jxqz
__git_ps1 имеет множество функций, таких как необязательные проверки состояния и цвета терминала - все, что вам нужно, это фактическая базовая команда, которую он использует для любой информации о состоянии, которую вы хотите, а OP только спрашивал о нахождении внутри рабочего дерева. По сути, вы пытаетесь использовать бульдозер, чтобы заменить лампочку.
! отрицает, поэтому даже если вы запустите это в каталоге, который не является репозиторием git, он не даст вам фатальных ошибок
> / DEV / нуль 2> & 1 отправляет сообщения / DEV / нуль , так как вы только после того, как статус выхода. {} Предназначены для командных группировок так что все команды после того , как || запустится, если git rev-parse завершился успешно, поскольку мы используем! что отменяет статус выхода git rev-parse. Printf просто напечатать некоторые сообщения и GIT статус для печати статус репо.
Оберните его в функцию или поместите в сценарий. Надеюсь это поможет
$GIT_DIR
или$GIT_WORK_TREE
переменные окружения, или как они взаимодействуют.Ответы:
Скопировано из файла завершения bash, вот наивный способ сделать это
Вы можете заключить это в функцию или использовать в скрипте.
Сконцентрировано в однострочное условие, подходящее для bash и zsh
источник
git rev-parse --is-inside-git-dir
. Я лично используюgit rev-parse --is-inside-work-tree
перед установкой PS1.--is-inside-git-dir
вернет true только в том случае, если вы действительно находитесь в.git
каталоге репозитория. Я не думаю, что OP этого ищет.--is-inside-work-tree
ни другое не--is-inside-git-dir
будет работать, когда вы находитесь вне репозитория git. см. groups.google.com/forum/#!topic/git-users/dWc23LFhWxE.git
. Для надежности опустите[ -d .git ]
и просто используйтеgit rev-parse ...
.Ты можешь использовать:
Что напечатает «истина», если вы находитесь в рабочем дереве репозиториев git.
Обратите внимание, что он по-прежнему возвращает вывод в STDERR, если вы находитесь за пределами репозитория git (и не печатает false).
Взято из этого ответа: https://stackoverflow.com/a/2044714/12983
источник
git rev-parse --show-toplevel
соответствует ли подпапка, которую я проверяю,Используйте git rev-parse --git-dir
источник
Или вы можете сделать это:
источник
-e
режиме:[ "$(git rev-parse --is-inside-work-tree 2>/dev/null)" == "true" ]
На основе ответа @Alex Cory :
не содержит лишних операций и работает в
-e
режиме.git rev-parse
успешность, игнорируя его вывод.git
команды действительны только внутри рабочего дерева. Таким образом, для написания сценариев вам, скорее всего, будет интересно находиться не просто внутри «репозитория git», а внутри рабочего дерева.источник
[
. Просто делайтеif git rev-parse --is-inside-work-tree; then ...
(с перенаправлением по желанию)Не уверен, есть ли общедоступный / документированный способ сделать это (есть некоторые внутренние функции git, которые вы можете использовать / злоупотреблять в самом источнике git)
Вы могли бы сделать что-то вроде:
источник
Другое решение - проверить код выхода команды.
Это напечатает 1, если вы находитесь в папке репозитория git.
источник
.git
каталога, что может вам понадобиться, а может и нет.git rev-parse 2>&-
.Этот ответ предоставляет образец функции оболочки POSIX и пример использования, дополняющий ответ @ jabbie .
git
возвращает errorlevel,0
если он находится внутри репозитория git, иначе он возвращает errorlevel128
. (Он также возвращаетсяtrue
илиfalse
находится в репозитории git.)Пример использования
источник
.git
получится, но распечататьfalse
.git rev-parse --is-inside-work-tree
возвращается,true
илиfalse
тогда он находится внутри репозитория git, и это то, что возвращает функция. то есть функция правильнаяэто работает для меня. Вы по-прежнему получаете ошибки, но их достаточно легко подавить. он также работает из подпапок!
git status> / dev / null 2> & 1 && echo Hello World!
Вы можете поместить это в оператор if then, если вам нужно условно сделать больше.
источник
git status
может быть очень медленным на большом / старом репо. Я бы не стал использовать его для этой цели.# проверяем, есть ли git repo
источник
[
. Просто сделайте:if git rev-parse --is-inside-work-tree > /dev/null 2>&1; then ....
Почему бы не использовать коды выхода? Если мерзавец хранилище существует в текущем каталоге, а затем
git branch
иgit tag
команды возвращают код выхода на 0; в противном случае будет возвращен ненулевой код выхода. Таким образом, вы можете определить, существует ли репозиторий git или нет. Просто вы можете запустить:Преимущество : Flexibe. Он работает как с голыми, так и с обычными репозиториями, а также с sh, zsh и bash.
Объяснение
git tag
: Получение тегов репозитория, чтобы определить, существует он или нет.> /dev/null 2>&1
: Предотвращение печати чего-либо, включая нормальный вывод и вывод ошибок.[ $? -eq 0 ]
: Проверить, вернула ли предыдущая команда код выхода 0 или нет. Как вы, наверное, знаете, каждый ненулевой выход означает, что произошло что-то плохое.$?
получает код выхода предыдущей команды, и[
,-eq
и]
выполняет сравнение.Например, вы можете создать файл
check-git-repo
со следующим содержимым, сделать его исполняемым и запустить:#!/bin/sh if git tag > /dev/null 2>&1 && [ $? -eq 0 ]; then echo "Repository exists!"; else echo "No repository here."; fi
источник
Спасибо ivan_pozdeev , теперь у меня есть тест, если внутри каталога .git код не запускается, поэтому ошибки не распечатываются или статус ложного выхода.
Команда " ! [[$ (Pwd) = .git / || $ (pwd) = * .git]] " проверяет, не находитесь ли вы внутри репозитория .git, тогда он выполнит команду git. Команда встроенного типа используется для проверки того, установлен ли у вас git или он находится в вашем PATH. см. тип помощи
источник
Вы можете добавить или заменить свой $ PS1 в zshrc с помощью тех или иных инструментов git-prompt. Таким образом, вы можете удобно узнать, находитесь ли вы в репозитории git и находится ли оно в состоянии.
источник
! отрицает, поэтому даже если вы запустите это в каталоге, который не является репозиторием git, он не даст вам фатальных ошибок
> / DEV / нуль 2> & 1 отправляет сообщения / DEV / нуль , так как вы только после того, как статус выхода. {} Предназначены для командных группировок так что все команды после того , как || запустится, если git rev-parse завершился успешно, поскольку мы используем! что отменяет статус выхода git rev-parse. Printf просто напечатать некоторые сообщения и GIT статус для печати статус репо.
Оберните его в функцию или поместите в сценарий. Надеюсь это поможет
источник
.git
все получится, но распечататьfalse
.