Objects
There are four types of Git objects: blobs, trees, commits and tags. For each
one pygit2 has a type, and all four types inherit from the base Object
type.
Contents
Object lookup
In the previous chapter we learnt about Object IDs. With an Oid we can ask the
repository to get the associated object. To do that the Repository
class
implementes a subset of the mapping interface.
The Object base type
The Object type is a base type, it is not possible to make instances of it, in any way.
It is the base type of the Blob
, Tree
, Commit
and Tag
types, so
it is possible to check whether a Python value is an Object or not:
>>> from pygit2 import Object
>>> commit = repository.revparse_single('HEAD')
>>> print(isinstance(commit, Object))
True
All Objects are immutable, they cannot be modified once they are created:
>>> commit.message = u"foobar"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: attribute 'message' of '_pygit2.Commit' objects is not writable
Derived types (blobs, trees, etc.) don’t have a constructor, this means they cannot be created with the common idiom:
>>> from pygit2 import Blob
>>> blob = Blob("data")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: cannot create '_pygit2.Blob' instances
New objects are created using an specific API we will see later.
This is the common interface for all Git objects:
Blobs
A blob is just a raw byte string. They are the Git equivalent to files in a filesytem.
This is their API:
Creating blobs
There are a number of methods in the repository to create new blobs, and add them to the Git object database:
There are also some functions to calculate the id for a byte string without creating the blob object:
Trees
At the low level (libgit2) a tree is a sorted collection of tree entries. In pygit2 accessing an entry directly returns the object.
A tree can be iterated, and partially implements the sequence and mapping interfaces.
Example:
>>> tree = commit.tree
>>> len(tree) # Number of entries
6
>>> for obj in tree: # Iteration
... print(obj.id, obj.type_str, obj.name)
...
7151ca7cd3e59f3eab19c485cfbf3cb30928d7fa blob .gitignore
c36f4cf1e38ec1bb9d9ad146ed572b89ecfc9f18 blob COPYING
32b30b90b062f66957d6790c3c155c289c34424e blob README.md
c87dae4094b3a6d10e08bc6c5ef1f55a7e448659 blob pygit2.c
85a67270a49ef16cdd3d328f06a3e4b459f09b27 blob setup.py
3d8985bbec338eb4d47c5b01b863ee89d044bd53 tree test
>>> obj = tree / 'pygit2.c' # Get an object by name
>>> obj
<_pygit2.Blob at 0x7f08a70acc10>
Creating trees
Commits
A commit is a snapshot of the working dir with meta informations like author, committer and others.
Signatures
The author and committer attributes of commit objects are Signature
objects:
>>> commit.author
<pygit2.Signature object at 0x7f75e9b1f5f8>
Signatures can be compared for (in)equality.
Creating commits
Commits can be created by calling the create_commit
method of the
repository with the following parameters:
>>> author = Signature('Alice Author', 'alice@authors.tld')
>>> committer = Signature('Cecil Committer', 'cecil@committers.tld')
>>> tree = repo.TreeBuilder().write()
>>> repo.create_commit(
... 'refs/heads/master', # the name of the reference to update
... author, committer, 'one line commit message\n\ndetailed commit message',
... tree, # binary string representing the tree object ID
... [] # list of binary strings representing parents of the new commit
... )
'#\xe4<u\xfe\xd6\x17\xa0\xe6\xa2\x8b\xb6\xdc35$\xcf-\x8b~'