IndexEntry: keep a copy of the underlying git_index_entry

The tree entries exist more or less independently of the index they were
retrieved from. The idea behind them is that they can be kept by a
binding without needing to refer to the original anymore, which may
disappear at any moment if the index is modified.

Keep a copy of the data in TreeEntry instead of pointing to the one
retrieved from the index, which is not safe to keep around.
IndexEntry: allow creation of this object

They are not required to belong to a particular index, so it should be
possible to create them at runtime in order to insert them.
IndexEntry: make the attributes writable

When updating entries in an index, it is necessary to modify the
attributes of tree entries. make it possible to do so.
Index: accept adding either a path or an IndexEntry

A path is only useful if we have the file on the worktree. Passing an
IndexEntry allows us to add an entry with arbitrary attributes.
Index: allow writing the tree to a particular repository

Take an optional repository in Index.write_tree() to serialize to a tree
into a particular repository's odb.