# 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

- The Object base type

- Blobs

  - Creating blobs

- Trees

  - Creating trees

- Commits

  - Signatures

  - Creating commits

- Tags

  - Creating tags

## 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~'

## Tags

A tag is a static label for a commit. See references for more information.

### Creating tags