I bent the serialization rules a little here. Git commit objects store
pointers to various other objects - other parent commits, the project,
the tree, etc. These references would be lost upon serialization.
Therefore, in the __sleep magic method to prepare for serialization, I
"reference" each object - I turn the object into a string identifier
that can be used to retrieve the object again later (for commits and
trees the hash, for the project the name, etc).
But the problem is that I can't "dereference" these objects in the
equivalent __wakeup method - if the commit points to the tree and the
tree points to the commit, then when you try to deserialize the commit
it'll try to deserialize the tree, which will then try to deserialize
the commit... which is an infinite loop.
Therefore, now these references actually remain in the object and are
just-in-time dereferenced when you want to actually access that
referenced object (using a getter). This also has the advantage of
easing the processing when loading from the cache, so that all the
object references aren't resolved at once, they're only resolved when
you need them.