現在のディレクトリがGitリポジトリかどうかを確認する


197

zshでGit管理用の一連のスクリプトを書いています。

現在のディレクトリがGitリポジトリかどうかを確認するにはどうすればよいですか?(私がGitリポジトリにいないときは、一連のコマンドを実行して一連のfatal: Not a git repository応答を取得する必要はありません)。


インスピレーションを得るために(contrib / completion / git-completion.bashにある)bash完了ファイルを確認しましたか?私はbashプロンプトの一部として__git_ps1コマンドを使用しています。実際、そのほとんどはzsh内で提供されます。__gitdir関数はおそらく必要なものです。
ジャビー

1
@jabbie:答えを出してみませんか?
2010

zshディストリビューションですでに機能を確認しましたか?
MBO


1
注:現在の回答では、$GIT_DIR$GIT_WORK_TREE環境変数、またはそれらの相互作用については考慮されていません。
o11c 2018

回答:


154

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に適した1行の条件に圧縮

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

3
@William Pursellなぜ必要がないのにフォークするのですか?ささいな場合の速度を主に。
ジャビー

16
回答はを使用するように更新する必要がありますgit rev-parse --is-inside-git-dirgit rev-parse --is-inside-work-treePS1をセットする前に個人的に使用しています。
juliohm 2013

11
@juliohm --is-inside-git-dirは、実際にリポジトリの.gitディレクトリ内にいる場合にのみtrueを返します。OPがそれを探しているとは思いません。
nyuszika7h

7
どちら--is-inside-work-tree--is-inside-git-dir、gitリポジトリの外にいるときは機能しません。参照:groups.google.com/forum
#!topic

7
gitディレクトリが以外の場合、これは失敗し.gitます。堅牢性のために、を省略して[ -d .git ]を使用してくださいgit rev-parse ...
Peter John Acklam

133

以下を使用できます。

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

git reposワーキングツリーにいる場合は、「true」と出力されます。

gitリポジトリの外にいる場合でも、出力はSTDERRに返されることに注意してください(「false」を出力しません)。

この回答から引用:https : //stackoverflow.com/a/2044714/12983


これは、これをチェックする最も簡単な方法です。
calbertts

3
これは、作業ツリーのないベアリポジトリでは引き続きfalseを出力します
noggin182

これはサブディレクトリを考慮しません。私がgit rev-parse --show-toplevelチェックしているサブフォルダーと一致するかどうかを確認する必要があります
alper

選ばれた答えは何も出力しませんでした。これはうまくいきました。
ScottyBlades

47

git rev-parse --git-dirを使用します

if git rev-parse --git-dir> / dev / null 2>&1; その後
  :#これは有効なgitリポジトリです(ただし、現在の作業
    #ディレクトリが最上位でない可能性があります。
    #必要に応じてgit rev-parseコマンドの出力を確認してください)
そうしないと
  :#これはgitリポジトリではありません
fi


7

これを行うための公的にアクセス可能な/文書化された方法があるかどうかは不明です(gitソース自体で使用/乱用できる内部git関数がいくつかあります)

次のようなことができます。

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

7

@アレックスコーリーの答えに基づいて:

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

冗長な操作は含まれておらず、-eモードで動作します。

  • @ go2nullが指摘したように、これはベアリポジトリでは機能しません。何らかの理由でベアリポジトリで作業したい場合はgit rev-parse、その出力を無視して、成功したかどうかを確認できます。
    • 上記の行はスクリプト記述用であり、事実上すべてのgitコマンドはワークツリー内でのみ有効であるため、これを欠点とは考えていません。したがって、スクリプト作成の目的では、「gitリポジトリ」内だけでなく、ワークツリー内にも興味がある可能性があります。

これは裸のgitリポジトリ内では失敗します
go2null '29年

出力をチェックするのではなく、戻り値をチェックすることをお勧めします。まったく呼び出さない[でください。ただ、やるif git rev-parse --is-inside-work-tree; then ...(必要に応じてリダイレクトして。)
ウィリアム・Pursell

1
:終了値はここで働いていませんチェック@WilliamPursell stackoverflow.com/questions/2180270/...
ivan_pozdeev

@Ivan_pozdeev「仕事」の定義によって異なります。この場合、戻り値のチェックは機能しますが、出力のチェックは機能しません。どちらの場合でも、シェルでコードを記述するためのベストプラクティスの観点からは、戻り値を確認する方が適切です。
ウィリアムパーセル、

@WilliamPursellリンクされたコメントを読むと、ここで「機能しない」という意味を理解できます。
ivan_pozdeev

6

別の解決策は、コマンドの終了コードを確認することです。

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

gitリポジトリフォルダーにいる場合は、1が出力されます。


これは、.gitディレクトリ内にいる場合でもrc 0になることに注意してください。
ivan_pozdeev

Gitは正常に記述されているため、不要なファイルを閉じることができますgit rev-parse 2>&-
jthill

3

この回答では、サンプルのPOSIXシェル関数と、@ jabbieの回答を補足する使用例を示します

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

git0gitリポジトリ内にある場合はerrorlevelを返し、それ以外の場合はerrorlevelを返します128。(また、それが返されるtruefalse、それが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 '29年

展開するには、回答の説明を参照してください。gitから返された値は無視され、errorlevelが使用されます。
go2null

2

これは私にとってはうまくいきます。あなたはまだエラーを受け取りますが、それらは抑制するのに十分簡単です。サブフォルダー内からも機能します!

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

条件付きでさらに実行する必要がある場合、これをif thenステートメントに入れることができます。


2
おそらく多くの場合には十分ですが、gitのリポジトリでは失敗します。
ワイルドカード

3
git status大きな/古いリポジトリでは非常に遅くなる可能性があります。この目的には使用しません。
henrebotha

1

なぜ終了コードを使わないのですか?Gitのリポジトリが現在のディレクトリに存在する場合、git branchおよびgit tagコマンド0の終了コードを返します。それ以外の場合は、ゼロ以外の終了コードが返されます。このようにして、gitリポジトリが存在するかどうかを確認できます。簡単に言うと、次のように実行できます。

git tag > /dev/null 2>&1 && [ $? -eq 0 ]

利点:Flexibe。ベアリポジトリと非ベアリポジトリの両方、およびsh、zsh、bashで動作します。

説明

  1. git tag:リポジトリーのタグを取得して、存在するかどうかを判別します。
  2. > /dev/null 2>&1:通常の出力やエラー出力など、何も印刷しないようにします。
  3. [ $? -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

0

#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

これはベストプラクティスではありません。作業ディレクトリの外で実行すると、stderrに「致命的:gitリポジトリではない(または親ディレクトリのいずれか):.git」、標準出力では「いいえ、gitリポジトリではありません」と表示されます。[ここで呼び出す必要はまったくありません。ただやる:if git rev-parse --is-inside-work-tree > /dev/null 2>&1; then ....
ウィリアムパーセル

私の場合、私はこれに慣れており、このグリッチをログで追跡したいと思います。乾杯!
Pascalアンディ

0
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コマンドを実行します。組み込みのtypeコマンドは、gitがインストールされているかどうか、またはPATH内にあるかどうかを確認するために使用されます。ヘルプの種類を見る


0

これはどうですか:

if git status -s 2>/dev/null;then
    echo "this is a git repo"
else
    echo "this is NOT a git repo"
fi

-1

zshrc内の$ PS1を追加するか、1つまたは別の git-promptツールで置き換えることができます。このようにすると、gitリポジトリにいて、リポジトリの状態にあるかどうかを簡単に通知できます。


3
OP全体の質問は、スクリプト内からそれを行う方法でした
Andrew C

また、__ git_ps1をスクリプト内から使用できないようにするにはどうすればよいですか。git-promptの要点は、要求された現在のディレクトリのgitステータスを確認することです。
jxqz 2014年

-1
! git rev-parse --is-inside-work-tree >/dev/null 2>&1 || { 
  printf '%s\n\n' "GIT repository detected." && git status
}

!否定するので、gitリポジトリではないディレクトリでこれを実行しても、致命的なエラーは発生しません

>を/ dev / null 2>&1にメッセージを送信するの/ dev / nullにあなただけの終了ステータス後にしているからです。{}後、コマンドのグループのためにので、すべてのコマンドである|| !を使用しているため、git rev-parseが成功した場合に実行されます。これはgit rev-parseの終了ステータスを無効にしました。printf関数は、ちょうどレポの状況を印刷するためにいくつかのメッセージとgitの状態を印刷することです。

関数で囲むか、スクリプトに入れます。お役に立てれば


1
十分ではありません。内部.gitでは、成功しますが印刷されますfalse
ivan_pozdeev
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.