rugged 0.17.0.b7 → 0.18.0.b1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (310) hide show
  1. data/LICENSE +1 -1
  2. data/README.md +88 -32
  3. data/ext/rugged/extconf.rb +4 -2
  4. data/ext/rugged/rugged.c +72 -10
  5. data/ext/rugged/rugged.h +14 -10
  6. data/ext/rugged/rugged_blob.c +8 -10
  7. data/ext/rugged/rugged_branch.c +11 -14
  8. data/ext/rugged/rugged_commit.c +31 -24
  9. data/ext/rugged/rugged_config.c +2 -2
  10. data/ext/rugged/rugged_index.c +133 -198
  11. data/ext/rugged/rugged_note.c +372 -0
  12. data/ext/rugged/rugged_object.c +50 -22
  13. data/ext/rugged/rugged_reference.c +122 -130
  14. data/ext/rugged/rugged_remote.c +72 -29
  15. data/ext/rugged/rugged_repo.c +402 -20
  16. data/ext/rugged/rugged_revwalk.c +7 -3
  17. data/ext/rugged/rugged_settings.c +110 -0
  18. data/ext/rugged/rugged_signature.c +23 -7
  19. data/ext/rugged/rugged_tag.c +32 -16
  20. data/ext/rugged/rugged_tree.c +44 -15
  21. data/lib/rugged.rb +1 -0
  22. data/lib/rugged/index.rb +8 -0
  23. data/lib/rugged/remote.rb +13 -0
  24. data/lib/rugged/repository.rb +3 -3
  25. data/lib/rugged/version.rb +1 -1
  26. data/test/blob_test.rb +13 -15
  27. data/test/branch_test.rb +32 -67
  28. data/test/commit_test.rb +50 -12
  29. data/test/config_test.rb +12 -11
  30. data/test/coverage/HEAD.json +1 -1
  31. data/test/coverage/cover.rb +40 -21
  32. data/test/errors_test.rb +34 -0
  33. data/test/fixtures/alternate/objects/14/6ae76773c91e3b1d00cf7a338ec55ae58297e2 +0 -0
  34. data/test/fixtures/alternate/objects/14/9c32d47e99d0a3572ff1e70a2e0051bbf347a9 +0 -0
  35. data/test/fixtures/alternate/objects/14/fb3108588f9421bf764041e5e3ac305eb6277f +0 -0
  36. data/test/fixtures/testrepo.git/logs/refs/notes/commits +1 -0
  37. data/test/fixtures/testrepo.git/objects/44/1034f860c1d5d90e4188d11ae0d325176869a8 +1 -0
  38. data/test/fixtures/testrepo.git/objects/60/d415052a33de2150bf68757f6461df4f563ae4 +0 -0
  39. data/test/fixtures/testrepo.git/objects/68/8a8f4ef7496901d15322972f96e212a9e466cc +1 -0
  40. data/test/fixtures/testrepo.git/objects/94/eca2de348d5f672faf56b0decafa5937e3235e +0 -0
  41. data/test/fixtures/testrepo.git/objects/9b/7384fe1676186192842f5d3e129457b62db9e3 +0 -0
  42. data/test/fixtures/testrepo.git/objects/b7/4713326bc972cc15751ed504dca6f6f3b91f7a +3 -0
  43. data/test/fixtures/testrepo.git/refs/notes/commits +1 -0
  44. data/test/index_test.rb +65 -69
  45. data/test/lib_test.rb +76 -11
  46. data/test/note_test.rb +158 -0
  47. data/test/object_test.rb +8 -11
  48. data/test/reference_test.rb +77 -85
  49. data/test/remote_test.rb +86 -8
  50. data/test/repo_pack_test.rb +9 -7
  51. data/test/repo_reset_test.rb +80 -0
  52. data/test/repo_test.rb +176 -53
  53. data/test/tag_test.rb +44 -7
  54. data/test/test_helper.rb +63 -35
  55. data/test/tree_test.rb +34 -13
  56. data/test/walker_test.rb +14 -14
  57. data/vendor/libgit2/Makefile.embed +1 -1
  58. data/vendor/libgit2/deps/http-parser/http_parser.c +974 -578
  59. data/vendor/libgit2/deps/http-parser/http_parser.h +106 -70
  60. data/vendor/libgit2/deps/regex/regcomp.c +7 -6
  61. data/vendor/libgit2/deps/regex/regex_internal.c +1 -1
  62. data/vendor/libgit2/deps/regex/regex_internal.h +12 -3
  63. data/vendor/libgit2/deps/regex/regexec.c +5 -5
  64. data/vendor/libgit2/include/git2.h +5 -1
  65. data/vendor/libgit2/include/git2/attr.h +4 -2
  66. data/vendor/libgit2/include/git2/blob.h +39 -12
  67. data/vendor/libgit2/include/git2/branch.h +123 -35
  68. data/vendor/libgit2/include/git2/checkout.h +206 -48
  69. data/vendor/libgit2/include/git2/clone.h +72 -27
  70. data/vendor/libgit2/include/git2/commit.h +20 -17
  71. data/vendor/libgit2/include/git2/common.h +67 -1
  72. data/vendor/libgit2/include/git2/config.h +81 -60
  73. data/vendor/libgit2/include/git2/cred_helpers.h +53 -0
  74. data/vendor/libgit2/include/git2/diff.h +459 -150
  75. data/vendor/libgit2/include/git2/errors.h +9 -1
  76. data/vendor/libgit2/include/git2/graph.h +41 -0
  77. data/vendor/libgit2/include/git2/ignore.h +7 -6
  78. data/vendor/libgit2/include/git2/index.h +323 -97
  79. data/vendor/libgit2/include/git2/indexer.h +27 -59
  80. data/vendor/libgit2/include/git2/inttypes.h +4 -0
  81. data/vendor/libgit2/include/git2/merge.h +13 -3
  82. data/vendor/libgit2/include/git2/message.h +14 -8
  83. data/vendor/libgit2/include/git2/net.h +9 -7
  84. data/vendor/libgit2/include/git2/notes.h +88 -29
  85. data/vendor/libgit2/include/git2/object.h +16 -6
  86. data/vendor/libgit2/include/git2/odb.h +80 -17
  87. data/vendor/libgit2/include/git2/odb_backend.h +47 -11
  88. data/vendor/libgit2/include/git2/oid.h +26 -17
  89. data/vendor/libgit2/include/git2/pack.h +62 -8
  90. data/vendor/libgit2/include/git2/push.h +131 -0
  91. data/vendor/libgit2/include/git2/refdb.h +103 -0
  92. data/vendor/libgit2/include/git2/refdb_backend.h +109 -0
  93. data/vendor/libgit2/include/git2/reflog.h +30 -21
  94. data/vendor/libgit2/include/git2/refs.h +215 -193
  95. data/vendor/libgit2/include/git2/refspec.h +22 -2
  96. data/vendor/libgit2/include/git2/remote.h +158 -37
  97. data/vendor/libgit2/include/git2/repository.h +150 -31
  98. data/vendor/libgit2/include/git2/reset.h +43 -9
  99. data/vendor/libgit2/include/git2/revparse.h +48 -4
  100. data/vendor/libgit2/include/git2/revwalk.h +25 -10
  101. data/vendor/libgit2/include/git2/signature.h +20 -12
  102. data/vendor/libgit2/include/git2/stash.h +121 -0
  103. data/vendor/libgit2/include/git2/status.h +122 -53
  104. data/vendor/libgit2/include/git2/strarray.h +17 -11
  105. data/vendor/libgit2/include/git2/submodule.h +42 -7
  106. data/vendor/libgit2/include/git2/tag.h +72 -59
  107. data/vendor/libgit2/include/git2/threads.h +4 -2
  108. data/vendor/libgit2/include/git2/trace.h +68 -0
  109. data/vendor/libgit2/include/git2/transport.h +328 -0
  110. data/vendor/libgit2/include/git2/tree.h +149 -120
  111. data/vendor/libgit2/include/git2/types.h +13 -12
  112. data/vendor/libgit2/include/git2/version.h +3 -3
  113. data/vendor/libgit2/src/amiga/map.c +2 -2
  114. data/vendor/libgit2/src/attr.c +58 -48
  115. data/vendor/libgit2/src/attr.h +4 -18
  116. data/vendor/libgit2/src/attr_file.c +30 -6
  117. data/vendor/libgit2/src/attr_file.h +6 -8
  118. data/vendor/libgit2/src/attrcache.h +24 -0
  119. data/vendor/libgit2/src/blob.c +30 -7
  120. data/vendor/libgit2/src/blob.h +1 -1
  121. data/vendor/libgit2/src/branch.c +361 -68
  122. data/vendor/libgit2/src/branch.h +17 -0
  123. data/vendor/libgit2/src/bswap.h +1 -1
  124. data/vendor/libgit2/src/buf_text.c +291 -0
  125. data/vendor/libgit2/src/buf_text.h +122 -0
  126. data/vendor/libgit2/src/buffer.c +27 -101
  127. data/vendor/libgit2/src/buffer.h +54 -39
  128. data/vendor/libgit2/src/cache.c +15 -6
  129. data/vendor/libgit2/src/cache.h +1 -1
  130. data/vendor/libgit2/src/cc-compat.h +3 -1
  131. data/vendor/libgit2/src/checkout.c +1165 -222
  132. data/vendor/libgit2/src/checkout.h +24 -0
  133. data/vendor/libgit2/src/clone.c +171 -86
  134. data/vendor/libgit2/src/commit.c +44 -45
  135. data/vendor/libgit2/src/commit.h +3 -3
  136. data/vendor/libgit2/src/commit_list.c +194 -0
  137. data/vendor/libgit2/src/commit_list.h +49 -0
  138. data/vendor/libgit2/src/common.h +44 -10
  139. data/vendor/libgit2/src/compress.c +1 -1
  140. data/vendor/libgit2/src/compress.h +1 -1
  141. data/vendor/libgit2/src/config.c +211 -124
  142. data/vendor/libgit2/src/config.h +23 -4
  143. data/vendor/libgit2/src/config_cache.c +2 -2
  144. data/vendor/libgit2/src/config_file.c +129 -53
  145. data/vendor/libgit2/src/config_file.h +10 -8
  146. data/vendor/libgit2/src/crlf.c +66 -67
  147. data/vendor/libgit2/src/date.c +12 -12
  148. data/vendor/libgit2/src/delta-apply.c +14 -1
  149. data/vendor/libgit2/src/delta-apply.h +18 -1
  150. data/vendor/libgit2/src/delta.c +40 -107
  151. data/vendor/libgit2/src/delta.h +19 -17
  152. data/vendor/libgit2/src/diff.c +347 -496
  153. data/vendor/libgit2/src/diff.h +27 -1
  154. data/vendor/libgit2/src/diff_output.c +564 -249
  155. data/vendor/libgit2/src/diff_output.h +15 -8
  156. data/vendor/libgit2/src/diff_tform.c +687 -0
  157. data/vendor/libgit2/src/errors.c +27 -36
  158. data/vendor/libgit2/src/fetch.c +13 -351
  159. data/vendor/libgit2/src/fetch.h +13 -3
  160. data/vendor/libgit2/src/fetchhead.c +295 -0
  161. data/vendor/libgit2/src/fetchhead.h +34 -0
  162. data/vendor/libgit2/src/filebuf.c +42 -15
  163. data/vendor/libgit2/src/filebuf.h +4 -2
  164. data/vendor/libgit2/src/fileops.c +466 -113
  165. data/vendor/libgit2/src/fileops.h +154 -28
  166. data/vendor/libgit2/src/filter.c +3 -75
  167. data/vendor/libgit2/src/filter.h +1 -29
  168. data/vendor/libgit2/src/fnmatch.c +1 -1
  169. data/vendor/libgit2/src/fnmatch.h +1 -1
  170. data/vendor/libgit2/src/global.c +54 -10
  171. data/vendor/libgit2/src/global.h +10 -1
  172. data/vendor/libgit2/src/graph.c +178 -0
  173. data/vendor/libgit2/src/hash.c +25 -52
  174. data/vendor/libgit2/src/hash.h +21 -9
  175. data/vendor/libgit2/src/{sha1/sha1.c → hash/hash_generic.c} +20 -12
  176. data/vendor/libgit2/src/hash/hash_generic.h +24 -0
  177. data/vendor/libgit2/src/hash/hash_openssl.h +45 -0
  178. data/vendor/libgit2/src/hash/hash_win32.c +291 -0
  179. data/vendor/libgit2/src/hash/hash_win32.h +140 -0
  180. data/vendor/libgit2/src/hashsig.c +368 -0
  181. data/vendor/libgit2/src/hashsig.h +72 -0
  182. data/vendor/libgit2/src/ignore.c +22 -15
  183. data/vendor/libgit2/src/ignore.h +6 -1
  184. data/vendor/libgit2/src/index.c +770 -171
  185. data/vendor/libgit2/src/index.h +13 -5
  186. data/vendor/libgit2/src/indexer.c +286 -431
  187. data/vendor/libgit2/src/iterator.c +854 -466
  188. data/vendor/libgit2/src/iterator.h +134 -109
  189. data/vendor/libgit2/src/map.h +1 -1
  190. data/vendor/libgit2/src/merge.c +296 -0
  191. data/vendor/libgit2/src/merge.h +22 -0
  192. data/vendor/libgit2/src/message.c +1 -1
  193. data/vendor/libgit2/src/message.h +1 -1
  194. data/vendor/libgit2/src/mwindow.c +35 -30
  195. data/vendor/libgit2/src/mwindow.h +2 -2
  196. data/vendor/libgit2/src/netops.c +162 -98
  197. data/vendor/libgit2/src/netops.h +50 -15
  198. data/vendor/libgit2/src/notes.c +109 -58
  199. data/vendor/libgit2/src/notes.h +2 -1
  200. data/vendor/libgit2/src/object.c +46 -57
  201. data/vendor/libgit2/src/object.h +1 -8
  202. data/vendor/libgit2/src/odb.c +151 -40
  203. data/vendor/libgit2/src/odb.h +5 -1
  204. data/vendor/libgit2/src/odb_loose.c +4 -5
  205. data/vendor/libgit2/src/odb_pack.c +122 -80
  206. data/vendor/libgit2/src/offmap.h +65 -0
  207. data/vendor/libgit2/src/oid.c +12 -4
  208. data/vendor/libgit2/src/oidmap.h +1 -1
  209. data/vendor/libgit2/src/pack-objects.c +88 -61
  210. data/vendor/libgit2/src/pack-objects.h +8 -8
  211. data/vendor/libgit2/src/pack.c +293 -28
  212. data/vendor/libgit2/src/pack.h +49 -4
  213. data/vendor/libgit2/src/path.c +103 -14
  214. data/vendor/libgit2/src/path.h +23 -7
  215. data/vendor/libgit2/src/pathspec.c +168 -0
  216. data/vendor/libgit2/src/pathspec.h +40 -0
  217. data/vendor/libgit2/src/pool.c +29 -4
  218. data/vendor/libgit2/src/pool.h +8 -1
  219. data/vendor/libgit2/src/posix.c +26 -27
  220. data/vendor/libgit2/src/posix.h +2 -3
  221. data/vendor/libgit2/src/pqueue.c +23 -1
  222. data/vendor/libgit2/src/pqueue.h +23 -1
  223. data/vendor/libgit2/src/push.c +653 -0
  224. data/vendor/libgit2/src/push.h +51 -0
  225. data/vendor/libgit2/src/refdb.c +185 -0
  226. data/vendor/libgit2/src/refdb.h +46 -0
  227. data/vendor/libgit2/src/refdb_fs.c +1024 -0
  228. data/vendor/libgit2/src/refdb_fs.h +15 -0
  229. data/vendor/libgit2/src/reflog.c +77 -45
  230. data/vendor/libgit2/src/reflog.h +1 -3
  231. data/vendor/libgit2/src/refs.c +366 -1326
  232. data/vendor/libgit2/src/refs.h +22 -13
  233. data/vendor/libgit2/src/refspec.c +46 -7
  234. data/vendor/libgit2/src/refspec.h +11 -1
  235. data/vendor/libgit2/src/remote.c +758 -120
  236. data/vendor/libgit2/src/remote.h +10 -5
  237. data/vendor/libgit2/src/repo_template.h +6 -6
  238. data/vendor/libgit2/src/repository.c +315 -96
  239. data/vendor/libgit2/src/repository.h +5 -3
  240. data/vendor/libgit2/src/reset.c +99 -81
  241. data/vendor/libgit2/src/revparse.c +157 -84
  242. data/vendor/libgit2/src/revwalk.c +68 -470
  243. data/vendor/libgit2/src/revwalk.h +44 -0
  244. data/vendor/libgit2/src/sha1_lookup.c +1 -1
  245. data/vendor/libgit2/src/sha1_lookup.h +1 -1
  246. data/vendor/libgit2/src/signature.c +68 -200
  247. data/vendor/libgit2/src/signature.h +1 -1
  248. data/vendor/libgit2/src/stash.c +663 -0
  249. data/vendor/libgit2/src/status.c +101 -79
  250. data/vendor/libgit2/src/strmap.h +1 -1
  251. data/vendor/libgit2/src/submodule.c +67 -51
  252. data/vendor/libgit2/src/submodule.h +1 -1
  253. data/vendor/libgit2/src/tag.c +35 -29
  254. data/vendor/libgit2/src/tag.h +1 -1
  255. data/vendor/libgit2/src/thread-utils.c +1 -1
  256. data/vendor/libgit2/src/thread-utils.h +2 -2
  257. data/vendor/libgit2/src/trace.c +39 -0
  258. data/vendor/libgit2/src/trace.h +56 -0
  259. data/vendor/libgit2/src/transport.c +81 -34
  260. data/vendor/libgit2/src/transports/cred.c +60 -0
  261. data/vendor/libgit2/src/transports/cred_helpers.c +49 -0
  262. data/vendor/libgit2/src/transports/git.c +234 -127
  263. data/vendor/libgit2/src/transports/http.c +761 -433
  264. data/vendor/libgit2/src/transports/local.c +460 -64
  265. data/vendor/libgit2/src/transports/smart.c +345 -0
  266. data/vendor/libgit2/src/transports/smart.h +179 -0
  267. data/vendor/libgit2/src/{pkt.c → transports/smart_pkt.c} +131 -12
  268. data/vendor/libgit2/src/transports/smart_protocol.c +856 -0
  269. data/vendor/libgit2/src/transports/winhttp.c +1136 -0
  270. data/vendor/libgit2/src/tree-cache.c +2 -2
  271. data/vendor/libgit2/src/tree-cache.h +1 -1
  272. data/vendor/libgit2/src/tree.c +239 -166
  273. data/vendor/libgit2/src/tree.h +11 -2
  274. data/vendor/libgit2/src/tsort.c +39 -23
  275. data/vendor/libgit2/src/unix/map.c +1 -1
  276. data/vendor/libgit2/src/unix/posix.h +12 -2
  277. data/vendor/libgit2/src/unix/realpath.c +30 -0
  278. data/vendor/libgit2/src/util.c +250 -13
  279. data/vendor/libgit2/src/util.h +71 -14
  280. data/vendor/libgit2/src/vector.c +123 -60
  281. data/vendor/libgit2/src/vector.h +24 -22
  282. data/vendor/libgit2/src/win32/dir.c +1 -1
  283. data/vendor/libgit2/src/win32/dir.h +1 -1
  284. data/vendor/libgit2/src/win32/error.c +77 -0
  285. data/vendor/libgit2/src/win32/error.h +13 -0
  286. data/vendor/libgit2/src/win32/findfile.c +143 -54
  287. data/vendor/libgit2/src/win32/findfile.h +10 -6
  288. data/vendor/libgit2/src/win32/map.c +1 -1
  289. data/vendor/libgit2/src/win32/mingw-compat.h +1 -1
  290. data/vendor/libgit2/src/win32/msvc-compat.h +10 -1
  291. data/vendor/libgit2/src/win32/posix.h +10 -1
  292. data/vendor/libgit2/src/win32/posix_w32.c +132 -63
  293. data/vendor/libgit2/src/win32/precompiled.c +1 -1
  294. data/vendor/libgit2/src/win32/pthread.c +1 -1
  295. data/vendor/libgit2/src/win32/pthread.h +1 -1
  296. data/vendor/libgit2/src/win32/utf-conv.c +5 -5
  297. data/vendor/libgit2/src/win32/utf-conv.h +3 -3
  298. data/vendor/libgit2/src/win32/version.h +20 -0
  299. metadata +308 -252
  300. data/test/fixtures/testrepo.git/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 +0 -0
  301. data/test/fixtures/testrepo.git/objects/7f/043268ea43ce18e3540acaabf9e090c91965b0 +0 -0
  302. data/test/fixtures/testrepo.git/objects/a3/e05719b428a2d0ed7a55c4ce53dcc5768c6d5e +0 -0
  303. data/test/index_test.rb~ +0 -218
  304. data/vendor/libgit2/src/pkt.h +0 -91
  305. data/vendor/libgit2/src/ppc/sha1.c +0 -70
  306. data/vendor/libgit2/src/ppc/sha1.h +0 -26
  307. data/vendor/libgit2/src/protocol.c +0 -110
  308. data/vendor/libgit2/src/protocol.h +0 -21
  309. data/vendor/libgit2/src/sha1.h +0 -33
  310. data/vendor/libgit2/src/transport.h +0 -148
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (C) 2009-2012 the libgit2 contributors
2
+ * Copyright (C) the libgit2 contributors. All rights reserved.
3
3
  *
4
4
  * This file is part of libgit2, distributed under the GNU GPL v2 with
5
5
  * a Linking Exception. For full terms see the included COPYING file.
@@ -17,13 +17,6 @@ struct git_object {
17
17
  /* fully free the object; internal method, DO NOT EXPORT */
18
18
  void git_object__free(void *object);
19
19
 
20
- GIT_INLINE(int) git_object__dup(git_object **dest, git_object *source)
21
- {
22
- git_cached_obj_incref(source);
23
- *dest = source;
24
- return 0;
25
- }
26
-
27
20
  int git_object__from_odb_object(
28
21
  git_object **object_out,
29
22
  git_repository *repo,
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (C) 2009-2012 the libgit2 contributors
2
+ * Copyright (C) the libgit2 contributors. All rights reserved.
3
3
  *
4
4
  * This file is part of libgit2, distributed under the GNU GPL v2 with
5
5
  * a Linking Exception. For full terms see the included COPYING file.
@@ -23,6 +23,8 @@
23
23
  #define GIT_LOOSE_PRIORITY 2
24
24
  #define GIT_PACKED_PRIORITY 1
25
25
 
26
+ #define GIT_ALTERNATES_MAX_DEPTH 5
27
+
26
28
  typedef struct
27
29
  {
28
30
  git_odb_backend *backend;
@@ -30,7 +32,11 @@ typedef struct
30
32
  int is_alternate;
31
33
  } backend_internal;
32
34
 
33
- static int format_object_header(char *hdr, size_t n, size_t obj_len, git_otype obj_type)
35
+ size_t git_odb__cache_size = GIT_DEFAULT_CACHE_SIZE;
36
+
37
+ static int load_alternates(git_odb *odb, const char *objects_dir, int alternate_depth);
38
+
39
+ int git_odb__format_object_header(char *hdr, size_t n, size_t obj_len, git_otype obj_type)
34
40
  {
35
41
  const char *type_str = git_object_type2string(obj_type);
36
42
  int len = p_snprintf(hdr, n, "%s %"PRIuZ, type_str, obj_len);
@@ -51,7 +57,7 @@ int git_odb__hashobj(git_oid *id, git_rawobj *obj)
51
57
  if (!obj->data && obj->len != 0)
52
58
  return -1;
53
59
 
54
- hdrlen = format_object_header(header, sizeof(header), obj->len, obj->type);
60
+ hdrlen = git_odb__format_object_header(header, sizeof(header), obj->len, obj->type);
55
61
 
56
62
  vec[0].data = header;
57
63
  vec[0].len = hdrlen;
@@ -117,23 +123,27 @@ int git_odb__hashfd(git_oid *out, git_file fd, size_t size, git_otype type)
117
123
  {
118
124
  int hdr_len;
119
125
  char hdr[64], buffer[2048];
120
- git_hash_ctx *ctx;
126
+ git_hash_ctx ctx;
121
127
  ssize_t read_len = 0;
128
+ int error = 0;
122
129
 
123
130
  if (!git_object_typeisloose(type)) {
124
131
  giterr_set(GITERR_INVALID, "Invalid object type for hash");
125
132
  return -1;
126
133
  }
127
134
 
128
- hdr_len = format_object_header(hdr, sizeof(hdr), size, type);
135
+ if ((error = git_hash_ctx_init(&ctx)) < 0)
136
+ return -1;
129
137
 
130
- ctx = git_hash_new_ctx();
131
- GITERR_CHECK_ALLOC(ctx);
138
+ hdr_len = git_odb__format_object_header(hdr, sizeof(hdr), size, type);
132
139
 
133
- git_hash_update(ctx, hdr, hdr_len);
140
+ if ((error = git_hash_update(&ctx, hdr, hdr_len)) < 0)
141
+ goto done;
134
142
 
135
143
  while (size > 0 && (read_len = p_read(fd, buffer, sizeof(buffer))) > 0) {
136
- git_hash_update(ctx, buffer, read_len);
144
+ if ((error = git_hash_update(&ctx, buffer, read_len)) < 0)
145
+ goto done;
146
+
137
147
  size -= read_len;
138
148
  }
139
149
 
@@ -141,15 +151,18 @@ int git_odb__hashfd(git_oid *out, git_file fd, size_t size, git_otype type)
141
151
  * If size is not zero, the file was truncated after we originally
142
152
  * stat'd it, so we consider this a read failure too */
143
153
  if (read_len < 0 || size > 0) {
144
- git_hash_free_ctx(ctx);
145
154
  giterr_set(GITERR_OS, "Error reading file for hashing");
155
+ error = -1;
156
+
157
+ goto done;
146
158
  return -1;
147
159
  }
148
160
 
149
- git_hash_final(out, ctx);
150
- git_hash_free_ctx(ctx);
161
+ error = git_hash_final(out, &ctx);
151
162
 
152
- return 0;
163
+ done:
164
+ git_hash_ctx_cleanup(&ctx);
165
+ return error;
153
166
  }
154
167
 
155
168
  int git_odb__hashfd_filtered(
@@ -340,7 +353,7 @@ int git_odb_new(git_odb **out)
340
353
  git_odb *db = git__calloc(1, sizeof(*db));
341
354
  GITERR_CHECK_ALLOC(db);
342
355
 
343
- if (git_cache_init(&db->cache, GIT_DEFAULT_CACHE_SIZE, &free_odb_object) < 0 ||
356
+ if (git_cache_init(&db->cache, git_odb__cache_size, &free_odb_object) < 0 ||
344
357
  git_vector_init(&db->backends, 4, backend_sort_cmp) < 0)
345
358
  {
346
359
  git__free(db);
@@ -358,6 +371,8 @@ static int add_backend_internal(git_odb *odb, git_odb_backend *backend, int prio
358
371
 
359
372
  assert(odb && backend);
360
373
 
374
+ GITERR_CHECK_VERSION(backend, GIT_ODB_BACKEND_VERSION, "git_odb_backend");
375
+
361
376
  /* Check if the backend is already owned by another ODB */
362
377
  assert(!backend->odb || backend->odb == odb);
363
378
 
@@ -388,7 +403,7 @@ int git_odb_add_alternate(git_odb *odb, git_odb_backend *backend, int priority)
388
403
  return add_backend_internal(odb, backend, priority, 1);
389
404
  }
390
405
 
391
- static int add_default_backends(git_odb *db, const char *objects_dir, int as_alternates)
406
+ static int add_default_backends(git_odb *db, const char *objects_dir, int as_alternates, int alternate_depth)
392
407
  {
393
408
  git_odb_backend *loose, *packed;
394
409
 
@@ -402,10 +417,10 @@ static int add_default_backends(git_odb *db, const char *objects_dir, int as_alt
402
417
  add_backend_internal(db, packed, GIT_PACKED_PRIORITY, as_alternates) < 0)
403
418
  return -1;
404
419
 
405
- return 0;
420
+ return load_alternates(db, objects_dir, alternate_depth);
406
421
  }
407
422
 
408
- static int load_alternates(git_odb *odb, const char *objects_dir)
423
+ static int load_alternates(git_odb *odb, const char *objects_dir, int alternate_depth)
409
424
  {
410
425
  git_buf alternates_path = GIT_BUF_INIT;
411
426
  git_buf alternates_buf = GIT_BUF_INIT;
@@ -413,6 +428,11 @@ static int load_alternates(git_odb *odb, const char *objects_dir)
413
428
  const char *alternate;
414
429
  int result = 0;
415
430
 
431
+ /* Git reports an error, we just ignore anything deeper */
432
+ if (alternate_depth > GIT_ALTERNATES_MAX_DEPTH) {
433
+ return 0;
434
+ }
435
+
416
436
  if (git_buf_joinpath(&alternates_path, objects_dir, GIT_ALTERNATES_FILE) < 0)
417
437
  return -1;
418
438
 
@@ -433,14 +453,18 @@ static int load_alternates(git_odb *odb, const char *objects_dir)
433
453
  if (*alternate == '\0' || *alternate == '#')
434
454
  continue;
435
455
 
436
- /* relative path: build based on the current `objects` folder */
437
- if (*alternate == '.') {
456
+ /*
457
+ * Relative path: build based on the current `objects`
458
+ * folder. However, relative paths are only allowed in
459
+ * the current repository.
460
+ */
461
+ if (*alternate == '.' && !alternate_depth) {
438
462
  if ((result = git_buf_joinpath(&alternates_path, objects_dir, alternate)) < 0)
439
463
  break;
440
464
  alternate = git_buf_cstr(&alternates_path);
441
465
  }
442
466
 
443
- if ((result = add_default_backends(odb, alternate, 1)) < 0)
467
+ if ((result = add_default_backends(odb, alternate, 1, alternate_depth + 1)) < 0)
444
468
  break;
445
469
  }
446
470
 
@@ -450,6 +474,11 @@ static int load_alternates(git_odb *odb, const char *objects_dir)
450
474
  return result;
451
475
  }
452
476
 
477
+ int git_odb_add_disk_alternate(git_odb *odb, const char *path)
478
+ {
479
+ return add_default_backends(odb, path, 1, 0);
480
+ }
481
+
453
482
  int git_odb_open(git_odb **out, const char *objects_dir)
454
483
  {
455
484
  git_odb *db;
@@ -461,9 +490,7 @@ int git_odb_open(git_odb **out, const char *objects_dir)
461
490
  if (git_odb_new(&db) < 0)
462
491
  return -1;
463
492
 
464
- if (add_default_backends(db, objects_dir, 0) < 0 ||
465
- load_alternates(db, objects_dir) < 0)
466
- {
493
+ if (add_default_backends(db, objects_dir, 0, 0) < 0) {
467
494
  git_odb_free(db);
468
495
  return -1;
469
496
  }
@@ -474,7 +501,7 @@ int git_odb_open(git_odb **out, const char *objects_dir)
474
501
 
475
502
  static void odb_free(git_odb *db)
476
503
  {
477
- unsigned int i;
504
+ size_t i;
478
505
 
479
506
  for (i = 0; i < db->backends.length; ++i) {
480
507
  backend_internal *internal = git_vector_get(&db->backends, i);
@@ -502,8 +529,9 @@ void git_odb_free(git_odb *db)
502
529
  int git_odb_exists(git_odb *db, const git_oid *id)
503
530
  {
504
531
  git_odb_object *object;
505
- unsigned int i;
532
+ size_t i;
506
533
  bool found = false;
534
+ bool refreshed = false;
507
535
 
508
536
  assert(db && id);
509
537
 
@@ -512,6 +540,7 @@ int git_odb_exists(git_odb *db, const git_oid *id)
512
540
  return (int)true;
513
541
  }
514
542
 
543
+ attempt_lookup:
515
544
  for (i = 0; i < db->backends.length && !found; ++i) {
516
545
  backend_internal *internal = git_vector_get(&db->backends, i);
517
546
  git_odb_backend *b = internal->backend;
@@ -520,6 +549,16 @@ int git_odb_exists(git_odb *db, const git_oid *id)
520
549
  found = b->exists(b, id);
521
550
  }
522
551
 
552
+ if (!found && !refreshed) {
553
+ if (git_odb_refresh(db) < 0) {
554
+ giterr_clear();
555
+ return (int)false;
556
+ }
557
+
558
+ refreshed = true;
559
+ goto attempt_lookup;
560
+ }
561
+
523
562
  return (int)found;
524
563
  }
525
564
 
@@ -540,7 +579,7 @@ int git_odb__read_header_or_object(
540
579
  git_odb_object **out, size_t *len_p, git_otype *type_p,
541
580
  git_odb *db, const git_oid *id)
542
581
  {
543
- unsigned int i;
582
+ size_t i;
544
583
  int error = GIT_ENOTFOUND;
545
584
  git_odb_object *object;
546
585
 
@@ -582,16 +621,25 @@ int git_odb__read_header_or_object(
582
621
 
583
622
  int git_odb_read(git_odb_object **out, git_odb *db, const git_oid *id)
584
623
  {
585
- unsigned int i;
586
- int error = GIT_ENOTFOUND;
624
+ size_t i;
625
+ int error;
626
+ bool refreshed = false;
587
627
  git_rawobj raw;
588
628
 
589
629
  assert(out && db && id);
590
630
 
631
+ if (db->backends.length == 0) {
632
+ giterr_set(GITERR_ODB, "Failed to lookup object: no backends loaded");
633
+ return GIT_ENOTFOUND;
634
+ }
635
+
591
636
  *out = git_cache_get(&db->cache, id);
592
637
  if (*out != NULL)
593
638
  return 0;
594
639
 
640
+ attempt_lookup:
641
+ error = GIT_ENOTFOUND;
642
+
595
643
  for (i = 0; i < db->backends.length && error < 0; ++i) {
596
644
  backend_internal *internal = git_vector_get(&db->backends, i);
597
645
  git_odb_backend *b = internal->backend;
@@ -600,9 +648,13 @@ int git_odb_read(git_odb_object **out, git_odb *db, const git_oid *id)
600
648
  error = b->read(&raw.data, &raw.len, &raw.type, b, id);
601
649
  }
602
650
 
603
- /* TODO: If no backends are configured, this returns GIT_ENOTFOUND but
604
- * will never have called giterr_set().
605
- */
651
+ if (error == GIT_ENOTFOUND && !refreshed) {
652
+ if ((error = git_odb_refresh(db)) < 0)
653
+ return error;
654
+
655
+ refreshed = true;
656
+ goto attempt_lookup;
657
+ }
606
658
 
607
659
  if (error && error != GIT_PASSTHROUGH)
608
660
  return error;
@@ -614,12 +666,12 @@ int git_odb_read(git_odb_object **out, git_odb *db, const git_oid *id)
614
666
  int git_odb_read_prefix(
615
667
  git_odb_object **out, git_odb *db, const git_oid *short_id, size_t len)
616
668
  {
617
- unsigned int i;
669
+ size_t i;
618
670
  int error = GIT_ENOTFOUND;
619
671
  git_oid found_full_oid = {{0}};
620
672
  git_rawobj raw;
621
673
  void *data = NULL;
622
- bool found = false;
674
+ bool found = false, refreshed = false;
623
675
 
624
676
  assert(out && db);
625
677
 
@@ -635,11 +687,12 @@ int git_odb_read_prefix(
635
687
  return 0;
636
688
  }
637
689
 
690
+ attempt_lookup:
638
691
  for (i = 0; i < db->backends.length; ++i) {
639
692
  backend_internal *internal = git_vector_get(&db->backends, i);
640
693
  git_odb_backend *b = internal->backend;
641
694
 
642
- if (b->read != NULL) {
695
+ if (b->read_prefix != NULL) {
643
696
  git_oid full_oid;
644
697
  error = b->read_prefix(&full_oid, &raw.data, &raw.len, &raw.type, b, short_id, len);
645
698
  if (error == GIT_ENOTFOUND || error == GIT_PASSTHROUGH)
@@ -650,13 +703,23 @@ int git_odb_read_prefix(
650
703
 
651
704
  git__free(data);
652
705
  data = raw.data;
706
+
653
707
  if (found && git_oid_cmp(&full_oid, &found_full_oid))
654
708
  return git_odb__error_ambiguous("multiple matches for prefix");
709
+
655
710
  found_full_oid = full_oid;
656
711
  found = true;
657
712
  }
658
713
  }
659
714
 
715
+ if (!found && !refreshed) {
716
+ if ((error = git_odb_refresh(db)) < 0)
717
+ return error;
718
+
719
+ refreshed = true;
720
+ goto attempt_lookup;
721
+ }
722
+
660
723
  if (!found)
661
724
  return git_odb__error_notfound("no match for prefix", short_id);
662
725
 
@@ -664,14 +727,14 @@ int git_odb_read_prefix(
664
727
  return 0;
665
728
  }
666
729
 
667
- int git_odb_foreach(git_odb *db, int (*cb)(git_oid *oid, void *data), void *data)
730
+ int git_odb_foreach(git_odb *db, git_odb_foreach_cb cb, void *payload)
668
731
  {
669
732
  unsigned int i;
670
733
  backend_internal *internal;
671
734
 
672
735
  git_vector_foreach(&db->backends, i, internal) {
673
736
  git_odb_backend *b = internal->backend;
674
- int error = b->foreach(b, cb, data);
737
+ int error = b->foreach(b, cb, payload);
675
738
  if (error < 0)
676
739
  return error;
677
740
  }
@@ -682,12 +745,16 @@ int git_odb_foreach(git_odb *db, int (*cb)(git_oid *oid, void *data), void *data
682
745
  int git_odb_write(
683
746
  git_oid *oid, git_odb *db, const void *data, size_t len, git_otype type)
684
747
  {
685
- unsigned int i;
748
+ size_t i;
686
749
  int error = GIT_ERROR;
687
750
  git_odb_stream *stream;
688
751
 
689
752
  assert(oid && db);
690
753
 
754
+ git_odb_hash(oid, data, len, type);
755
+ if (git_odb_exists(db, oid))
756
+ return 0;
757
+
691
758
  for (i = 0; i < db->backends.length && error < 0; ++i) {
692
759
  backend_internal *internal = git_vector_get(&db->backends, i);
693
760
  git_odb_backend *b = internal->backend;
@@ -720,7 +787,7 @@ int git_odb_write(
720
787
  int git_odb_open_wstream(
721
788
  git_odb_stream **stream, git_odb *db, size_t size, git_otype type)
722
789
  {
723
- unsigned int i;
790
+ size_t i;
724
791
  int error = GIT_ERROR;
725
792
 
726
793
  assert(stream && db);
@@ -747,7 +814,7 @@ int git_odb_open_wstream(
747
814
 
748
815
  int git_odb_open_rstream(git_odb_stream **stream, git_odb *db, const git_oid *oid)
749
816
  {
750
- unsigned int i;
817
+ size_t i;
751
818
  int error = GIT_ERROR;
752
819
 
753
820
  assert(stream && db);
@@ -766,12 +833,56 @@ int git_odb_open_rstream(git_odb_stream **stream, git_odb *db, const git_oid *oi
766
833
  return error;
767
834
  }
768
835
 
769
- void * git_odb_backend_malloc(git_odb_backend *backend, size_t len)
836
+ int git_odb_write_pack(struct git_odb_writepack **out, git_odb *db, git_transfer_progress_callback progress_cb, void *progress_payload)
837
+ {
838
+ size_t i;
839
+ int error = GIT_ERROR;
840
+
841
+ assert(out && db);
842
+
843
+ for (i = 0; i < db->backends.length && error < 0; ++i) {
844
+ backend_internal *internal = git_vector_get(&db->backends, i);
845
+ git_odb_backend *b = internal->backend;
846
+
847
+ /* we don't write in alternates! */
848
+ if (internal->is_alternate)
849
+ continue;
850
+
851
+ if (b->writepack != NULL)
852
+ error = b->writepack(out, b, progress_cb, progress_payload);
853
+ }
854
+
855
+ if (error == GIT_PASSTHROUGH)
856
+ error = 0;
857
+
858
+ return error;
859
+ }
860
+
861
+ void *git_odb_backend_malloc(git_odb_backend *backend, size_t len)
770
862
  {
771
863
  GIT_UNUSED(backend);
772
864
  return git__malloc(len);
773
865
  }
774
866
 
867
+ int git_odb_refresh(struct git_odb *db)
868
+ {
869
+ size_t i;
870
+ assert(db);
871
+
872
+ for (i = 0; i < db->backends.length; ++i) {
873
+ backend_internal *internal = git_vector_get(&db->backends, i);
874
+ git_odb_backend *b = internal->backend;
875
+
876
+ if (b->refresh != NULL) {
877
+ int error = b->refresh(b);
878
+ if (error < 0)
879
+ return error;
880
+ }
881
+ }
882
+
883
+ return 0;
884
+ }
885
+
775
886
  int git_odb__error_notfound(const char *message, const git_oid *oid)
776
887
  {
777
888
  if (oid != NULL) {