找到文件所在的git存储库的根目录

Ame*_*ina 19 python git

在Python中工作(例如运行脚本)时,如何找到脚本所在的git存储库根目录的路径?

到目前为止,我知道我可以获得当前路径:

path_to_containing_folder = os.path.dirname(os.path.realpath(__file__))
Run Code Online (Sandbox Code Playgroud)

那么我怎样才能找到git存储库所在的位置?

mic*_*has 19

.git在所有情况下查找目录都不起作用.正确的git命令是:

git rev-parse --show-toplevel
Run Code Online (Sandbox Code Playgroud)

  • Future Self的注释:`repo_dir = subprocess.Popen(['git','rev-parse',' - show-toplevel'],stdout = subprocess.PIPE).communicate()[0] .rstrip().解码( 'UTF-8')` (7认同)
  • @danodonovan 如果你有工作树签出,你可以有一个 ``.git`` 文件而不是目录。 (3认同)
  • 只是想知道,在什么情况下寻找“.git”目录不起作用? (2认同)

qua*_*uat 15

使用GitPython模块http://gitpython.readthedocs.io/en/stable/.

pip install gitpython
Run Code Online (Sandbox Code Playgroud)

假设您有一个本地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")
Run Code Online (Sandbox Code Playgroud)

  • 一旦你有了 repo,你就可以使用 `git_repo.working_dir` (8认同)
  • 这个对我有用。在调用此函数时使用 `os.getcwd()` 而不是 `"/path/to/your/file"` 很有用。谢谢。 (2认同)

Civ*_*Fan 11

GitPython模块提供的这个属性右出的现成为您提供:

import git

repo = git.Repo('.', search_parent_directories=True)
repo.working_tree_dir
Run Code Online (Sandbox Code Playgroud)

  • 这是正确的答案,因为它不依赖于跨平台无法正常工作的 shell。 (4认同)
  • 如果您想支持裸存储库,请改用“working_dir”。 (2认同)

rou*_*ble 11

没有任何外部库:

import subprocess

def getGitRoot():
    return subprocess.Popen(['git', 'rev-parse', '--show-toplevel'], stdout=subprocess.PIPE).communicate()[0].rstrip().decode('utf-8')
Run Code Online (Sandbox Code Playgroud)

  • 我把这个答案变成了一个单功能Python包,可以通过pip(`pip install git_root`)和conda(`conda install -c conda-forge git_root`)获得:请参阅https://github.com/jtilly /git_root @rouble 我希望你没问题! (4认同)

Max*_*Noe 7

我刚刚为此任务编写了一个小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'))
Run Code Online (Sandbox Code Playgroud)

gitpath.abspath(relative_path) 将返回机器上的绝对路径,以获取相对于git存储库根目录的路径.

获取root的代码部分来自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()
Run Code Online (Sandbox Code Playgroud)

缓存第二次调用root()ca. 快3500倍(用ipython和测量%%timeit)


mik*_*sus 7

我发现其他答案对于这项任务来说太混乱了,所以我创建了这个函数来解决这个问题。基本上,它循环遍历给定路径的父目录并返回第一个包含“.git”目录的目录。如果没有找到,则返回 None。

from pathlib import Path

def find_repo(path):
    "Find repository root from the path's parents"
    for path in Path(path).parents:
        # Check whether "path/.git" exists and is a directory
        git_dir = path / ".git"
        if git_dir.is_dir():
            return path

# Find the repo root where the script is
find_repo(__file__)
Run Code Online (Sandbox Code Playgroud)

Pathlib 是标准库 (Python 3) 的一部分,因此没有额外的依赖项。如果这是你唯一需要的东西,Gitpython 就有点大材小用了。


ide*_*n42 6

这个函数是通用的(不依赖于外部模块或调用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
Run Code Online (Sandbox Code Playgroud)

使用示例:

import os
print(find_vcs_root(os.path.dirname(__file__)))
Run Code Online (Sandbox Code Playgroud)

或检查其他版本控制:

import os
print(find_vcs_root(os.path.dirname(__file__)), dirs=(".hg", ".git", ".svn"))
Run Code Online (Sandbox Code Playgroud)