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

ano*_*non 168 git zsh

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

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

jab*_*bie 141

从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;
Run Code Online (Sandbox Code Playgroud)

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

浓缩成适合bash或zsh的单行条件

[ -d .git ] || git rev-parse --git-dir > /dev/null 2>&1
Run Code Online (Sandbox Code Playgroud)

  • 应该更新答案以使用`git rev-parse --is-inside-git-dir`.在设置我的PS1之前,我个人使用`git rev-parse --is-inside-work-tree`. (14认同)
  • 你的一个班轮没有做同样的事情......也许它应该是这样的:`([ - d .git] && echo .git)|| git rev-parse --git-dir 2>/dev/null` (8认同)
  • @juliohm`-- is-inside-git-dir`只会在存储库的**..git`目录**中返回true.我不认为OP正在寻找那个. (7认同)
  • 当你在git repo之外时,`--is-inside-work-tree`和`--is-inside-git-dir`都不会起作用.请参阅:https://groups.google.com/forum/#!topic/git-users/dWc23LFhWxE (4认同)
  • 如果git目录不是`.git`,这将失败.为了健壮,省略`[-d .git]`并使用`git rev-parse ...`. (4认同)
  • 为什么不直接使用 git rev-parse? (3认同)
  • @ nyuszika7h,这也是我提到`--is-inside-work-tree`的原因. (3认同)
  • @fisherwebdev 该错误与我在 git repo 外部时从 `git rev-parse --git-dir` 得到的输出相同。这就是 stderr 被重定向的原因。该测试仍然适用于此目的。 (3认同)
  • @William Pursell为什么在你不需要时叉?主要针对琐碎案例中的速度. (2认同)
  • 请注意,只有当您当前位​​于存储库根目录中时,这才会按预期工作。不支持子目录。 (2认同)

TM.*_*TM. 105

您可以使用:

git rev-parse --is-inside-work-tree
Run Code Online (Sandbox Code Playgroud)

如果你在git repos工作树中,那将打印'true'.

请注意,如果您位于git repo之外,它仍然会将输出返回给STDERR(并且不会打印'false').

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

  • 对于没有工作树的裸存储库,这仍然会打印 false (4认同)

Wil*_*ell 41

使用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


Ale*_*ory 21

或者你可以这样做:

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
Run Code Online (Sandbox Code Playgroud)

  • [无冗余操作并在`-e`模式下工作:`[ "$(git rev-parse --is-inside-work-tree 2&gt;/dev/null)" == "true" ]`](https: //stackoverflow.com/questions/2180270/check-if-current-directory-is-a-git-repository/53367550#53367550) (3认同)
  • 我喜欢这个,因为它也适用于子目录 (2认同)

iva*_*eev 11

基于@Alex Cory 的回答

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

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

  • 正如@go2null 指出的那样,这在裸仓库中不起作用。如果您出于任何原因想使用裸仓库,您可以只检查是否git rev-parse成功,而忽略其输出。
    • 我不认为这是一个缺点,因为上面的行是为脚本编写的,而且几乎所有git命令都只在工作树内有效。因此,出于编写脚本的目的,您很可能不仅对“git repo”感兴趣,而且对工作树感兴趣。

  • 与其检查输出,不如检查返回值。根本不要调用`[`。只需执行“if git rev-parse --is-inside-work-tree;” 然后...`(根据需要进行重定向。) (4认同)
  • @WilliamPursell 检查退出值在这里不起作用:/sf/ask/152618931/#comment93611897_52938461 (2认同)
  • @Ivan_pozdeev 取决于你对“工作”的定义。在这种情况下,我想说检查返回值确实有效,而检查输出却不起作用。无论哪种情况,从在 shell 中编写代码的最佳实践的角度来看,检查返回值都更合适。 (2认同)

MAC*_*rha 8

为什么不使用退出代码?如果当前目录中存在 git 存储库,则git branchgit tag命令返回退出代码 0(即使没有标签或分支);否则,将返回非零退出代码。这样,您就可以确定 git 存储库是否存在。简单地说,您可以运行:

git tag > /dev/null 2>&1
Run Code Online (Sandbox Code Playgroud)

优点:便携。它适用于裸存储库和非裸存储库,以及 sh、zsh 和 bash。

解释

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

TLDR (真的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
Run Code Online (Sandbox Code Playgroud)


小智 7

不确定是否有可公开访问/记录的方法来执行此操作(有一些内部git函数可以在git源本身中使用/滥用)

你可以做点什么;

if ! git ls-files >& /dev/null; then
  echo "not in git"
fi
Run Code Online (Sandbox Code Playgroud)


小智 6

另一种解决方案是检查命令的退出代码.

git rev-parse 2> /dev/null; [ $? == 0 ] && echo 1
Run Code Online (Sandbox Code Playgroud)

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

  • `[ $? == 0 ]` 在这里是多余的;这就是 `&amp;&amp;` 已经做的隐含测试。上面的命令相当于 `git rev-parse 2&gt;/dev/null &amp;&amp; echo 1`。 (2认同)

go2*_*ull 5

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

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

git返回ERRORLEVEL0如果它是一个Git仓库里面,否则返回错误级别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
Run Code Online (Sandbox Code Playgroud)