GitPython получает дерево и объект blob от sha

Я использую GitPython с голым репозиторием и пытаюсь получить конкретный объект git по его SHA. Если бы я использовал 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">

Теперь у меня есть объект дерева, но я не могу получить доступ к его атрибутам, таким как путь, имя, капли и т. д.

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

Другая часть моего вопроса заключается в том, как получить объект blob с помощью GitPython. Я заметил, что единственное дерево объектов имеет большие двоичные объекты атрибутов, поэтому, чтобы получить большой двоичный объект с помощью SHA, я должен (а) сначала узнать, какому дереву он принадлежит, (б) найти этот большой двоичный объект, а затем (в) вызвать метод data_stream . я мог бы просто сделать

repo.git.execute("git show blob_sha")

но я хотел бы сначала знать, что это единственный способ сделать это.


person jernejl    schedule 23.05.2012    source источник


Ответы (3)


В общем, у дерева есть дети, которые являются каплями и другими деревьями. Блобы — это файлы, которые являются прямыми дочерними элементами этого дерева, а другие деревья — это каталоги, являющиеся дочерними элементами этого дерева.

Доступ к файлам непосредственно под этим деревом:

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

Давайте получим путь к первому большому двоичному объекту ранее:

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

Надеюсь, это даст вам лучшее представление о том, как перемещаться по этой структуре данных и как получить доступ к атрибутам этих объектов.

person jbranchaud    schedule 12.10.2012

Попробуй это:

   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
person Mark Riggins    schedule 17.04.2015
comment
Пожалуйста, добавьте еще несколько пояснений к вашему коду. Ответы только на код не очень полезны. Спасибо. - person Joshua Whitley; 18.04.2015

Я искал это, потому что у меня была такая же проблема, и я нашел решение:

>>> 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 через репо, но я не смог его найти.

person A. Wilson    schedule 15.02.2014