Vérifiez si le répertoire actuel est un référentiel Git


197

J'écris une série de scripts pour la gestion de Git dans zsh.

Comment vérifier si le répertoire courant est un référentiel Git? (Quand je ne suis pas dans un dépôt Git, je ne veux pas exécuter un tas de commandes et obtenir un tas de fatal: Not a git repositoryréponses).


Avez-vous consulté le fichier d'achèvement bash (dans contrib / complétement / git-complétion.bash) pour trouver l'inspiration? J'utilise la commande __git_ps1 dans le cadre de mon invite bash. En fait, la plupart de ces sources proviendront de zsh. La fonction __gitdir est probablement celle que vous souhaitez.
jabbie

1
@jabbie: pourquoi n'en faites-vous pas une réponse?
amarillion

Avez-vous déjà vérifié les fonctions de la distribution zsh?
MBO


1
Note: aucune des réponses actuelles considèrent les $GIT_DIRou $GIT_WORK_TREEvariables d' environnement, ou la façon dont ils interagissent.
o11c

Réponses:


154

Copié à partir du fichier d'achèvement bash, ce qui suit est une façon naïve de le faire

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

Vous pouvez soit envelopper cela dans une fonction, soit l'utiliser dans un script.

Condensé dans une condition d'une ligne adaptée à bash et zsh

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

3
@William Pursell Pourquoi bifurquer quand vous n'en avez pas besoin? Principalement pour la vitesse dans le cas trivial.
jabbie

16
La réponse doit être mise à jour pour être utilisée git rev-parse --is-inside-git-dir. J'utilise personnellement git rev-parse --is-inside-work-treeavant de régler ma PS1.
juliohm

11
@juliohm --is-inside-git-dirne retournera true que si vous êtes réellement dans le .gitrépertoire d'un référentiel. Je ne pense pas que le PO recherche cela.
nyuszika7h

7
Ni --is-inside-work-treeni --is-inside-git-dirne fonctionnera lorsque vous êtes en dehors d'un dépôt git. voir: groups.google.com/forum/#!topic/git-users/dWc23LFhWxE
fisherwebdev

7
Cela échouera si le répertoire git est autre chose que .git. Pour la robustesse, omettez le [ -d .git ]et utilisez simplement git rev-parse ....
Peter John Acklam

133

Vous pouvez utiliser:

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

Ce qui sera affiché `` vrai '' si vous êtes dans une arborescence de travail git repos.

Notez qu'il retourne toujours la sortie à STDERR si vous êtes en dehors d'un dépôt git (et n'imprimez pas 'false').

Tiré de cette réponse: https://stackoverflow.com/a/2044714/12983


C'est le moyen le plus simple de le vérifier.
calbertts

3
Cela affichera toujours faux pour un référentiel nu qui n'a pas d'arbre de travail
noggin182

Cela ne prend pas en compte le sous-répertoire. Je dois vérifier la git rev-parse --show-toplevelcorrespondance avec le sous-dossier que je vérifie
alper

La réponse choisie n'a même rien imprimé. Celui-ci a fonctionné.
ScottyBlades

47

Utilisez git rev-parse --git-dir

if git rev-parse --git-dir> / dev / null 2> & 1; puis
  : # Ceci est un dépôt git valide (mais le fonctionnement actuel
    Le répertoire # n'est peut-être pas le niveau supérieur.
    # Vérifiez la sortie de la commande git rev-parse si vous vous en souciez)
autre
  : # ce n'est pas un dépôt git
Fi


7

Je ne sais pas s'il existe un moyen accessible au public / documenté de le faire (il existe certaines fonctions internes de git que vous pouvez utiliser / abuser dans la source git elle-même)

Vous pourriez faire quelque chose comme;

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

7

D' après la réponse de @Alex Cory :

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

ne contient aucune opération redondante et fonctionne en -emode.

  • Comme l'a noté @ go2null , cela ne fonctionnera pas dans un référentiel nu. Si vous souhaitez travailler avec un référentiel nu pour une raison quelconque, vous pouvez simplement vérifier la git rev-parseréussite, en ignorant sa sortie.
    • Je ne considère pas cela comme un inconvénient car la ligne ci-dessus est destinée aux scripts, et pratiquement toutes les gitcommandes ne sont valides qu'à l'intérieur d'un arbre de travail. Donc, à des fins de script, vous êtes probablement intéressé non seulement à l'intérieur d'un "git repo" mais à l'intérieur d'un worktree.

cela échoue à l'intérieur d'un repo nu git
go2null

Plutôt que de vérifier la sortie, il est préférable de vérifier la valeur de retour. N'invoquez pas [du tout. if git rev-parse --is-inside-work-tree; then ...
William Pursell

1
@WilliamPursell vérifier la valeur de sortie ne fonctionne pas ici: stackoverflow.com/questions/2180270/…
ivan_pozdeev

@Ivan_pozdeev Dépend de votre définition du "travail". Dans ce cas, je dirais que la vérification de la valeur de retour fonctionne, tandis que la vérification de la sortie ne fonctionne pas. Dans les deux cas, du point de vue des meilleures pratiques pour écrire du code dans le shell, il est plus approprié de vérifier la valeur de retour.
William Pursell

@WilliamPursell si vous lisez le commentaire lié, vous saurez ce que je voulais dire par "ne fonctionne pas" ici.
ivan_pozdeev

6

Une autre solution consiste à vérifier le code de sortie de la commande.

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

Cela affichera 1 si vous êtes dans un dossier de référentiel git.


Notez que cela aura rc 0 même si vous êtes dans le .gitrépertoire - que vous souhaitiez ou non.
ivan_pozdeev

Git est écrit sanely afin que vous puissiez tout simplement fermer les fichiers que vous ne voulez pas, git rev-parse 2>&-.
jthill

3

Cette réponse fournit un exemple de fonction shell POSIX et un exemple d'utilisation pour compléter la réponse de @ jabbie .

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

gitrenvoie errorlevel 0s'il se trouve dans un référentiel git, sinon il renvoie errorlevel 128. (Il retourne également trueou falses'il se trouve dans un référentiel git.)

Exemple d'utilisation

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

Insuffisant. A l'intérieur .git, il réussira mais s'imprimera false.
ivan_pozdeev

@ivan_pozdeev: Si le git rev-parse --is-inside-work-treerendement trueou falsealors il est dans un git, et c'est - ce que la fonction retourne. c'est-à-dire que la fonction est correcte
go2null

pour développer, voir la description dans la réponse, la valeur retournée par git est ignorée, le niveau d'erreur est ce qui est utilisé.
go2null

2

cela fonctionne pour moi. Vous obtenez toujours les erreurs mais elles sont assez faciles à supprimer. cela fonctionne également à partir des sous-dossiers!

git status> / dev / null 2> & 1 && echo Bonjour tout le monde!

Vous pouvez mettre cela dans une instruction if then si vous devez en faire plus conditionnellement.


2
Peut-être assez bon pour de nombreux cas, mais il échoue sur un repo nu.
Wildcard

3
git statuspeut être très lent sur un gros / vieux dépôt. Je ne l'utiliserais pas à cette fin.
henrebotha

1

Pourquoi ne pas utiliser les codes de sortie? Si un référentiel git existe dans le répertoire courant, alors git branchet les git tagcommandes renvoient le code de sortie de 0; sinon, un code de sortie différent de zéro sera retourné. De cette façon, vous pouvez déterminer si un référentiel git existe ou non. Vous pouvez simplement exécuter:

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

Avantage : Flexibe. Il fonctionne pour les référentiels nus et non nus, ainsi que pour sh, zsh et bash.

Explication

  1. git tag: Obtenir des balises du référentiel pour déterminer s'il existe ou non.
  2. > /dev/null 2>&1: Empêche d'imprimer quoi que ce soit, y compris les sorties normales et d'erreur.
  3. [ $? -eq 0 ]: Vérifiez si la commande précédente est retournée avec le code de sortie 0 ou non. Comme vous le savez peut-être, chaque sortie non nulle signifie que quelque chose de mauvais s'est produit. $?obtient le code de sortie de la commande précédente, et [, -eqet ]effectue la comparaison.

Par exemple, vous pouvez créer un fichier nommé check-git-repoavec le contenu suivant, le rendre exécutable et l'exécuter:

#!/bin/sh

if git tag > /dev/null 2>&1 && [ $? -eq 0 ]; then
    echo "Repository exists!";
else
    echo "No repository here.";
fi

0

# vérifier si 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

Ce n'est pas la meilleure pratique. S'il est exécuté en dehors d'un répertoire de travail, vous obtiendrez "fatal: pas un référentiel git (ou aucun des répertoires parents): .git" écrit sur stderr, et "non, n'est pas un dépôt git" sur stdout. Il n'est pas du tout nécessaire d'invoquer [ici. Faites juste:if git rev-parse --is-inside-work-tree > /dev/null 2>&1; then ....
William Pursell

Dans mon cas, je suis à l'aise avec cela et je veux suivre ce problème dans mes journaux. À votre santé!
Pascal Andy

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

Merci ivan_pozdeev , maintenant j'ai un test si à l'intérieur du répertoire .git le code ne fonctionnera pas donc aucune erreur imprimée ou faux statut de sortie.

Les tests " ! [[$ (Pwd) = .git / || $ (pwd) = * .git]] " "si vous n'êtes pas dans un dépôt .git alors il exécutera la commande git. La commande de type intégré est utilisée pour vérifier si vous avez installé git ou s'il se trouve dans votre PATH. voir le type d'aide


0

Comment ça:

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

-1

Vous pouvez ajouter ou remplacer votre $ PS1 dans votre zshrc avec l' un ou l' autre des outils git-prompt. De cette façon, vous pouvez être facilement informé de si vous êtes dans un dépôt git et de l'état du dépôt.


3
Toute la question du PO était de savoir comment le faire à partir d'un script
Andrew C

et comment __git_ps1 ne peut-il pas être utilisé à partir d'un script? L'intérêt de git-prompt est de vérifier l'état git du répertoire courant, ce qui a été demandé.
jxqz

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

Le ! nie donc même si vous l'exécutez dans un répertoire qui n'est pas un dépôt git, cela ne vous donnera pas d'erreurs fatales

Le > / dev / null 2> & 1 envoie les messages à / dev / null puisque vous êtes juste après l'état de sortie. Les {} sont pour les groupes de commandes, donc toutes les commandes après le || fonctionnera si git rev-parse a réussi puisque nous utilisons a! ce qui annule le statut de sortie de git rev-parse. Le printf est juste pour imprimer un message et un statut git pour imprimer le statut du dépôt.

Enveloppez-le dans une fonction ou mettez-le dans un script. J'espère que cela t'aides


1
Insuffisant. A l'intérieur .git, il réussira mais s'imprimera false.
ivan_pozdeev
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.