Commits

evhan committed d3c2557 Merge

Merge branch 'libgit2-v0.20.0' into development

  • Participants
  • Parent commits fc07161, 953230f

Comments (0)

Files changed (7)

     $ cd chicken-git
     $ chicken-install -test
 
-This library requires libgit2 0.19.0 and Chicken 4.7 or newer.
+This library requires libgit2 0.20.0 and Chicken 4.7 or newer.
 
 ## API
 

File git-exports.scm

  commit-ancestor
  commit-author
  commit-committer
+ commit-header
  commit-id
  commit-message
  commit-message-encoding
+ commit-message-raw
  commit-parent
  commit-parent-id
  commit-parentcount
  remote-connect
  remote-connected?
  remote-disconnect
- remote-download
+ ;remote-download
  remote-name
  remote-pushurl
  remote-pushurl-set!
  repository-empty?
  repository-head
  repository-head-detached?
- repository-head-orphan?
+ repository-head-unborn?
  repository-open
  repository-path
  repository-ref

File git-lolevel-exports.scm

  blob-rawsize
  branch-create
  branch-delete
- branch-foreach
  branch-is-head
+ branch-iterator-new
+ branch-iterator-free
  branch-lookup
  branch-move
  branch-name
+ branch-next
  checkout-head
  checkout-index
  checkout-tree
  commit-lookup
  commit-message
  commit-message-encoding
+ commit-message-raw
  commit-nth-gen-ancestor
  commit-parent
  commit-parent-id
  commit-time-offset
  commit-tree
  commit-tree-id
+ commit-raw-header
  config-delete-entry
  config-entry-level
  config-entry-name
  repository-free
  repository-head
  repository-head-detached
- repository-head-orphan
+ repository-head-unborn
  repository-index
  repository-init
  repository-is-bare

File git-lolevel.scm

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; branch.h
 
+(define-foreign-type branch-iterator (c-pointer "git_branch_iterator"))
+
 (define-external GIT_BRANCH_ALL int
   (foreign-value "GIT_BRANCH_LOCAL | GIT_BRANCH_REMOTE" int))
 
 (define branch-delete       (foreign-lambda/retval git_branch_delete reference))
 (define branch-is-head      (foreign-lambda bool git_branch_is_head reference))
 
-(define-foreign-type branch-foreach-cb (function int ((const c-string) branch-type c-pointer)))
-(define-external (branch_foreach_cb (c-string name) (branch-type type) (c-pointer fn)) int
-  ((callback-lookup fn) name type) 0)
-
-(define (branch-foreach repo flags fn)
-  (call-with-callback fn
-   (lambda (callback)
-     (guard-errors git_branch_foreach
-      ((foreign-safe-lambda int git_branch_foreach
-        repository branch-type branch-foreach-cb            c-pointer)
-        repo       flags       (location branch_foreach_cb) callback)))))
+;; Branch iterators.
+(define branch-iterator-new  (foreign-lambda/allocate branch-iterator git_branch_iterator_new repository branch-type))
+(define branch-iterator-free (foreign-lambda void git_branch_iterator_free branch-iterator))
+(define branch-next
+  (let ((next (foreign-lambda/allocate reference git_branch_next (c-pointer branch-type) branch-iterator)))
+    (lambda (iter)
+      (let-location ((t branch-type))
+        (let ((b (next (location t) iter)))
+          (values b t))))))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; checkout.h
 (define commit-free             (foreign-lambda void git_commit_free commit))
 (define commit-id               (foreign-lambda oid git_commit_id commit))
 (define commit-message          (foreign-lambda c-string git_commit_message commit))
+(define commit-message-raw      (foreign-lambda c-string git_commit_message_raw commit))
 (define commit-message-encoding (foreign-lambda c-string git_commit_message_encoding commit))
 (define commit-time             (foreign-lambda time-t git_commit_time commit))
 (define commit-time-offset      (foreign-lambda int git_commit_time_offset commit))
+(define commit-raw-header       (foreign-lambda c-string git_commit_raw_header commit))
 (define commit-committer        (foreign-lambda signature git_commit_committer commit))
 (define commit-author           (foreign-lambda signature git_commit_author commit))
 (define commit-tree-id          (foreign-lambda oid git_commit_tree_id commit))
 (define commit-parentcount      (foreign-lambda unsigned-int git_commit_parentcount commit))
 (define commit-parent-id        (foreign-lambda oid git_commit_parent_id commit unsigned-int))
 
-(define (pack-commit-pointer-array ptrs)
-  ((foreign-lambda* (c-pointer commit) ((scheme-object ptrs) (int len))
-    "int i;
-     C_word iter;
-     git_commit **out = malloc(sizeof(git_commit *) * len);
-     for(i = 0, iter = ptrs; i < len; i++, iter = C_u_i_cdr(iter))
-       out[i] = (git_commit *) C_pointer_address(C_u_i_car(iter));
-     C_return(out);")
-    ptrs
-    (length ptrs)))
+(define pack-commit-pointer-array
+  (foreign-lambda* (c-pointer commit) ((scheme-object ptrs) (int len))
+   "int i;
+    C_word iter;
+    git_commit **out = malloc(sizeof(git_commit *) * len);
+    for(i = 0, iter = ptrs; i < len; i++, iter = C_u_i_cdr(iter))
+      out[i] = (git_commit *) C_pointer_address(C_u_i_car(iter));
+    C_return(out);"))
 
 (define (commit-create repo ref author commit msg tree parents)
-  (let ((parents* #f))
-    (dynamic-wind
-     (lambda ()
-       (set! parents* (pack-commit-pointer-array parents)))
-     (lambda ()
-       ((foreign-lambda/allocate oid git_commit_create
-         repository c-string signature signature c-string nonnull-c-string tree int              (c-pointer (const commit)))
-         repo       ref      author    commit    #f       msg              tree (length parents) parents*))
-     (lambda ()
-       (free parents*)))))
+  (let* ((parent-count (length parents))
+         (parent-array (pack-commit-pointer-array parents parent-count))
+         (commit-oid
+          ((foreign-lambda/allocate oid git_commit_create
+            repository c-string signature signature c-string nonnull-c-string tree int          (c-pointer (const commit)))
+            repo       ref      author    commit    #f       msg              tree parent-count parent-array)))
+    (free parent-array)
+    commit-oid))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; common.h
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; diff.h
 
-(define-foreign-type diff-list (c-pointer "git_diff_list"))
+(define-foreign-type diff (c-pointer "git_diff"))
 (define-foreign-type diff-file-fn (c-pointer "git_diff_file_fn"))
 
 (define-foreign-enum-type (diff-line char)
   (unsigned-int16 mode   diff-file-mode))
 
 (define-foreign-record-type (diff-delta git_diff_delta)
-  ((struct diff-file) old_file   diff-delta-old-file)
-  ((struct diff-file) new_file   diff-delta-new-file)
   (delta              status     diff-delta-status)
-  (unsigned-int32     similarity diff-delta-similarity)
-  (unsigned-int32     flags      diff-delta-flags))
-
-(define-foreign-record-type (diff-range git_diff_range)
-  (int old_start diff-range-old-start)
-  (int old_lines diff-range-old-lines)
-  (int new_start diff-range-new-start)
-  (int new_lines diff-range-new-lines))
+  (unsigned-int32     flags      diff-delta-flags)
+  (unsigned-int16     similarity diff-delta-similarity)
+  (unsigned-int16     nfiles     diff-delta-nfiles)
+  ((struct diff-file) old_file   diff-delta-old-file)
+  ((struct diff-file) new_file   diff-delta-new-file))
 
-(define diff-list-free (foreign-lambda void git_diff_list_free diff-list))
-(define diff-merge     (foreign-lambda/retval git_diff_merge diff-list diff-list))
+(define diff-merge        (foreign-lambda/retval git_diff_merge diff diff))
+(define diff-find-similar (foreign-lambda/retval git_diff_find_similar diff c-pointer)) ; git_diff_find_options
+(define diff-num-deltas   (foreign-lambda size_t git_diff_num_deltas diff))
+(define diff-num-deltas-of-type (foreign-lambda size_t git_diff_num_deltas_of_type diff delta))
+(define diff-free         (foreign-lambda void git_diff_free diff))
 
 (define-syntax foreign-lambda/diff
   (lambda (e . _)
            (types (cddr e))
            (args  (map gensym types)))
       `(lambda (repo ,@args)
-         (let-location ((diffs diff-list))
+         (let-location ((diff diff))
            ((foreign-lambda/retval ,name
-            (c-pointer diff-list) repository ,@types diff-options)
-            (location diffs)      repo       ,@args  #f)
-           (set-finalizer! diffs diff-list-free))))))
+            (c-pointer diff) repository ,@types diff-options)
+            (location diff)  repo       ,@args  #f)
+           (set-finalizer! diff diff-free))))))
 
 (define diff-tree-to-tree     (foreign-lambda/diff git_diff_tree_to_tree tree tree))
 (define diff-tree-to-index    (foreign-lambda/diff git_diff_tree_to_index tree index))
 (define diff-index-to-workdir (foreign-lambda/diff git_diff_index_to_workdir index))
 (define diff-tree-to-workdir  (foreign-lambda/diff git_diff_tree_to_workdir tree))
 
-;; (define-foreign-type diff-file-cb (c-pointer "git_diff_file_cb"))
 (define-foreign-type diff-file-cb (function int ((const diff-delta) float c-pointer)))
 (define-external (diff_file_cb (diff-delta diff) (float progress) (c-pointer fn)) int
   ((callback-lookup fn) diff progress) 0)
 
-;; (define-foreign-type diff-hunk-cb (c-pointer "git_diff_hunk_cb"))
-(define-foreign-type diff-hunk-cb (function int ((const diff-delta) (const diff-range) (const c-string) size_t c-pointer)))
-(define-external (diff_hunk_cb (diff-delta diff) (diff-range range) (float progress) (c-pointer fn)) int
-  ((callback-lookup fn) diff range) 0)
-
-;; (define-foreign-type diff-data-cb (c-pointer "git_diff_data_cb"))
-(define-foreign-type diff-data-cb (function int ((const diff-delta) (const diff-range) char (const c-string) size_t c-pointer)))
-(define-external (diff_data_cb (diff-delta diff) (diff-range range) (char line) (c-string content) (size_t len) (c-pointer fn)) int
-  ((callback-lookup fn) diff range line content) 0)
-
 (define (diff-foreach fn diffs)
   (call-with-callback fn
    (lambda (callback)
      (guard-errors git_diff_foreach
       ((foreign-safe-lambda int git_diff_foreach
-        diff-list diff-file-cb            diff-hunk-cb diff-data-cb c-pointer)
-        diffs     (location diff_file_cb) #f           #f           callback)))))
+        diff  diff-file-cb            c-pointer c-pointer c-pointer)
+        diffs (location diff_file_cb) #f        #f        callback)))))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; errors.h
 (define index-open             (foreign-lambda/allocate index git_index_open nonnull-c-string))
 (define index-write-tree       (foreign-lambda/allocate oid git_index_write_tree index))
 (define index-write-tree-to    (foreign-lambda/allocate oid git_index_write_tree_to index repository))
-(define index-read             (foreign-lambda/retval git_index_read index))
+(define index-read             (foreign-lambda/retval git_index_read index bool))
 (define index-write            (foreign-lambda/retval git_index_write index))
 (define index-add              (foreign-lambda/retval git_index_add index index-entry))
 (define index-add-bypath       (foreign-lambda/retval git_index_add_bypath index nonnull-c-string))
 (define object-string2type (foreign-lambda object-type git_object_string2type nonnull-c-string))
 (define object-typeisloose (foreign-lambda bool git_object_typeisloose object-type))
 
+(define object-lookup-bypath
+  (foreign-lambda/allocate object git_object_lookup_bypath object nonnull-c-string object-type))
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; odb_backend.h
 ;;
 (define repository-path          (foreign-lambda c-string git_repository_path repository))
 (define repository-workdir       (foreign-lambda c-string git_repository_workdir repository))
 (define repository-head-detached (foreign-lambda bool git_repository_head_detached repository))
-(define repository-head-orphan   (foreign-lambda bool git_repository_head_orphan repository))
+(define repository-head-unborn   (foreign-lambda bool git_repository_head_unborn repository))
 
 (define (repository-discover path)
   (let* ((len (foreign-value GIT_PATH_MAX int))
 (define remote-create-inmemory      (foreign-lambda/allocate remote git_remote_create_inmemory repository nonnull-c-string nonnull-c-string))
 (define remote-get-refspec          (foreign-lambda refspec git_remote_get_refspec remote int))
 (define remote-connect              (foreign-lambda/retval git_remote_connect remote direction))
+(define remote-download             (foreign-lambda/retval git_remote_download remote))
 (define remote-save                 (foreign-lambda/retval git_remote_save remote))
 (define remote-set-url              (foreign-lambda/retval git_remote_set_url remote nonnull-c-string))
 (define remote-set-pushurl          (foreign-lambda/retval git_remote_set_pushurl remote nonnull-c-string))
 (define remote-update-tips          (foreign-lambda/retval git_remote_update_tips remote))
 (define remote-update-fetchhead     (foreign-lambda/retval git_remote_update_fetchhead remote))
-(define remote-remove-refspec       (foreign-lambda/retval git_remote_remove_refspec remote int))
 (define remote-clear-refspecs       (foreign-lambda void git_remote_clear_refspecs remote))
 (define remote-refspec-count        (foreign-lambda int git_remote_refspec_count remote))
 (define remote-stats                (foreign-lambda transfer-progress git_remote_stats remote))
 (define remote-supported-url        (foreign-lambda bool git_remote_supported_url nonnull-c-string))
 (define remote-is-valid-name        (foreign-lambda bool git_remote_is_valid_name nonnull-c-string))
 
-(define (remote-download remote fn)
-  (if (not fn)
-      ((foreign-lambda/retval git_remote_download remote transfer-progress-cb c-pointer) remote #f #f)
-      (call-with-callback fn
-       (lambda (cb)
-         (guard-errors git_remote_download
-          ((foreign-safe-lambda int git_remote_download
-            remote transfer-progress-cb            c-pointer)
-            remote (location transfer_progress_cb) cb))))))
-
 (define-foreign-type remote-rename-problem-cb (function int ((const c-string) c-pointer)))
 (define-external (remote_rename_problem_cb (c-string path) (c-pointer fn)) int
   ((callback-lookup fn) path) 0)
                             (,(s+ 'git- getter) (,->pointer obj)))))))
                   attrs))))))
 
+(define-syntax begin0-let
+  (syntax-rules ()
+    ((_ ((n e) . rest) . body)
+     (let ((n e) . rest) (begin . body) n))))
+
 (define ((git-record-attribute-setter f) r v) (f (object->pointer r) v))
 (define ((set-owner m f) o) (m o (f o)))
 (define ((preserve-owner m f) o) (m (object-owner o) (f o)))
 ;;;
 
 (define-git-record-type repository
-  ((repository) is-empty is-bare path workdir head-orphan head-detached)
+  ((repository) is-empty is-bare path workdir head-unborn head-detached)
   (format "#<repository ~S>" (repository-path repository))
   (git-repository-free))
 
 (define repository-empty? repository-is-empty)
 (define repository-bare? repository-is-bare)
-(define repository-head-orphan? repository-head-orphan)
+(define repository-head-unborn? repository-head-unborn)
 (define repository-head-detached? repository-head-detached)
 (define repository-working-directory repository-workdir)
 
   (pointer->reference repo (git-reference-lookup (repository->pointer repo) name)))
 
 (define (references-fold kons knil repo #!optional (type 'all))
-  (let ((state knil))
+  (begin0-let ((state knil))
     (git-reference-foreach-name
      (repository->pointer repo)
      (lambda (name)
                 (git-reference-lookup
                  (repository->pointer repo)
                  name))
-               state))))
-    state))
+               state))))))
 
 (define (references repo #!optional (type 'all))
   (references-fold cons '() repo type))
 (define branch-head?    (compose git-branch-is-head reference->pointer))
 
 (define (branches-fold kons knil repo #!optional (type 'all))
-  (let ((state knil))
-    (git-branch-foreach
-     (repository->pointer repo)
-     type
-     (lambda (name type)
-       (set! state
-         (kons (pointer->reference
-                repo
-                (git-branch-lookup
-                 (repository->pointer repo)
-                 name
-                 type))
-               state))))
-    state))
+  (let* ((repo* (repository->pointer repo))
+         (iter  (set-finalizer! (git-branch-iterator-new repo* type) git-branch-iterator-free)))
+     (let loop ((state knil))
+       (let ((b (condition-case
+                  (git-branch-next iter)
+                  ((git) #f))))
+         (if (not b)
+             state
+             (loop (kons (pointer->reference repo b) state)))))))
 
 (define (branches repo #!optional (type 'all))
   (branches-fold cons '() repo type))
 ;; Commits
 
 (define-git-record-type commit
-  ((commit repository) id message message-encoding time time-offset parentcount)
+  ((commit repository) id parentcount message message-raw message-encoding time time-offset raw-header)
   (format "#<commit ~S>" (oid->string (commit-id commit) 7))
   (git-commit-free))
 
+(define commit-header commit-raw-header)
+
 (define commit-tree      (preserve-owner pointer->tree (compose git-commit-tree commit->pointer)))
 (define commit-tree-id   (compose pointer->oid git-oid-cpy git-commit-tree-id commit->pointer))
 (define commit-parent-id (compose pointer->oid git-oid-cpy git-commit-parent-id commit->pointer))
     (->oid->pointer ref))))
 
 (define (commits-fold kons knil repo #!key initial (hide '()) (sort 'none))
-  (let* ((repo*  (repository->pointer repo))
-         (walker (set-finalizer! (git-revwalk-new repo*) git-revwalk-free)))
-    (call-with-current-continuation
-     (lambda (k)
-       ;; Sort mode, one of '(none topo time rev)
-       (git-revwalk-sorting walker sort)
-       ;; Set hidden commits. These exclude full branches from the
-       ;; traversal, rather than just the commits.
-       (for-each (lambda (h) (git-revwalk-hide walker (->oid->pointer h))) hide)
-       (condition-case
-         (if initial ; Set the initial revision.
-             (git-revwalk-push walker (->oid->pointer initial))
-             (git-revwalk-push-head walker))
-         ((git) (k '())))
-       (let loop ((state knil))
-         (loop (kons (pointer->commit
-                      repo
-                      (git-commit-lookup
-                       repo*
-                       (condition-case
-                         (git-revwalk-next walker)
-                         ((git) (k state)))))
-                     state)))))))
+  (let ((repo* (repository->pointer repo)))
+    (if (git-repository-head-unborn repo*)
+        '() ; No HEAD means no commits.
+        (let ((iter (set-finalizer! (git-revwalk-new repo*) git-revwalk-free)))
+          (if initial ; Set the initial revision.
+              (git-revwalk-push iter (->oid->pointer initial))
+              (git-revwalk-push-head iter))
+          ;; Set sort mode, from '(none topo time rev).
+          (git-revwalk-sorting iter sort)
+          ;; Set hidden commits.
+          (for-each (lambda (h) (git-revwalk-hide iter (->oid->pointer h))) hide)
+          ;; Iterate commits.
+          (let loop ((state knil))
+            (let ((c (condition-case
+                       (git-revwalk-next iter)
+                       ((git) #f))))
+              (if (not c)
+                  state ; Exhausted iterator.
+                  (loop (kons (pointer->commit
+                               repo
+                               (git-commit-lookup repo* c))
+                              state)))))))))
 
 (define (commits repo #!rest rest)
   (apply commits-fold cons '() repo rest))
 ;; Index
 
 (define-git-record-type index
-  ((index) entrycount read write clear)
+  ((index) entrycount write clear)
   "#<index>"
   (git-index-free))
 
 (define (index-remove ix ref)
   (git-index-remove (index->pointer ix) ref 0))
 
+(define (index-read ix #!optional force)
+  (git-index-read (index->pointer ix) force))
+
 (define (index-ref ix key)
   (let ((ix* (index->pointer ix)))
     (pointer->index-entry
   (git-status-should-ignore (repository->pointer repo) path))
 
 (define (file-statuses-fold kons knil repo)
-  (let ((state knil))
+  (begin0-let ((state knil))
     (git-status-foreach
      (lambda (path status)
        (set! state (kons path status state)))
-     (repository->pointer repo))
-    state))
+     (repository->pointer repo))))
 
 (define (file-statuses repo)
   (file-statuses-fold
         ;; If the notes reference doesn't exist, return knil immediately.
         (if (not (reference-exists? repo* (or reference (git-note-default-ref repo*))))
             knil
-            (let ((state knil))
+            (begin0-let ((state knil))
               (git-note-foreach
                repo*
                reference
                (lambda (bid* oid*)
                  (set! state
-                   (kons (pointer->note repo (git-note-read repo* reference oid*)) state))))
-              state))))))
+                   (kons (pointer->note repo (git-note-read repo* reference oid*)) state))))))))))
 
 (define (notes repo #!optional reference)
   (notes-fold cons '() repo reference))
     (->oid->pointer ref))))
 
 (define (tags-fold kons knil repo)
-  (let ((state knil))
+  (begin0-let ((state knil))
     (git-tag-foreach
      (lambda (name oid*)
        (set! state
                  (repository->pointer repo)
                  oid*))
                state)))
-     (repository->pointer repo))
-    state))
+     (repository->pointer repo))))
 
 (define (tags repo)
   (tags-fold cons '() repo))
    (or (diff-new-file diff)
        (diff-old-file diff))))
 
-;; Helper for `diff`, below.
-;;
-;; Adds a refcount to the diff-list, to delay GC until all its
-;; diff-deltas are unreachable.
-(define (build-diff-list diffs)
-  (let ((acc '()))
-    (git-diff-foreach
-     (lambda (delta* progress)
-       (set! acc (cons (pointer->diff-delta diffs delta*) acc)))
-     diffs)
-    acc))
-
 (define diff
-  (case-lambda
-    ((repo)
-     (diff repo (index-open repo)))
-    ((repo object)
-     (build-diff-list
-      (let ((repo* (repository->pointer repo)))
-        (cond ((index? object)
-               (git-diff-index-to-workdir repo* (index->pointer object)))
-              ((tree? object)
-               (git-diff-tree-to-workdir repo* (tree->pointer  object)))
-              (else
-               (git-error 'diff "Undiffable object" object))))))
-    ((repo tree object)
-     (build-diff-list
-      (let ((repo* (repository->pointer repo))
-            (tree* (tree->pointer tree)))
-        (cond ((tree? object)
-               (git-diff-tree-to-tree repo* tree* (tree->pointer object)))
-              ((index? object)
-               (git-diff-tree-to-index repo* tree* (index->pointer object)))
-              (else
-               (git-error 'diff "Undiffable object" object))))))))
+  (let ((build-diff-list
+         (lambda (diffs)
+           (begin0-let ((acc '()))
+             (git-diff-foreach
+              (lambda (delta* progress)
+                (set! acc (cons (pointer->diff-delta diffs delta*) acc)))
+              diffs)))))
+    (case-lambda
+      ((repo)
+       (diff repo (index-open repo)))
+      ((repo object)
+       (build-diff-list
+        (let ((repo* (repository->pointer repo)))
+          (cond ((index? object)
+                 (git-diff-index-to-workdir repo* (index->pointer object)))
+                ((tree? object)
+                 (git-diff-tree-to-workdir repo* (tree->pointer  object)))
+                (else
+                 (git-error 'diff "Undiffable object" object))))))
+      ((repo tree object)
+       (build-diff-list
+        (let ((repo* (repository->pointer repo))
+              (tree* (tree->pointer tree)))
+          (cond ((tree? object)
+                 (git-diff-tree-to-tree repo* tree* (tree->pointer object)))
+                ((index? object)
+                 (git-diff-tree-to-index repo* tree* (index->pointer object)))
+                (else
+                 (git-error 'diff "Undiffable object" object)))))))))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;
    rem
    (git-remote-stats (remote->pointer rem))))
 
-(define remote-download
-  (let ((make-remote-download-callback
-         (lambda (rem fn)
-           (and fn (lambda (tp*)
-                     (fn (pointer->transfer-progress rem tp*)))))))
-    (lambda (rem #!optional fn)
-      (if (remote-connected? rem)
-          (git-remote-download
-           (remote->pointer rem)
-           (make-remote-download-callback rem fn))
-          (dynamic-wind
-           (lambda ()
-             (remote-connect rem))
-           (lambda ()
-             (remote-download rem (make-remote-download-callback rem fn))
-             (remote-update-tips rem)
-             (remote-stats rem))
-           (lambda ()
-             (remote-disconnect rem)))))))
+;(define remote-download
+;  (let ((make-remote-download-callback
+;         (lambda (rem fn)
+;           (and fn (lambda (tp*)
+;                     (fn (pointer->transfer-progress rem tp*)))))))
+;    (lambda (rem #!optional fn)
+;      (if (remote-connected? rem)
+;          (git-remote-download
+;           (remote->pointer rem)
+;           (make-remote-download-callback rem fn))
+;          (dynamic-wind
+;           (lambda ()
+;             (remote-connect rem))
+;           (lambda ()
+;             (remote-download rem (make-remote-download-callback rem fn))
+;             (remote-update-tips rem)
+;             (remote-stats rem))
+;           (lambda ()
+;             (remote-disconnect rem)))))))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;
 (define *required-chicken* '("4.7.0"  . #(4 7 0)))
-(define *required-libgit2* '("0.19.0" . #(0 19 0)))
+(define *required-libgit2* '("0.20.0" . #(0 20 0)))
 
 ;; Verify the CHICKEN version.
 (when (string<? (chicken-version) (car *required-chicken*))
 (unless (or (string-null? pkg-config-version)
             (string=? pkg-config-version (car *required-libgit2*)))
   (fprintf (current-error-port)
-           "\n  git: This extension requires libgit2 version ~a or later."
+           "\n  git: This extension requires libgit2 version ~a."
            (car *required-libgit2*))
   (exit 1))
 
 
 Bindings to the [[http://libgit2.github.com|libgit2]] library.
 
-This library requires libgit2 0.19.0 and Chicken 4.7 or newer.
+This library requires libgit2 0.20.0 and Chicken 4.7 or newer.
 
 The source for this egg is available at [[http://github.com/evhan/chicken-git]].