GitPython通过sha获取树和blob对象

时间:2012-05-23 10:11:14

标签: git gitpython

我正在使用GitPython和裸存储库,我正在尝试通过其SHA获取特定的git对象。如果我直接使用git,我会这样做

git ls-tree sha_of_tree
git show sha_of_blob

由于我正在使用GitPython并且我想获得一个特定的树,我会执行以下操作:

repo = Repo("path_to_my_repo")
repo.tree("b466a6098a0287ac568ef0ad783ae2c35d86362b")

然后回来

<git.Tree "b466a6098a0287ac568ef0ad783ae2c35d86362b">

现在我有一个树对象,但我无法访问路径,名称,blob等属性。

repo.tree("b466a6098a0287ac568ef0ad783ae2c35d86362b").path
Traceback (most recent call last):

File "<stdin>", line 1, in <module>
File "c:\Python27\lib\site-packages\gitdb\util.py", line 238, in __getattr__
self._set_cache_(attr)
File "c:\Python27\lib\site-packages\git\objects\tree.py", line 147, in _set_cache_
super(Tree, self)._set_cache_(attr)
File "c:\Python27\lib\site-packages\git\objects\base.py", line 157, in _set_cache_
raise AttributeError( "path and mode attributes must have been set during %s object creation" % type(self).__name__ )
AttributeError: path and mode attributes must have been set during Tree object creation

但如果我键入以下内容,则可以正常使用

repo.tree().trees[0].path

我的问题的另一部分是如何使用GitPython获取blob对象。我注意到唯一的对象树有属性blob,所以为了通过SHA得到blob,我必须(a)首先知道它属于哪个树,(b)找到这个blob,然后(c)调用{{ 1}}方法。 我可以做到

data_stream

但我想首先知道这是实现这一目标的唯一方法。

3 个答案:

答案 0 :(得分:3)

一般来说,一棵树上有孩子,这些孩子是斑点和更多的树木。 blob是该树的直接子项的文件,其他树是该树的方向子目录。

直接访问该树下面的文件:

repo.tree().blobs # returns a list of blobs

访问该树正下方的目录:

repo.tree().trees # returns a list of trees

如何查看子目录中的blob:

for t in repo.tree().trees:
    print t.blobs

让我们从前面得到第一个blob的路径:

repo.tree().blobs[0].path # gives the relative path
repo.tree().blobs[0].abspath # gives the absolute path

希望这可以让您更好地了解如何导航此数据结构以及如何访问这些对象的属性。

答案 1 :(得分:3)

试试这个:

   def read_file_from_branch(self, repo, branch, path, charset='ascii'):
            '''
            return the contents of a file in a branch, without checking out the
            branch
            '''
            if branch in repo.heads:
                blob = (repo.heads[branch].commit.tree / path)
                if blob:
                    data = blob.data_stream.read()
                    if charset:
                        return data.decode(charset)
                    return data
            return None

答案 2 :(得分:1)

我一直在寻找这个,因为我有同样的问题,我找到了解决方案:

>>> import binascii
>>> id_to_find = repo.head.commit.tree['README'].hexsha  # For example
>>> id_to_find
"aee35f14ee5515ee98d546a170be60690576db4b"
>>> git.objects.blob.Blob(repo, binascii.a2b_hex(id_to_find))
<git.Blob "aee35f14ee5515ee98d546a170be60690576db4b">

我觉得应该有办法通过回购引用Blob,但我找不到它。