2014-02-27 86 views
13

當使用Python(例如運行腳本)時,如何找到腳本所在的git存儲庫根目錄的路徑?找到該文件所在的git存儲庫的根目錄

到目前爲止,我知道我可以得到當前路徑:

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

我如何再找出Git倉庫的生命在哪裏?

回答

7

使用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") 
+0

這個爲我做了詭計。在調用此函數時,使用'os.getcwd()'而不是'「/ path/to/your/file」'有用。謝謝。 –

+1

一旦你有回購,你可以使用'git_repo.working_dir' –

1

我不知道很多關於蟒蛇,但我認爲你可以繼續下去的目錄與

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

直到你發現一個.git目錄(os.walk可能幫助)

+0

謝謝,但文件很深在git倉庫中,所以漫步(至少現在是這樣)會失敗,並且僅僅走上很多關卡並重新運行漫步並不能保證找到最接近的'.git'祖先。 –

+0

你必須從底部走起來。在當前目錄中查找.git目錄,如果不切掉最後一個目錄組件,請重試。直到你遇到邊界(例如文件系統的根目錄) –

+0

添加了這樣的答案:http://stackoverflow.com/a/43786287/432509 – ideasman42

14

尋找一個.git目錄在所有情況下都不起作用。正確的git的命令是:

git rev-parse --show-toplevel 
+5

注意未來自我:'repo_dir = subprocess.Popen( ['git','rev-parse','--show-toplevel'],stdout = subprocess.PIPE).communicate()[0] .rstrip()。decode('utf-8')' –

+0

@RyneEverett此致敬禮,FYI它在2.7.6拋出'LookupError:unknown encoding:utf-8',我不得不刪除'.decode('utf-8')' – qneill

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

gitpath.abspath(relative_path)將返回路徑gi上的機器上的絕對路徑 ven相對於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()約快3500倍(用ipython%%timeit測量)

+0

參見http://stackoverflow.com/questions/35948875/python-git-module-invalid-git-repository-error/39299502#39299502 – qneill

+1

值得在pypi上! – nowox

2

該函數是通用的(不依賴於外部模塊或調用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")) 
+1

謝謝,正是我在找什麼,因爲我不能安裝包在哪裏運行我的腳本 – RonK

0

GitPython模塊提供的這個屬性右出的現成的你:

import git 

repo = git.Repo('.', search_parent_directories=True) 
repo.working_tree_dir 
相關問題