web-dev-qa-db-fra.com

Déterminer si le répertoire est sous contrôle git

Comment savoir si un répertoire donné fait partie d'un référentiel git?

(Ce qui suit est en python, mais bash ou quelque chose irait bien.)

os.path.isdir('.svn')

vous dira si le répertoire courant est contrôlé par Subversion. Mercurial et Git ont juste un .hg/.git en haut du dépôt, donc pour hg je peux utiliser

os.system('hg -q stat 2> /dev/null > /dev/null') == 0)

mais git status renvoie un état de sortie non nul (erreur) si rien n'a changé.

Parcourt le chemin à la recherche de .git moi du mieux que je peux faire?

63
Grumdrig

Dans Ruby, system('git rev-parse') renverra true si le répertoire courant est dans un dépôt git, et false sinon. J'imagine que l'équivalent Pythonic devrait fonctionner de la même manière.

EDIT: Bien sûr:

# in a git repo, running ipython
>>> system('git rev-parse')
0

# not in a git repo
>>> system('git rev-parse')
32768

Notez qu'il y a une sortie sur STDERR lorsque vous n'êtes pas dans un repo, si cela vous importe.

43
John Hyland

Je viens de trouver ceci dans git help rev-parse

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

affiche true s'il se trouve dans l'arborescence de travail, false s'il se trouve dans l'arborescence '.git', et une erreur fatale si ce n'est ni l'un ni l'autre. 'True' et 'false' sont imprimés sur stdout avec un état de sortie de 0, l'erreur fatale est imprimée sur stderr avec un état de sortie de 128.

82
falstro

Avec gitpython, vous pouvez créer une fonction comme celle-ci:

import git

...

def is_git_repo(path):
    try:
        _ = git.Repo(path).git_dir
        return True
    except git.exc.InvalidGitRepositoryError:
        return False
7
Pablo

Pour mémoire, utilisez git status ou similaire, c'est juste pour être complet: :)

La recherche vers le haut d'un arbre n'est pas vraiment un problème, en bash, vous pouvez faire cette simple ligne (si vous la mettez sur une seule ligne ...);) Retourne 0 si on en trouve, 1 sinon.

d=`pwd`
while [ "$d" != "" ]; do
  [ -d "$d"/.git ] && exit 0
  d=${d%/*}
done
exit 1

recherchera vers le haut un dossier .git.

4
falstro

Eh bien, le répertoire peut également être ignoré par le fichier .gitignore - vous devez donc rechercher un référentiel .git, et s'il en existe un, analysez le .gitignore pour voir si ce répertoire se trouve bien dans le référentiel git.

Que veux-tu faire exactement? Il peut y avoir un moyen plus simple de procéder.

EDIT: Voulez-vous dire "Ce répertoire est-il la racine d'un référentiel GIT" ou, voulez-vous dire "Ce répertoire fait-il partie d'un référentiel GIT"?

Pour le premier, vérifiez simplement s'il y a un .git - puisque c'est à la racine, et vous avez terminé. Pour le second, une fois que vous avez déterminé que vous êtes dans un référentiel GIT, vous devez vérifier .gitignore pour le sous-répertoire en question.

4
Trevoke

Il est difficile de définir ce qu'un .git/ le référentiel est

J'ai fait un peu d'expérimentation pour voir ce que Git considère comme un référentiel Git.

Depuis la version 1.9.1, la structure de répertoire minimale qui doit être à l'intérieur d'un .git répertoire pour que Git le considère comme:

mkdir objects refs
printf 'ref: refs/' > HEAD

tel que reconnu par rev-parse.

C'est aussi évidemment un référentiel corrompu dans lequel les commandes les plus utiles échoueront.

Le moral est: comme toute autre détection de format, les faux positifs sont inévitables, surtout ici que le repo minimal est si simple.

Si vous voulez quelque chose de robuste, au lieu de détecter s'il s'agit d'un dépôt Git, essayez de faire ce que vous voulez faire, et soulevez des erreurs et traitez-les en cas d'échec.

Il est plus facile de demander pardon que d'obtenir la permission.

De git help rev-parse encore une fois, je pense que vous pouvez faire quelque chose comme:

git rev-parse --resolve-git-dir <directory> 

et vérifiez si la commande renvoie le chemin du répertoire lui-même. Selon le manuel git rev-parse renvoie le chemin d'accès au répertoire si l'argument contient un dépôt git ou est un fichier qui contient le chemin d'accès à un dépôt git.

2
eerpini

En utilisant git rev-parse --is-inside-work-tree de même que subprocess.Popen, vous pouvez vérifier si "true" est imprimé à partir de la sortie indiquant que le répertoire a un dépôt git:

import subprocess

repo_dir = "../path/to/check/" 

command = ['git', 'rev-parse', '--is-inside-work-tree']
process = subprocess.Popen(command, stdout=subprocess.PIPE, cwd=repo_dir,
                           universal_newlines=True)
process_output = process.communicate()[0]

is_git_repo = str(process_output.strip())

if is_git_repo == "true":
    print("success! git repo found under {0}".format(repo_dir))
else:
    print("sorry. no git repo found under {0}".format(repo_dir))
0
Ray Vega

Si vous préférez rechercher un .gitdirectory, voici une jolie façon de le faire dans Ruby:

require 'pathname'

def gitcheck()
  Pathname.pwd.ascend {|p| return true if (p + ".git").directory? }
  false
end

Je ne peux pas trouver quelque chose de similaire à monter en Python.

0
skagedal

Ajoutez-le à votre .bash_profile, et votre invite affichera toujours la branche git active et si vous avez des modifications non validées.

function parse_git_dirty {
  [[ $(git status 2> /dev/null | tail -n1) != "nothing to commit (working directory clean)" ]] && echo "*"
}
function parse_git_branch {
  git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e "s/* \(.*\)/[\1$(parse_git_dirty)]/"
}

export PS1=' \[\033[0;33m\]\w\[\033[00m\]\[\033[01;00m\]$(parse_git_branch): ' #PS1='\w> '

Vous verrez ceci:

 ~: 
 ~: cd code/scala-plugin/
 ~/code/scala-plugin[master*]: 
0
retronym