rugged 0.1.2 → 0.16.0b1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (277) hide show
  1. data/README.md +25 -36
  2. data/Rakefile +20 -98
  3. data/ext/rugged/extconf.rb +44 -4
  4. data/ext/rugged/remote.c +215 -0
  5. data/ext/rugged/rugged.c +171 -0
  6. data/ext/rugged/rugged.h +126 -0
  7. data/ext/rugged/rugged_blob.c +99 -0
  8. data/ext/rugged/rugged_commit.c +224 -0
  9. data/ext/rugged/rugged_config.c +238 -0
  10. data/ext/rugged/rugged_index.c +440 -0
  11. data/ext/rugged/rugged_object.c +203 -0
  12. data/ext/rugged/rugged_reference.c +401 -0
  13. data/ext/rugged/rugged_repo.c +482 -0
  14. data/ext/rugged/rugged_revwalk.c +138 -0
  15. data/ext/rugged/rugged_signature.c +80 -0
  16. data/ext/rugged/rugged_tag.c +216 -0
  17. data/ext/rugged/rugged_tree.c +322 -0
  18. data/ext/rugged/vendor/libgit2-dist.tar.gz +0 -0
  19. data/ext/rugged/vendor/libgit2-dist/deps/http-parser/http_parser.c +1778 -0
  20. data/ext/rugged/vendor/libgit2-dist/deps/http-parser/http_parser.h +267 -0
  21. data/ext/rugged/vendor/libgit2-dist/deps/zlib/adler32.c +169 -0
  22. data/ext/rugged/vendor/libgit2-dist/deps/zlib/crc32.c +442 -0
  23. data/ext/rugged/vendor/libgit2-dist/deps/zlib/crc32.h +441 -0
  24. data/ext/rugged/vendor/libgit2-dist/deps/zlib/deflate.c +1834 -0
  25. data/ext/rugged/vendor/libgit2-dist/deps/zlib/deflate.h +342 -0
  26. data/ext/rugged/vendor/libgit2-dist/deps/zlib/inffast.c +340 -0
  27. data/ext/rugged/vendor/libgit2-dist/deps/zlib/inffast.h +11 -0
  28. data/ext/rugged/vendor/libgit2-dist/deps/zlib/inffixed.h +94 -0
  29. data/ext/rugged/vendor/libgit2-dist/deps/zlib/inflate.c +1480 -0
  30. data/ext/rugged/vendor/libgit2-dist/deps/zlib/inflate.h +122 -0
  31. data/ext/rugged/vendor/libgit2-dist/deps/zlib/inftrees.c +330 -0
  32. data/ext/rugged/vendor/libgit2-dist/deps/zlib/inftrees.h +62 -0
  33. data/ext/rugged/vendor/libgit2-dist/deps/zlib/trees.c +1244 -0
  34. data/ext/rugged/vendor/libgit2-dist/deps/zlib/trees.h +128 -0
  35. data/ext/rugged/vendor/libgit2-dist/deps/zlib/zconf.h +54 -0
  36. data/ext/rugged/vendor/libgit2-dist/deps/zlib/zlib.h +1613 -0
  37. data/ext/rugged/vendor/libgit2-dist/deps/zlib/zutil.c +318 -0
  38. data/ext/rugged/vendor/libgit2-dist/deps/zlib/zutil.h +274 -0
  39. data/ext/rugged/vendor/libgit2-dist/examples/general.c +451 -0
  40. data/ext/rugged/vendor/libgit2-dist/examples/network/common.h +14 -0
  41. data/ext/rugged/vendor/libgit2-dist/examples/network/fetch.c +97 -0
  42. data/ext/rugged/vendor/libgit2-dist/examples/network/git2.c +58 -0
  43. data/ext/rugged/vendor/libgit2-dist/examples/network/index-pack.c +47 -0
  44. data/ext/rugged/vendor/libgit2-dist/examples/network/ls-remote.c +76 -0
  45. data/ext/rugged/vendor/libgit2-dist/examples/showindex.c +43 -0
  46. data/ext/rugged/vendor/libgit2-dist/include/git2.h +44 -0
  47. data/ext/rugged/vendor/libgit2-dist/include/git2/blob.h +120 -0
  48. data/ext/rugged/vendor/libgit2-dist/include/git2/branch.h +15 -0
  49. data/ext/rugged/vendor/libgit2-dist/include/git2/commit.h +263 -0
  50. data/ext/rugged/vendor/libgit2-dist/include/git2/common.h +103 -0
  51. data/ext/rugged/vendor/libgit2-dist/include/git2/config.h +278 -0
  52. data/ext/rugged/vendor/libgit2-dist/include/git2/errors.h +144 -0
  53. data/ext/rugged/vendor/libgit2-dist/include/git2/index.h +306 -0
  54. data/ext/rugged/vendor/libgit2-dist/include/git2/indexer.h +76 -0
  55. data/ext/rugged/vendor/libgit2-dist/include/git2/inttypes.h +305 -0
  56. data/ext/rugged/vendor/libgit2-dist/include/git2/net.h +51 -0
  57. data/ext/rugged/vendor/libgit2-dist/include/git2/object.h +173 -0
  58. data/ext/rugged/vendor/libgit2-dist/include/git2/odb.h +331 -0
  59. data/ext/rugged/vendor/libgit2-dist/include/git2/odb_backend.h +100 -0
  60. data/ext/rugged/vendor/libgit2-dist/include/git2/oid.h +218 -0
  61. data/ext/rugged/vendor/libgit2-dist/include/git2/reflog.h +128 -0
  62. data/ext/rugged/vendor/libgit2-dist/include/git2/refs.h +309 -0
  63. data/ext/rugged/vendor/libgit2-dist/include/git2/refspec.h +60 -0
  64. data/ext/rugged/vendor/libgit2-dist/include/git2/remote.h +176 -0
  65. data/ext/rugged/vendor/libgit2-dist/include/git2/repository.h +290 -0
  66. data/ext/rugged/vendor/libgit2-dist/include/git2/revwalk.h +169 -0
  67. data/ext/rugged/vendor/libgit2-dist/include/git2/signature.h +65 -0
  68. data/ext/rugged/vendor/libgit2-dist/include/git2/status.h +63 -0
  69. data/ext/rugged/vendor/libgit2-dist/include/git2/stdint.h +247 -0
  70. data/ext/rugged/vendor/libgit2-dist/include/git2/tag.h +279 -0
  71. data/ext/rugged/vendor/libgit2-dist/include/git2/threads.h +48 -0
  72. data/ext/rugged/vendor/libgit2-dist/include/git2/tree.h +318 -0
  73. data/ext/rugged/vendor/libgit2-dist/include/git2/types.h +169 -0
  74. data/ext/rugged/vendor/libgit2-dist/include/git2/version.h +15 -0
  75. data/ext/rugged/vendor/libgit2-dist/include/git2/windows.h +59 -0
  76. data/ext/rugged/vendor/libgit2-dist/include/git2/zlib.h +40 -0
  77. data/ext/rugged/vendor/libgit2-dist/src/blob.c +135 -0
  78. data/ext/rugged/vendor/libgit2-dist/src/blob.h +23 -0
  79. data/ext/rugged/vendor/libgit2-dist/src/bswap.h +97 -0
  80. data/ext/rugged/vendor/libgit2-dist/src/buffer.c +113 -0
  81. data/ext/rugged/vendor/libgit2-dist/src/buffer.h +32 -0
  82. data/ext/rugged/vendor/libgit2-dist/src/cache.c +111 -0
  83. data/ext/rugged/vendor/libgit2-dist/src/cache.h +64 -0
  84. data/ext/rugged/vendor/libgit2-dist/src/cc-compat.h +67 -0
  85. data/ext/rugged/vendor/libgit2-dist/src/commit.c +299 -0
  86. data/ext/rugged/vendor/libgit2-dist/src/commit.h +34 -0
  87. data/ext/rugged/vendor/libgit2-dist/src/common.h +64 -0
  88. data/ext/rugged/vendor/libgit2-dist/src/config.c +418 -0
  89. data/ext/rugged/vendor/libgit2-dist/src/config.h +24 -0
  90. data/ext/rugged/vendor/libgit2-dist/src/config_file.c +1210 -0
  91. data/ext/rugged/vendor/libgit2-dist/src/delta-apply.c +115 -0
  92. data/ext/rugged/vendor/libgit2-dist/src/delta-apply.h +33 -0
  93. data/ext/rugged/vendor/libgit2-dist/src/dir.h +47 -0
  94. data/ext/rugged/vendor/libgit2-dist/src/errors.c +104 -0
  95. data/ext/rugged/vendor/libgit2-dist/src/fetch.c +172 -0
  96. data/ext/rugged/vendor/libgit2-dist/src/fetch.h +18 -0
  97. data/ext/rugged/vendor/libgit2-dist/src/filebuf.c +400 -0
  98. data/ext/rugged/vendor/libgit2-dist/src/filebuf.h +72 -0
  99. data/ext/rugged/vendor/libgit2-dist/src/fileops.c +358 -0
  100. data/ext/rugged/vendor/libgit2-dist/src/fileops.h +151 -0
  101. data/ext/rugged/vendor/libgit2-dist/src/global.c +134 -0
  102. data/ext/rugged/vendor/libgit2-dist/src/global.h +24 -0
  103. data/ext/rugged/vendor/libgit2-dist/src/hash.c +74 -0
  104. data/ext/rugged/vendor/libgit2-dist/src/hash.h +29 -0
  105. data/ext/rugged/vendor/libgit2-dist/src/hashtable.c +243 -0
  106. data/ext/rugged/vendor/libgit2-dist/src/hashtable.h +80 -0
  107. data/ext/rugged/vendor/libgit2-dist/src/index.c +918 -0
  108. data/ext/rugged/vendor/libgit2-dist/src/index.h +34 -0
  109. data/ext/rugged/vendor/libgit2-dist/src/indexer.c +401 -0
  110. data/ext/rugged/vendor/libgit2-dist/src/map.h +37 -0
  111. data/ext/rugged/vendor/libgit2-dist/src/mwindow.c +272 -0
  112. data/ext/rugged/vendor/libgit2-dist/src/mwindow.h +45 -0
  113. data/ext/rugged/vendor/libgit2-dist/src/netops.c +198 -0
  114. data/ext/rugged/vendor/libgit2-dist/src/netops.h +36 -0
  115. data/ext/rugged/vendor/libgit2-dist/src/object.c +295 -0
  116. data/ext/rugged/vendor/libgit2-dist/src/odb.c +672 -0
  117. data/ext/rugged/vendor/libgit2-dist/src/odb.h +43 -0
  118. data/ext/rugged/vendor/libgit2-dist/src/odb_loose.c +855 -0
  119. data/ext/rugged/vendor/libgit2-dist/src/odb_pack.c +485 -0
  120. data/ext/rugged/vendor/libgit2-dist/src/oid.c +388 -0
  121. data/ext/rugged/vendor/libgit2-dist/src/pack.c +788 -0
  122. data/ext/rugged/vendor/libgit2-dist/src/pack.h +99 -0
  123. data/ext/rugged/vendor/libgit2-dist/src/path.c +270 -0
  124. data/ext/rugged/vendor/libgit2-dist/src/path.h +84 -0
  125. data/ext/rugged/vendor/libgit2-dist/src/pkt.c +426 -0
  126. data/ext/rugged/vendor/libgit2-dist/src/pkt.h +77 -0
  127. data/ext/rugged/vendor/libgit2-dist/src/posix.c +94 -0
  128. data/ext/rugged/vendor/libgit2-dist/src/posix.h +69 -0
  129. data/ext/rugged/vendor/libgit2-dist/src/ppc/sha1.c +70 -0
  130. data/ext/rugged/vendor/libgit2-dist/src/ppc/sha1.h +26 -0
  131. data/ext/rugged/vendor/libgit2-dist/src/pqueue.c +141 -0
  132. data/ext/rugged/vendor/libgit2-dist/src/pqueue.h +81 -0
  133. data/ext/rugged/vendor/libgit2-dist/src/protocol.c +50 -0
  134. data/ext/rugged/vendor/libgit2-dist/src/protocol.h +23 -0
  135. data/ext/rugged/vendor/libgit2-dist/src/reflog.c +318 -0
  136. data/ext/rugged/vendor/libgit2-dist/src/reflog.h +34 -0
  137. data/ext/rugged/vendor/libgit2-dist/src/refs.c +1693 -0
  138. data/ext/rugged/vendor/libgit2-dist/src/refs.h +58 -0
  139. data/ext/rugged/vendor/libgit2-dist/src/refspec.c +95 -0
  140. data/ext/rugged/vendor/libgit2-dist/src/refspec.h +23 -0
  141. data/ext/rugged/vendor/libgit2-dist/src/remote.c +339 -0
  142. data/ext/rugged/vendor/libgit2-dist/src/remote.h +25 -0
  143. data/ext/rugged/vendor/libgit2-dist/src/repository.c +849 -0
  144. data/ext/rugged/vendor/libgit2-dist/src/repository.h +60 -0
  145. data/ext/rugged/vendor/libgit2-dist/src/revwalk.c +569 -0
  146. data/ext/rugged/vendor/libgit2-dist/src/sha1.c +280 -0
  147. data/ext/rugged/vendor/libgit2-dist/src/sha1.h +21 -0
  148. data/ext/rugged/vendor/libgit2-dist/src/sha1_lookup.c +177 -0
  149. data/ext/rugged/vendor/libgit2-dist/src/sha1_lookup.h +18 -0
  150. data/ext/rugged/vendor/libgit2-dist/src/signature.c +335 -0
  151. data/ext/rugged/vendor/libgit2-dist/src/signature.h +18 -0
  152. data/ext/rugged/vendor/libgit2-dist/src/status.c +696 -0
  153. data/ext/rugged/vendor/libgit2-dist/src/tag.c +446 -0
  154. data/ext/rugged/vendor/libgit2-dist/src/tag.h +28 -0
  155. data/ext/rugged/vendor/libgit2-dist/src/thread-utils.c +55 -0
  156. data/ext/rugged/vendor/libgit2-dist/src/thread-utils.h +108 -0
  157. data/ext/rugged/vendor/libgit2-dist/src/transport.c +85 -0
  158. data/ext/rugged/vendor/libgit2-dist/src/transport.h +110 -0
  159. data/ext/rugged/vendor/libgit2-dist/src/transports/git.c +502 -0
  160. data/ext/rugged/vendor/libgit2-dist/src/transports/http.c +756 -0
  161. data/ext/rugged/vendor/libgit2-dist/src/transports/local.c +235 -0
  162. data/ext/rugged/vendor/libgit2-dist/src/tree-cache.c +201 -0
  163. data/ext/rugged/vendor/libgit2-dist/src/tree-cache.h +31 -0
  164. data/ext/rugged/vendor/libgit2-dist/src/tree.c +758 -0
  165. data/ext/rugged/vendor/libgit2-dist/src/tree.h +37 -0
  166. data/ext/rugged/vendor/libgit2-dist/src/tsort.c +365 -0
  167. data/ext/rugged/vendor/libgit2-dist/src/unix/map.c +70 -0
  168. data/ext/rugged/vendor/libgit2-dist/src/unix/posix.h +25 -0
  169. data/ext/rugged/vendor/libgit2-dist/src/util.c +381 -0
  170. data/ext/rugged/vendor/libgit2-dist/src/util.h +137 -0
  171. data/ext/rugged/vendor/libgit2-dist/src/vector.c +174 -0
  172. data/ext/rugged/vendor/libgit2-dist/src/vector.h +45 -0
  173. data/ext/rugged/vendor/libgit2-dist/src/win32/dir.c +115 -0
  174. data/ext/rugged/vendor/libgit2-dist/src/win32/fnmatch.c +180 -0
  175. data/ext/rugged/vendor/libgit2-dist/src/win32/fnmatch.h +27 -0
  176. data/ext/rugged/vendor/libgit2-dist/src/win32/map.c +131 -0
  177. data/ext/rugged/vendor/libgit2-dist/src/win32/mingw-compat.h +24 -0
  178. data/ext/rugged/vendor/libgit2-dist/src/win32/msvc-compat.h +38 -0
  179. data/ext/rugged/vendor/libgit2-dist/src/win32/posix.h +53 -0
  180. data/ext/rugged/vendor/libgit2-dist/src/win32/posix_w32.c +404 -0
  181. data/ext/rugged/vendor/libgit2-dist/src/win32/pthread.c +65 -0
  182. data/ext/rugged/vendor/libgit2-dist/src/win32/pthread.h +40 -0
  183. data/ext/rugged/vendor/libgit2-dist/src/win32/utf-conv.c +88 -0
  184. data/ext/rugged/vendor/libgit2-dist/src/win32/utf-conv.h +17 -0
  185. data/ext/rugged/vendor/libgit2-dist/tests-clay/buf/basic.c +29 -0
  186. data/ext/rugged/vendor/libgit2-dist/tests-clay/clay.h +187 -0
  187. data/ext/rugged/vendor/libgit2-dist/tests-clay/clay_libgit2.h +28 -0
  188. data/ext/rugged/vendor/libgit2-dist/tests-clay/clay_main.c +1073 -0
  189. data/ext/rugged/vendor/libgit2-dist/tests-clay/config/add.c +37 -0
  190. data/ext/rugged/vendor/libgit2-dist/tests-clay/config/new.c +36 -0
  191. data/ext/rugged/vendor/libgit2-dist/tests-clay/config/read.c +209 -0
  192. data/ext/rugged/vendor/libgit2-dist/tests-clay/config/stress.c +39 -0
  193. data/ext/rugged/vendor/libgit2-dist/tests-clay/config/write.c +77 -0
  194. data/ext/rugged/vendor/libgit2-dist/tests-clay/core/dirent.c +222 -0
  195. data/ext/rugged/vendor/libgit2-dist/tests-clay/core/filebuf.c +106 -0
  196. data/ext/rugged/vendor/libgit2-dist/tests-clay/core/oid.c +18 -0
  197. data/ext/rugged/vendor/libgit2-dist/tests-clay/core/path.c +139 -0
  198. data/ext/rugged/vendor/libgit2-dist/tests-clay/core/rmdir.c +50 -0
  199. data/ext/rugged/vendor/libgit2-dist/tests-clay/core/string.c +28 -0
  200. data/ext/rugged/vendor/libgit2-dist/tests-clay/core/strtol.c +37 -0
  201. data/ext/rugged/vendor/libgit2-dist/tests-clay/core/vector.c +66 -0
  202. data/ext/rugged/vendor/libgit2-dist/tests-clay/index/rename.c +60 -0
  203. data/ext/rugged/vendor/libgit2-dist/tests-clay/network/remotes.c +50 -0
  204. data/ext/rugged/vendor/libgit2-dist/tests-clay/object/raw/chars.c +52 -0
  205. data/ext/rugged/vendor/libgit2-dist/tests-clay/object/raw/compare.c +124 -0
  206. data/ext/rugged/vendor/libgit2-dist/tests-clay/object/raw/convert.c +75 -0
  207. data/ext/rugged/vendor/libgit2-dist/tests-clay/object/raw/data.h +323 -0
  208. data/ext/rugged/vendor/libgit2-dist/tests-clay/object/raw/fromstr.c +30 -0
  209. data/ext/rugged/vendor/libgit2-dist/tests-clay/object/raw/hash.c +162 -0
  210. data/ext/rugged/vendor/libgit2-dist/tests-clay/object/raw/short.c +94 -0
  211. data/ext/rugged/vendor/libgit2-dist/tests-clay/object/raw/size.c +13 -0
  212. data/ext/rugged/vendor/libgit2-dist/tests-clay/object/raw/type2string.c +54 -0
  213. data/ext/rugged/vendor/libgit2-dist/tests-clay/object/tree/frompath.c +75 -0
  214. data/ext/rugged/vendor/libgit2-dist/tests-clay/odb/loose.c +84 -0
  215. data/ext/rugged/vendor/libgit2-dist/tests-clay/odb/loose_data.h +522 -0
  216. data/ext/rugged/vendor/libgit2-dist/tests-clay/odb/pack_data.h +151 -0
  217. data/ext/rugged/vendor/libgit2-dist/tests-clay/odb/packed.c +78 -0
  218. data/ext/rugged/vendor/libgit2-dist/tests-clay/odb/sorting.c +71 -0
  219. data/ext/rugged/vendor/libgit2-dist/tests-clay/repo/getters.c +68 -0
  220. data/ext/rugged/vendor/libgit2-dist/tests-clay/repo/init.c +104 -0
  221. data/ext/rugged/vendor/libgit2-dist/tests-clay/repo/open.c +54 -0
  222. data/ext/rugged/vendor/libgit2-dist/tests-clay/status/single.c +38 -0
  223. data/ext/rugged/vendor/libgit2-dist/tests-clay/status/status_data.h +48 -0
  224. data/ext/rugged/vendor/libgit2-dist/tests-clay/status/worktree.c +124 -0
  225. data/ext/rugged/vendor/libgit2-dist/tests/t00-core.c +628 -0
  226. data/ext/rugged/vendor/libgit2-dist/tests/t01-data.h +322 -0
  227. data/ext/rugged/vendor/libgit2-dist/tests/t01-rawobj.c +638 -0
  228. data/ext/rugged/vendor/libgit2-dist/tests/t03-data.h +344 -0
  229. data/ext/rugged/vendor/libgit2-dist/tests/t03-objwrite.c +255 -0
  230. data/ext/rugged/vendor/libgit2-dist/tests/t04-commit.c +788 -0
  231. data/ext/rugged/vendor/libgit2-dist/tests/t05-revwalk.c +140 -0
  232. data/ext/rugged/vendor/libgit2-dist/tests/t06-index.c +219 -0
  233. data/ext/rugged/vendor/libgit2-dist/tests/t07-hashtable.c +192 -0
  234. data/ext/rugged/vendor/libgit2-dist/tests/t08-tag.c +357 -0
  235. data/ext/rugged/vendor/libgit2-dist/tests/t09-tree.c +221 -0
  236. data/ext/rugged/vendor/libgit2-dist/tests/t10-refs.c +1294 -0
  237. data/ext/rugged/vendor/libgit2-dist/tests/t12-repo.c +174 -0
  238. data/ext/rugged/vendor/libgit2-dist/tests/t13-threads.c +41 -0
  239. data/ext/rugged/vendor/libgit2-dist/tests/t17-bufs.c +61 -0
  240. data/ext/rugged/vendor/libgit2-dist/tests/t18-status.c +448 -0
  241. data/ext/rugged/vendor/libgit2-dist/tests/test_helpers.c +310 -0
  242. data/ext/rugged/vendor/libgit2-dist/tests/test_helpers.h +83 -0
  243. data/ext/rugged/vendor/libgit2-dist/tests/test_lib.c +198 -0
  244. data/ext/rugged/vendor/libgit2-dist/tests/test_lib.h +54 -0
  245. data/ext/rugged/vendor/libgit2-dist/tests/test_main.c +89 -0
  246. data/lib/rugged.rb +4 -3
  247. data/lib/rugged/index.rb +0 -8
  248. data/lib/rugged/objects.rb +45 -0
  249. data/lib/rugged/repository.rb +29 -0
  250. data/lib/rugged/tree.rb +16 -6
  251. data/lib/rugged/version.rb +1 -1
  252. data/lib/rugged/walker.rb +5 -0
  253. data/test/blob_test.rb +18 -14
  254. data/test/commit_test.rb +28 -26
  255. data/test/coverage/HEAD.json +1 -0
  256. data/test/coverage/cover.rb +106 -0
  257. data/test/fixtures/testrepo.git/refs/heads/new_name +1 -0
  258. data/test/index_test.rb +101 -78
  259. data/test/lib_test.rb +4 -4
  260. data/test/object_test.rb +3 -3
  261. data/test/reference_test.rb +75 -0
  262. data/test/remote_test.rb +19 -0
  263. data/test/repo_pack_test.rb +4 -4
  264. data/test/repo_test.rb +44 -15
  265. data/test/tag_test.rb +7 -17
  266. data/test/test_helper.rb +24 -5
  267. data/test/tree_test.rb +30 -12
  268. data/test/walker_test.rb +40 -31
  269. metadata +273 -50
  270. data/lib/rugged/person.rb +0 -20
  271. data/lib/rugged/tree_entry.rb +0 -9
  272. data/test/fixtures/testrepo.git/objects/1d/83f106355e4309a293e42ad2a2c4b8bdbe77ae +0 -0
  273. data/test/fixtures/testrepo.git/objects/2f/3321418db5b2a841375b8b70880a8ab5a4148f +0 -0
  274. data/test/fixtures/testrepo.git/objects/36/9b00a7700cca3a506d79e301d6ad8bf735d9ee +0 -3
  275. data/test/fixtures/testrepo.git/objects/3d/b1b5ceace59ff65279757003763046fd4cbbe6 +0 -0
  276. data/test/fixtures/testrepo.git/objects/4c/d1604907792e2c43e03dcec1216f99d63e68c4 +0 -3
  277. data/test/fixtures/testrepo.git/objects/e0/f46d77041c149296549b01ed4a18b02c4b7400 +0 -0
@@ -0,0 +1,36 @@
1
+ /*
2
+ * Copyright (C) 2009-2011 the libgit2 contributors
3
+ *
4
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
5
+ * a Linking Exception. For full terms see the included COPYING file.
6
+ */
7
+ #ifndef INCLUDE_netops_h__
8
+ #define INCLUDE_netops_h__
9
+
10
+ #ifndef GIT_WIN32
11
+ typedef int GIT_SOCKET;
12
+ #else
13
+ typedef SOCKET GIT_SOCKET;
14
+ #endif
15
+
16
+ typedef struct gitno_buffer {
17
+ char *data;
18
+ size_t len;
19
+ size_t offset;
20
+ GIT_SOCKET fd;
21
+ } gitno_buffer;
22
+
23
+ void gitno_buffer_setup(gitno_buffer *buf, char *data, unsigned int len, int fd);
24
+ int gitno_recv(gitno_buffer *buf);
25
+ void gitno_consume(gitno_buffer *buf, const char *ptr);
26
+ void gitno_consume_n(gitno_buffer *buf, size_t cons);
27
+
28
+ int gitno_connect(const char *host, const char *port);
29
+ int gitno_send(GIT_SOCKET s, const char *msg, size_t len, int flags);
30
+ int gitno_close(GIT_SOCKET s);
31
+ int gitno_send_chunk_size(int s, size_t len);
32
+ int gitno_select_in(gitno_buffer *buf, long int sec, long int usec);
33
+
34
+ int gitno_extract_host_and_port(char **host, char **port, const char *url, const char *default_port);
35
+
36
+ #endif
@@ -0,0 +1,295 @@
1
+ /*
2
+ * Copyright (C) 2009-2011 the libgit2 contributors
3
+ *
4
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
5
+ * a Linking Exception. For full terms see the included COPYING file.
6
+ */
7
+ #include <stdarg.h>
8
+
9
+ #include "git2/object.h"
10
+
11
+ #include "common.h"
12
+ #include "repository.h"
13
+
14
+ #include "commit.h"
15
+ #include "tree.h"
16
+ #include "blob.h"
17
+ #include "tag.h"
18
+
19
+ static const int OBJECT_BASE_SIZE = 4096;
20
+
21
+ static struct {
22
+ const char *str; /* type name string */
23
+ int loose; /* valid loose object type flag */
24
+ size_t size; /* size in bytes of the object structure */
25
+ } git_objects_table[] = {
26
+ /* 0 = GIT_OBJ__EXT1 */
27
+ { "", 0, 0},
28
+
29
+ /* 1 = GIT_OBJ_COMMIT */
30
+ { "commit", 1, sizeof(struct git_commit)},
31
+
32
+ /* 2 = GIT_OBJ_TREE */
33
+ { "tree", 1, sizeof(struct git_tree) },
34
+
35
+ /* 3 = GIT_OBJ_BLOB */
36
+ { "blob", 1, sizeof(struct git_blob) },
37
+
38
+ /* 4 = GIT_OBJ_TAG */
39
+ { "tag", 1, sizeof(struct git_tag) },
40
+
41
+ /* 5 = GIT_OBJ__EXT2 */
42
+ { "", 0, 0 },
43
+
44
+ /* 6 = GIT_OBJ_OFS_DELTA */
45
+ { "OFS_DELTA", 0, 0 },
46
+
47
+ /* 7 = GIT_OBJ_REF_DELTA */
48
+ { "REF_DELTA", 0, 0 }
49
+ };
50
+
51
+ static int create_object(git_object **object_out, git_otype type)
52
+ {
53
+ git_object *object = NULL;
54
+
55
+ assert(object_out);
56
+
57
+ *object_out = NULL;
58
+
59
+ switch (type) {
60
+ case GIT_OBJ_COMMIT:
61
+ case GIT_OBJ_TAG:
62
+ case GIT_OBJ_BLOB:
63
+ case GIT_OBJ_TREE:
64
+ object = git__malloc(git_object__size(type));
65
+ if (object == NULL)
66
+ return GIT_ENOMEM;
67
+ memset(object, 0x0, git_object__size(type));
68
+ break;
69
+
70
+ default:
71
+ return git__throw(GIT_EINVALIDTYPE, "The given type is invalid");
72
+ }
73
+
74
+ object->type = type;
75
+
76
+ *object_out = object;
77
+ return GIT_SUCCESS;
78
+ }
79
+
80
+ int git_object_lookup_prefix(
81
+ git_object **object_out,
82
+ git_repository *repo,
83
+ const git_oid *id,
84
+ unsigned int len,
85
+ git_otype type)
86
+ {
87
+ git_object *object = NULL;
88
+ git_odb *odb = NULL;
89
+ git_odb_object *odb_obj;
90
+ int error = GIT_SUCCESS;
91
+
92
+ assert(repo && object_out && id);
93
+
94
+ if (len < GIT_OID_MINPREFIXLEN)
95
+ return git__throw(GIT_EAMBIGUOUSOIDPREFIX,
96
+ "Failed to lookup object. Prefix length is lower than %d.", GIT_OID_MINPREFIXLEN);
97
+
98
+ error = git_repository_odb__weakptr(&odb, repo);
99
+ if (error < GIT_SUCCESS)
100
+ return error;
101
+
102
+ if (len > GIT_OID_HEXSZ)
103
+ len = GIT_OID_HEXSZ;
104
+
105
+ if (len == GIT_OID_HEXSZ) {
106
+ /* We want to match the full id : we can first look up in the cache,
107
+ * since there is no need to check for non ambiguousity
108
+ */
109
+ object = git_cache_get(&repo->objects, id);
110
+ if (object != NULL) {
111
+ if (type != GIT_OBJ_ANY && type != object->type) {
112
+ git_object_free(object);
113
+ return git__throw(GIT_EINVALIDTYPE,
114
+ "Failed to lookup object. "
115
+ "The given type does not match the type on the ODB");
116
+ }
117
+
118
+ *object_out = object;
119
+ return GIT_SUCCESS;
120
+ }
121
+
122
+ /* Object was not found in the cache, let's explore the backends.
123
+ * We could just use git_odb_read_unique_short_oid,
124
+ * it is the same cost for packed and loose object backends,
125
+ * but it may be much more costly for sqlite and hiredis.
126
+ */
127
+ error = git_odb_read(&odb_obj, odb, id);
128
+ } else {
129
+ git_oid short_oid;
130
+
131
+ /* We copy the first len*4 bits from id and fill the remaining with 0s */
132
+ memcpy(short_oid.id, id->id, (len + 1) / 2);
133
+ if (len % 2)
134
+ short_oid.id[len / 2] &= 0xF0;
135
+ memset(short_oid.id + (len + 1) / 2, 0, (GIT_OID_HEXSZ - len) / 2);
136
+
137
+ /* If len < GIT_OID_HEXSZ (a strict short oid was given), we have
138
+ * 2 options :
139
+ * - We always search in the cache first. If we find that short oid is
140
+ * ambiguous, we can stop. But in all the other cases, we must then
141
+ * explore all the backends (to find an object if there was match,
142
+ * or to check that oid is not ambiguous if we have found 1 match in
143
+ * the cache)
144
+ * - We never explore the cache, go right to exploring the backends
145
+ * We chose the latter : we explore directly the backends.
146
+ */
147
+ error = git_odb_read_prefix(&odb_obj, odb, &short_oid, len);
148
+ }
149
+
150
+ if (error < GIT_SUCCESS)
151
+ return git__rethrow(error, "Failed to lookup object");
152
+
153
+ if (type != GIT_OBJ_ANY && type != odb_obj->raw.type) {
154
+ git_odb_object_free(odb_obj);
155
+ return git__throw(GIT_EINVALIDTYPE, "Failed to lookup object. The given type does not match the type on the ODB");
156
+ }
157
+
158
+ type = odb_obj->raw.type;
159
+
160
+ if ((error = create_object(&object, type)) < GIT_SUCCESS)
161
+ return git__rethrow(error, "Failed to lookup object");
162
+
163
+ /* Initialize parent object */
164
+ git_oid_cpy(&object->cached.oid, &odb_obj->cached.oid);
165
+ object->repo = repo;
166
+
167
+ switch (type) {
168
+ case GIT_OBJ_COMMIT:
169
+ error = git_commit__parse((git_commit *)object, odb_obj);
170
+ break;
171
+
172
+ case GIT_OBJ_TREE:
173
+ error = git_tree__parse((git_tree *)object, odb_obj);
174
+ break;
175
+
176
+ case GIT_OBJ_TAG:
177
+ error = git_tag__parse((git_tag *)object, odb_obj);
178
+ break;
179
+
180
+ case GIT_OBJ_BLOB:
181
+ error = git_blob__parse((git_blob *)object, odb_obj);
182
+ break;
183
+
184
+ default:
185
+ break;
186
+ }
187
+
188
+ git_odb_object_free(odb_obj);
189
+
190
+ if (error < GIT_SUCCESS) {
191
+ git_object__free(object);
192
+ return git__rethrow(error, "Failed to lookup object");
193
+ }
194
+
195
+ *object_out = git_cache_try_store(&repo->objects, object);
196
+ return GIT_SUCCESS;
197
+ }
198
+
199
+ int git_object_lookup(git_object **object_out, git_repository *repo, const git_oid *id, git_otype type) {
200
+ return git_object_lookup_prefix(object_out, repo, id, GIT_OID_HEXSZ, type);
201
+ }
202
+
203
+ void git_object__free(void *_obj)
204
+ {
205
+ git_object *object = (git_object *)_obj;
206
+
207
+ assert(object);
208
+
209
+ switch (object->type) {
210
+ case GIT_OBJ_COMMIT:
211
+ git_commit__free((git_commit *)object);
212
+ break;
213
+
214
+ case GIT_OBJ_TREE:
215
+ git_tree__free((git_tree *)object);
216
+ break;
217
+
218
+ case GIT_OBJ_TAG:
219
+ git_tag__free((git_tag *)object);
220
+ break;
221
+
222
+ case GIT_OBJ_BLOB:
223
+ git_blob__free((git_blob *)object);
224
+ break;
225
+
226
+ default:
227
+ git__free(object);
228
+ break;
229
+ }
230
+ }
231
+
232
+ void git_object_free(git_object *object)
233
+ {
234
+ if (object == NULL)
235
+ return;
236
+
237
+ git_cached_obj_decref((git_cached_obj *)object, git_object__free);
238
+ }
239
+
240
+ const git_oid *git_object_id(const git_object *obj)
241
+ {
242
+ assert(obj);
243
+ return &obj->cached.oid;
244
+ }
245
+
246
+ git_otype git_object_type(const git_object *obj)
247
+ {
248
+ assert(obj);
249
+ return obj->type;
250
+ }
251
+
252
+ git_repository *git_object_owner(const git_object *obj)
253
+ {
254
+ assert(obj);
255
+ return obj->repo;
256
+ }
257
+
258
+ const char *git_object_type2string(git_otype type)
259
+ {
260
+ if (type < 0 || ((size_t) type) >= ARRAY_SIZE(git_objects_table))
261
+ return "";
262
+
263
+ return git_objects_table[type].str;
264
+ }
265
+
266
+ git_otype git_object_string2type(const char *str)
267
+ {
268
+ size_t i;
269
+
270
+ if (!str || !*str)
271
+ return GIT_OBJ_BAD;
272
+
273
+ for (i = 0; i < ARRAY_SIZE(git_objects_table); i++)
274
+ if (!strcmp(str, git_objects_table[i].str))
275
+ return (git_otype)i;
276
+
277
+ return GIT_OBJ_BAD;
278
+ }
279
+
280
+ int git_object_typeisloose(git_otype type)
281
+ {
282
+ if (type < 0 || ((size_t) type) >= ARRAY_SIZE(git_objects_table))
283
+ return 0;
284
+
285
+ return git_objects_table[type].loose;
286
+ }
287
+
288
+ size_t git_object__size(git_otype type)
289
+ {
290
+ if (type < 0 || ((size_t) type) >= ARRAY_SIZE(git_objects_table))
291
+ return 0;
292
+
293
+ return git_objects_table[type].size;
294
+ }
295
+
@@ -0,0 +1,672 @@
1
+ /*
2
+ * Copyright (C) 2009-2011 the libgit2 contributors
3
+ *
4
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
5
+ * a Linking Exception. For full terms see the included COPYING file.
6
+ */
7
+
8
+ #include "common.h"
9
+ #include "git2/zlib.h"
10
+ #include "git2/object.h"
11
+ #include "fileops.h"
12
+ #include "hash.h"
13
+ #include "odb.h"
14
+ #include "delta-apply.h"
15
+
16
+ #include "git2/odb_backend.h"
17
+
18
+ #define GIT_ALTERNATES_FILE "info/alternates"
19
+
20
+ /* TODO: is this correct? */
21
+ #define GIT_LOOSE_PRIORITY 2
22
+ #define GIT_PACKED_PRIORITY 1
23
+
24
+ typedef struct
25
+ {
26
+ git_odb_backend *backend;
27
+ int priority;
28
+ int is_alternate;
29
+ } backend_internal;
30
+
31
+ static int format_object_header(char *hdr, size_t n, size_t obj_len, git_otype obj_type)
32
+ {
33
+ const char *type_str = git_object_type2string(obj_type);
34
+ int len = p_snprintf(hdr, n, "%s %"PRIuZ, type_str, obj_len);
35
+
36
+ if (len < 0 || ((size_t) len) >= n)
37
+ return git__throw(GIT_ERROR, "Cannot format object header. Length is out of bounds");
38
+
39
+ return len+1;
40
+ }
41
+
42
+ int git_odb__hash_obj(git_oid *id, git_rawobj *obj)
43
+ {
44
+ git_buf_vec vec[2];
45
+ char header[64];
46
+ int hdrlen;
47
+
48
+ assert(id && obj);
49
+
50
+ if (!git_object_typeisloose(obj->type))
51
+ return git__throw(GIT_ERROR, "Failed to hash object. Wrong object type");
52
+
53
+ if (!obj->data && obj->len != 0)
54
+ return git__throw(GIT_ERROR, "Failed to hash object. No data given");
55
+
56
+ if ((hdrlen = format_object_header(header, sizeof(header), obj->len, obj->type)) < 0)
57
+ return git__rethrow(hdrlen, "Failed to hash object");
58
+
59
+ vec[0].data = header;
60
+ vec[0].len = hdrlen;
61
+ vec[1].data = obj->data;
62
+ vec[1].len = obj->len;
63
+
64
+ git_hash_vec(id, vec, 2);
65
+
66
+ return GIT_SUCCESS;
67
+ }
68
+
69
+
70
+ static git_odb_object *new_odb_object(const git_oid *oid, git_rawobj *source)
71
+ {
72
+ git_odb_object *object = git__malloc(sizeof(git_odb_object));
73
+ memset(object, 0x0, sizeof(git_odb_object));
74
+
75
+ git_oid_cpy(&object->cached.oid, oid);
76
+ memcpy(&object->raw, source, sizeof(git_rawobj));
77
+
78
+ return object;
79
+ }
80
+
81
+ static void free_odb_object(void *o)
82
+ {
83
+ git_odb_object *object = (git_odb_object *)o;
84
+
85
+ if (object != NULL) {
86
+ git__free(object->raw.data);
87
+ git__free(object);
88
+ }
89
+ }
90
+
91
+ const git_oid *git_odb_object_id(git_odb_object *object)
92
+ {
93
+ return &object->cached.oid;
94
+ }
95
+
96
+ const void *git_odb_object_data(git_odb_object *object)
97
+ {
98
+ return object->raw.data;
99
+ }
100
+
101
+ size_t git_odb_object_size(git_odb_object *object)
102
+ {
103
+ return object->raw.len;
104
+ }
105
+
106
+ git_otype git_odb_object_type(git_odb_object *object)
107
+ {
108
+ return object->raw.type;
109
+ }
110
+
111
+ void git_odb_object_free(git_odb_object *object)
112
+ {
113
+ git_cached_obj_decref((git_cached_obj *)object, &free_odb_object);
114
+ }
115
+
116
+ int git_odb_hashfile(git_oid *out, const char *path, git_otype type)
117
+ {
118
+ int fd, hdr_len;
119
+ char hdr[64], buffer[2048];
120
+ git_off_t size;
121
+ git_hash_ctx *ctx;
122
+
123
+ if ((fd = p_open(path, O_RDONLY)) < 0)
124
+ return git__throw(GIT_ENOTFOUND, "Could not open '%s'", path);
125
+
126
+ if ((size = git_futils_filesize(fd)) < 0 || !git__is_sizet(size)) {
127
+ p_close(fd);
128
+ return git__throw(GIT_EOSERR, "'%s' appears to be corrupted", path);
129
+ }
130
+
131
+ hdr_len = format_object_header(hdr, sizeof(hdr), (size_t)size, type);
132
+ if (hdr_len < 0)
133
+ return git__throw(GIT_ERROR, "Failed to format blob header. Length is out of bounds");
134
+
135
+ ctx = git_hash_new_ctx();
136
+
137
+ git_hash_update(ctx, hdr, hdr_len);
138
+
139
+ while (size > 0) {
140
+ ssize_t read_len;
141
+
142
+ read_len = read(fd, buffer, sizeof(buffer));
143
+
144
+ if (read_len < 0) {
145
+ p_close(fd);
146
+ git_hash_free_ctx(ctx);
147
+ return git__throw(GIT_EOSERR, "Can't read full file '%s'", path);
148
+ }
149
+
150
+ git_hash_update(ctx, buffer, read_len);
151
+ size -= read_len;
152
+ }
153
+
154
+ p_close(fd);
155
+
156
+ git_hash_final(out, ctx);
157
+ git_hash_free_ctx(ctx);
158
+
159
+ return GIT_SUCCESS;
160
+ }
161
+
162
+ int git_odb_hash(git_oid *id, const void *data, size_t len, git_otype type)
163
+ {
164
+ git_rawobj raw;
165
+
166
+ assert(id);
167
+
168
+ raw.data = (void *)data;
169
+ raw.len = len;
170
+ raw.type = type;
171
+
172
+ return git_odb__hash_obj(id, &raw);
173
+ }
174
+
175
+ /**
176
+ * FAKE WSTREAM
177
+ */
178
+
179
+ typedef struct {
180
+ git_odb_stream stream;
181
+ char *buffer;
182
+ size_t size, written;
183
+ git_otype type;
184
+ } fake_wstream;
185
+
186
+ static int fake_wstream__fwrite(git_oid *oid, git_odb_stream *_stream)
187
+ {
188
+ fake_wstream *stream = (fake_wstream *)_stream;
189
+ return _stream->backend->write(oid, _stream->backend, stream->buffer, stream->size, stream->type);
190
+ }
191
+
192
+ static int fake_wstream__write(git_odb_stream *_stream, const char *data, size_t len)
193
+ {
194
+ fake_wstream *stream = (fake_wstream *)_stream;
195
+
196
+ if (stream->written + len > stream->size)
197
+ return GIT_ENOMEM;
198
+
199
+ memcpy(stream->buffer + stream->written, data, len);
200
+ stream->written += len;
201
+ return GIT_SUCCESS;
202
+ }
203
+
204
+ static void fake_wstream__free(git_odb_stream *_stream)
205
+ {
206
+ fake_wstream *stream = (fake_wstream *)_stream;
207
+
208
+ git__free(stream->buffer);
209
+ git__free(stream);
210
+ }
211
+
212
+ static int init_fake_wstream(git_odb_stream **stream_p, git_odb_backend *backend, size_t size, git_otype type)
213
+ {
214
+ fake_wstream *stream;
215
+
216
+ stream = git__calloc(1, sizeof(fake_wstream));
217
+ if (stream == NULL)
218
+ return GIT_ENOMEM;
219
+
220
+ stream->size = size;
221
+ stream->type = type;
222
+ stream->buffer = git__malloc(size);
223
+ if (stream->buffer == NULL) {
224
+ git__free(stream);
225
+ return GIT_ENOMEM;
226
+ }
227
+
228
+ stream->stream.backend = backend;
229
+ stream->stream.read = NULL; /* read only */
230
+ stream->stream.write = &fake_wstream__write;
231
+ stream->stream.finalize_write = &fake_wstream__fwrite;
232
+ stream->stream.free = &fake_wstream__free;
233
+ stream->stream.mode = GIT_STREAM_WRONLY;
234
+
235
+ *stream_p = (git_odb_stream *)stream;
236
+ return GIT_SUCCESS;
237
+ }
238
+
239
+ /***********************************************************
240
+ *
241
+ * OBJECT DATABASE PUBLIC API
242
+ *
243
+ * Public calls for the ODB functionality
244
+ *
245
+ ***********************************************************/
246
+
247
+ static int backend_sort_cmp(const void *a, const void *b)
248
+ {
249
+ const backend_internal *backend_a = (const backend_internal *)(a);
250
+ const backend_internal *backend_b = (const backend_internal *)(b);
251
+
252
+ if (backend_a->is_alternate == backend_b->is_alternate)
253
+ return (backend_b->priority - backend_a->priority);
254
+
255
+ return backend_a->is_alternate ? 1 : -1;
256
+ }
257
+
258
+ int git_odb_new(git_odb **out)
259
+ {
260
+ int error;
261
+
262
+ git_odb *db = git__calloc(1, sizeof(*db));
263
+ if (!db)
264
+ return GIT_ENOMEM;
265
+
266
+ error = git_cache_init(&db->cache, GIT_DEFAULT_CACHE_SIZE, &free_odb_object);
267
+ if (error < GIT_SUCCESS) {
268
+ git__free(db);
269
+ return git__rethrow(error, "Failed to create object database");
270
+ }
271
+
272
+ if ((error = git_vector_init(&db->backends, 4, backend_sort_cmp)) < GIT_SUCCESS) {
273
+ git__free(db);
274
+ return git__rethrow(error, "Failed to create object database");
275
+ }
276
+
277
+ *out = db;
278
+ GIT_REFCOUNT_INC(db);
279
+ return GIT_SUCCESS;
280
+ }
281
+
282
+ static int add_backend_internal(git_odb *odb, git_odb_backend *backend, int priority, int is_alternate)
283
+ {
284
+ backend_internal *internal;
285
+
286
+ assert(odb && backend);
287
+
288
+ if (backend->odb != NULL && backend->odb != odb)
289
+ return git__throw(GIT_EBUSY, "The backend is already owned by another ODB");
290
+
291
+ internal = git__malloc(sizeof(backend_internal));
292
+ if (internal == NULL)
293
+ return GIT_ENOMEM;
294
+
295
+ internal->backend = backend;
296
+ internal->priority = priority;
297
+ internal->is_alternate = is_alternate;
298
+
299
+ if (git_vector_insert(&odb->backends, internal) < 0) {
300
+ git__free(internal);
301
+ return GIT_ENOMEM;
302
+ }
303
+
304
+ git_vector_sort(&odb->backends);
305
+ internal->backend->odb = odb;
306
+ return GIT_SUCCESS;
307
+ }
308
+
309
+ int git_odb_add_backend(git_odb *odb, git_odb_backend *backend, int priority)
310
+ {
311
+ return add_backend_internal(odb, backend, priority, 0);
312
+ }
313
+
314
+ int git_odb_add_alternate(git_odb *odb, git_odb_backend *backend, int priority)
315
+ {
316
+ return add_backend_internal(odb, backend, priority, 1);
317
+ }
318
+
319
+ static int add_default_backends(git_odb *db, const char *objects_dir, int as_alternates)
320
+ {
321
+ git_odb_backend *loose, *packed;
322
+ int error;
323
+
324
+ /* add the loose object backend */
325
+ error = git_odb_backend_loose(&loose, objects_dir, -1, 0);
326
+ if (error < GIT_SUCCESS)
327
+ return error;
328
+
329
+ error = add_backend_internal(db, loose, GIT_LOOSE_PRIORITY, as_alternates);
330
+ if (error < GIT_SUCCESS)
331
+ return git__rethrow(error, "Failed to add backend");
332
+
333
+ /* add the packed file backend */
334
+ error = git_odb_backend_pack(&packed, objects_dir);
335
+ if (error < GIT_SUCCESS)
336
+ return error;
337
+
338
+ error = add_backend_internal(db, packed, GIT_PACKED_PRIORITY, as_alternates);
339
+ if (error < GIT_SUCCESS)
340
+ return git__rethrow(error, "Failed to add backend");
341
+
342
+ return GIT_SUCCESS;
343
+ }
344
+
345
+ static int load_alternates(git_odb *odb, const char *objects_dir)
346
+ {
347
+ char alternates_path[GIT_PATH_MAX];
348
+ char *buffer, *alternate;
349
+
350
+ git_fbuffer alternates_buf = GIT_FBUFFER_INIT;
351
+ int error;
352
+
353
+ git_path_join(alternates_path, objects_dir, GIT_ALTERNATES_FILE);
354
+
355
+ if (git_futils_exists(alternates_path) < GIT_SUCCESS)
356
+ return GIT_SUCCESS;
357
+
358
+ if (git_futils_readbuffer(&alternates_buf, alternates_path) < GIT_SUCCESS)
359
+ return git__throw(GIT_EOSERR, "Failed to add backend. Can't read alternates");
360
+
361
+ buffer = (char *)alternates_buf.data;
362
+ error = GIT_SUCCESS;
363
+
364
+ /* add each alternate as a new backend; one alternate per line */
365
+ while ((alternate = git__strtok(&buffer, "\r\n")) != NULL) {
366
+ char full_path[GIT_PATH_MAX];
367
+
368
+ if (*alternate == '\0' || *alternate == '#')
369
+ continue;
370
+
371
+ /* relative path: build based on the current `objects` folder */
372
+ if (*alternate == '.') {
373
+ git_path_join(full_path, objects_dir, alternate);
374
+ alternate = full_path;
375
+ }
376
+
377
+ if ((error = add_default_backends(odb, alternate, 1)) < GIT_SUCCESS)
378
+ break;
379
+ }
380
+
381
+ git_futils_freebuffer(&alternates_buf);
382
+ if (error < GIT_SUCCESS)
383
+ return git__rethrow(error, "Failed to load alternates");
384
+ return error;
385
+ }
386
+
387
+ int git_odb_open(git_odb **out, const char *objects_dir)
388
+ {
389
+ git_odb *db;
390
+ int error;
391
+
392
+ assert(out && objects_dir);
393
+
394
+ *out = NULL;
395
+
396
+ if ((error = git_odb_new(&db)) < 0)
397
+ return git__rethrow(error, "Failed to open ODB");
398
+
399
+ if ((error = add_default_backends(db, objects_dir, 0)) < GIT_SUCCESS)
400
+ goto cleanup;
401
+
402
+ if ((error = load_alternates(db, objects_dir)) < GIT_SUCCESS)
403
+ goto cleanup;
404
+
405
+ *out = db;
406
+ return GIT_SUCCESS;
407
+
408
+ cleanup:
409
+ git_odb_free(db);
410
+ return error; /* error already set - pass through */
411
+ }
412
+
413
+ static void odb_free(git_odb *db)
414
+ {
415
+ unsigned int i;
416
+
417
+ for (i = 0; i < db->backends.length; ++i) {
418
+ backend_internal *internal = git_vector_get(&db->backends, i);
419
+ git_odb_backend *backend = internal->backend;
420
+
421
+ if (backend->free) backend->free(backend);
422
+ else git__free(backend);
423
+
424
+ git__free(internal);
425
+ }
426
+
427
+ git_vector_free(&db->backends);
428
+ git_cache_free(&db->cache);
429
+ git__free(db);
430
+ }
431
+
432
+ void git_odb_free(git_odb *db)
433
+ {
434
+ if (db == NULL)
435
+ return;
436
+
437
+ GIT_REFCOUNT_DEC(db, odb_free);
438
+ }
439
+
440
+ int git_odb_exists(git_odb *db, const git_oid *id)
441
+ {
442
+ git_odb_object *object;
443
+ unsigned int i;
444
+ int found = 0;
445
+
446
+ assert(db && id);
447
+
448
+ if ((object = git_cache_get(&db->cache, id)) != NULL) {
449
+ git_odb_object_free(object);
450
+ return 1;
451
+ }
452
+
453
+ for (i = 0; i < db->backends.length && !found; ++i) {
454
+ backend_internal *internal = git_vector_get(&db->backends, i);
455
+ git_odb_backend *b = internal->backend;
456
+
457
+ if (b->exists != NULL)
458
+ found = b->exists(b, id);
459
+ }
460
+
461
+ return found;
462
+ }
463
+
464
+ int git_odb_read_header(size_t *len_p, git_otype *type_p, git_odb *db, const git_oid *id)
465
+ {
466
+ unsigned int i;
467
+ int error = GIT_ENOTFOUND;
468
+ git_odb_object *object;
469
+
470
+ assert(db && id);
471
+
472
+ if ((object = git_cache_get(&db->cache, id)) != NULL) {
473
+ *len_p = object->raw.len;
474
+ *type_p = object->raw.type;
475
+ git_odb_object_free(object);
476
+ return GIT_SUCCESS;
477
+ }
478
+
479
+ for (i = 0; i < db->backends.length && error < 0; ++i) {
480
+ backend_internal *internal = git_vector_get(&db->backends, i);
481
+ git_odb_backend *b = internal->backend;
482
+
483
+ if (b->read_header != NULL)
484
+ error = b->read_header(len_p, type_p, b, id);
485
+ }
486
+
487
+ if (error == GIT_EPASSTHROUGH)
488
+ return GIT_SUCCESS;
489
+
490
+ /*
491
+ * no backend could read only the header.
492
+ * try reading the whole object and freeing the contents
493
+ */
494
+ if (error < 0) {
495
+ if ((error = git_odb_read(&object, db, id)) < GIT_SUCCESS)
496
+ return error; /* error already set - pass through */
497
+
498
+ *len_p = object->raw.len;
499
+ *type_p = object->raw.type;
500
+ git_odb_object_free(object);
501
+ }
502
+
503
+ return GIT_SUCCESS;
504
+ }
505
+
506
+ int git_odb_read(git_odb_object **out, git_odb *db, const git_oid *id)
507
+ {
508
+ unsigned int i;
509
+ int error = GIT_ENOTFOUND;
510
+ git_rawobj raw;
511
+
512
+ assert(out && db && id);
513
+
514
+ *out = git_cache_get(&db->cache, id);
515
+ if (*out != NULL)
516
+ return GIT_SUCCESS;
517
+
518
+ for (i = 0; i < db->backends.length && error < 0; ++i) {
519
+ backend_internal *internal = git_vector_get(&db->backends, i);
520
+ git_odb_backend *b = internal->backend;
521
+
522
+ if (b->read != NULL)
523
+ error = b->read(&raw.data, &raw.len, &raw.type, b, id);
524
+ }
525
+
526
+ if (error == GIT_EPASSTHROUGH || error == GIT_SUCCESS) {
527
+ *out = git_cache_try_store(&db->cache, new_odb_object(id, &raw));
528
+ return GIT_SUCCESS;
529
+ }
530
+
531
+ return git__rethrow(error, "Failed to read object");
532
+ }
533
+
534
+ int git_odb_read_prefix(git_odb_object **out, git_odb *db, const git_oid *short_id, unsigned int len)
535
+ {
536
+ unsigned int i;
537
+ int error = GIT_ENOTFOUND;
538
+ git_oid full_oid;
539
+ git_rawobj raw;
540
+ int found = 0;
541
+
542
+ assert(out && db);
543
+
544
+ if (len < GIT_OID_MINPREFIXLEN)
545
+ return git__throw(GIT_EAMBIGUOUSOIDPREFIX, "Failed to lookup object. Prefix length is lower than %d.", GIT_OID_MINPREFIXLEN);
546
+
547
+ if (len > GIT_OID_HEXSZ)
548
+ len = GIT_OID_HEXSZ;
549
+
550
+ if (len == GIT_OID_HEXSZ) {
551
+ *out = git_cache_get(&db->cache, short_id);
552
+ if (*out != NULL)
553
+ return GIT_SUCCESS;
554
+ }
555
+
556
+ for (i = 0; i < db->backends.length && found < 2; ++i) {
557
+ backend_internal *internal = git_vector_get(&db->backends, i);
558
+ git_odb_backend *b = internal->backend;
559
+
560
+ if (b->read != NULL) {
561
+ error = b->read_prefix(&full_oid, &raw.data, &raw.len, &raw.type, b, short_id, len);
562
+ switch (error) {
563
+ case GIT_SUCCESS:
564
+ found++;
565
+ break;
566
+ case GIT_ENOTFOUND:
567
+ case GIT_EPASSTHROUGH:
568
+ break;
569
+ case GIT_EAMBIGUOUSOIDPREFIX:
570
+ return git__rethrow(error, "Failed to read object. Ambiguous sha1 prefix");
571
+ default:
572
+ return git__rethrow(error, "Failed to read object");
573
+ }
574
+ }
575
+ }
576
+
577
+ if (found == 1) {
578
+ *out = git_cache_try_store(&db->cache, new_odb_object(&full_oid, &raw));
579
+ } else if (found > 1) {
580
+ return git__throw(GIT_EAMBIGUOUSOIDPREFIX, "Failed to read object. Ambiguous sha1 prefix");
581
+ } else {
582
+ return git__throw(GIT_ENOTFOUND, "Failed to read object. Object not found");
583
+ }
584
+
585
+ return GIT_SUCCESS;
586
+ }
587
+
588
+ int git_odb_write(git_oid *oid, git_odb *db, const void *data, size_t len, git_otype type)
589
+ {
590
+ unsigned int i;
591
+ int error = GIT_ERROR;
592
+ git_odb_stream *stream;
593
+
594
+ assert(oid && db);
595
+
596
+ for (i = 0; i < db->backends.length && error < 0; ++i) {
597
+ backend_internal *internal = git_vector_get(&db->backends, i);
598
+ git_odb_backend *b = internal->backend;
599
+
600
+ /* we don't write in alternates! */
601
+ if (internal->is_alternate)
602
+ continue;
603
+
604
+ if (b->write != NULL)
605
+ error = b->write(oid, b, data, len, type);
606
+ }
607
+
608
+ if (error == GIT_EPASSTHROUGH || error == GIT_SUCCESS)
609
+ return GIT_SUCCESS;
610
+
611
+ /* if no backends were able to write the object directly, we try a streaming
612
+ * write to the backends; just write the whole object into the stream in one
613
+ * push */
614
+
615
+ if ((error = git_odb_open_wstream(&stream, db, len, type)) == GIT_SUCCESS) {
616
+ stream->write(stream, data, len);
617
+ error = stream->finalize_write(oid, stream);
618
+ stream->free(stream);
619
+ return GIT_SUCCESS;
620
+ }
621
+
622
+ return git__rethrow(error, "Failed to write object");
623
+ }
624
+
625
+ int git_odb_open_wstream(git_odb_stream **stream, git_odb *db, size_t size, git_otype type)
626
+ {
627
+ unsigned int i;
628
+ int error = GIT_ERROR;
629
+
630
+ assert(stream && db);
631
+
632
+ for (i = 0; i < db->backends.length && error < 0; ++i) {
633
+ backend_internal *internal = git_vector_get(&db->backends, i);
634
+ git_odb_backend *b = internal->backend;
635
+
636
+ /* we don't write in alternates! */
637
+ if (internal->is_alternate)
638
+ continue;
639
+
640
+ if (b->writestream != NULL)
641
+ error = b->writestream(stream, b, size, type);
642
+ else if (b->write != NULL)
643
+ error = init_fake_wstream(stream, b, size, type);
644
+ }
645
+
646
+ if (error == GIT_EPASSTHROUGH || error == GIT_SUCCESS)
647
+ return GIT_SUCCESS;
648
+
649
+ return git__rethrow(error, "Failed to open write stream");
650
+ }
651
+
652
+ int git_odb_open_rstream(git_odb_stream **stream, git_odb *db, const git_oid *oid)
653
+ {
654
+ unsigned int i;
655
+ int error = GIT_ERROR;
656
+
657
+ assert(stream && db);
658
+
659
+ for (i = 0; i < db->backends.length && error < 0; ++i) {
660
+ backend_internal *internal = git_vector_get(&db->backends, i);
661
+ git_odb_backend *b = internal->backend;
662
+
663
+ if (b->readstream != NULL)
664
+ error = b->readstream(stream, b, oid);
665
+ }
666
+
667
+ if (error == GIT_EPASSTHROUGH || error == GIT_SUCCESS)
668
+ return GIT_SUCCESS;
669
+
670
+ return git__rethrow(error, "Failed to open read stream");
671
+ }
672
+