检查当前目录是否是Git存储库

我正在zsh中编写Git管理的一系列脚本。

如何检查当前目录是否是Git存储库?(当我不在Git repo时,我不想执行一堆命令并获得一堆fatal: Not a git repository响应)。

160397 次浏览

从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;

您可以将其包装在函数中,也可以在脚本中使用。

浓缩成适合bashzsh的一行条件

[ -d .git ] && echo .git || git rev-parse --git-dir > /dev/null 2>&1

不确定是否有公开可访问/记录的方法来做到这一点(有一些内部git函数,你可以在git源代码中使用/滥用)

你可以这样做;

if ! git ls-files >& /dev/null; then
echo "not in git"
fi

使用git rev-parse——git-dir

if git rev-parse --git-dir > /dev/null 2>&1; then
: # This is a valid git repository (but the current working
# directory may not be the top level.
# Check the output of the git rev-parse command if you care)
else
: # this is not a git repository
fi

edit: git-rev-parse现在(从1.7.0开始)支持--show-toplevel,所以你可以执行if test "$(pwd)" = "$(git rev-parse --show-toplevel)"来确定当前目录是否是顶级目录。

你可以使用:

git rev-parse --is-inside-work-tree

这将打印'true'如果你在一个git回购工作树。

注意,如果你在git repo之外,它仍然返回输出到STDERR(并且不打印'false')。

从这个答案:https://stackoverflow.com/a/2044714/12983

这对我很有用。您仍然会得到错误,但它们很容易被抑制。它也可以在子文件夹中工作!

git status >/dev/null 2>&1 && echo Hello World!

如果需要有条件地执行更多操作,可以将其放入if then语句中。

另一个解决方案是检查命令的退出码。

git rev-parse 2> /dev/null; [ $? == 0 ] && echo 1

如果你在git存储库文件夹中,这将打印1。

或者你可以这样做:

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

这个答案提供了一个示例POSIX shell函数和一个使用示例来补充@jabbie的回答

is_inside_git_repo() {
git rev-parse --is-inside-work-tree >/dev/null 2>&1
}

如果它在git存储库中,git返回errorlevel 0,否则返回errorlevel 128。(如果它在git存储库中,它也会返回truefalse。)

使用的例子

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

基于@Alex Cory的回答:

[ "$(git rev-parse --is-inside-work-tree 2>/dev/null)" = "true" ]

不包含任何冗余操作,工作在-e模式。

  • 正如@go2null所指出的,这将在裸回购中不起作用。如果你出于某种原因想要使用空回购,你可以只检查git rev-parse是否成功,忽略它的输出。
    • 我不认为这是一个缺点,因为上面的行对于脚本是缩进的,而且实际上所有git命令只在工作树中有效。因此,出于编写脚本的目的,您最感兴趣的可能不仅仅是在“;git repo"但是在工作树中。

#检查git是否回购

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

为什么不用退出码?如果当前目录中存在git存储库,则git branchgit tag命令返回退出码为0;否则,将返回非零退出代码。通过这种方式,您可以确定git存储库是否存在。简单地说,你可以运行:

git tag > /dev/null 2>&1

优势:便携式。它既适用于裸库,也适用于非裸库,以及在sh、zsh和bash中。

解释

  1. git tag:获取存储库的标记,以确定是否存在。
  2. > /dev/null 2>&1:阻止打印任何东西,包括正常和错误输出。

TLDR (Re一个lly?): check-git-repo

例如,你可以创建一个名为check-git-repo的文件,包含以下内容,使其可执行并运行:

#!/bin/sh


if git tag > /dev/null 2>&1; then
echo "Repository exists!";
else
echo "No repository here.";
fi
##Current branch
echo $(git branch --show-current 2> /dev/null && echo '')
echo $(git branch --show-current 2> /dev/null)


##OR
GIT_DIR=$(git rev-parse --git-dir 2> /dev/null)