Encuentra la raíz del repository de git donde vive el file

Cuando trabajo en Python (por ejemplo, ejecutando un script), ¿cómo puedo encontrar la ruta de la raíz del repository de git donde vive el script?

Hasta ahora sé que puedo get la ruta actual con:

path_to_containing_folder = os.path.dirname(os.path.realpath(__file__)) 

¿Cómo puedo averiguar dónde vive el repository git?

Use el module de GitPython http://gitpython.readthedocs.io/en/stable/ .

 pip install gitpython 

Supongamos que tiene un /path/to/.git local de Git en /path/to/.git . El ejemplo siguiente recibe /path/to/your/file como input, devuelve correctamente la raíz de Git como /path/to/ .

 import git def get_git_root(path): git_repo = git.Repo(path, search_parent_directories=True) git_root = git_repo.git.rev_parse("--show-toplevel") print git_root if __name__ == "__main__": get_git_root("/path/to/your/file") 

Buscar un directory .git no funcionará en todos los casos. El command correcto de git es:

 git rev-parse --show-toplevel 

Acabo de escribir un pequeño module de python para esta tarea: https://github.com/MaxNoe/python-gitpath

Instalar con pip install git+https://github.com/maxnoe/python-gitpath

Uso:

 import gitpath print(gitpath.root()) print(gitpath.abspath('myfile.txt')) 

gitpath.abspath(relative_path) devolverá la ruta absoluta en su máquina para una ruta dada relativa a la raíz del repository de git.

El código para get la raíz se deriva parcialmente del comentario de Ryne Everetts:

 from subprocess import check_output, CalledProcessError from functools import lru_cache @lru_cache(maxsize=1) def root(): ''' returns the absolute path of the repository root ''' try: base = check_output('git rev-parse --show-toplevel', shell=True) except CalledProcessError: raise IOError('Current working directory is not a git repository') return base.decode('utf-8').strip() 

El almacenamiento en caching hace que la segunda llamada a root() ca. 3500 veces más rápido (medido con ipython y %%timeit )

Esta function es genérica (no depende del module externo ni git command de llamada git ). Busca desde una ruta determinada para encontrar la primera que contiene un directory .git .

 def find_vcs_root(test, dirs=(".git",), default=None): import os prev, test = None, os.path.abspath(test) while prev != test: if any(os.path.isdir(os.path.join(test, d)) for d in dirs): return test prev, test = test, os.path.abspath(os.path.join(test, os.pardir)) return default 

Ejemplo de uso:

 import os print(vcs_root(os.path.dirname(__file__))) 

O busca otro control de versión:

 import os print(vcs_root(os.path.dirname(__file__)), dirs=(".hg", ".git", ".svn")) 

No sé mucho sobre Python, pero creo que podrías seguir bajando por un directory con

 os.path.abspath(os.path.join(dir, '..')) 

Hasta que detecte un directory .git ( os.walk podría ayudar)