diff --git a/hlibgit2.cabal b/hlibgit2.cabal
--- a/hlibgit2.cabal
+++ b/hlibgit2.cabal
@@ -1,5 +1,5 @@
 Name:                hlibgit2
-Version:             0.3.1
+Version:             0.4.0
 Synopsis:            Low-level bindings to libgit2.
 Description:         Bindings to libgit2 v0.16.0-471-g5b9fac3
 License-file:        LICENSE
diff --git a/src/Bindings/Libgit2/Attr.hsc b/src/Bindings/Libgit2/Attr.hsc
--- a/src/Bindings/Libgit2/Attr.hsc
+++ b/src/Bindings/Libgit2/Attr.hsc
@@ -12,19 +12,7 @@
 {- extern __attribute__((visibility("default"))) const char * git_attr__unset; -}
 
 #ccall git_attr_get , Ptr (CString) -> Ptr <git_repository> -> CUInt -> CString -> CString -> IO (CInt)
-#ccall git_attr_get_many , Ptr (CString) -> Ptr <git_repository> -> CUInt -> CString -> CLong -> Ptr (CString) -> IO (CInt)
-#ccall git_attr_foreach , Ptr <git_repository> -> CUInt -> CString -> Ptr () -> Ptr () -> IO (CInt)
+#ccall git_attr_get_many , Ptr (CString) -> Ptr <git_repository> -> CUInt -> CString -> CSize -> Ptr (CString) -> IO (CInt)
+#ccall git_attr_foreach , Ptr <git_repository> -> CUInt -> CString -> FunPtr (CString -> CString -> Ptr () -> CInt) -> Ptr () -> IO (CInt)
 #ccall git_attr_cache_flush , Ptr <git_repository> -> IO ()
 #ccall git_attr_add_macro , Ptr <git_repository> -> CString -> CString -> IO (CInt)
-
-{- BEGIN MANUAL ENTRY -}
-#cinline GIT_ATTR_TRUE , CString -> CInt
-#cinline GIT_ATTR_FALSE , CString -> CInt
-#cinline GIT_ATTR_UNSPECIFIED , CString -> CInt
-#cinline GIT_ATTR_HAS_VALUE , CString -> CInt
-
-#num GIT_ATTR_CHECK_FILE_THEN_INDEX
-#num GIT_ATTR_CHECK_INDEX_THEN_FILE
-#num GIT_ATTR_CHECK_INDEX_ONLY
-#num GIT_ATTR_CHECK_NO_SYSTEM
-{- END MANUAL ENTRY -}
diff --git a/src/Bindings/Libgit2/Blob.hsc b/src/Bindings/Libgit2/Blob.hsc
--- a/src/Bindings/Libgit2/Blob.hsc
+++ b/src/Bindings/Libgit2/Blob.hsc
@@ -11,7 +11,7 @@
 #cinline git_blob_lookup_prefix , Ptr (Ptr <git_blob>) -> Ptr <git_repository> -> Ptr <git_oid> -> CUInt -> IO (CInt)
 #cinline git_blob_free , Ptr <git_blob> -> IO ()
 #ccall git_blob_rawcontent , Ptr <git_blob> -> IO (Ptr ())
-#ccall git_blob_rawsize , Ptr <git_blob> -> IO (CLong)
+#ccall git_blob_rawsize , Ptr <git_blob> -> IO (CSize)
 #ccall git_blob_create_fromfile , Ptr <git_oid> -> Ptr <git_repository> -> CString -> IO (CInt)
 #ccall git_blob_create_fromdisk , Ptr <git_oid> -> Ptr <git_repository> -> CString -> IO (CInt)
-#ccall git_blob_create_frombuffer , Ptr <git_oid> -> Ptr <git_repository> -> Ptr () -> CLong -> IO (CInt)
+#ccall git_blob_create_frombuffer , Ptr <git_oid> -> Ptr <git_repository> -> Ptr () -> CSize -> IO (CInt)
diff --git a/src/Bindings/Libgit2/Common.hsc b/src/Bindings/Libgit2/Common.hsc
--- a/src/Bindings/Libgit2/Common.hsc
+++ b/src/Bindings/Libgit2/Common.hsc
@@ -8,7 +8,7 @@
         } git_strarray; -}
 #starttype git_strarray
 #field strings , Ptr (CString)
-#field count , CLong
+#field count , CSize
 #stoptype
 #ccall git_strarray_free , Ptr <git_strarray> -> IO ()
 #ccall git_strarray_copy , Ptr <git_strarray> -> Ptr <git_strarray> -> IO (CInt)
diff --git a/src/Bindings/Libgit2/Config.hsc b/src/Bindings/Libgit2/Config.hsc
--- a/src/Bindings/Libgit2/Config.hsc
+++ b/src/Bindings/Libgit2/Config.hsc
@@ -5,6 +5,41 @@
 
 import Bindings.Libgit2.Common
 import Bindings.Libgit2.Types
+{- struct git_config_file {
+    struct git_config * cfg;
+    int (* open)(struct git_config_file *);
+    int (* get)(struct git_config_file *,
+                const char * key,
+                const char * * value);
+    int (* get_multivar)(struct git_config_file *,
+                         const char * key,
+                         const char * regexp,
+                         int (* fn)(const char *, void *),
+                         void * data);
+    int (* set)(struct git_config_file *,
+                const char * key,
+                const char * value);
+    int (* set_multivar)(git_config_file * cfg,
+                         const char * name,
+                         const char * regexp,
+                         const char * value);
+    int (* del)(struct git_config_file *, const char * key);
+    int (* foreach)(struct git_config_file *,
+                    int (* fn)(const char *, const char *, void *),
+                    void * data);
+    void (* free)(struct git_config_file *);
+}; -}
+#starttype git_config_file
+#field cfg , Ptr <git_config>
+#field open , FunPtr (Ptr <git_config_file> -> CInt)
+#field get , FunPtr (Ptr <git_config_file> -> CString -> Ptr (CString) -> CInt)
+#field get_multivar , FunPtr (Ptr <git_config_file> -> CString -> CString -> FunPtr (CString -> Ptr () -> CInt) -> Ptr () -> CInt)
+#field set , FunPtr (Ptr <git_config_file> -> CString -> CString -> CInt)
+#field set_multivar , FunPtr (Ptr <git_config_file> -> CString -> CString -> CString -> CInt)
+#field del , FunPtr (Ptr <git_config_file> -> CString -> CInt)
+#field foreach , FunPtr (Ptr <git_config_file> -> FunPtr (CString -> CString -> Ptr () -> CInt) -> Ptr () -> CInt)
+#field free , FunPtr (Ptr <git_config_file>)
+#stoptype
 {- typedef enum {
             GIT_CVAR_FALSE = 0,
             GIT_CVAR_TRUE = 1,
@@ -24,10 +59,10 @@
 #field str_match , CString
 #field map_value , CInt
 #stoptype
-#ccall git_config_find_global , CString -> CLong -> IO (CInt)
-#ccall git_config_find_system , CString -> CLong -> IO (CInt)
+#ccall git_config_find_global , CString -> CSize -> IO (CInt)
+#ccall git_config_find_system , CString -> CSize -> IO (CInt)
 #ccall git_config_open_global , Ptr (Ptr <git_config>) -> IO (CInt)
-#ccall git_config_file__ondisk , Ptr (Ptr ()) -> CString -> IO (CInt)
+#ccall git_config_file__ondisk , Ptr (Ptr <git_config_file>) -> CString -> IO (CInt)
 #ccall git_config_new , Ptr (Ptr <git_config>) -> IO (CInt)
 #ccall git_config_add_file , Ptr <git_config> -> Ptr <git_config_file> -> CInt -> IO (CInt)
 #ccall git_config_add_file_ondisk , Ptr <git_config> -> CString -> CInt -> IO (CInt)
@@ -37,26 +72,12 @@
 #ccall git_config_get_int64 , Ptr CLong -> Ptr <git_config> -> CString -> IO (CInt)
 #ccall git_config_get_bool , Ptr CInt -> Ptr <git_config> -> CString -> IO (CInt)
 #ccall git_config_get_string , Ptr (CString) -> Ptr <git_config> -> CString -> IO (CInt)
-#ccall git_config_get_multivar , Ptr <git_config> -> CString -> CString -> Ptr () -> Ptr () -> IO (CInt)
+#ccall git_config_get_multivar , Ptr <git_config> -> CString -> CString -> FunPtr (CString -> Ptr () -> CInt) -> Ptr () -> IO (CInt)
 #ccall git_config_set_int32 , Ptr <git_config> -> CString -> CInt -> IO (CInt)
 #ccall git_config_set_int64 , Ptr <git_config> -> CString -> CLong -> IO (CInt)
 #ccall git_config_set_bool , Ptr <git_config> -> CString -> CInt -> IO (CInt)
 #ccall git_config_set_string , Ptr <git_config> -> CString -> CString -> IO (CInt)
 #ccall git_config_set_multivar , Ptr <git_config> -> CString -> CString -> CString -> IO (CInt)
 #ccall git_config_delete , Ptr <git_config> -> CString -> IO (CInt)
-#ccall git_config_foreach , Ptr <git_config> -> Ptr () -> Ptr () -> IO (CInt)
-#ccall git_config_get_mapped , Ptr CInt -> Ptr <git_config> -> CString -> Ptr <git_cvar_map> -> CLong -> IO (CInt)
-
-{- BEGIN MANUAL ENTRY -}
-#starttype struct git_config_file
-#field cfg, Ptr <git_config>
-#field open, FunPtr (Ptr <git_config_file> -> IO CInt)
-#field get, FunPtr (Ptr <git_config_file> -> CString -> Ptr CString -> IO CInt)
-#field get_multivar, FunPtr (Ptr <git_config_file> -> CString -> CString -> FunPtr (CString -> Ptr () -> CInt) -> Ptr () -> IO CInt)
-#field set, FunPtr (Ptr <git_config_file> -> CString -> CString -> IO CInt)
-#field set_multivar, FunPtr (Ptr <git_config_file> -> CString -> CString -> CString -> IO CInt)
-#field del, FunPtr (Ptr <git_config_file> -> CString -> IO CInt)
-#field foreach, FunPtr (Ptr <git_config_file> -> FunPtr (CString -> CString -> Ptr () -> CInt) -> Ptr () -> IO CInt)
-#field free, FunPtr (Ptr <git_config_file> -> IO ())
-#stoptype
-{- END MANUAL ENTRY -}
+#ccall git_config_foreach , Ptr <git_config> -> FunPtr (CString -> CString -> Ptr () -> CInt) -> Ptr () -> IO (CInt)
+#ccall git_config_get_mapped , Ptr CInt -> Ptr <git_config> -> CString -> Ptr <git_cvar_map> -> CSize -> IO (CInt)
diff --git a/src/Bindings/Libgit2/Diff.hsc b/src/Bindings/Libgit2/Diff.hsc
--- a/src/Bindings/Libgit2/Diff.hsc
+++ b/src/Bindings/Libgit2/Diff.hsc
@@ -8,6 +8,32 @@
 import Bindings.Libgit2.Oid
 import Bindings.Libgit2.Tree
 import Bindings.Libgit2.Refs
+{- enum {
+    GIT_DIFF_NORMAL = 0,
+    GIT_DIFF_REVERSE = 1 << 0,
+    GIT_DIFF_FORCE_TEXT = 1 << 1,
+    GIT_DIFF_IGNORE_WHITESPACE = 1 << 2,
+    GIT_DIFF_IGNORE_WHITESPACE_CHANGE = 1 << 3,
+    GIT_DIFF_IGNORE_WHITESPACE_EOL = 1 << 4,
+    GIT_DIFF_IGNORE_SUBMODULES = 1 << 5,
+    GIT_DIFF_PATIENCE = 1 << 6,
+    GIT_DIFF_INCLUDE_IGNORED = 1 << 7,
+    GIT_DIFF_INCLUDE_UNTRACKED = 1 << 8,
+    GIT_DIFF_INCLUDE_UNMODIFIED = 1 << 9,
+    GIT_DIFF_RECURSE_UNTRACKED_DIRS = 1 << 10
+}; -}
+#num GIT_DIFF_NORMAL
+#num GIT_DIFF_REVERSE
+#num GIT_DIFF_FORCE_TEXT
+#num GIT_DIFF_IGNORE_WHITESPACE
+#num GIT_DIFF_IGNORE_WHITESPACE_CHANGE
+#num GIT_DIFF_IGNORE_WHITESPACE_EOL
+#num GIT_DIFF_IGNORE_SUBMODULES
+#num GIT_DIFF_PATIENCE
+#num GIT_DIFF_INCLUDE_IGNORED
+#num GIT_DIFF_INCLUDE_UNTRACKED
+#num GIT_DIFF_INCLUDE_UNMODIFIED
+#num GIT_DIFF_RECURSE_UNTRACKED_DIRS
 {- typedef struct {
             uint32_t flags;
             uint16_t context_lines;
@@ -26,6 +52,20 @@
 #stoptype
 {- typedef struct git_diff_list git_diff_list; -}
 #opaque_t git_diff_list
+{- enum {
+    GIT_DIFF_FILE_VALID_OID = 1 << 0,
+    GIT_DIFF_FILE_FREE_PATH = 1 << 1,
+    GIT_DIFF_FILE_BINARY = 1 << 2,
+    GIT_DIFF_FILE_NOT_BINARY = 1 << 3,
+    GIT_DIFF_FILE_FREE_DATA = 1 << 4,
+    GIT_DIFF_FILE_UNMAP_DATA = 1 << 5
+}; -}
+#num GIT_DIFF_FILE_VALID_OID
+#num GIT_DIFF_FILE_FREE_PATH
+#num GIT_DIFF_FILE_BINARY
+#num GIT_DIFF_FILE_NOT_BINARY
+#num GIT_DIFF_FILE_FREE_DATA
+#num GIT_DIFF_FILE_UNMAP_DATA
 {- typedef enum {
             GIT_DELTA_UNMODIFIED = 0,
             GIT_DELTA_ADDED = 1,
@@ -76,6 +116,7 @@
 {- typedef int (* git_diff_file_fn)(void * cb_data,
                                  git_diff_delta * delta,
                                  float progress); -}
+#synonym_t git_diff_file_fn , CInt
 {- typedef struct {
             int old_start; int old_lines; int new_start; int new_lines;
         } git_diff_range; -}
@@ -90,12 +131,32 @@
                                  git_diff_range * range,
                                  const char * header,
                                  size_t header_len); -}
+#synonym_t git_diff_hunk_fn , CInt
+{- enum {
+    GIT_DIFF_LINE_CONTEXT = ' ',
+    GIT_DIFF_LINE_ADDITION = '+',
+    GIT_DIFF_LINE_DELETION = '-',
+    GIT_DIFF_LINE_ADD_EOFNL = '\n',
+    GIT_DIFF_LINE_DEL_EOFNL = '\0',
+    GIT_DIFF_LINE_FILE_HDR = 'F',
+    GIT_DIFF_LINE_HUNK_HDR = 'H',
+    GIT_DIFF_LINE_BINARY = 'B'
+}; -}
+#num GIT_DIFF_LINE_CONTEXT
+#num GIT_DIFF_LINE_ADDITION
+#num GIT_DIFF_LINE_DELETION
+#num GIT_DIFF_LINE_ADD_EOFNL
+#num GIT_DIFF_LINE_DEL_EOFNL
+#num GIT_DIFF_LINE_FILE_HDR
+#num GIT_DIFF_LINE_HUNK_HDR
+#num GIT_DIFF_LINE_BINARY
 {- typedef int (* git_diff_data_fn)(void * cb_data,
                                  git_diff_delta * delta,
                                  git_diff_range * range,
                                  char line_origin,
                                  const char * content,
                                  size_t content_len); -}
+#synonym_t git_diff_data_fn , CInt
 #ccall git_diff_list_free , Ptr <git_diff_list> -> IO ()
 #ccall git_diff_tree_to_tree , Ptr <git_repository> -> Ptr <git_diff_options> -> Ptr <git_tree> -> Ptr <git_tree> -> Ptr (Ptr <git_diff_list>) -> IO (CInt)
 #ccall git_diff_index_to_tree , Ptr <git_repository> -> Ptr <git_diff_options> -> Ptr <git_tree> -> Ptr (Ptr <git_diff_list>) -> IO (CInt)
diff --git a/src/Bindings/Libgit2/Errors.hsc b/src/Bindings/Libgit2/Errors.hsc
--- a/src/Bindings/Libgit2/Errors.hsc
+++ b/src/Bindings/Libgit2/Errors.hsc
@@ -4,6 +4,24 @@
 #strict_import
 
 import Bindings.Libgit2.Common
+{- enum {
+    GIT_OK = 0,
+    GIT_ERROR = -1,
+    GIT_ENOTFOUND = -3,
+    GIT_EEXISTS = -4,
+    GIT_EAMBIGUOUS = -5,
+    GIT_EBUFS = -6,
+    GIT_PASSTHROUGH = -30,
+    GIT_REVWALKOVER = -31
+}; -}
+#num GIT_OK
+#num GIT_ERROR
+#num GIT_ENOTFOUND
+#num GIT_EEXISTS
+#num GIT_EAMBIGUOUS
+#num GIT_EBUFS
+#num GIT_PASSTHROUGH
+#num GIT_REVWALKOVER
 {- typedef struct {
             char * message; int klass;
         } git_error; -}
diff --git a/src/Bindings/Libgit2/Indexer.hsc b/src/Bindings/Libgit2/Indexer.hsc
--- a/src/Bindings/Libgit2/Indexer.hsc
+++ b/src/Bindings/Libgit2/Indexer.hsc
@@ -17,7 +17,7 @@
 {- typedef struct git_indexer_stream git_indexer_stream; -}
 #opaque_t git_indexer_stream
 #ccall git_indexer_stream_new , Ptr (Ptr <git_indexer_stream>) -> CString -> IO (CInt)
-#ccall git_indexer_stream_add , Ptr <git_indexer_stream> -> Ptr () -> CLong -> Ptr <git_indexer_stats> -> IO (CInt)
+#ccall git_indexer_stream_add , Ptr <git_indexer_stream> -> Ptr () -> CSize -> Ptr <git_indexer_stats> -> IO (CInt)
 #ccall git_indexer_stream_finalize , Ptr <git_indexer_stream> -> Ptr <git_indexer_stats> -> IO (CInt)
 #ccall git_indexer_stream_hash , Ptr <git_indexer_stream> -> IO (Ptr <git_oid>)
 #ccall git_indexer_stream_free , Ptr <git_indexer_stream> -> IO ()
diff --git a/src/Bindings/Libgit2/Net.hsc b/src/Bindings/Libgit2/Net.hsc
--- a/src/Bindings/Libgit2/Net.hsc
+++ b/src/Bindings/Libgit2/Net.hsc
@@ -6,4 +6,14 @@
 import Bindings.Libgit2.Common
 import Bindings.Libgit2.Oid
 import Bindings.Libgit2.Types
+{- struct git_remote_head {
+    int local : 1; git_oid oid; git_oid loid; char * name;
+}; -}
+#starttype git_remote_head
+-- #field local , CInt
+#field oid , <git_oid>
+#field loid , <git_oid>
+#field name , CString
+#stoptype
 {- typedef int (* git_headlist_cb)(git_remote_head *, void *); -}
+#synonym_t git_headlist_cb , CInt
diff --git a/src/Bindings/Libgit2/Notes.hsc b/src/Bindings/Libgit2/Notes.hsc
--- a/src/Bindings/Libgit2/Notes.hsc
+++ b/src/Bindings/Libgit2/Notes.hsc
@@ -19,4 +19,4 @@
 #field blob_oid , <git_oid>
 #field annotated_object_oid , <git_oid>
 #stoptype
-#ccall git_note_foreach , Ptr <git_repository> -> CString -> Ptr () -> Ptr () -> IO (CInt)
+#ccall git_note_foreach , Ptr <git_repository> -> CString -> FunPtr (Ptr <git_note_data> -> Ptr () -> CInt) -> Ptr () -> IO (CInt)
diff --git a/src/Bindings/Libgit2/Object.hsc b/src/Bindings/Libgit2/Object.hsc
--- a/src/Bindings/Libgit2/Object.hsc
+++ b/src/Bindings/Libgit2/Object.hsc
@@ -15,4 +15,4 @@
 #ccall git_object_type2string , <git_otype> -> IO (CString)
 #ccall git_object_string2type , CString -> IO (<git_otype>)
 #ccall git_object_typeisloose , <git_otype> -> IO (CInt)
-#ccall git_object__size , <git_otype> -> IO (CLong)
+#ccall git_object__size , <git_otype> -> IO (CSize)
diff --git a/src/Bindings/Libgit2/Odb.hsc b/src/Bindings/Libgit2/Odb.hsc
--- a/src/Bindings/Libgit2/Odb.hsc
+++ b/src/Bindings/Libgit2/Odb.hsc
@@ -14,15 +14,15 @@
 #ccall git_odb_free , Ptr <git_odb> -> IO ()
 #ccall git_odb_read , Ptr (Ptr <git_odb_object>) -> Ptr <git_odb> -> Ptr <git_oid> -> IO (CInt)
 #ccall git_odb_read_prefix , Ptr (Ptr <git_odb_object>) -> Ptr <git_odb> -> Ptr <git_oid> -> CUInt -> IO (CInt)
-#ccall git_odb_read_header , Ptr CLong -> Ptr <git_otype> -> Ptr <git_odb> -> Ptr <git_oid> -> IO (CInt)
+#ccall git_odb_read_header , Ptr CSize -> Ptr <git_otype> -> Ptr <git_odb> -> Ptr <git_oid> -> IO (CInt)
 #ccall git_odb_exists , Ptr <git_odb> -> Ptr <git_oid> -> IO (CInt)
-#ccall git_odb_write , Ptr <git_oid> -> Ptr <git_odb> -> Ptr () -> CLong -> <git_otype> -> IO (CInt)
-#ccall git_odb_open_wstream , Ptr (Ptr <git_odb_stream>) -> Ptr <git_odb> -> CLong -> <git_otype> -> IO (CInt)
+#ccall git_odb_write , Ptr <git_oid> -> Ptr <git_odb> -> Ptr () -> CSize -> <git_otype> -> IO (CInt)
+#ccall git_odb_open_wstream , Ptr (Ptr <git_odb_stream>) -> Ptr <git_odb> -> CSize -> <git_otype> -> IO (CInt)
 #ccall git_odb_open_rstream , Ptr (Ptr <git_odb_stream>) -> Ptr <git_odb> -> Ptr <git_oid> -> IO (CInt)
-#ccall git_odb_hash , Ptr <git_oid> -> Ptr () -> CLong -> <git_otype> -> IO (CInt)
+#ccall git_odb_hash , Ptr <git_oid> -> Ptr () -> CSize -> <git_otype> -> IO (CInt)
 #ccall git_odb_hashfile , Ptr <git_oid> -> CString -> <git_otype> -> IO (CInt)
 #ccall git_odb_object_free , Ptr <git_odb_object> -> IO ()
 #ccall git_odb_object_id , Ptr <git_odb_object> -> IO (Ptr <git_oid>)
 #ccall git_odb_object_data , Ptr <git_odb_object> -> IO (Ptr ())
-#ccall git_odb_object_size , Ptr <git_odb_object> -> IO (CLong)
+#ccall git_odb_object_size , Ptr <git_odb_object> -> IO (CSize)
 #ccall git_odb_object_type , Ptr <git_odb_object> -> IO (<git_otype>)
diff --git a/src/Bindings/Libgit2/OdbBackend.hsc b/src/Bindings/Libgit2/OdbBackend.hsc
--- a/src/Bindings/Libgit2/OdbBackend.hsc
+++ b/src/Bindings/Libgit2/OdbBackend.hsc
@@ -6,5 +6,78 @@
 import Bindings.Libgit2.Common
 import Bindings.Libgit2.Types
 import Bindings.Libgit2.Oid
+{- struct git_odb_backend {
+    git_odb * odb;
+    int (* read)(void * *,
+                 size_t *,
+                 git_otype *,
+                 struct git_odb_backend *,
+                 const git_oid *);
+    int (* read_prefix)(git_oid *,
+                        void * *,
+                        size_t *,
+                        git_otype *,
+                        struct git_odb_backend *,
+                        const git_oid *,
+                        unsigned int);
+    int (* read_header)(size_t *,
+                        git_otype *,
+                        struct git_odb_backend *,
+                        const git_oid *);
+    int (* write)(git_oid *,
+                  struct git_odb_backend *,
+                  const void *,
+                  size_t,
+                  git_otype);
+    int (* writestream)(struct git_odb_stream * *,
+                        struct git_odb_backend *,
+                        size_t,
+                        git_otype);
+    int (* readstream)(struct git_odb_stream * *,
+                       struct git_odb_backend *,
+                       const git_oid *);
+    int (* exists)(struct git_odb_backend *, const git_oid *);
+    void (* free)(struct git_odb_backend *);
+}; -}
+#starttype git_odb_backend
+#field odb , Ptr <git_odb>
+#field read , FunPtr (Ptr (Ptr ()) -> Ptr CSize -> Ptr <git_otype> -> Ptr <git_odb_backend> -> Ptr <git_oid> -> CInt)
+#field read_prefix , FunPtr (Ptr <git_oid> -> Ptr (Ptr ()) -> Ptr CSize -> Ptr <git_otype> -> Ptr <git_odb_backend> -> Ptr <git_oid> -> CUInt -> CInt)
+#field read_header , FunPtr (Ptr CSize -> Ptr <git_otype> -> Ptr <git_odb_backend> -> Ptr <git_oid> -> CInt)
+#field write , FunPtr (Ptr <git_oid> -> Ptr <git_odb_backend> -> Ptr () -> CSize -> <git_otype> -> CInt)
+#field writestream , FunPtr (Ptr (Ptr <git_odb_stream>) -> Ptr <git_odb_backend> -> CSize -> <git_otype> -> CInt)
+#field readstream , FunPtr (Ptr (Ptr <git_odb_stream>) -> Ptr <git_odb_backend> -> Ptr <git_oid> -> CInt)
+#field exists , FunPtr (Ptr <git_odb_backend> -> Ptr <git_oid> -> CInt)
+#field free , FunPtr (Ptr <git_odb_backend>)
+#stoptype
+{- enum {
+    GIT_STREAM_RDONLY = 1 << 1,
+    GIT_STREAM_WRONLY = 1 << 2,
+    GIT_STREAM_RW = GIT_STREAM_RDONLY | GIT_STREAM_WRONLY
+}; -}
+#num GIT_STREAM_RDONLY
+#num GIT_STREAM_WRONLY
+#num GIT_STREAM_RW
+{- struct git_odb_stream {
+    struct git_odb_backend * backend;
+    int mode;
+    int (* read)(struct git_odb_stream * stream,
+                 char * buffer,
+                 size_t len);
+    int (* write)(struct git_odb_stream * stream,
+                  const char * buffer,
+                  size_t len);
+    int (* finalize_write)(git_oid * oid_p,
+                           struct git_odb_stream * stream);
+    void (* free)(struct git_odb_stream * stream);
+}; -}
+#starttype git_odb_stream
+#field backend , Ptr <git_odb_backend>
+#field mode , CInt
+#field read , FunPtr (Ptr <git_odb_stream> -> CString -> CSize -> CInt)
+#field write , FunPtr (Ptr <git_odb_stream> -> CString -> CSize -> CInt)
+#field finalize_write , FunPtr (Ptr <git_oid> -> Ptr <git_odb_stream> -> CInt)
+#field free , FunPtr (Ptr <git_odb_stream>)
+#stoptype
 #ccall git_odb_backend_pack , Ptr (Ptr <git_odb_backend>) -> CString -> IO (CInt)
 #ccall git_odb_backend_loose , Ptr (Ptr <git_odb_backend>) -> CString -> CInt -> CInt -> IO (CInt)
diff --git a/src/Bindings/Libgit2/Oid.hsc b/src/Bindings/Libgit2/Oid.hsc
--- a/src/Bindings/Libgit2/Oid.hsc
+++ b/src/Bindings/Libgit2/Oid.hsc
@@ -8,19 +8,19 @@
 #num GIT_OID_RAWSZ
 #num GIT_OID_HEXSZ
 #num GIT_OID_MINPREFIXLEN
-{- typedef struct {
-	unsigned char id[GIT_OID_RAWSZ];
-} git_oid; -}
+{- struct _git_oid {
+    unsigned char id[20];
+}; -}
 #starttype git_oid
-#array_field    id , Word8
+#array_field id , CUChar
 #stoptype
 #ccall git_oid_fromstr , Ptr <git_oid> -> CString -> IO (CInt)
-#ccall git_oid_fromstrn , Ptr <git_oid> -> CString -> CLong -> IO (CInt)
+#ccall git_oid_fromstrn , Ptr <git_oid> -> CString -> CSize -> IO (CInt)
 #ccall git_oid_fromraw , Ptr <git_oid> -> Ptr CUChar -> IO ()
 #ccall git_oid_fmt , CString -> Ptr <git_oid> -> IO ()
 #ccall git_oid_pathfmt , CString -> Ptr <git_oid> -> IO ()
 #ccall git_oid_allocfmt , Ptr <git_oid> -> IO (CString)
-#ccall git_oid_tostr , CString -> CLong -> Ptr <git_oid> -> IO (CString)
+#ccall git_oid_tostr , CString -> CSize -> Ptr <git_oid> -> IO (CString)
 #ccall git_oid_cpy , Ptr <git_oid> -> Ptr <git_oid> -> IO ()
 #ccall git_oid_cmp , Ptr <git_oid> -> Ptr <git_oid> -> IO (CInt)
 #ccall git_oid_ncmp , Ptr <git_oid> -> Ptr <git_oid> -> CUInt -> IO (CInt)
@@ -28,6 +28,6 @@
 #ccall git_oid_iszero , Ptr <git_oid> -> IO (CInt)
 {- typedef struct git_oid_shorten git_oid_shorten; -}
 #opaque_t git_oid_shorten
-#ccall git_oid_shorten_new , CLong -> IO (Ptr <git_oid_shorten>)
+#ccall git_oid_shorten_new , CSize -> IO (Ptr <git_oid_shorten>)
 #ccall git_oid_shorten_add , Ptr <git_oid_shorten> -> CString -> IO (CInt)
 #ccall git_oid_shorten_free , Ptr <git_oid_shorten> -> IO ()
diff --git a/src/Bindings/Libgit2/Refs.hsc b/src/Bindings/Libgit2/Refs.hsc
--- a/src/Bindings/Libgit2/Refs.hsc
+++ b/src/Bindings/Libgit2/Refs.hsc
@@ -22,7 +22,7 @@
 #ccall git_reference_delete , Ptr <git_reference> -> IO (CInt)
 #ccall git_reference_packall , Ptr <git_repository> -> IO (CInt)
 #ccall git_reference_list , Ptr <git_strarray> -> Ptr <git_repository> -> CUInt -> IO (CInt)
-#ccall git_reference_foreach , Ptr <git_repository> -> CUInt -> Ptr () -> Ptr () -> IO (CInt)
+#ccall git_reference_foreach , Ptr <git_repository> -> CUInt -> FunPtr (CString -> Ptr () -> CInt) -> Ptr () -> IO (CInt)
 #ccall git_reference_is_packed , Ptr <git_reference> -> IO (CInt)
 #ccall git_reference_reload , Ptr <git_reference> -> IO (CInt)
 #ccall git_reference_free , Ptr <git_reference> -> IO ()
diff --git a/src/Bindings/Libgit2/Refspec.hsc b/src/Bindings/Libgit2/Refspec.hsc
--- a/src/Bindings/Libgit2/Refspec.hsc
+++ b/src/Bindings/Libgit2/Refspec.hsc
@@ -8,4 +8,4 @@
 #ccall git_refspec_src , Ptr <git_refspec> -> IO (CString)
 #ccall git_refspec_dst , Ptr <git_refspec> -> IO (CString)
 #ccall git_refspec_src_matches , Ptr <git_refspec> -> CString -> IO (CInt)
-#ccall git_refspec_transform , CString -> CLong -> Ptr <git_refspec> -> CString -> IO (CInt)
+#ccall git_refspec_transform , CString -> CSize -> Ptr <git_refspec> -> CString -> IO (CInt)
diff --git a/src/Bindings/Libgit2/Remote.hsc b/src/Bindings/Libgit2/Remote.hsc
--- a/src/Bindings/Libgit2/Remote.hsc
+++ b/src/Bindings/Libgit2/Remote.hsc
@@ -8,6 +8,7 @@
 import Bindings.Libgit2.Refspec
 import Bindings.Libgit2.Net
 import Bindings.Libgit2.Indexer
+import Bindings.Libgit2.Oid
 import Bindings.Libgit2.Types
 #ccall git_remote_new , Ptr (Ptr <git_remote>) -> Ptr <git_repository> -> CString -> CString -> CString -> IO (CInt)
 #ccall git_remote_load , Ptr (Ptr <git_remote>) -> Ptr <git_repository> -> CString -> IO (CInt)
@@ -24,7 +25,7 @@
 #ccall git_remote_connected , Ptr <git_remote> -> IO (CInt)
 #ccall git_remote_disconnect , Ptr <git_remote> -> IO ()
 #ccall git_remote_free , Ptr <git_remote> -> IO ()
-#ccall git_remote_update_tips , Ptr <git_remote> -> Ptr () -> IO (CInt)
+#ccall git_remote_update_tips , Ptr <git_remote> -> FunPtr (CString -> Ptr <git_oid> -> Ptr <git_oid> -> CInt) -> IO (CInt)
 #ccall git_remote_valid_url , CString -> IO (CInt)
 #ccall git_remote_supported_url , CString -> IO (CInt)
 #ccall git_remote_list , Ptr <git_strarray> -> Ptr <git_repository> -> IO (CInt)
diff --git a/src/Bindings/Libgit2/Repository.hsc b/src/Bindings/Libgit2/Repository.hsc
--- a/src/Bindings/Libgit2/Repository.hsc
+++ b/src/Bindings/Libgit2/Repository.hsc
@@ -7,7 +7,13 @@
 import Bindings.Libgit2.Types
 import Bindings.Libgit2.Oid
 #ccall git_repository_open , Ptr (Ptr <git_repository>) -> CString -> IO (CInt)
-#ccall git_repository_discover , CString -> CLong -> CString -> CInt -> CString -> IO (CInt)
+#ccall git_repository_discover , CString -> CSize -> CString -> CInt -> CString -> IO (CInt)
+{- enum {
+    GIT_REPOSITORY_OPEN_NO_SEARCH = 1 << 0,
+    GIT_REPOSITORY_OPEN_CROSS_FS = 1 << 1
+}; -}
+#num GIT_REPOSITORY_OPEN_NO_SEARCH
+#num GIT_REPOSITORY_OPEN_CROSS_FS
 #ccall git_repository_open_ext , Ptr (Ptr <git_repository>) -> CString -> CUInt -> CString -> IO (CInt)
 #ccall git_repository_free , Ptr <git_repository> -> IO ()
 #ccall git_repository_init , Ptr (Ptr <git_repository>) -> CString -> CUInt -> IO (CInt)
diff --git a/src/Bindings/Libgit2/Status.hsc b/src/Bindings/Libgit2/Status.hsc
--- a/src/Bindings/Libgit2/Status.hsc
+++ b/src/Bindings/Libgit2/Status.hsc
@@ -5,7 +5,25 @@
 
 import Bindings.Libgit2.Common
 import Bindings.Libgit2.Types
-#ccall git_status_foreach , Ptr <git_repository> -> Ptr () -> Ptr () -> IO (CInt)
+{- enum {
+    GIT_STATUS_CURRENT = 0,
+    GIT_STATUS_INDEX_NEW = 1 << 0,
+    GIT_STATUS_INDEX_MODIFIED = 1 << 1,
+    GIT_STATUS_INDEX_DELETED = 1 << 2,
+    GIT_STATUS_WT_NEW = 1 << 3,
+    GIT_STATUS_WT_MODIFIED = 1 << 4,
+    GIT_STATUS_WT_DELETED = 1 << 5,
+    GIT_STATUS_IGNORED = 1 << 6
+}; -}
+#num GIT_STATUS_CURRENT
+#num GIT_STATUS_INDEX_NEW
+#num GIT_STATUS_INDEX_MODIFIED
+#num GIT_STATUS_INDEX_DELETED
+#num GIT_STATUS_WT_NEW
+#num GIT_STATUS_WT_MODIFIED
+#num GIT_STATUS_WT_DELETED
+#num GIT_STATUS_IGNORED
+#ccall git_status_foreach , Ptr <git_repository> -> FunPtr (CString -> CUInt -> Ptr () -> CInt) -> Ptr () -> IO (CInt)
 {- typedef enum {
             GIT_STATUS_SHOW_INDEX_AND_WORKDIR = 0,
             GIT_STATUS_SHOW_INDEX_ONLY = 1,
@@ -17,6 +35,18 @@
 #num GIT_STATUS_SHOW_INDEX_ONLY
 #num GIT_STATUS_SHOW_WORKDIR_ONLY
 #num GIT_STATUS_SHOW_INDEX_THEN_WORKDIR
+{- enum {
+    GIT_STATUS_OPT_INCLUDE_UNTRACKED = 1 << 0,
+    GIT_STATUS_OPT_INCLUDE_IGNORED = 1 << 1,
+    GIT_STATUS_OPT_INCLUDE_UNMODIFIED = 1 << 2,
+    GIT_STATUS_OPT_EXCLUDE_SUBMODULED = 1 << 3,
+    GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS = 1 << 4
+}; -}
+#num GIT_STATUS_OPT_INCLUDE_UNTRACKED
+#num GIT_STATUS_OPT_INCLUDE_IGNORED
+#num GIT_STATUS_OPT_INCLUDE_UNMODIFIED
+#num GIT_STATUS_OPT_EXCLUDE_SUBMODULED
+#num GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS
 {- typedef struct {
             git_status_show_t show; unsigned int flags; git_strarray pathspec;
         } git_status_options; -}
@@ -25,6 +55,6 @@
 #field flags , CUInt
 #field pathspec , <git_strarray>
 #stoptype
-#ccall git_status_foreach_ext , Ptr <git_repository> -> Ptr <git_status_options> -> Ptr () -> Ptr () -> IO (CInt)
+#ccall git_status_foreach_ext , Ptr <git_repository> -> Ptr <git_status_options> -> FunPtr (CString -> CUInt -> Ptr () -> CInt) -> Ptr () -> IO (CInt)
 #ccall git_status_file , Ptr CUInt -> Ptr <git_repository> -> CString -> IO (CInt)
 #ccall git_status_should_ignore , Ptr CInt -> Ptr <git_repository> -> CString -> IO (CInt)
diff --git a/src/Bindings/Libgit2/Submodule.hsc b/src/Bindings/Libgit2/Submodule.hsc
--- a/src/Bindings/Libgit2/Submodule.hsc
+++ b/src/Bindings/Libgit2/Submodule.hsc
@@ -46,5 +46,5 @@
 #field fetch_recurse , CInt
 #field refcount , CInt
 #stoptype
-#ccall git_submodule_foreach , Ptr <git_repository> -> Ptr () -> Ptr () -> IO (CInt)
+#ccall git_submodule_foreach , Ptr <git_repository> -> FunPtr (CString -> Ptr () -> CInt) -> Ptr () -> IO (CInt)
 #ccall git_submodule_lookup , Ptr (Ptr <git_submodule>) -> Ptr <git_repository> -> CString -> IO (CInt)
diff --git a/src/Bindings/Libgit2/Tag.hsc.helper.c b/src/Bindings/Libgit2/Tag.hsc.helper.c
--- a/src/Bindings/Libgit2/Tag.hsc.helper.c
+++ b/src/Bindings/Libgit2/Tag.hsc.helper.c
@@ -1,6 +1,6 @@
 #include <bindings.cmacros.h>
 #include <git2.h>
 
-BC_INLINE3(git_tag_lookup, git_tag * *, git_repository *, const git_oid *, int)
-BC_INLINE4(git_tag_lookup_prefix, git_tag * *, git_repository *, const git_oid *, unsigned int, int)
-BC_INLINE1VOID(git_tag_free, git_tag *)
+BC_INLINE3(git_tag_lookup, git_tag**, git_repository*, const git_oid*, int)
+BC_INLINE4(git_tag_lookup_prefix, git_tag**, git_repository*, const git_oid*, unsigned int, int)
+BC_INLINE1VOID(git_tag_free, git_tag*)
diff --git a/src/Bindings/Libgit2/Tree.hsc b/src/Bindings/Libgit2/Tree.hsc
--- a/src/Bindings/Libgit2/Tree.hsc
+++ b/src/Bindings/Libgit2/Tree.hsc
@@ -1,5 +1,6 @@
 #include <bindings.dsl.h>
 #include <git2.h>
+#include <git2/tree.h>
 module Bindings.Libgit2.Tree where
 #strict_import
 
@@ -26,10 +27,16 @@
 #ccall git_treebuilder_get , Ptr <git_treebuilder> -> CString -> IO (Ptr <git_tree_entry>)
 #ccall git_treebuilder_insert , Ptr (Ptr <git_tree_entry>) -> Ptr <git_treebuilder> -> CString -> Ptr <git_oid> -> CUInt -> IO (CInt)
 #ccall git_treebuilder_remove , Ptr <git_treebuilder> -> CString -> IO (CInt)
-#ccall git_treebuilder_filter , Ptr <git_treebuilder> -> Ptr () -> Ptr () -> IO ()
+#ccall git_treebuilder_filter , Ptr <git_treebuilder> -> FunPtr (Ptr <git_tree_entry> -> Ptr () -> CInt) -> Ptr () -> IO ()
 #ccall git_treebuilder_write , Ptr <git_oid> -> Ptr <git_repository> -> Ptr <git_treebuilder> -> IO (CInt)
 #ccall git_tree_get_subtree , Ptr (Ptr <git_tree>) -> Ptr <git_tree> -> CString -> IO (CInt)
 {- typedef int (* git_treewalk_cb)(const char * root,
                                 git_tree_entry * entry,
                                 void * payload); -}
+#synonym_t git_treewalk_cb , CInt
+{- enum git_treewalk_mode {
+    GIT_TREEWALK_PRE = 0, GIT_TREEWALK_POST = 1
+}; -}
+#num GIT_TREEWALK_PRE
+#num GIT_TREEWALK_POST
 #ccall git_tree_walk , Ptr <git_tree> -> CInt -> CInt -> Ptr () -> IO (CInt)
diff --git a/src/Bindings/Libgit2/Tree.hsc.helper.c b/src/Bindings/Libgit2/Tree.hsc.helper.c
--- a/src/Bindings/Libgit2/Tree.hsc.helper.c
+++ b/src/Bindings/Libgit2/Tree.hsc.helper.c
@@ -1,6 +1,6 @@
 #include <bindings.cmacros.h>
 #include <git2.h>
 
-BC_INLINE3(git_tree_lookup, git_tree * *, git_repository *, const git_oid *, int)
-BC_INLINE4(git_tree_lookup_prefix, git_tree * *, git_repository *, const git_oid *, unsigned int, int)
-BC_INLINE1VOID(git_tree_free, git_tree *)
+BC_INLINE3(git_tree_lookup, git_tree**, git_repository*, const git_oid*, int)
+BC_INLINE4(git_tree_lookup_prefix, git_tree**, git_repository*, const git_oid*, unsigned int, int)
+BC_INLINE1VOID(git_tree_free, git_tree*)
diff --git a/src/Bindings/Libgit2/Types.hsc b/src/Bindings/Libgit2/Types.hsc
--- a/src/Bindings/Libgit2/Types.hsc
+++ b/src/Bindings/Libgit2/Types.hsc
@@ -5,7 +5,9 @@
 
 import Bindings.Libgit2.Common
 {- typedef int64_t git_off_t; -}
+#synonym_t git_off_t , CLong
 {- typedef int64_t git_time_t; -}
+#synonym_t git_time_t , CLong
 {- typedef enum {
             GIT_OBJ_ANY = -2,
             GIT_OBJ_BAD = -1,
@@ -31,12 +33,12 @@
 #num GIT_OBJ_REF_DELTA
 {- typedef struct git_odb git_odb; -}
 #opaque_t git_odb
-{- typedef struct git_odb_backend git_odb_backend; -}
-#opaque_t git_odb_backend
+-- {- typedef struct git_odb_backend git_odb_backend; -}
+-- #opaque_t git_odb_backend
 {- typedef struct git_odb_object git_odb_object; -}
 #opaque_t git_odb_object
-{- typedef struct git_odb_stream git_odb_stream; -}
-#opaque_t git_odb_stream
+-- {- typedef struct git_odb_stream git_odb_stream; -}
+-- #opaque_t git_odb_stream
 {- typedef struct git_repository git_repository; -}
 #opaque_t git_repository
 {- typedef struct git_object git_object; -}
@@ -59,6 +61,8 @@
 #opaque_t git_index
 {- typedef struct git_config git_config; -}
 #opaque_t git_config
+-- {- typedef struct git_config_file git_config_file; -}
+-- #opaque_t git_config_file
 {- typedef struct git_reflog_entry git_reflog_entry; -}
 #opaque_t git_reflog_entry
 {- typedef struct git_reflog git_reflog; -}
@@ -107,5 +111,5 @@
 #opaque_t git_refspec
 {- typedef struct git_remote git_remote; -}
 #opaque_t git_remote
-{- typedef struct git_remote_head git_remote_head; -}
-#opaque_t git_remote_head
+-- {- typedef struct git_remote_head git_remote_head; -}
+-- #opaque_t git_remote_head
