添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

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

39 人关注

当在Python中工作时(例如运行一个脚本),我怎样才能找到脚本所在的git仓库根目录的路径?

到目前为止,我知道我可以通过以下方式获得当前的路径。

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

那我怎么才能找到git仓库的位置呢?

python
git
Amelio Vazquez-Reina
Amelio Vazquez-Reina
发布于 2014-02-28
8 个回答
quat
quat
发布于 2014-02-28
已采纳
0 人赞同

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

pip install gitpython

假设你有一个本地Git repo在/path/to/.git。下面的例子接收了/path/to/your/file的输入,它正确地返回了/path/to/的Git根。

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")
    
这个对我来说是个好主意。在调用这个函数时,使用 os.getcwd() 而不是 "/path/to/your/file" 很有用。谢谢。
一旦你有了repo,你可以直接使用 git_repo.working_dir
CivFan
CivFan
发布于 2014-02-28
0 人赞同

The GitPython 模块为你提供了这个属性的开箱即用。

import git
repo = git.Repo('.', search_parent_directories=True)
repo.working_tree_dir
    
这是正确的答案,因为它不依赖shell,而shell在不同的平台上运行得并不好。
如果你想支持裸仓库,请使用 working_dir 来代替。
michas
michas
发布于 2014-02-28
0 人赞同

寻找一个 .git 的目录并不是在所有情况下都有效。正确的git命令是。

git rev-parse --show-toplevel
    
Note to Future Self: repo_dir = subprocess.Popen(['git', 'rev-parse', '--show-toplevel'], stdout=subprocess.PIPE).communicate()[0].rstrip().decode('utf-8')
@RyneEverett 谢谢你的提醒,在2.7.6版本中,我发现了 LookupError: unknown encoding: utf-8 ,我不得不去掉 .decode('utf-8')
只是想知道,在什么情况下寻找 .git 的目录会不工作?
@danodonovan fatal: Not a git repository (or any of the parent directories): .git
@danodonovan 你可以有一个 .git 的文件,而不是一个目录,如果你有一个worktree checkout。
MaxNoe
MaxNoe
发布于 2014-02-28
0 人赞同

我刚刚为这个任务写了一个小的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'))

替换代码2】将返回您机器上的绝对路径 而相对于 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 '''
        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()的速度提高了约3500倍(用ipython%%timeit测量)。3500倍的速度(用ipython%%timeit测量)。

qneill
Deserves to be on pypi!
正如@CivFan所指出的--GitPython现在通过Reop(...,search_parent_directories)提供这个功能。
rouble
rouble
发布于 2014-02-28
0 人赞同

没有任何外部库。

import subprocess
def getGitRoot():
    return subprocess.Popen(['git', 'rev-parse', '--show-toplevel'], stdout=subprocess.PIPE).communicate()[0].rstrip().decode('utf-8')
    
我把这个答案变成了一个单一功能的python包,可以通过pip( pip install git_root )和conda( conda install -c conda-forge git_root )获得:见 github.com/jtilly/git_root @麻烦,我希望这对你来说是件好事!
ideasman42
ideasman42
发布于 2014-02-28
0 人赞同

这个函数是通用的(不依赖于外部模块或调用 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(find_vcs_root(os.path.dirname(__file__)))

Or check for other version control:

import os
print(find_vcs_root(os.path.dirname(__file__)), dirs=(".hg", ".git", ".svn"))
    
RonK
谢谢,这正是我在寻找的,因为我不能在运行脚本的地方安装软件包。
很好。容易实现。
miksus
miksus
发布于 2014-02-28
0 人赞同

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

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__)

Pathlib是标准库的一部分(Python 3),所以没有额外的依赖性。如果这是你唯一需要的东西,那么Gitpython是多余的。

PlasmaPower
PlasmaPower
发布于 2014-02-28
0 人赞同

我对Python了解不多,但我认为你可以继续往下走,在一个目录中用