rugged 0.27.10.1 → 0.28.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (297) hide show
  1. checksums.yaml +4 -4
  2. data/ext/rugged/extconf.rb +23 -2
  3. data/ext/rugged/rugged.c +48 -2
  4. data/ext/rugged/rugged.h +5 -0
  5. data/ext/rugged/rugged_allocator.c +89 -0
  6. data/ext/rugged/rugged_blob.c +3 -3
  7. data/ext/rugged/rugged_branch.c +1 -1
  8. data/ext/rugged/rugged_commit.c +8 -8
  9. data/ext/rugged/rugged_config.c +1 -1
  10. data/ext/rugged/rugged_diff.c +24 -4
  11. data/ext/rugged/rugged_note.c +1 -1
  12. data/ext/rugged/rugged_repo.c +10 -10
  13. data/ext/rugged/rugged_settings.c +1 -1
  14. data/lib/rugged/version.rb +1 -1
  15. data/vendor/libgit2/CMakeLists.txt +69 -47
  16. data/vendor/libgit2/cmake/Modules/AddCFlagIfSupported.cmake +15 -1
  17. data/vendor/libgit2/cmake/Modules/EnableWarnings.cmake +5 -8
  18. data/vendor/libgit2/cmake/Modules/FindmbedTLS.cmake +93 -0
  19. data/vendor/libgit2/deps/http-parser/CMakeLists.txt +2 -0
  20. data/vendor/libgit2/deps/http-parser/{LICENSE-MIT → COPYING} +0 -0
  21. data/vendor/libgit2/deps/regex/COPYING +502 -0
  22. data/vendor/libgit2/deps/winhttp/COPYING.GPL +993 -0
  23. data/vendor/libgit2/deps/winhttp/COPYING.LGPL +502 -0
  24. data/vendor/libgit2/deps/zlib/CMakeLists.txt +1 -0
  25. data/vendor/libgit2/deps/zlib/COPYING +27 -0
  26. data/vendor/libgit2/include/git2.h +3 -0
  27. data/vendor/libgit2/include/git2/annotated_commit.h +9 -0
  28. data/vendor/libgit2/include/git2/apply.h +129 -0
  29. data/vendor/libgit2/include/git2/attr.h +19 -8
  30. data/vendor/libgit2/include/git2/blame.h +41 -24
  31. data/vendor/libgit2/include/git2/blob.h +1 -1
  32. data/vendor/libgit2/include/git2/branch.h +1 -1
  33. data/vendor/libgit2/include/git2/buffer.h +2 -2
  34. data/vendor/libgit2/include/git2/checkout.h +20 -19
  35. data/vendor/libgit2/include/git2/cherrypick.h +6 -4
  36. data/vendor/libgit2/include/git2/clone.h +11 -9
  37. data/vendor/libgit2/include/git2/commit.h +30 -2
  38. data/vendor/libgit2/include/git2/common.h +54 -4
  39. data/vendor/libgit2/include/git2/config.h +18 -7
  40. data/vendor/libgit2/include/git2/deprecated.h +253 -0
  41. data/vendor/libgit2/include/git2/describe.h +30 -7
  42. data/vendor/libgit2/include/git2/diff.h +193 -143
  43. data/vendor/libgit2/include/git2/errors.h +54 -46
  44. data/vendor/libgit2/include/git2/ignore.h +2 -2
  45. data/vendor/libgit2/include/git2/index.h +72 -51
  46. data/vendor/libgit2/include/git2/indexer.h +30 -4
  47. data/vendor/libgit2/include/git2/mailmap.h +115 -0
  48. data/vendor/libgit2/include/git2/merge.h +29 -8
  49. data/vendor/libgit2/include/git2/net.h +1 -1
  50. data/vendor/libgit2/include/git2/notes.h +1 -1
  51. data/vendor/libgit2/include/git2/object.h +16 -16
  52. data/vendor/libgit2/include/git2/odb.h +10 -10
  53. data/vendor/libgit2/include/git2/odb_backend.h +7 -7
  54. data/vendor/libgit2/include/git2/oid.h +1 -1
  55. data/vendor/libgit2/include/git2/pack.h +2 -2
  56. data/vendor/libgit2/include/git2/proxy.h +9 -5
  57. data/vendor/libgit2/include/git2/rebase.h +7 -4
  58. data/vendor/libgit2/include/git2/refs.h +14 -15
  59. data/vendor/libgit2/include/git2/refspec.h +17 -0
  60. data/vendor/libgit2/include/git2/remote.h +92 -16
  61. data/vendor/libgit2/include/git2/repository.h +52 -37
  62. data/vendor/libgit2/include/git2/revert.h +5 -3
  63. data/vendor/libgit2/include/git2/revwalk.h +7 -7
  64. data/vendor/libgit2/include/git2/signature.h +2 -2
  65. data/vendor/libgit2/include/git2/stash.h +13 -10
  66. data/vendor/libgit2/include/git2/status.h +8 -4
  67. data/vendor/libgit2/include/git2/submodule.h +11 -10
  68. data/vendor/libgit2/include/git2/sys/alloc.h +101 -0
  69. data/vendor/libgit2/include/git2/sys/commit.h +1 -1
  70. data/vendor/libgit2/include/git2/sys/config.h +13 -13
  71. data/vendor/libgit2/include/git2/sys/filter.h +6 -6
  72. data/vendor/libgit2/include/git2/sys/index.h +3 -0
  73. data/vendor/libgit2/include/git2/sys/mempack.h +35 -35
  74. data/vendor/libgit2/include/git2/sys/merge.h +9 -4
  75. data/vendor/libgit2/include/git2/sys/odb_backend.h +19 -19
  76. data/vendor/libgit2/include/git2/sys/path.h +64 -0
  77. data/vendor/libgit2/include/git2/sys/refdb_backend.h +19 -19
  78. data/vendor/libgit2/include/git2/sys/stream.h +92 -12
  79. data/vendor/libgit2/include/git2/sys/transport.h +127 -81
  80. data/vendor/libgit2/include/git2/tag.h +2 -2
  81. data/vendor/libgit2/include/git2/trace.h +1 -1
  82. data/vendor/libgit2/include/git2/transaction.h +1 -0
  83. data/vendor/libgit2/include/git2/transport.h +47 -18
  84. data/vendor/libgit2/include/git2/tree.h +3 -3
  85. data/vendor/libgit2/include/git2/types.h +35 -28
  86. data/vendor/libgit2/include/git2/version.h +4 -4
  87. data/vendor/libgit2/include/git2/worktree.h +47 -12
  88. data/vendor/libgit2/src/CMakeLists.txt +87 -26
  89. data/vendor/libgit2/src/alloc.c +55 -0
  90. data/vendor/libgit2/src/alloc.h +40 -0
  91. data/vendor/libgit2/src/annotated_commit.c +15 -8
  92. data/vendor/libgit2/src/apply.c +490 -14
  93. data/vendor/libgit2/src/apply.h +3 -1
  94. data/vendor/libgit2/src/array.h +2 -2
  95. data/vendor/libgit2/src/attr.c +11 -11
  96. data/vendor/libgit2/src/attr_file.c +20 -15
  97. data/vendor/libgit2/src/attrcache.c +11 -11
  98. data/vendor/libgit2/src/blame.c +30 -15
  99. data/vendor/libgit2/src/blame.h +1 -0
  100. data/vendor/libgit2/src/blame_git.c +16 -13
  101. data/vendor/libgit2/src/blob.c +50 -28
  102. data/vendor/libgit2/src/blob.h +18 -1
  103. data/vendor/libgit2/src/branch.c +38 -38
  104. data/vendor/libgit2/src/buf_text.c +7 -6
  105. data/vendor/libgit2/src/buffer.c +55 -50
  106. data/vendor/libgit2/src/buffer.h +1 -1
  107. data/vendor/libgit2/src/cache.c +16 -16
  108. data/vendor/libgit2/src/cache.h +2 -2
  109. data/vendor/libgit2/src/cc-compat.h +15 -3
  110. data/vendor/libgit2/src/checkout.c +83 -74
  111. data/vendor/libgit2/src/cherrypick.c +6 -6
  112. data/vendor/libgit2/src/clone.c +20 -20
  113. data/vendor/libgit2/src/commit.c +53 -33
  114. data/vendor/libgit2/src/commit.h +1 -0
  115. data/vendor/libgit2/src/commit_list.c +6 -10
  116. data/vendor/libgit2/src/common.h +32 -30
  117. data/vendor/libgit2/src/config.c +167 -147
  118. data/vendor/libgit2/src/config.h +1 -14
  119. data/vendor/libgit2/src/config_backend.h +84 -0
  120. data/vendor/libgit2/src/config_cache.c +7 -1
  121. data/vendor/libgit2/src/config_entries.c +259 -0
  122. data/vendor/libgit2/src/config_entries.h +23 -0
  123. data/vendor/libgit2/src/config_file.c +167 -439
  124. data/vendor/libgit2/src/config_mem.c +224 -0
  125. data/vendor/libgit2/src/config_parse.c +69 -38
  126. data/vendor/libgit2/src/config_parse.h +4 -4
  127. data/vendor/libgit2/src/crlf.c +215 -186
  128. data/vendor/libgit2/src/delta.c +25 -18
  129. data/vendor/libgit2/src/describe.c +23 -23
  130. data/vendor/libgit2/src/diff.c +12 -12
  131. data/vendor/libgit2/src/diff_driver.c +14 -15
  132. data/vendor/libgit2/src/diff_file.c +10 -10
  133. data/vendor/libgit2/src/diff_generate.c +29 -23
  134. data/vendor/libgit2/src/diff_generate.h +1 -1
  135. data/vendor/libgit2/src/diff_parse.c +3 -3
  136. data/vendor/libgit2/src/diff_print.c +17 -17
  137. data/vendor/libgit2/src/diff_stats.c +22 -7
  138. data/vendor/libgit2/src/diff_tform.c +12 -12
  139. data/vendor/libgit2/src/diff_xdiff.c +15 -3
  140. data/vendor/libgit2/src/errors.c +42 -20
  141. data/vendor/libgit2/src/features.h.in +2 -1
  142. data/vendor/libgit2/src/fetch.c +3 -3
  143. data/vendor/libgit2/src/fetchhead.c +16 -16
  144. data/vendor/libgit2/src/filebuf.c +28 -28
  145. data/vendor/libgit2/src/fileops.c +54 -54
  146. data/vendor/libgit2/src/fileops.h +1 -1
  147. data/vendor/libgit2/src/filter.c +30 -30
  148. data/vendor/libgit2/src/filter.h +0 -10
  149. data/vendor/libgit2/src/global.c +36 -23
  150. data/vendor/libgit2/src/hash.h +4 -1
  151. data/vendor/libgit2/src/hash/hash_collisiondetect.h +6 -2
  152. data/vendor/libgit2/src/hash/hash_common_crypto.h +5 -1
  153. data/vendor/libgit2/src/hash/hash_generic.h +5 -1
  154. data/vendor/libgit2/src/hash/hash_mbedtls.c +38 -0
  155. data/vendor/libgit2/src/hash/hash_mbedtls.h +24 -0
  156. data/vendor/libgit2/src/hash/hash_openssl.h +8 -4
  157. data/vendor/libgit2/src/hash/hash_win32.c +13 -13
  158. data/vendor/libgit2/src/hashsig.c +4 -4
  159. data/vendor/libgit2/src/idxmap.c +25 -5
  160. data/vendor/libgit2/src/idxmap.h +4 -18
  161. data/vendor/libgit2/src/ignore.c +9 -9
  162. data/vendor/libgit2/src/index.c +280 -198
  163. data/vendor/libgit2/src/index.h +16 -0
  164. data/vendor/libgit2/src/indexer.c +311 -139
  165. data/vendor/libgit2/src/integer.h +32 -22
  166. data/vendor/libgit2/src/iterator.c +116 -49
  167. data/vendor/libgit2/src/iterator.h +15 -0
  168. data/vendor/libgit2/src/khash.h +3 -1
  169. data/vendor/libgit2/src/mailmap.c +485 -0
  170. data/vendor/libgit2/src/mailmap.h +35 -0
  171. data/vendor/libgit2/src/merge.c +89 -59
  172. data/vendor/libgit2/src/merge_driver.c +7 -7
  173. data/vendor/libgit2/src/merge_file.c +1 -1
  174. data/vendor/libgit2/src/mwindow.c +8 -8
  175. data/vendor/libgit2/src/netops.c +22 -13
  176. data/vendor/libgit2/src/netops.h +2 -0
  177. data/vendor/libgit2/src/notes.c +15 -10
  178. data/vendor/libgit2/src/object.c +118 -67
  179. data/vendor/libgit2/src/object.h +20 -9
  180. data/vendor/libgit2/src/object_api.c +8 -8
  181. data/vendor/libgit2/src/odb.c +72 -72
  182. data/vendor/libgit2/src/odb.h +7 -7
  183. data/vendor/libgit2/src/odb_loose.c +46 -46
  184. data/vendor/libgit2/src/odb_mempack.c +14 -14
  185. data/vendor/libgit2/src/odb_pack.c +14 -10
  186. data/vendor/libgit2/src/offmap.c +30 -0
  187. data/vendor/libgit2/src/offmap.h +20 -11
  188. data/vendor/libgit2/src/oid.c +6 -6
  189. data/vendor/libgit2/src/oidmap.c +20 -0
  190. data/vendor/libgit2/src/oidmap.h +9 -12
  191. data/vendor/libgit2/src/pack-objects.c +71 -63
  192. data/vendor/libgit2/src/pack-objects.h +1 -7
  193. data/vendor/libgit2/src/pack.c +58 -58
  194. data/vendor/libgit2/src/pack.h +6 -6
  195. data/vendor/libgit2/src/parse.h +1 -1
  196. data/vendor/libgit2/src/patch.c +3 -3
  197. data/vendor/libgit2/src/patch_generate.c +18 -18
  198. data/vendor/libgit2/src/patch_parse.c +13 -13
  199. data/vendor/libgit2/src/path.c +93 -225
  200. data/vendor/libgit2/src/path.h +2 -84
  201. data/vendor/libgit2/src/pathspec.c +6 -6
  202. data/vendor/libgit2/src/posix.c +3 -3
  203. data/vendor/libgit2/src/proxy.c +1 -1
  204. data/vendor/libgit2/src/push.c +27 -26
  205. data/vendor/libgit2/src/push.h +2 -1
  206. data/vendor/libgit2/src/reader.c +265 -0
  207. data/vendor/libgit2/src/reader.h +107 -0
  208. data/vendor/libgit2/src/rebase.c +49 -52
  209. data/vendor/libgit2/src/refdb.c +3 -3
  210. data/vendor/libgit2/src/refdb_fs.c +181 -103
  211. data/vendor/libgit2/src/reflog.c +3 -3
  212. data/vendor/libgit2/src/refs.c +98 -74
  213. data/vendor/libgit2/src/refs.h +5 -3
  214. data/vendor/libgit2/src/refspec.c +47 -21
  215. data/vendor/libgit2/src/refspec.h +1 -1
  216. data/vendor/libgit2/src/remote.c +219 -166
  217. data/vendor/libgit2/src/remote.h +9 -0
  218. data/vendor/libgit2/src/repository.c +173 -133
  219. data/vendor/libgit2/src/repository.h +6 -3
  220. data/vendor/libgit2/src/reset.c +8 -8
  221. data/vendor/libgit2/src/revert.c +6 -6
  222. data/vendor/libgit2/src/revparse.c +30 -30
  223. data/vendor/libgit2/src/revwalk.c +60 -30
  224. data/vendor/libgit2/src/revwalk.h +2 -1
  225. data/vendor/libgit2/src/settings.c +42 -10
  226. data/vendor/libgit2/src/signature.c +11 -11
  227. data/vendor/libgit2/src/sortedcache.c +13 -13
  228. data/vendor/libgit2/src/stash.c +91 -45
  229. data/vendor/libgit2/src/status.c +13 -13
  230. data/vendor/libgit2/src/stdalloc.c +120 -0
  231. data/vendor/libgit2/src/{streams/curl.h → stdalloc.h} +6 -6
  232. data/vendor/libgit2/src/stream.h +17 -2
  233. data/vendor/libgit2/src/streams/mbedtls.c +483 -0
  234. data/vendor/libgit2/src/streams/mbedtls.h +23 -0
  235. data/vendor/libgit2/src/streams/openssl.c +204 -114
  236. data/vendor/libgit2/src/streams/openssl.h +4 -108
  237. data/vendor/libgit2/src/streams/registry.c +118 -0
  238. data/vendor/libgit2/src/streams/registry.h +19 -0
  239. data/vendor/libgit2/src/streams/socket.c +54 -29
  240. data/vendor/libgit2/src/streams/stransport.c +57 -32
  241. data/vendor/libgit2/src/streams/stransport.h +5 -0
  242. data/vendor/libgit2/src/streams/tls.c +50 -19
  243. data/vendor/libgit2/src/streams/tls.h +12 -4
  244. data/vendor/libgit2/src/strmap.c +22 -2
  245. data/vendor/libgit2/src/strmap.h +18 -15
  246. data/vendor/libgit2/src/submodule.c +179 -155
  247. data/vendor/libgit2/src/sysdir.c +18 -18
  248. data/vendor/libgit2/src/tag.c +31 -26
  249. data/vendor/libgit2/src/tag.h +2 -1
  250. data/vendor/libgit2/src/trace.c +1 -1
  251. data/vendor/libgit2/src/trace.h +1 -1
  252. data/vendor/libgit2/src/trailer.c +6 -6
  253. data/vendor/libgit2/src/transaction.c +23 -23
  254. data/vendor/libgit2/src/transport.c +5 -5
  255. data/vendor/libgit2/src/transports/auth.c +7 -4
  256. data/vendor/libgit2/src/transports/auth.h +1 -1
  257. data/vendor/libgit2/src/transports/auth_negotiate.c +12 -11
  258. data/vendor/libgit2/src/transports/cred.c +18 -18
  259. data/vendor/libgit2/src/transports/git.c +15 -15
  260. data/vendor/libgit2/src/transports/http.c +606 -216
  261. data/vendor/libgit2/src/transports/http.h +2 -0
  262. data/vendor/libgit2/src/transports/local.c +26 -26
  263. data/vendor/libgit2/src/transports/smart.c +54 -31
  264. data/vendor/libgit2/src/transports/smart.h +1 -2
  265. data/vendor/libgit2/src/transports/smart_pkt.c +43 -40
  266. data/vendor/libgit2/src/transports/smart_protocol.c +61 -57
  267. data/vendor/libgit2/src/transports/ssh.c +34 -33
  268. data/vendor/libgit2/src/transports/winhttp.c +99 -119
  269. data/vendor/libgit2/src/tree-cache.c +5 -5
  270. data/vendor/libgit2/src/tree.c +96 -121
  271. data/vendor/libgit2/src/tree.h +1 -12
  272. data/vendor/libgit2/src/unix/map.c +2 -2
  273. data/vendor/libgit2/src/util.c +22 -6
  274. data/vendor/libgit2/src/util.h +12 -135
  275. data/vendor/libgit2/src/vector.c +4 -4
  276. data/vendor/libgit2/src/win32/dir.c +3 -3
  277. data/vendor/libgit2/src/win32/findfile.c +3 -3
  278. data/vendor/libgit2/src/win32/map.c +6 -6
  279. data/vendor/libgit2/src/win32/msvc-compat.h +6 -0
  280. data/vendor/libgit2/src/win32/path_w32.c +101 -7
  281. data/vendor/libgit2/src/win32/path_w32.h +18 -0
  282. data/vendor/libgit2/src/win32/posix_w32.c +24 -43
  283. data/vendor/libgit2/src/win32/w32_buffer.c +2 -2
  284. data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.c +96 -2
  285. data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.h +28 -75
  286. data/vendor/libgit2/src/win32/w32_stack.c +2 -2
  287. data/vendor/libgit2/src/win32/w32_util.c +1 -69
  288. data/vendor/libgit2/src/win32/w32_util.h +1 -19
  289. data/vendor/libgit2/src/worktree.c +75 -54
  290. data/vendor/libgit2/src/worktree.h +2 -0
  291. data/vendor/libgit2/src/xdiff/xdiffi.c +7 -5
  292. data/vendor/libgit2/src/xdiff/xhistogram.c +1 -1
  293. data/vendor/libgit2/src/xdiff/xmerge.c +15 -15
  294. data/vendor/libgit2/src/zstream.c +4 -4
  295. metadata +33 -7
  296. data/vendor/libgit2/src/config_file.h +0 -73
  297. data/vendor/libgit2/src/streams/curl.c +0 -385
@@ -20,6 +20,8 @@
20
20
  #define GIT_INDEX_FILE "index"
21
21
  #define GIT_INDEX_FILE_MODE 0666
22
22
 
23
+ extern bool git_index__enforce_unsaved_safety;
24
+
23
25
  struct git_index {
24
26
  git_refcount rc;
25
27
 
@@ -37,6 +39,7 @@ struct git_index {
37
39
  unsigned int ignore_case:1;
38
40
  unsigned int distrust_filemode:1;
39
41
  unsigned int no_symlinks:1;
42
+ unsigned int dirty:1; /* whether we have unsaved changes */
40
43
 
41
44
  git_tree_cache *tree;
42
45
  git_pool tree_pool;
@@ -52,6 +55,12 @@ struct git_index {
52
55
  unsigned int version;
53
56
  };
54
57
 
58
+ struct git_index_iterator {
59
+ git_index *index;
60
+ git_vector snap;
61
+ size_t cur;
62
+ };
63
+
55
64
  struct git_index_conflict_iterator {
56
65
  git_index *index;
57
66
  size_t cur;
@@ -143,6 +152,13 @@ extern int git_index_snapshot_find(
143
152
  /* Replace an index with a new index */
144
153
  int git_index_read_index(git_index *index, const git_index *new_index);
145
154
 
155
+ GIT_INLINE(int) git_index_is_dirty(git_index *index)
156
+ {
157
+ return index->dirty;
158
+ }
159
+
160
+ extern int git_index_read_safely(git_index *index);
161
+
146
162
  typedef struct {
147
163
  git_index *index;
148
164
  git_filebuf file;
@@ -10,6 +10,9 @@
10
10
  #include "git2/indexer.h"
11
11
  #include "git2/object.h"
12
12
 
13
+ #include "commit.h"
14
+ #include "tree.h"
15
+ #include "tag.h"
13
16
  #include "pack.h"
14
17
  #include "mwindow.h"
15
18
  #include "posix.h"
@@ -22,6 +25,8 @@
22
25
 
23
26
  extern git_mutex git__mwindow_mutex;
24
27
 
28
+ size_t git_indexer__max_objects = UINT32_MAX;
29
+
25
30
  #define UINT31_MAX (0x7FFFFFFF)
26
31
 
27
32
  struct entry {
@@ -36,12 +41,15 @@ struct git_indexer {
36
41
  pack_committed :1,
37
42
  have_stream :1,
38
43
  have_delta :1,
39
- do_fsync :1;
44
+ do_fsync :1,
45
+ do_verify :1;
40
46
  struct git_pack_header hdr;
41
47
  struct git_pack_file *pack;
42
48
  unsigned int mode;
43
49
  git_off_t off;
44
50
  git_off_t entry_start;
51
+ git_object_t entry_type;
52
+ git_buf entry_data;
45
53
  git_packfile_stream stream;
46
54
  size_t nr_objects;
47
55
  git_vector objects;
@@ -53,6 +61,9 @@ struct git_indexer {
53
61
  void *progress_payload;
54
62
  char objbuf[8*1024];
55
63
 
64
+ /* OIDs referenced from pack objects. Used for verification. */
65
+ git_oidmap *expected_oids;
66
+
56
67
  /* Needed to look up objects which we want to inject to fix a thin pack */
57
68
  git_odb *odb;
58
69
 
@@ -84,12 +95,12 @@ static int parse_header(struct git_pack_header *hdr, struct git_pack_file *pack)
84
95
 
85
96
  /* Verify we recognize this pack file format. */
86
97
  if (hdr->hdr_signature != ntohl(PACK_SIGNATURE)) {
87
- giterr_set(GITERR_INDEXER, "wrong pack signature");
98
+ git_error_set(GIT_ERROR_INDEXER, "wrong pack signature");
88
99
  return -1;
89
100
  }
90
101
 
91
102
  if (!pack_version_ok(hdr->hdr_version)) {
92
- giterr_set(GITERR_INDEXER, "wrong pack version");
103
+ git_error_set(GIT_ERROR_INDEXER, "wrong pack version");
93
104
  return -1;
94
105
  }
95
106
 
@@ -104,27 +115,42 @@ static int objects_cmp(const void *a, const void *b)
104
115
  return git_oid__cmp(&entrya->oid, &entryb->oid);
105
116
  }
106
117
 
118
+ int git_indexer_init_options(git_indexer_options *opts, unsigned int version)
119
+ {
120
+ GIT_INIT_STRUCTURE_FROM_TEMPLATE(
121
+ opts, version, git_indexer_options, GIT_INDEXER_OPTIONS_INIT);
122
+ return 0;
123
+ }
124
+
107
125
  int git_indexer_new(
108
126
  git_indexer **out,
109
127
  const char *prefix,
110
128
  unsigned int mode,
111
129
  git_odb *odb,
112
- git_transfer_progress_cb progress_cb,
113
- void *progress_payload)
130
+ git_indexer_options *in_opts)
114
131
  {
132
+ git_indexer_options opts = GIT_INDEXER_OPTIONS_INIT;
115
133
  git_indexer *idx;
116
134
  git_buf path = GIT_BUF_INIT, tmp_path = GIT_BUF_INIT;
117
135
  static const char suff[] = "/pack";
118
136
  int error, fd = -1;
119
137
 
138
+ if (in_opts)
139
+ memcpy(&opts, in_opts, sizeof(opts));
140
+
120
141
  idx = git__calloc(1, sizeof(git_indexer));
121
- GITERR_CHECK_ALLOC(idx);
142
+ GIT_ERROR_CHECK_ALLOC(idx);
122
143
  idx->odb = odb;
123
- idx->progress_cb = progress_cb;
124
- idx->progress_payload = progress_payload;
144
+ idx->progress_cb = opts.progress_cb;
145
+ idx->progress_payload = opts.progress_cb_payload;
125
146
  idx->mode = mode ? mode : GIT_PACK_FILE_MODE;
126
147
  git_hash_ctx_init(&idx->hash_ctx);
127
148
  git_hash_ctx_init(&idx->trailer);
149
+ git_buf_init(&idx->entry_data, 0);
150
+ idx->expected_oids = git_oidmap_alloc();
151
+ GIT_ERROR_CHECK_ALLOC(idx->expected_oids);
152
+
153
+ idx->do_verify = opts.verify;
128
154
 
129
155
  if (git_repository__fsync_gitdir)
130
156
  idx->do_fsync = 1;
@@ -134,12 +160,12 @@ int git_indexer_new(
134
160
  goto cleanup;
135
161
 
136
162
  fd = git_futils_mktmp(&tmp_path, git_buf_cstr(&path), idx->mode);
137
- git_buf_free(&path);
163
+ git_buf_dispose(&path);
138
164
  if (fd < 0)
139
165
  goto cleanup;
140
166
 
141
167
  error = git_packfile_alloc(&idx->pack, git_buf_cstr(&tmp_path));
142
- git_buf_free(&tmp_path);
168
+ git_buf_dispose(&tmp_path);
143
169
 
144
170
  if (error < 0)
145
171
  goto cleanup;
@@ -161,8 +187,8 @@ cleanup:
161
187
  if (idx->pack != NULL)
162
188
  p_unlink(idx->pack->pack_name);
163
189
 
164
- git_buf_free(&path);
165
- git_buf_free(&tmp_path);
190
+ git_buf_dispose(&path);
191
+ git_buf_dispose(&tmp_path);
166
192
  git__free(idx);
167
193
  return -1;
168
194
  }
@@ -178,7 +204,7 @@ static int store_delta(git_indexer *idx)
178
204
  struct delta_info *delta;
179
205
 
180
206
  delta = git__calloc(1, sizeof(struct delta_info));
181
- GITERR_CHECK_ALLOC(delta);
207
+ GIT_ERROR_CHECK_ALLOC(delta);
182
208
  delta->delta_off = idx->entry_start;
183
209
 
184
210
  if (git_vector_insert(&idx->deltas, delta) < 0)
@@ -187,7 +213,7 @@ static int store_delta(git_indexer *idx)
187
213
  return 0;
188
214
  }
189
215
 
190
- static int hash_header(git_hash_ctx *ctx, git_off_t len, git_otype type)
216
+ static int hash_header(git_hash_ctx *ctx, git_off_t len, git_object_t type)
191
217
  {
192
218
  char buffer[64];
193
219
  size_t hdrlen;
@@ -210,6 +236,9 @@ static int hash_object_stream(git_indexer*idx, git_packfile_stream *stream)
210
236
  if ((read = git_packfile_stream_read(stream, idx->objbuf, sizeof(idx->objbuf))) < 0)
211
237
  break;
212
238
 
239
+ if (idx->do_verify)
240
+ git_buf_put(&idx->entry_data, idx->objbuf, read);
241
+
213
242
  git_hash_update(&idx->hash_ctx, idx->objbuf, read);
214
243
  } while (read > 0);
215
244
 
@@ -220,13 +249,13 @@ static int hash_object_stream(git_indexer*idx, git_packfile_stream *stream)
220
249
  }
221
250
 
222
251
  /* In order to create the packfile stream, we need to skip over the delta base description */
223
- static int advance_delta_offset(git_indexer *idx, git_otype type)
252
+ static int advance_delta_offset(git_indexer *idx, git_object_t type)
224
253
  {
225
254
  git_mwindow *w = NULL;
226
255
 
227
- assert(type == GIT_OBJ_REF_DELTA || type == GIT_OBJ_OFS_DELTA);
256
+ assert(type == GIT_OBJECT_REF_DELTA || type == GIT_OBJECT_OFS_DELTA);
228
257
 
229
- if (type == GIT_OBJ_REF_DELTA) {
258
+ if (type == GIT_OBJECT_REF_DELTA) {
230
259
  idx->off += GIT_OID_RAWSZ;
231
260
  } else {
232
261
  git_off_t base_off = get_delta_base(idx->pack, &w, &idx->off, type, idx->entry_start);
@@ -279,10 +308,101 @@ static int crc_object(uint32_t *crc_out, git_mwindow_file *mwf, git_off_t start,
279
308
  return 0;
280
309
  }
281
310
 
311
+ static void add_expected_oid(git_indexer *idx, const git_oid *oid)
312
+ {
313
+ int ret;
314
+
315
+ /*
316
+ * If we know about that object because it is stored in our ODB or
317
+ * because we have already processed it as part of our pack file, we do
318
+ * not have to expect it.
319
+ */
320
+ if ((!idx->odb || !git_odb_exists(idx->odb, oid)) &&
321
+ !git_oidmap_exists(idx->pack->idx_cache, oid) &&
322
+ !git_oidmap_exists(idx->expected_oids, oid)) {
323
+ git_oid *dup = git__malloc(sizeof(*oid));
324
+ git_oid_cpy(dup, oid);
325
+ git_oidmap_put(idx->expected_oids, dup, &ret);
326
+ }
327
+ }
328
+
329
+ static int check_object_connectivity(git_indexer *idx, const git_rawobj *obj)
330
+ {
331
+ git_object *object;
332
+ size_t keyidx;
333
+ int error;
334
+
335
+ if (obj->type != GIT_OBJECT_BLOB &&
336
+ obj->type != GIT_OBJECT_TREE &&
337
+ obj->type != GIT_OBJECT_COMMIT &&
338
+ obj->type != GIT_OBJECT_TAG)
339
+ return 0;
340
+
341
+ if ((error = git_object__from_raw(&object, obj->data, obj->len, obj->type)) < 0)
342
+ goto out;
343
+
344
+ keyidx = git_oidmap_lookup_index(idx->expected_oids, &object->cached.oid);
345
+ if (git_oidmap_valid_index(idx->expected_oids, keyidx)) {
346
+ const git_oid *key = git_oidmap_key(idx->expected_oids, keyidx);
347
+ git__free((git_oid *) key);
348
+ git_oidmap_delete_at(idx->expected_oids, keyidx);
349
+ }
350
+
351
+ /*
352
+ * Check whether this is a known object. If so, we can just continue as
353
+ * we assume that the ODB has a complete graph.
354
+ */
355
+ if (idx->odb && git_odb_exists(idx->odb, &object->cached.oid))
356
+ return 0;
357
+
358
+ switch (obj->type) {
359
+ case GIT_OBJECT_TREE:
360
+ {
361
+ git_tree *tree = (git_tree *) object;
362
+ git_tree_entry *entry;
363
+ size_t i;
364
+
365
+ git_array_foreach(tree->entries, i, entry)
366
+ add_expected_oid(idx, entry->oid);
367
+
368
+ break;
369
+ }
370
+ case GIT_OBJECT_COMMIT:
371
+ {
372
+ git_commit *commit = (git_commit *) object;
373
+ git_oid *parent_oid;
374
+ size_t i;
375
+
376
+ git_array_foreach(commit->parent_ids, i, parent_oid)
377
+ add_expected_oid(idx, parent_oid);
378
+
379
+ add_expected_oid(idx, &commit->tree_id);
380
+
381
+ break;
382
+ }
383
+ case GIT_OBJECT_TAG:
384
+ {
385
+ git_tag *tag = (git_tag *) object;
386
+
387
+ add_expected_oid(idx, &tag->target);
388
+
389
+ break;
390
+ }
391
+ case GIT_OBJECT_BLOB:
392
+ default:
393
+ break;
394
+ }
395
+
396
+ out:
397
+ git_object_free(object);
398
+
399
+ return error;
400
+ }
401
+
282
402
  static int store_object(git_indexer *idx)
283
403
  {
284
404
  int i, error;
285
- khiter_t k;
405
+ size_t k;
286
406
  git_oid oid;
287
407
  struct entry *entry;
288
408
  git_off_t entry_size;
@@ -290,10 +410,10 @@ static int store_object(git_indexer *idx)
290
410
  git_off_t entry_start = idx->entry_start;
291
411
 
292
412
  entry = git__calloc(1, sizeof(*entry));
293
- GITERR_CHECK_ALLOC(entry);
413
+ GIT_ERROR_CHECK_ALLOC(entry);
294
414
 
295
415
  pentry = git__calloc(1, sizeof(struct git_pack_entry));
296
- GITERR_CHECK_ALLOC(pentry);
416
+ GIT_ERROR_CHECK_ALLOC(pentry);
297
417
 
298
418
  git_hash_final(&oid, &idx->hash_ctx);
299
419
  entry_size = idx->off - entry_start;
@@ -304,18 +424,29 @@ static int store_object(git_indexer *idx)
304
424
  entry->offset = (uint32_t)entry_start;
305
425
  }
306
426
 
427
+ if (idx->do_verify) {
428
+ git_rawobj rawobj = {
429
+ idx->entry_data.ptr,
430
+ idx->entry_data.size,
431
+ idx->entry_type
432
+ };
433
+
434
+ if ((error = check_object_connectivity(idx, &rawobj)) < 0)
435
+ goto on_error;
436
+ }
437
+
307
438
  git_oid_cpy(&pentry->sha1, &oid);
308
439
  pentry->offset = entry_start;
309
440
 
310
441
  k = git_oidmap_put(idx->pack->idx_cache, &pentry->sha1, &error);
311
442
  if (error == -1) {
312
443
  git__free(pentry);
313
- giterr_set_oom();
444
+ git_error_set_oom();
314
445
  goto on_error;
315
446
  }
316
447
 
317
448
  if (error == 0) {
318
- giterr_set(GITERR_INDEXER, "duplicate object %s found in pack", git_oid_tostr_s(&pentry->sha1));
449
+ git_error_set(GIT_ERROR_INDEXER, "duplicate object %s found in pack", git_oid_tostr_s(&pentry->sha1));
319
450
  git__free(pentry);
320
451
  goto on_error;
321
452
  }
@@ -352,7 +483,7 @@ GIT_INLINE(bool) has_entry(git_indexer *idx, git_oid *id)
352
483
  static int save_entry(git_indexer *idx, struct entry *entry, struct git_pack_entry *pentry, git_off_t entry_start)
353
484
  {
354
485
  int i, error;
355
- khiter_t k;
486
+ size_t k;
356
487
 
357
488
  if (entry_start > UINT31_MAX) {
358
489
  entry->offset = UINT32_MAX;
@@ -365,7 +496,7 @@ static int save_entry(git_indexer *idx, struct entry *entry, struct git_pack_ent
365
496
  k = git_oidmap_put(idx->pack->idx_cache, &pentry->sha1, &error);
366
497
 
367
498
  if (error <= 0) {
368
- giterr_set(GITERR_INDEXER, "cannot insert object into pack");
499
+ git_error_set(GIT_ERROR_INDEXER, "cannot insert object into pack");
369
500
  return -1;
370
501
  }
371
502
 
@@ -390,15 +521,15 @@ static int hash_and_save(git_indexer *idx, git_rawobj *obj, git_off_t entry_star
390
521
  struct git_pack_entry *pentry = NULL;
391
522
 
392
523
  entry = git__calloc(1, sizeof(*entry));
393
- GITERR_CHECK_ALLOC(entry);
524
+ GIT_ERROR_CHECK_ALLOC(entry);
394
525
 
395
526
  if (git_odb__hashobj(&oid, obj) < 0) {
396
- giterr_set(GITERR_INDEXER, "failed to hash object");
527
+ git_error_set(GIT_ERROR_INDEXER, "failed to hash object");
397
528
  goto on_error;
398
529
  }
399
530
 
400
531
  pentry = git__calloc(1, sizeof(struct git_pack_entry));
401
- GITERR_CHECK_ALLOC(pentry);
532
+ GIT_ERROR_CHECK_ALLOC(pentry);
402
533
 
403
534
  git_oid_cpy(&pentry->sha1, &oid);
404
535
  git_oid_cpy(&entry->oid, &oid);
@@ -420,7 +551,7 @@ on_error:
420
551
  static int do_progress_callback(git_indexer *idx, git_transfer_progress *stats)
421
552
  {
422
553
  if (idx->progress_cb)
423
- return giterr_set_after_callback_function(
554
+ return git_error_set_after_callback_function(
424
555
  idx->progress_cb(stats, idx->progress_payload),
425
556
  "indexer progress");
426
557
  return 0;
@@ -518,24 +649,110 @@ static int append_to_pack(git_indexer *idx, const void *data, size_t size)
518
649
 
519
650
  if (p_lseek(fd, page_start + mmap_alignment - 1, SEEK_SET) < 0 ||
520
651
  p_write(idx->pack->mwf.fd, data, 1) < 0) {
521
- giterr_set(GITERR_OS, "cannot extend packfile '%s'", idx->pack->pack_name);
652
+ git_error_set(GIT_ERROR_OS, "cannot extend packfile '%s'", idx->pack->pack_name);
522
653
  return -1;
523
654
  }
524
655
 
525
656
  return write_at(idx, data, idx->pack->mwf.size, size);
526
657
  }
527
658
 
659
+ static int read_stream_object(git_indexer *idx, git_transfer_progress *stats)
660
+ {
661
+ git_packfile_stream *stream = &idx->stream;
662
+ git_off_t entry_start = idx->off;
663
+ size_t entry_size;
664
+ git_object_t type;
665
+ git_mwindow *w = NULL;
666
+ int error;
667
+
668
+ if (idx->pack->mwf.size <= idx->off + 20)
669
+ return GIT_EBUFS;
670
+
671
+ if (!idx->have_stream) {
672
+ error = git_packfile_unpack_header(&entry_size, &type, &idx->pack->mwf, &w, &idx->off);
673
+ if (error == GIT_EBUFS) {
674
+ idx->off = entry_start;
675
+ return error;
676
+ }
677
+ if (error < 0)
678
+ return error;
679
+
680
+ git_mwindow_close(&w);
681
+ idx->entry_start = entry_start;
682
+ git_hash_init(&idx->hash_ctx);
683
+ git_buf_clear(&idx->entry_data);
684
+
685
+ if (type == GIT_OBJECT_REF_DELTA || type == GIT_OBJECT_OFS_DELTA) {
686
+ error = advance_delta_offset(idx, type);
687
+ if (error == GIT_EBUFS) {
688
+ idx->off = entry_start;
689
+ return error;
690
+ }
691
+ if (error < 0)
692
+ return error;
693
+
694
+ idx->have_delta = 1;
695
+ } else {
696
+ idx->have_delta = 0;
697
+
698
+ error = hash_header(&idx->hash_ctx, entry_size, type);
699
+ if (error < 0)
700
+ return error;
701
+ }
702
+
703
+ idx->have_stream = 1;
704
+ idx->entry_type = type;
705
+
706
+ error = git_packfile_stream_open(stream, idx->pack, idx->off);
707
+ if (error < 0)
708
+ return error;
709
+ }
710
+
711
+ if (idx->have_delta) {
712
+ error = read_object_stream(idx, stream);
713
+ } else {
714
+ error = hash_object_stream(idx, stream);
715
+ }
716
+
717
+ idx->off = stream->curpos;
718
+ if (error == GIT_EBUFS)
719
+ return error;
720
+
721
+ /* We want to free the stream reasorces no matter what here */
722
+ idx->have_stream = 0;
723
+ git_packfile_stream_dispose(stream);
724
+
725
+ if (error < 0)
726
+ return error;
727
+
728
+ if (idx->have_delta) {
729
+ error = store_delta(idx);
730
+ } else {
731
+ error = store_object(idx);
732
+ }
733
+
734
+ if (error < 0)
735
+ return error;
736
+
737
+ if (!idx->have_delta) {
738
+ stats->indexed_objects++;
739
+ }
740
+ stats->received_objects++;
741
+
742
+ if ((error = do_progress_callback(idx, stats)) != 0)
743
+ return error;
744
+
745
+ return 0;
746
+ }
747
+
528
748
  int git_indexer_append(git_indexer *idx, const void *data, size_t size, git_transfer_progress *stats)
529
749
  {
530
750
  int error = -1;
531
- size_t processed;
532
751
  struct git_pack_header *hdr = &idx->hdr;
533
752
  git_mwindow_file *mwf = &idx->pack->mwf;
534
753
 
535
754
  assert(idx && data && stats);
536
755
 
537
- processed = stats->indexed_objects;
538
-
539
756
  if ((error = append_to_pack(idx, data, size)) < 0)
540
757
  return error;
541
758
 
@@ -557,15 +774,15 @@ int git_indexer_append(git_indexer *idx, const void *data, size_t size, git_tran
557
774
  idx->nr_objects = ntohl(hdr->hdr_entries);
558
775
  idx->off = sizeof(struct git_pack_header);
559
776
 
560
- /* for now, limit to 2^32 objects */
561
- assert(idx->nr_objects == (size_t)((unsigned int)idx->nr_objects));
562
- if (idx->nr_objects == (size_t)((unsigned int)idx->nr_objects))
777
+ if (idx->nr_objects <= git_indexer__max_objects) {
563
778
  total_objects = (unsigned int)idx->nr_objects;
564
- else
565
- total_objects = UINT_MAX;
779
+ } else {
780
+ git_error_set(GIT_ERROR_INDEXER, "too many objects");
781
+ return -1;
782
+ }
566
783
 
567
784
  idx->pack->idx_cache = git_oidmap_alloc();
568
- GITERR_CHECK_ALLOC(idx->pack->idx_cache);
785
+ GIT_ERROR_CHECK_ALLOC(idx->pack->idx_cache);
569
786
 
570
787
  idx->pack->has_cache = 1;
571
788
  if (git_vector_init(&idx->objects, total_objects, objects_cmp) < 0)
@@ -578,7 +795,7 @@ int git_indexer_append(git_indexer *idx, const void *data, size_t size, git_tran
578
795
  stats->local_objects = 0;
579
796
  stats->total_deltas = 0;
580
797
  stats->indexed_deltas = 0;
581
- processed = stats->indexed_objects = 0;
798
+ stats->indexed_objects = 0;
582
799
  stats->total_objects = total_objects;
583
800
 
584
801
  if ((error = do_progress_callback(idx, stats)) != 0)
@@ -590,87 +807,13 @@ int git_indexer_append(git_indexer *idx, const void *data, size_t size, git_tran
590
807
  /* As the file grows any windows we try to use will be out of date */
591
808
  git_mwindow_free_all(mwf);
592
809
 
593
- while (processed < idx->nr_objects) {
594
- git_packfile_stream *stream = &idx->stream;
595
- git_off_t entry_start = idx->off;
596
- size_t entry_size;
597
- git_otype type;
598
- git_mwindow *w = NULL;
599
-
600
- if (idx->pack->mwf.size <= idx->off + 20)
601
- return 0;
602
-
603
- if (!idx->have_stream) {
604
- error = git_packfile_unpack_header(&entry_size, &type, mwf, &w, &idx->off);
605
- if (error == GIT_EBUFS) {
606
- idx->off = entry_start;
607
- return 0;
608
- }
609
- if (error < 0)
810
+ while (stats->indexed_objects < idx->nr_objects) {
811
+ if ((error = read_stream_object(idx, stats)) != 0) {
812
+ if (error == GIT_EBUFS)
813
+ break;
814
+ else
610
815
  goto on_error;
611
-
612
- git_mwindow_close(&w);
613
- idx->entry_start = entry_start;
614
- git_hash_init(&idx->hash_ctx);
615
-
616
- if (type == GIT_OBJ_REF_DELTA || type == GIT_OBJ_OFS_DELTA) {
617
- error = advance_delta_offset(idx, type);
618
- if (error == GIT_EBUFS) {
619
- idx->off = entry_start;
620
- return 0;
621
- }
622
- if (error < 0)
623
- goto on_error;
624
-
625
- idx->have_delta = 1;
626
- } else {
627
- idx->have_delta = 0;
628
-
629
- error = hash_header(&idx->hash_ctx, entry_size, type);
630
- if (error < 0)
631
- goto on_error;
632
- }
633
-
634
- idx->have_stream = 1;
635
-
636
- error = git_packfile_stream_open(stream, idx->pack, idx->off);
637
- if (error < 0)
638
- goto on_error;
639
- }
640
-
641
- if (idx->have_delta) {
642
- error = read_object_stream(idx, stream);
643
- } else {
644
- error = hash_object_stream(idx, stream);
645
- }
646
-
647
- idx->off = stream->curpos;
648
- if (error == GIT_EBUFS)
649
- return 0;
650
-
651
- /* We want to free the stream reasorces no matter what here */
652
- idx->have_stream = 0;
653
- git_packfile_stream_free(stream);
654
-
655
- if (error < 0)
656
- goto on_error;
657
-
658
- if (idx->have_delta) {
659
- error = store_delta(idx);
660
- } else {
661
- error = store_object(idx);
662
816
  }
663
-
664
- if (error < 0)
665
- goto on_error;
666
-
667
- if (!idx->have_delta) {
668
- stats->indexed_objects = (unsigned int)++processed;
669
- }
670
- stats->received_objects++;
671
-
672
- if ((error = do_progress_callback(idx, stats)) != 0)
673
- goto on_error;
674
817
  }
675
818
 
676
819
  return 0;
@@ -729,7 +872,7 @@ static int inject_object(git_indexer *idx, git_oid *id)
729
872
  entry_start = idx->pack->mwf.size;
730
873
 
731
874
  if (git_odb_read(&obj, idx->odb, id) < 0) {
732
- giterr_set(GITERR_INDEXER, "missing delta bases");
875
+ git_error_set(GIT_ERROR_INDEXER, "missing delta bases");
733
876
  return -1;
734
877
  }
735
878
 
@@ -737,7 +880,7 @@ static int inject_object(git_indexer *idx, git_oid *id)
737
880
  len = git_odb_object_size(obj);
738
881
 
739
882
  entry = git__calloc(1, sizeof(*entry));
740
- GITERR_CHECK_ALLOC(entry);
883
+ GIT_ERROR_CHECK_ALLOC(entry);
741
884
 
742
885
  entry->crc = crc32(0L, Z_NULL, 0);
743
886
 
@@ -758,7 +901,7 @@ static int inject_object(git_indexer *idx, git_oid *id)
758
901
 
759
902
  idx->pack->mwf.size += buf.size;
760
903
  entry->crc = htonl(crc32(entry->crc, (unsigned char *)buf.ptr, (uInt)buf.size));
761
- git_buf_free(&buf);
904
+ git_buf_dispose(&buf);
762
905
 
763
906
  /* Write a fake trailer so the pack functions play ball */
764
907
 
@@ -768,7 +911,7 @@ static int inject_object(git_indexer *idx, git_oid *id)
768
911
  idx->pack->mwf.size += GIT_OID_RAWSZ;
769
912
 
770
913
  pentry = git__calloc(1, sizeof(struct git_pack_entry));
771
- GITERR_CHECK_ALLOC(pentry);
914
+ GIT_ERROR_CHECK_ALLOC(pentry);
772
915
 
773
916
  git_oid_cpy(&pentry->sha1, id);
774
917
  git_oid_cpy(&entry->oid, id);
@@ -792,7 +935,7 @@ static int fix_thin_pack(git_indexer *idx, git_transfer_progress *stats)
792
935
  unsigned int i;
793
936
  struct delta_info *delta;
794
937
  size_t size;
795
- git_otype type;
938
+ git_object_t type;
796
939
  git_mwindow *w = NULL;
797
940
  git_off_t curpos = 0;
798
941
  unsigned char *base_info;
@@ -802,7 +945,7 @@ static int fix_thin_pack(git_indexer *idx, git_transfer_progress *stats)
802
945
  assert(git_vector_length(&idx->deltas) > 0);
803
946
 
804
947
  if (idx->odb == NULL) {
805
- giterr_set(GITERR_INDEXER, "cannot fix a thin pack without an ODB");
948
+ git_error_set(GIT_ERROR_INDEXER, "cannot fix a thin pack without an ODB");
806
949
  return -1;
807
950
  }
808
951
 
@@ -816,21 +959,21 @@ static int fix_thin_pack(git_indexer *idx, git_transfer_progress *stats)
816
959
  if (error < 0)
817
960
  return error;
818
961
 
819
- if (type == GIT_OBJ_REF_DELTA) {
962
+ if (type == GIT_OBJECT_REF_DELTA) {
820
963
  found_ref_delta = 1;
821
964
  break;
822
965
  }
823
966
  }
824
967
 
825
968
  if (!found_ref_delta) {
826
- giterr_set(GITERR_INDEXER, "no REF_DELTA found, cannot inject object");
969
+ git_error_set(GIT_ERROR_INDEXER, "no REF_DELTA found, cannot inject object");
827
970
  return -1;
828
971
  }
829
972
 
830
973
  /* curpos now points to the base information, which is an OID */
831
974
  base_info = git_mwindow_open(&idx->pack->mwf, &w, curpos, GIT_OID_RAWSZ, &left);
832
975
  if (base_info == NULL) {
833
- giterr_set(GITERR_INDEXER, "failed to map delta information");
976
+ git_error_set(GIT_ERROR_INDEXER, "failed to map delta information");
834
977
  return -1;
835
978
  }
836
979
 
@@ -859,7 +1002,7 @@ static int resolve_deltas(git_indexer *idx, git_transfer_progress *stats)
859
1002
  progressed = 0;
860
1003
  non_null = 0;
861
1004
  git_vector_foreach(&idx->deltas, i, delta) {
862
- git_rawobj obj = {NULL};
1005
+ git_rawobj obj = {0};
863
1006
 
864
1007
  if (!delta)
865
1008
  continue;
@@ -874,6 +1017,10 @@ static int resolve_deltas(git_indexer *idx, git_transfer_progress *stats)
874
1017
  return -1;
875
1018
  }
876
1019
 
1020
+ if (idx->do_verify && check_object_connectivity(idx, &obj) < 0)
1021
+ /* TODO: error? continue? */
1022
+ continue;
1023
+
877
1024
  if (hash_and_save(idx, &obj, delta->delta_off) < 0)
878
1025
  continue;
879
1026
 
@@ -955,17 +1102,17 @@ int git_indexer_commit(git_indexer *idx, git_transfer_progress *stats)
955
1102
  void *packfile_trailer;
956
1103
 
957
1104
  if (!idx->parsed_header) {
958
- giterr_set(GITERR_INDEXER, "incomplete pack header");
1105
+ git_error_set(GIT_ERROR_INDEXER, "incomplete pack header");
959
1106
  return -1;
960
1107
  }
961
1108
 
962
1109
  /* Test for this before resolve_deltas(), as it plays with idx->off */
963
1110
  if (idx->off + 20 < idx->pack->mwf.size) {
964
- giterr_set(GITERR_INDEXER, "unexpected data at the end of the pack");
1111
+ git_error_set(GIT_ERROR_INDEXER, "unexpected data at the end of the pack");
965
1112
  return -1;
966
1113
  }
967
1114
  if (idx->off + 20 > idx->pack->mwf.size) {
968
- giterr_set(GITERR_INDEXER, "missing trailer at the end of the pack");
1115
+ git_error_set(GIT_ERROR_INDEXER, "missing trailer at the end of the pack");
969
1116
  return -1;
970
1117
  }
971
1118
 
@@ -981,7 +1128,7 @@ int git_indexer_commit(git_indexer *idx, git_transfer_progress *stats)
981
1128
 
982
1129
  git_hash_final(&trailer_hash, &idx->trailer);
983
1130
  if (git_oid_cmp(&file_hash, &trailer_hash)) {
984
- giterr_set(GITERR_INDEXER, "packfile trailer mismatch");
1131
+ git_error_set(GIT_ERROR_INDEXER, "packfile trailer mismatch");
985
1132
  return -1;
986
1133
  }
987
1134
 
@@ -992,7 +1139,7 @@ int git_indexer_commit(git_indexer *idx, git_transfer_progress *stats)
992
1139
  return error;
993
1140
 
994
1141
  if (stats->indexed_objects != stats->total_objects) {
995
- giterr_set(GITERR_INDEXER, "early EOF");
1142
+ git_error_set(GIT_ERROR_INDEXER, "early EOF");
996
1143
  return -1;
997
1144
  }
998
1145
 
@@ -1004,6 +1151,18 @@ int git_indexer_commit(git_indexer *idx, git_transfer_progress *stats)
1004
1151
  write_at(idx, &trailer_hash, idx->pack->mwf.size - GIT_OID_RAWSZ, GIT_OID_RAWSZ);
1005
1152
  }
1006
1153
 
1154
+ /*
1155
+ * Is the resulting graph fully connected or are we still
1156
+ * missing some objects? In the second case, we can
1157
+ * bail out due to an incomplete and thus corrupt
1158
+ * packfile.
1159
+ */
1160
+ if (git_oidmap_size(idx->expected_oids) > 0) {
1161
+ git_error_set(GIT_ERROR_INDEXER, "packfile is missing %"PRIuZ" objects",
1162
+ git_oidmap_size(idx->expected_oids));
1163
+ return -1;
1164
+ }
1165
+
1007
1166
  git_vector_sort(&idx->objects);
1008
1167
 
1009
1168
  /* Use the trailer hash as the pack file name to ensure
@@ -1090,18 +1249,18 @@ int git_indexer_commit(git_indexer *idx, git_transfer_progress *stats)
1090
1249
 
1091
1250
  /* Truncate file to undo rounding up to next page_size in append_to_pack */
1092
1251
  if (p_ftruncate(idx->pack->mwf.fd, idx->pack->mwf.size) < 0) {
1093
- giterr_set(GITERR_OS, "failed to truncate pack file '%s'", idx->pack->pack_name);
1252
+ git_error_set(GIT_ERROR_OS, "failed to truncate pack file '%s'", idx->pack->pack_name);
1094
1253
  return -1;
1095
1254
  }
1096
1255
 
1097
1256
  if (idx->do_fsync && p_fsync(idx->pack->mwf.fd) < 0) {
1098
- giterr_set(GITERR_OS, "failed to fsync packfile");
1257
+ git_error_set(GIT_ERROR_OS, "failed to fsync packfile");
1099
1258
  goto on_error;
1100
1259
  }
1101
1260
 
1102
1261
  /* We need to close the descriptor here so Windows doesn't choke on commit_at */
1103
1262
  if (p_close(idx->pack->mwf.fd) < 0) {
1104
- giterr_set(GITERR_OS, "failed to close packfile");
1263
+ git_error_set(GIT_ERROR_OS, "failed to close packfile");
1105
1264
  goto on_error;
1106
1265
  }
1107
1266
 
@@ -1121,23 +1280,25 @@ int git_indexer_commit(git_indexer *idx, git_transfer_progress *stats)
1121
1280
 
1122
1281
  idx->pack_committed = 1;
1123
1282
 
1124
- git_buf_free(&filename);
1283
+ git_buf_dispose(&filename);
1125
1284
  return 0;
1126
1285
 
1127
1286
  on_error:
1128
1287
  git_mwindow_free_all(&idx->pack->mwf);
1129
1288
  git_filebuf_cleanup(&index_file);
1130
- git_buf_free(&filename);
1289
+ git_buf_dispose(&filename);
1131
1290
  return -1;
1132
1291
  }
1133
1292
 
1134
1293
  void git_indexer_free(git_indexer *idx)
1135
1294
  {
1295
+ size_t pos;
1296
+
1136
1297
  if (idx == NULL)
1137
1298
  return;
1138
1299
 
1139
1300
  if (idx->have_stream)
1140
- git_packfile_stream_free(&idx->stream);
1301
+ git_packfile_stream_dispose(&idx->stream);
1141
1302
 
1142
1303
  git_vector_free_deep(&idx->objects);
1143
1304
 
@@ -1160,7 +1321,18 @@ void git_indexer_free(git_indexer *idx)
1160
1321
  git_mutex_unlock(&git__mwindow_mutex);
1161
1322
  }
1162
1323
 
1324
+ for (pos = git_oidmap_begin(idx->expected_oids);
1325
+ pos != git_oidmap_end(idx->expected_oids); pos++)
1326
+ {
1327
+ if (git_oidmap_has_data(idx->expected_oids, pos)) {
1328
+ git__free((git_oid *) git_oidmap_key(idx->expected_oids, pos));
1329
+ git_oidmap_delete_at(idx->expected_oids, pos);
1330
+ }
1331
+ }
1332
+
1163
1333
  git_hash_ctx_cleanup(&idx->trailer);
1164
1334
  git_hash_ctx_cleanup(&idx->hash_ctx);
1335
+ git_buf_dispose(&idx->entry_data);
1336
+ git_oidmap_free(idx->expected_oids);
1165
1337
  git__free(idx);
1166
1338
  }