检查对象是否在gitpython中的repo中

时间:2012-05-05 22:17:59

标签: gitpython

我正在开发一个程序,它将在git repo中添加和更新文件。由于我不能确定我正在使用的文件当前是否在回购中,我需要检查它的存在 - 这个动作似乎比我想象的要难。

'in'比较似乎不适用于gitpython中树上的非根级别。实施例

>>> repo = Repo(path)
>>> hct = repo.head.commit.tree
>>>> 'A' in hct['documents']
False
>>> hct['documents']['A']
<git.Tree "8c74cba527a814a3700a96d8b168715684013857">

所以我想知道,在尝试使用它之前,人们如何检查给定文件是否在git树中?尝试访问不在树中的文件的对象将抛出KeyError,因此我可以尝试捕获。但这对于例行存在检查的异常处理感觉很差。

我错过了一些非常明显的东西吗?如何使用gitpython(或Python中的任何库/方法)检查​​提交树中是否存在文件?

自我答案

好的,我在Tree class挖了一下,看看__contains__做了什么。事实证明,当在子文件夹中搜索时,必须使用来自repo根的完整相对路径来检查文件是否存在。所以我上面检查的工作版本是:

>>> 'documents/A' in hct['documents']
True

3 个答案:

答案 0 :(得分:2)

扩展Bill的解决方案,这是一个确定文件是否在回购中的函数:

def fileInRepo(repo,path_to_file):
    '''
    repo is a gitPython Repo object
    path_to_file is the full path to the file from the repository root
    returns true if file is found in the repo at the specified path, false otherwise
    '''
    pathdir = os.path.dirname(path_to_file)

    #Build up reference to desired repo path
    rsub = repo.head.commit.tree
    for path_element in pathdir.split(os.path.sep):
        rsub = rsub[path_element]
    return(path_to_file in rsub)

使用示例:

file_found = fileInRepo(repo, 'documents/A')

答案 1 :(得分:1)

EricP的答案有一个错误。这是一个固定版本:

def fileInRepo(repo,filePath):
    '''
    repo is a gitPython Repo object
    filePath is the full path to the file from the repository root
    returns true if file is found in the repo at the specified path, false otherwise
    '''
    pathdir = os.path.dirname(filePath)

    #Build up reference to desired repo path
    rsub = repo.head.commit.tree

    for path_element in pathdir.split(os.path.sep):

        # If dir on file path is not in repo, neither is file. 
        try : 
            rsub = rsub[path_element]

        except KeyError : 

            return False

    return(filePath in rsub)

用法:

file_found = fileInRepo(repo, 'documents/A')

这与EricP的代码非常相似,但处理包含该文件的文件夹不在repo中的情况。在这种情况下,EricP的函数引发了KeyError。该函数返回False。

(我提议编辑EricP的代码,但遭到拒绝。)

答案 2 :(得分:0)

如果要忽略捕获,请尝试使用以下命令检查对象是否在回购中:

def fileInRepo(repo, path_to_file):
    dir_path = os.path.dirname(path_to_file)
    rsub = repo.head.commit.tree
    path_elements = dir_path.split(os.path.sep)
    for el_id, element in enumerate(path_elements):
        sub_path = os.path.join(*path_elements[:el_id + 1])
        if sub_path in rsub:
            rsub = rsub[element]
        else:
            return False
    return path_to_file in rsub

或者您可以遍历回购中的所有项目,但是肯定会变慢:

def isFileInRepo(repo, path_to_file):
    rsub = repo.head.commit.tree
    for element in rsub.traverse():
        if element.path == path_to_file:
            return True
    return False