Найдите корень репозитория git, где находится файл
При работе в Python (например, запустите script), как я могу найти путь к корню репозитория git, где живет script?
До сих пор я знаю, что могу получить текущий путь:
path_to_containing_folder = os.path.dirname(os.path.realpath(__file__))
Как я могу узнать, где живет репозиторий git?
Ответы
Ответ 1
Используйте модуль GitPython http://gitpython.readthedocs.io/en/stable/.
pip install gitpython
Предположим, что у вас есть локальный репозиторий Git в /path/to/.git
. Нижеприведенный пример получает /path/to/your/file
как вход, он правильно возвращает корень Git как /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")
Ответ 2
Поиск каталога .git
не будет работать во всех случаях. Правильная команда git:
git rev-parse --show-toplevel
Ответ 3
Я написал небольшой модуль python для этой задачи:
https://github.com/MaxNoe/python-gitpath
Установить с помощью pip install git+https://github.com/maxnoe/python-gitpath
Использование:
import gitpath
print(gitpath.root())
print(gitpath.abspath('myfile.txt'))
gitpath.abspath(relative_path)
вернет абсолютный путь на вашем компьютере
для пути, заданного относительно корня репозитория git.
Код для получения корня частично получен из комментария 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()
Кэширование делает второй вызов root()
ca. 3500 раз быстрее (измеряется с помощью ipython
и %%timeit
)
Ответ 4
Модуль GitPython предоставляет этот атрибут прямо из коробки:
import git
repo = git.Repo('.', search_parent_directories=True)
repo.working_tree_dir
Ответ 5
Эта функция является общей (не зависит от внешнего модуля или вызова команды git
).
Он ищет путь от заданного пути, чтобы найти первый, содержащий каталог .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
Пример использования:
import os
print(vcs_root(os.path.dirname(__file__)))
Или проверьте наличие другого контроля версий:
import os
print(vcs_root(os.path.dirname(__file__)), dirs=(".hg", ".git", ".svn"))
Ответ 6
Я не знаю много о python, но я думаю, что вы можете продолжать каталоги с помощью
os.path.abspath(os.path.join(dir, '..'))
Пока вы не обнаружите каталог .git
(os.walk
может помочь)
Ответ 7
Без каких-либо внешних библиотек:
import subprocess
def getGitRoot():
return subprocess.Popen(['git', 'rev-parse', '--show-toplevel'], stdout=subprocess.PIPE).communicate()[0].rstrip().decode('utf-8')