diff --git a/README.rst b/README.rst
index 081972f..cf095a4 100644
--- a/README.rst
+++ b/README.rst
@@ -199,7 +199,7 @@ This is the interface of a tree entry::
     TreeEntry.name        -- name of the tree entry
     TreeEntry.oid         -- the id of the git object
     TreeEntry.hex         -- hexadecimal representation of the oid
-    TreeEntry.attributes  -- the Unix file attributes
+    TreeEntry.filemode    -- the Unix file attributes
     TreeEntry.to_object() -- returns the git object (equivalent to repo[entry.oid])
 
 
@@ -269,6 +269,12 @@ The interface for RefLogEntry::
     RefLogEntry.oid_old   -- oid of old reference
     RefLogEntry.oid_new   -- oid of new reference
 
+Revision parsing
+================
+
+You can use any of the fancy `<rev>` forms supported by libgit2::
+
+    >>> commit = repo.revparse_single('HEAD^')
 
 Revision walking
 =================
diff --git a/include/pygit2/object.h b/include/pygit2/object.h
index 5255996..64bf612 100644
--- a/include/pygit2/object.h
+++ b/include/pygit2/object.h
@@ -37,5 +37,6 @@ PyObject* Object_get_oid(Object *self);
 PyObject* Object_get_hex(Object *self);
 PyObject* Object_get_type(Object *self);
 PyObject* Object_read_raw(Object *self);
+PyObject* wrap_object(git_object *c_object, Repository *repo);
 
 #endif
diff --git a/include/pygit2/tree.h b/include/pygit2/tree.h
index e4b086f..68218f7 100644
--- a/include/pygit2/tree.h
+++ b/include/pygit2/tree.h
@@ -33,7 +33,7 @@
 #include <git2.h>
 #include <pygit2/types.h>
 
-PyObject* TreeEntry_get_attributes(TreeEntry *self);
+PyObject* TreeEntry_get_filemode(TreeEntry *self);
 PyObject* TreeEntry_get_name(TreeEntry *self);
 PyObject* TreeEntry_get_oid(TreeEntry *self);
 PyObject* TreeEntry_get_hex(TreeEntry *self);
diff --git a/src/pygit2/object.c b/src/pygit2/object.c
index 12a0855..172cf3f 100644
--- a/src/pygit2/object.c
+++ b/src/pygit2/object.c
@@ -34,6 +34,12 @@
 #include <pygit2/repository.h>
 #include <pygit2/object.h>
 
+extern PyTypeObject TreeType;
+extern PyTypeObject CommitType;
+extern PyTypeObject BlobType;
+extern PyTypeObject TagType;
+
+
 void
 Object_dealloc(Object* self)
 {
@@ -145,3 +151,35 @@ PyTypeObject ObjectType = {
     0,                                         /* tp_alloc          */
     0,                                         /* tp_new            */
 };
+
+PyObject *
+wrap_object(git_object *c_object, Repository *repo)
+{
+    Object *py_obj = NULL;
+
+    switch (git_object_type(c_object)) {
+        case GIT_OBJ_COMMIT:
+            py_obj = PyObject_New(Object, &CommitType);
+            break;
+        case GIT_OBJ_TREE:
+            py_obj = PyObject_New(Object, &TreeType);
+            break;
+        case GIT_OBJ_BLOB:
+            py_obj = PyObject_New(Object, &BlobType);
+            break;
+        case GIT_OBJ_TAG:
+            py_obj = PyObject_New(Object, &TagType);
+            break;
+        default:
+            assert(0);
+    }
+
+    if (py_obj) {
+        py_obj->obj = c_object;
+				if (repo) {
+            py_obj->repo = repo;
+            Py_INCREF(repo);
+        }
+    }
+    return (PyObject *)py_obj;
+}
diff --git a/src/pygit2/repository.c b/src/pygit2/repository.c
index 7650388..8ba3704 100644
--- a/src/pygit2/repository.c
+++ b/src/pygit2/repository.c
@@ -31,6 +31,7 @@
 #include <pygit2/types.h>
 #include <pygit2/reference.h>
 #include <pygit2/utils.h>
+#include <pygit2/object.h>
 #include <pygit2/oid.h>
 #include <pygit2/repository.h>
 
@@ -40,9 +41,6 @@ extern PyTypeObject IndexType;
 extern PyTypeObject WalkerType;
 extern PyTypeObject SignatureType;
 extern PyTypeObject TreeType;
-extern PyTypeObject CommitType;
-extern PyTypeObject BlobType;
-extern PyTypeObject TagType;
 extern PyTypeObject TreeBuilderType;
 extern PyTypeObject ConfigType;
 extern PyTypeObject DiffType;
@@ -72,29 +70,7 @@ lookup_object_prefix(Repository *repo, const git_oid *oid, size_t len,
     if (err < 0)
         return Error_set_oid(err, oid, len);
 
-    switch (git_object_type(obj)) {
-        case GIT_OBJ_COMMIT:
-            py_obj = PyObject_New(Object, &CommitType);
-            break;
-        case GIT_OBJ_TREE:
-            py_obj = PyObject_New(Object, &TreeType);
-            break;
-        case GIT_OBJ_BLOB:
-            py_obj = PyObject_New(Object, &BlobType);
-            break;
-        case GIT_OBJ_TAG:
-            py_obj = PyObject_New(Object, &TagType);
-            break;
-        default:
-            assert(0);
-    }
-
-    if (py_obj) {
-        py_obj->obj = obj;
-        py_obj->repo = repo;
-        Py_INCREF(repo);
-    }
-    return (PyObject*)py_obj;
+    return wrap_object(obj, repo);
 }
 
 PyObject *
@@ -222,6 +198,30 @@ Repository_getitem(Repository *self, PyObject *value)
     return lookup_object_prefix(self, &oid, len, GIT_OBJ_ANY);
 }
 
+PyObject *
+Repository_revparse_single(Repository *self, PyObject *py_spec)
+{
+    git_object *c_obj;
+    char *c_spec;
+		char *encoding = "ascii";
+    int err;
+
+    /* 1- Get the C revision spec */
+    c_spec = py_str_to_c_str(py_spec, encoding);
+    if (c_spec == NULL)
+        return NULL;
+
+    /* 2- Lookup */
+    err = git_revparse_single(&c_obj, self->repo, c_spec);
+    if (err < 0)  {
+        PyObject *err_obj = Error_set_str(err, c_spec);
+        free(c_spec);
+        return err_obj;
+    }
+
+    return wrap_object(c_obj, self);
+}
+
 git_odb_object *
 Repository_read_raw(git_repository *repo, const git_oid *oid, size_t len)
 {
@@ -816,6 +816,10 @@ PyMethodDef Repository_methods[] = {
       "Return a list with all the references in the repository."},
     {"lookup_reference", (PyCFunction)Repository_lookup_reference, METH_O,
        "Lookup a reference by its name in a repository."},
+    {"revparse_single", (PyCFunction)Repository_revparse_single, METH_O,
+     "Find an object, as specified by a revision string. See "
+     "`man gitrevisions`, or the documentation for `git rev-parse` for "
+     "information on the syntax accepted."},
     {"create_blob", (PyCFunction)Repository_create_blob,
      METH_VARARGS,
      "Create a new blob from memory"},
diff --git a/src/pygit2/tree.c b/src/pygit2/tree.c
index e81dc3c..76cefcb 100644
--- a/src/pygit2/tree.c
+++ b/src/pygit2/tree.c
@@ -47,7 +47,7 @@ TreeEntry_dealloc(TreeEntry *self)
 }
 
 PyObject *
-TreeEntry_get_attributes(TreeEntry *self)
+TreeEntry_get_filemode(TreeEntry *self)
 {
     return PyInt_FromLong(git_tree_entry_filemode(self->entry));
 }
@@ -85,7 +85,7 @@ TreeEntry_to_object(TreeEntry *self)
 }
 
 PyGetSetDef TreeEntry_getseters[] = {
-    {"attributes", (getter)TreeEntry_get_attributes, NULL, "attributes", NULL},
+    {"filemode", (getter)TreeEntry_get_filemode, NULL, "filemode", NULL},
     {"name", (getter)TreeEntry_get_name, NULL, "name", NULL},
     {"oid", (getter)TreeEntry_get_oid, NULL, "object id", NULL},
     {"hex", (getter)TreeEntry_get_hex, NULL, "hex oid", NULL},
diff --git a/test/test_diff.py b/test/test_diff.py
index 7133bb0..5f61b09 100644
--- a/test/test_diff.py
+++ b/test/test_diff.py
@@ -123,9 +123,9 @@ class DiffTest(utils.BareRepoTestCase):
 
         hunk = diff.changes['hunks'][0]
         self.assertEqual(hunk.old_start, 1)
-        self.assertEqual(hunk.old_lines, 0)
+        self.assertEqual(hunk.old_lines, 1)
         self.assertEqual(hunk.new_start, 1)
-        self.assertEqual(hunk.new_lines, 0)
+        self.assertEqual(hunk.new_lines, 1)
 
         self.assertEqual(hunk.old_file, 'a')
         self.assertEqual(hunk.new_file, 'a')
@@ -157,9 +157,9 @@ class DiffTest(utils.BareRepoTestCase):
 
         hunk = diff_b.changes['hunks'][1]
         self.assertEqual(hunk.old_start, 1)
-        self.assertEqual(hunk.old_lines, 0)
+        self.assertEqual(hunk.old_lines, 1)
         self.assertEqual(hunk.new_start, 1)
-        self.assertEqual(hunk.new_lines, 0)
+        self.assertEqual(hunk.new_lines, 1)
 
         self.assertEqual(hunk.old_file, 'b')
         self.assertEqual(hunk.new_file, 'b')
diff --git a/test/test_repository.py b/test/test_repository.py
index bdb4c1a..fa3a932 100644
--- a/test/test_repository.py
+++ b/test/test_repository.py
@@ -40,6 +40,7 @@ from . import utils
 
 
 HEAD_SHA  = '2cdae28389c059815e951d0bb9eed6533f61a46b'
+PARENT_SHA = '5fe808e8953c12735680c257f56600cb0de44b10'  # HEAD^
 A_HEX_SHA = 'af431f20fc541ed6d5afede3e2dc7160f6f01f16'
 A_BIN_SHA = binascii.unhexlify(A_HEX_SHA.encode('ascii'))
 
@@ -127,6 +128,9 @@ class RepositoryTest(utils.BareRepoTestCase):
     def test_get_workdir(self):
         self.assertEqual(self.repo.workdir, None)
 
+    def test_revparse_single(self):
+        parent = self.repo.revparse_single('HEAD^')
+        self.assertEqual(parent.hex, PARENT_SHA)
 
 
 class RepositoryTest_II(utils.RepoTestCase):
diff --git a/test/test_tree.py b/test/test_tree.py
index 44e85c6..a88d0d1 100644
--- a/test/test_tree.py
+++ b/test/test_tree.py
@@ -42,11 +42,11 @@ SUBTREE_SHA = '614fd9a3094bf618ea938fffc00e7d1a54f89ad0'
 
 class TreeTest(utils.BareRepoTestCase):
 
-    def assertTreeEntryEqual(self, entry, sha, name, attributes):
+    def assertTreeEntryEqual(self, entry, sha, name, filemode):
         self.assertEqual(entry.hex, sha)
         self.assertEqual(entry.name, name)
-        self.assertEqual(entry.attributes, attributes,
-                         '0%o != 0%o' % (entry.attributes, attributes))
+        self.assertEqual(entry.filemode, filemode,
+                         '0%o != 0%o' % (entry.filemode, filemode))
 
     def test_read_tree(self):
         tree = self.repo[TREE_SHA]
diff --git a/test/test_treebuilder.py b/test/test_treebuilder.py
index 8dbea77..de6e85d 100644
--- a/test/test_treebuilder.py
+++ b/test/test_treebuilder.py
@@ -57,7 +57,7 @@ class TreeBuilderTest(utils.BareRepoTestCase):
         tree = self.repo[TREE_SHA]
         bld = self.repo.TreeBuilder()
         for e in tree:
-            bld.insert(e.name, e.hex, e.attributes)
+            bld.insert(e.name, e.hex, e.filemode)
 
         result = bld.write()
         self.assertEqual(tree.oid, result)