使用 GitPython 列出特定 git 提交的目录内容

List the content of a directory for a specific git commit using GitPython

使用 GitPython,我试图在给定提交时列出目录的内容(即当时目录的 "snapshot")。

在终端中,我要做的是:

git ls-tree --name-only 4b645551aa82ec55d1794d0bae039dd28e6c5704

我如何在 GitPyhon 中做同样的事情?

根据我对类似问题 (GitPython get tree and blob object by sha) 的回答,我尝试递归遍历 base_commit.tree 及其 .trees,但我似乎没有去任何地方。

有什么想法吗?

我找不到比实际调用 execute 更优雅的方法了。 这是最终结果:

configFiles = repo.git.execute(
    ['git', 'ls-tree', '--name-only', commit.hexsha, path]).split()

其中 commit 是一个 git.Commit 对象,path 是我感兴趣的路径。

的确,遍历trees/subtrees才是正确的做法。但是,内置的 traverse 方法可能与子模块有关。相反,我们可以自己迭代遍历并找到所有 blob 对象(在给定提交时包含我们 repo 中的文件)。没有必要使用 execute.

def list_files_in_commit(commit):
    """
    Lists all the files in a repo at a given commit

    :param commit: A gitpython Commit object
    """
    file_list = []
    dir_list = []
    stack = [commit.tree]
    while len(stack) > 0:
        tree = stack.pop()
        # enumerate blobs (files) at this level
        for b in tree.blobs:
            file_list.append(b.path)
        for subtree in tree.trees:
            stack.append(subtree)
    # you can return dir_list if you want directories too
    return file_list

如果您想要受给定提交影响的文件,可以通过 commit.stats.files 获得。

如果你知道目录的路径,假设它是 foo/bar/baz 并且你有一个 GitPython Commit 对象,我们称它为 commit 然后你可以访问 blobs 在这样的目录中 commit.tree['foo']['bar']['baz'].blobs 然后获取单个 blob(文件)names 以在提交时间点得出该目录中的文件列表。

import git

repo = git.Repo('path/to/my/repo')
commit = next(repo.iter_commits(max_count=1))
files_in_dir = [b.name for b in commit.tree['foo']['bar']['baz'].blobs]