diff --git a/pygit2.c b/pygit2.c
index 6a65f3a..c1bf4df 100644
--- a/pygit2.c
+++ b/pygit2.c
@@ -190,9 +190,10 @@ Error_set_py_obj(int err, PyObject *py_obj)
 
     assert(err < 0);
 
-    if (err == GIT_ENOTOID && !PyString_Check(py_obj)) {
+    if (err == GIT_ENOTOID && !PyString_Check(py_obj)
+        && !PyUnicode_Check(py_obj)) {
         PyErr_Format(PyExc_TypeError,
-                     "Git object id must be byte string, not: %.200s",
+                     "Git object id must be byte or a text string, not: %.200s",
                      Py_TYPE(py_obj)->tp_name);
         return NULL;
     }
@@ -209,17 +210,19 @@ Error_set_py_obj(int err, PyObject *py_obj)
 }
 
 static PyObject *
-lookup_object(Repository *repo, const git_oid *oid, git_otype type)
+lookup_object_prefix(Repository *repo, const git_oid *oid, size_t len,
+                     git_otype type)
 {
     int err;
     char hex[GIT_OID_HEXSZ + 1];
     git_object *obj;
     Object *py_obj = NULL;
 
-    err = git_object_lookup(&obj, repo->repo, oid, type);
+    err = git_object_lookup_prefix(&obj, repo->repo, oid,
+                                   (unsigned int)len, type);
     if (err < 0) {
         git_oid_fmt(hex, oid);
-        hex[GIT_OID_HEXSZ] = '\0';
+        hex[len] = '\0';
         return Error_set_str(err, hex);
     }
 
@@ -248,6 +251,12 @@ lookup_object(Repository *repo, const git_oid *oid, git_otype type)
     return (PyObject*)py_obj;
 }
 
+static PyObject *
+lookup_object(Repository *repo, const git_oid *oid, git_otype type)
+{
+    return lookup_object_prefix(repo, oid, GIT_OID_HEXSZ, type);
+}
+
 static git_otype
 int_to_loose_object_type(int type_id)
 {
@@ -415,18 +424,18 @@ Repository_getitem(Repository *self, PyObject *value)
     size_t len;
 
     len = py_str_to_git_oid(value, &oid);
-    TODO_SUPPORT_SHORT_HEXS(len)
     if (len == 0)
         return NULL;
 
-    return lookup_object(self, &oid, GIT_OBJ_ANY);
+    return lookup_object_prefix(self, &oid, len, GIT_OBJ_ANY);
 }
 
 static int
 Repository_read_raw(git_odb_object **obj, git_repository *repo,
-                    const git_oid *oid)
+                    const git_oid *oid, size_t len)
 {
-    return git_odb_read(obj, git_repository_database(repo), oid);
+    return git_odb_read_prefix(obj, git_repository_database(repo),
+                               oid, (unsigned int)len);
 }
 
 static PyObject *
@@ -438,11 +447,10 @@ Repository_read(Repository *self, PyObject *py_hex)
     size_t len;
 
     len = py_str_to_git_oid(py_hex, &oid);
-    TODO_SUPPORT_SHORT_HEXS(len)
     if (len == 0)
         return NULL;
 
-    err = Repository_read_raw(&obj, self->repo, &oid);
+    err = Repository_read_raw(&obj, self->repo, &oid, len);
     if (err < 0)
         return Error_set_py_obj(err, py_hex);
 
@@ -659,13 +667,12 @@ Repository_create_commit(Repository *self, PyObject *args)
         return NULL;
 
     len = py_str_to_git_oid(py_oid, &oid);
-    TODO_SUPPORT_SHORT_HEXS(len)
     if (len == 0)
         return NULL;
 
     message = py_str_to_c_str(py_message);
 
-    err = git_tree_lookup(&tree, self->repo, &oid);
+    err = git_tree_lookup_prefix(&tree, self->repo, &oid, (unsigned int)len);
     if (err < 0)
         return Error_set(err);
 
@@ -679,12 +686,12 @@ Repository_create_commit(Repository *self, PyObject *args)
     for (i = 0; i < parent_count; i++) {
         py_parent = PyList_GET_ITEM(py_parents, i);
         len = py_str_to_git_oid(py_parent, &oid);
-        TODO_SUPPORT_SHORT_HEXS(len)
         if (len == 0) {
             git_tree_close(tree);
             return free_parents(parents, i);
         }
-        if (git_commit_lookup(&parents[i], self->repo, &oid)) {
+        if (git_commit_lookup_prefix(&parents[i], self->repo, &oid,
+                                     (unsigned int)len)) {
             git_tree_close(tree);
             return free_parents(parents, i);
         }
@@ -721,14 +728,14 @@ Repository_create_tag(Repository *self, PyObject *args)
         return NULL;
 
     len = py_str_to_git_oid(py_oid, &oid);
-    TODO_SUPPORT_SHORT_HEXS(len)
     if (len == 0)
         return NULL;
 
-    err = git_object_lookup(&target, self->repo, &oid, target_type);
+    err = git_object_lookup_prefix(&target, self->repo, &oid,
+                                   (unsigned int)len, target_type);
     if (err < 0) {
         git_oid_fmt(hex, &oid);
-        hex[GIT_OID_HEXSZ] = '\0';
+        hex[len] = '\0';
         return Error_set_str(err, hex);
     }
 
@@ -1041,7 +1048,7 @@ Object_read_raw(Object *self)
     oid = git_object_id(self->obj);
     assert(oid);
 
-    err = Repository_read_raw(&obj, self->repo->repo, oid);
+    err = Repository_read_raw(&obj, self->repo->repo, oid, GIT_OID_HEXSZ);
     if (err < 0) {
         aux = git_oid_to_py_str(oid);
         Error_set_py_obj(err, aux);
diff --git a/test/test_commit.py b/test/test_commit.py
index f67fd74..6635959 100644
--- a/test/test_commit.py
+++ b/test/test_commit.py
@@ -71,10 +71,15 @@ class CommitTest(utils.BareRepoTestCase):
         committer = ('John Doe', 'jdoe@example.com', 12346, 0)
         author = ('J. David Ibáñez', 'jdavid@example.com', 12345, 0)
         tree = '967fce8df97cc71722d3c2a5930ef3e6f1d27b12'
+        tree_prefix = tree[:5]
+        too_short_prefix = tree[:3]
 
-        parents = [COMMIT_SHA]
-        sha = repo.create_commit(None, author, committer, message, tree,
-                                 parents)
+        parents = [COMMIT_SHA[:5]]
+        self.assertRaises(ValueError, repo.create_commit, None, author,
+                          committer, message, too_short_prefix, parents)
+        
+        sha = repo.create_commit(None, author, committer, message,
+                                 tree_prefix, parents)
         commit = repo[sha]
 
         self.assertEqual(GIT_OBJ_COMMIT, commit.type)
diff --git a/test/test_repository.py b/test/test_repository.py
index 89edcbe..c62537f 100644
--- a/test/test_repository.py
+++ b/test/test_repository.py
@@ -58,6 +58,10 @@ class RepositoryTest(utils.BareRepoTestCase):
 
         a2 = self.repo.read('7f129fd57e31e935c6d60a0c794efe4e6927664b')
         self.assertEqual((GIT_OBJ_BLOB, 'a contents 2\n'), a2)
+        
+        a_hex_prefix = A_HEX_SHA[:4]
+        a3 = self.repo.read(a_hex_prefix)
+        self.assertEqual((GIT_OBJ_BLOB, 'a contents\n'), a3)
 
     def test_write(self):
         data = b"hello world"
@@ -82,6 +86,12 @@ class RepositoryTest(utils.BareRepoTestCase):
         self.assertEqual(A_HEX_SHA, a.hex)
         self.assertEqual(GIT_OBJ_BLOB, a.type)
 
+    def test_lookup_blob_prefix(self):
+        a = self.repo[A_HEX_SHA[:5]]
+        self.assertEqual(b'a contents\n', a.read_raw())
+        self.assertEqual(A_HEX_SHA, a.hex)
+        self.assertEqual(GIT_OBJ_BLOB, a.type)
+
     def test_lookup_commit(self):
         commit_sha = '5fe808e8953c12735680c257f56600cb0de44b10'
         commit = self.repo[commit_sha]
@@ -91,6 +101,18 @@ class RepositoryTest(utils.BareRepoTestCase):
                           'This commit has some additional text.\n'),
                          commit.message)
 
+    def test_lookup_commit_prefix(self):
+        commit_sha = '5fe808e8953c12735680c257f56600cb0de44b10'
+        commit_sha_prefix = commit_sha[:7]
+        too_short_prefix = commit_sha[:3]
+        commit = self.repo[commit_sha_prefix]
+        self.assertEqual(commit_sha, commit.hex)
+        self.assertEqual(GIT_OBJ_COMMIT, commit.type)
+        self.assertEqual(('Second test data commit.\n\n'
+                    'This commit has some additional text.\n'),
+                   commit.message)
+        self.assertRaises(ValueError, self.repo.__getitem__, too_short_prefix)
+
     def test_get_path(self):
         directory = realpath(self.repo.path)
         expected = realpath(join(self._temp_dir, 'testrepo.git'))
diff --git a/test/test_tag.py b/test/test_tag.py
index ad786f0..a138882 100644
--- a/test/test_tag.py
+++ b/test/test_tag.py
@@ -62,8 +62,13 @@ class TagTest(utils.BareRepoTestCase):
         message = 'Tag a blob.\n'
         tagger = ('John Doe', 'jdoe@example.com', 12347, 0)
 
-        sha = self.repo.create_tag(name, target, pygit2.GIT_OBJ_BLOB, tagger,
-                                   message)
+        target_prefix = target[:5]
+        too_short_prefix = target[:3]
+        self.assertRaises(ValueError, self.repo.create_tag, name, 
+                          too_short_prefix, pygit2.GIT_OBJ_BLOB, tagger,
+                          message)
+        sha = self.repo.create_tag(name, target_prefix, pygit2.GIT_OBJ_BLOB,
+                                   tagger, message)
         tag = self.repo[sha]
 
         self.assertEqual('3ee44658fd11660e828dfc96b9b5c5f38d5b49bb', tag.hex)