rugged 0.17.0.b7 → 0.18.0.b1

Sign up to get free protection for your applications and to get access to all the features.
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.
@@ -10,16 +10,34 @@
10
10
  #include "git2/repository.h"
11
11
  #include "git2/object.h"
12
12
  #include "git2/tag.h"
13
+ #include "git2/transport.h"
14
+ #include "git2/revwalk.h"
15
+ #include "git2/odb_backend.h"
16
+ #include "git2/pack.h"
17
+ #include "git2/commit.h"
18
+ #include "git2/revparse.h"
19
+ #include "git2/push.h"
20
+ #include "pack-objects.h"
13
21
  #include "refs.h"
14
- #include "transport.h"
15
22
  #include "posix.h"
16
23
  #include "path.h"
17
24
  #include "buffer.h"
18
- #include "pkt.h"
25
+ #include "repository.h"
26
+ #include "odb.h"
27
+ #include "push.h"
28
+ #include "remote.h"
19
29
 
20
30
  typedef struct {
21
31
  git_transport parent;
32
+ git_remote *owner;
33
+ char *url;
34
+ int direction;
35
+ int flags;
36
+ git_atomic cancelled;
22
37
  git_repository *repo;
38
+ git_vector refs;
39
+ unsigned connected : 1,
40
+ have_refs : 1;
23
41
  } transport_local;
24
42
 
25
43
  static int add_ref(transport_local *t, const char *name)
@@ -27,32 +45,32 @@ static int add_ref(transport_local *t, const char *name)
27
45
  const char peeled[] = "^{}";
28
46
  git_remote_head *head;
29
47
  git_object *obj = NULL, *target = NULL;
30
- git_transport *transport = (git_transport *) t;
31
48
  git_buf buf = GIT_BUF_INIT;
32
- git_pkt_ref *pkt;
49
+ int error;
33
50
 
34
- head = git__malloc(sizeof(git_remote_head));
51
+ head = git__calloc(1, sizeof(git_remote_head));
35
52
  GITERR_CHECK_ALLOC(head);
36
- pkt = git__malloc(sizeof(git_pkt_ref));
37
- GITERR_CHECK_ALLOC(pkt);
38
53
 
39
54
  head->name = git__strdup(name);
40
55
  GITERR_CHECK_ALLOC(head->name);
41
56
 
42
- if (git_reference_name_to_oid(&head->oid, t->repo, name) < 0) {
57
+ error = git_reference_name_to_id(&head->oid, t->repo, name);
58
+ if (error < 0) {
59
+ git__free(head->name);
43
60
  git__free(head);
44
- git__free(pkt->head.name);
45
- git__free(pkt);
61
+ if (!strcmp(name, GIT_HEAD_FILE) && error == GIT_ENOTFOUND) {
62
+ /* This is actually okay. Empty repos often have a HEAD that points to
63
+ * a nonexistent "refs/heads/master". */
64
+ giterr_clear();
65
+ return 0;
66
+ }
67
+ return error;
46
68
  }
47
69
 
48
- pkt->type = GIT_PKT_REF;
49
- memcpy(&pkt->head, head, sizeof(git_remote_head));
50
- git__free(head);
51
-
52
- if (git_vector_insert(&transport->refs, pkt) < 0)
70
+ if (git_vector_insert(&t->refs, head) < 0)
53
71
  {
54
- git__free(pkt->head.name);
55
- git__free(pkt);
72
+ git__free(head->name);
73
+ git__free(head);
56
74
  return -1;
57
75
  }
58
76
 
@@ -60,39 +78,35 @@ static int add_ref(transport_local *t, const char *name)
60
78
  if (git__prefixcmp(name, GIT_REFS_TAGS_DIR))
61
79
  return 0;
62
80
 
63
- if (git_object_lookup(&obj, t->repo, &pkt->head.oid, GIT_OBJ_ANY) < 0)
81
+ if (git_object_lookup(&obj, t->repo, &head->oid, GIT_OBJ_ANY) < 0)
64
82
  return -1;
65
83
 
66
84
  head = NULL;
67
85
 
68
- /* If it's not an annotated tag, just get out */
69
- if (git_object_type(obj) != GIT_OBJ_TAG) {
86
+ /* If it's not an annotated tag, or if we're mocking
87
+ * git-receive-pack, just get out */
88
+ if (git_object_type(obj) != GIT_OBJ_TAG ||
89
+ t->direction != GIT_DIRECTION_FETCH) {
70
90
  git_object_free(obj);
71
91
  return 0;
72
92
  }
73
93
 
74
94
  /* And if it's a tag, peel it, and add it to the list */
75
- head = git__malloc(sizeof(git_remote_head));
95
+ head = git__calloc(1, sizeof(git_remote_head));
76
96
  GITERR_CHECK_ALLOC(head);
77
97
  if (git_buf_join(&buf, 0, name, peeled) < 0)
78
98
  return -1;
79
99
 
80
100
  head->name = git_buf_detach(&buf);
81
101
 
82
- pkt = git__malloc(sizeof(git_pkt_ref));
83
- GITERR_CHECK_ALLOC(pkt);
84
- pkt->type = GIT_PKT_REF;
85
-
86
102
  if (git_tag_peel(&target, (git_tag *) obj) < 0)
87
103
  goto on_error;
88
104
 
89
105
  git_oid_cpy(&head->oid, git_object_id(target));
90
106
  git_object_free(obj);
91
107
  git_object_free(target);
92
- memcpy(&pkt->head, head, sizeof(git_remote_head));
93
- git__free(head);
94
108
 
95
- if (git_vector_insert(&transport->refs, pkt) < 0)
109
+ if (git_vector_insert(&t->refs, head) < 0)
96
110
  return -1;
97
111
 
98
112
  return 0;
@@ -107,19 +121,18 @@ static int store_refs(transport_local *t)
107
121
  {
108
122
  unsigned int i;
109
123
  git_strarray ref_names = {0};
110
- git_transport *transport = (git_transport *) t;
111
124
 
112
125
  assert(t);
113
126
 
114
127
  if (git_reference_list(&ref_names, t->repo, GIT_REF_LISTALL) < 0 ||
115
- git_vector_init(&transport->refs, (unsigned int)ref_names.count, NULL) < 0)
128
+ git_vector_init(&t->refs, ref_names.count, NULL) < 0)
116
129
  goto on_error;
117
130
 
118
131
  /* Sort the references first */
119
132
  git__tsort((void **)ref_names.strings, ref_names.count, &git__strcmp_cb);
120
133
 
121
- /* Add HEAD */
122
- if (add_ref(t, GIT_HEAD_FILE) < 0)
134
+ /* Add HEAD iff direction is fetch */
135
+ if (t->direction == GIT_DIRECTION_FETCH && add_ref(t, GIT_HEAD_FILE) < 0)
123
136
  goto on_error;
124
137
 
125
138
  for (i = 0; i < ref_names.count; ++i) {
@@ -127,11 +140,12 @@ static int store_refs(transport_local *t)
127
140
  goto on_error;
128
141
  }
129
142
 
143
+ t->have_refs = 1;
130
144
  git_strarray_free(&ref_names);
131
145
  return 0;
132
146
 
133
147
  on_error:
134
- git_vector_free(&transport->refs);
148
+ git_vector_free(&t->refs);
135
149
  git_strarray_free(&ref_names);
136
150
  return -1;
137
151
  }
@@ -140,7 +154,12 @@ on_error:
140
154
  * Try to open the url as a git directory. The direction doesn't
141
155
  * matter in this case because we're calulating the heads ourselves.
142
156
  */
143
- static int local_connect(git_transport *transport, int direction)
157
+ static int local_connect(
158
+ git_transport *transport,
159
+ const char *url,
160
+ git_cred_acquire_cb cred_acquire_cb,
161
+ void *cred_acquire_payload,
162
+ int direction, int flags)
144
163
  {
145
164
  git_repository *repo;
146
165
  int error;
@@ -148,18 +167,24 @@ static int local_connect(git_transport *transport, int direction)
148
167
  const char *path;
149
168
  git_buf buf = GIT_BUF_INIT;
150
169
 
151
- GIT_UNUSED(direction);
170
+ GIT_UNUSED(cred_acquire_cb);
171
+ GIT_UNUSED(cred_acquire_payload);
172
+
173
+ t->url = git__strdup(url);
174
+ GITERR_CHECK_ALLOC(t->url);
175
+ t->direction = direction;
176
+ t->flags = flags;
152
177
 
153
178
  /* The repo layer doesn't want the prefix */
154
- if (!git__prefixcmp(transport->url, "file://")) {
155
- if (git_path_fromurl(&buf, transport->url) < 0) {
179
+ if (!git__prefixcmp(t->url, "file://")) {
180
+ if (git_path_fromurl(&buf, t->url) < 0) {
156
181
  git_buf_free(&buf);
157
182
  return -1;
158
183
  }
159
184
  path = git_buf_cstr(&buf);
160
185
 
161
186
  } else { /* We assume transport->url is already a path */
162
- path = transport->url;
187
+ path = t->url;
163
188
  }
164
189
 
165
190
  error = git_repository_open(&repo, path);
@@ -174,48 +199,411 @@ static int local_connect(git_transport *transport, int direction)
174
199
  if (store_refs(t) < 0)
175
200
  return -1;
176
201
 
177
- t->parent.connected = 1;
202
+ t->connected = 1;
178
203
 
179
204
  return 0;
180
205
  }
181
206
 
182
- static int local_negotiate_fetch(git_transport *transport, git_repository *repo, const git_vector *wants)
207
+ static int local_ls(git_transport *transport, git_headlist_cb list_cb, void *payload)
183
208
  {
184
- GIT_UNUSED(transport);
185
- GIT_UNUSED(repo);
186
- GIT_UNUSED(wants);
209
+ transport_local *t = (transport_local *)transport;
210
+ unsigned int i;
211
+ git_remote_head *head = NULL;
187
212
 
188
- giterr_set(GITERR_NET, "Fetch via local transport isn't implemented. Sorry");
189
- return -1;
213
+ if (!t->have_refs) {
214
+ giterr_set(GITERR_NET, "The transport has not yet loaded the refs");
215
+ return -1;
216
+ }
217
+
218
+ git_vector_foreach(&t->refs, i, head) {
219
+ if (list_cb(head, payload))
220
+ return GIT_EUSER;
221
+ }
222
+
223
+ return 0;
224
+ }
225
+
226
+ static int local_negotiate_fetch(
227
+ git_transport *transport,
228
+ git_repository *repo,
229
+ const git_remote_head * const *refs,
230
+ size_t count)
231
+ {
232
+ transport_local *t = (transport_local*)transport;
233
+ git_remote_head *rhead;
234
+ unsigned int i;
235
+
236
+ GIT_UNUSED(refs);
237
+ GIT_UNUSED(count);
238
+
239
+ /* Fill in the loids */
240
+ git_vector_foreach(&t->refs, i, rhead) {
241
+ git_object *obj;
242
+
243
+ int error = git_revparse_single(&obj, repo, rhead->name);
244
+ if (!error)
245
+ git_oid_cpy(&rhead->loid, git_object_id(obj));
246
+ else if (error != GIT_ENOTFOUND)
247
+ return error;
248
+ git_object_free(obj);
249
+ giterr_clear();
250
+ }
251
+
252
+ return 0;
253
+ }
254
+
255
+ static int local_push_copy_object(
256
+ git_odb *local_odb,
257
+ git_odb *remote_odb,
258
+ git_pobject *obj)
259
+ {
260
+ int error = 0;
261
+ git_odb_object *odb_obj = NULL;
262
+ git_odb_stream *odb_stream;
263
+ size_t odb_obj_size;
264
+ git_otype odb_obj_type;
265
+ git_oid remote_odb_obj_oid;
266
+
267
+ /* Object already exists in the remote ODB; do nothing and return 0*/
268
+ if (git_odb_exists(remote_odb, &obj->id))
269
+ return 0;
270
+
271
+ if ((error = git_odb_read(&odb_obj, local_odb, &obj->id)) < 0)
272
+ return error;
273
+
274
+ odb_obj_size = git_odb_object_size(odb_obj);
275
+ odb_obj_type = git_odb_object_type(odb_obj);
276
+
277
+ if ((error = git_odb_open_wstream(&odb_stream, remote_odb,
278
+ odb_obj_size, odb_obj_type)) < 0)
279
+ goto on_error;
280
+
281
+ if (odb_stream->write(odb_stream, (char *)git_odb_object_data(odb_obj),
282
+ odb_obj_size) < 0 ||
283
+ odb_stream->finalize_write(&remote_odb_obj_oid, odb_stream) < 0) {
284
+ error = -1;
285
+ } else if (git_oid_cmp(&obj->id, &remote_odb_obj_oid) != 0) {
286
+ giterr_set(GITERR_ODB, "Error when writing object to remote odb "
287
+ "during local push operation. Remote odb object oid does not "
288
+ "match local oid.");
289
+ error = -1;
290
+ }
291
+
292
+ odb_stream->free(odb_stream);
293
+
294
+ on_error:
295
+ git_odb_object_free(odb_obj);
296
+ return error;
297
+ }
298
+
299
+ static int local_push_update_remote_ref(
300
+ git_repository *remote_repo,
301
+ const char *lref,
302
+ const char *rref,
303
+ git_oid *loid,
304
+ git_oid *roid)
305
+ {
306
+ int error;
307
+ git_reference *remote_ref = NULL;
308
+
309
+ /* rref will be NULL if it is implicit in the pushspec (e.g. 'b1:') */
310
+ rref = rref ? rref : lref;
311
+
312
+ if (lref) {
313
+ /* Create or update a ref */
314
+ if ((error = git_reference_create(NULL, remote_repo, rref, loid,
315
+ !git_oid_iszero(roid))) < 0)
316
+ return error;
317
+ } else {
318
+ /* Delete a ref */
319
+ if ((error = git_reference_lookup(&remote_ref, remote_repo, rref)) < 0) {
320
+ if (error == GIT_ENOTFOUND)
321
+ error = 0;
322
+ return error;
323
+ }
324
+
325
+ if ((error = git_reference_delete(remote_ref)) < 0)
326
+ return error;
327
+
328
+ git_reference_free(remote_ref);
329
+ }
330
+
331
+ return 0;
332
+ }
333
+
334
+ static int local_push(
335
+ git_transport *transport,
336
+ git_push *push)
337
+ {
338
+ transport_local *t = (transport_local *)transport;
339
+ git_odb *remote_odb = NULL;
340
+ git_odb *local_odb = NULL;
341
+ git_repository *remote_repo = NULL;
342
+ push_spec *spec;
343
+ char *url = NULL;
344
+ int error;
345
+ unsigned int i;
346
+ size_t j;
347
+
348
+ if ((error = git_repository_open(&remote_repo, push->remote->url)) < 0)
349
+ return error;
350
+
351
+ /* We don't currently support pushing locally to non-bare repos. Proper
352
+ non-bare repo push support would require checking configs to see if
353
+ we should override the default 'don't let this happen' behavior */
354
+ if (!remote_repo->is_bare) {
355
+ error = -1;
356
+ goto on_error;
357
+ }
358
+
359
+ if ((error = git_repository_odb__weakptr(&remote_odb, remote_repo)) < 0 ||
360
+ (error = git_repository_odb__weakptr(&local_odb, push->repo)) < 0)
361
+ goto on_error;
362
+
363
+ for (i = 0; i < push->pb->nr_objects; i++) {
364
+ if ((error = local_push_copy_object(local_odb, remote_odb,
365
+ &push->pb->object_list[i])) < 0)
366
+ goto on_error;
367
+ }
368
+
369
+ push->unpack_ok = 1;
370
+
371
+ git_vector_foreach(&push->specs, j, spec) {
372
+ push_status *status;
373
+ const git_error *last;
374
+ char *ref = spec->rref ? spec->rref : spec->lref;
375
+
376
+ status = git__calloc(sizeof(push_status), 1);
377
+ if (!status)
378
+ goto on_error;
379
+
380
+ status->ref = git__strdup(ref);
381
+ if (!status->ref) {
382
+ git_push_status_free(status);
383
+ goto on_error;
384
+ }
385
+
386
+ error = local_push_update_remote_ref(remote_repo, spec->lref, spec->rref,
387
+ &spec->loid, &spec->roid);
388
+
389
+ switch (error) {
390
+ case GIT_OK:
391
+ break;
392
+ case GIT_EINVALIDSPEC:
393
+ status->msg = git__strdup("funny refname");
394
+ break;
395
+ case GIT_ENOTFOUND:
396
+ status->msg = git__strdup("Remote branch not found to delete");
397
+ break;
398
+ default:
399
+ last = giterr_last();
400
+
401
+ if (last && last->message)
402
+ status->msg = git__strdup(last->message);
403
+ else
404
+ status->msg = git__strdup("Unspecified error encountered");
405
+ break;
406
+ }
407
+
408
+ /* failed to allocate memory for a status message */
409
+ if (error < 0 && !status->msg) {
410
+ git_push_status_free(status);
411
+ goto on_error;
412
+ }
413
+
414
+ /* failed to insert the ref update status */
415
+ if ((error = git_vector_insert(&push->status, status)) < 0) {
416
+ git_push_status_free(status);
417
+ goto on_error;
418
+ }
419
+ }
420
+
421
+ if (push->specs.length) {
422
+ int flags = t->flags;
423
+ url = git__strdup(t->url);
424
+
425
+ if (!url || t->parent.close(&t->parent) < 0 ||
426
+ t->parent.connect(&t->parent, url,
427
+ push->remote->cred_acquire_cb, NULL, GIT_DIRECTION_PUSH, flags))
428
+ goto on_error;
429
+ }
430
+
431
+ error = 0;
432
+
433
+ on_error:
434
+ git_repository_free(remote_repo);
435
+ git__free(url);
436
+
437
+ return error;
438
+ }
439
+
440
+ typedef struct foreach_data {
441
+ git_transfer_progress *stats;
442
+ git_transfer_progress_callback progress_cb;
443
+ void *progress_payload;
444
+ git_odb_writepack *writepack;
445
+ } foreach_data;
446
+
447
+ static int foreach_cb(void *buf, size_t len, void *payload)
448
+ {
449
+ foreach_data *data = (foreach_data*)payload;
450
+
451
+ data->stats->received_bytes += len;
452
+ return data->writepack->add(data->writepack, buf, len, data->stats);
453
+ }
454
+
455
+ static int local_download_pack(
456
+ git_transport *transport,
457
+ git_repository *repo,
458
+ git_transfer_progress *stats,
459
+ git_transfer_progress_callback progress_cb,
460
+ void *progress_payload)
461
+ {
462
+ transport_local *t = (transport_local*)transport;
463
+ git_revwalk *walk = NULL;
464
+ git_remote_head *rhead;
465
+ unsigned int i;
466
+ int error = -1;
467
+ git_oid oid;
468
+ git_packbuilder *pack = NULL;
469
+ git_odb_writepack *writepack = NULL;
470
+ git_odb *odb = NULL;
471
+
472
+ if ((error = git_revwalk_new(&walk, t->repo)) < 0)
473
+ goto cleanup;
474
+ git_revwalk_sorting(walk, GIT_SORT_TIME);
475
+
476
+ if ((error = git_packbuilder_new(&pack, t->repo)) < 0)
477
+ goto cleanup;
478
+
479
+ stats->total_objects = 0;
480
+ stats->indexed_objects = 0;
481
+ stats->received_objects = 0;
482
+ stats->received_bytes = 0;
483
+
484
+ git_vector_foreach(&t->refs, i, rhead) {
485
+ git_object *obj;
486
+ if ((error = git_object_lookup(&obj, t->repo, &rhead->oid, GIT_OBJ_ANY)) < 0)
487
+ goto cleanup;
488
+
489
+ if (git_object_type(obj) == GIT_OBJ_COMMIT) {
490
+ /* Revwalker includes only wanted commits */
491
+ error = git_revwalk_push(walk, &rhead->oid);
492
+ if (!git_oid_iszero(&rhead->loid))
493
+ error = git_revwalk_hide(walk, &rhead->loid);
494
+ } else {
495
+ /* Tag or some other wanted object. Add it on its own */
496
+ error = git_packbuilder_insert(pack, &rhead->oid, rhead->name);
497
+ }
498
+ git_object_free(obj);
499
+ }
500
+
501
+ /* Walk the objects, building a packfile */
502
+ if ((error = git_repository_odb__weakptr(&odb, repo)) < 0)
503
+ goto cleanup;
504
+
505
+ while ((error = git_revwalk_next(&oid, walk)) == 0) {
506
+ git_commit *commit;
507
+
508
+ /* Skip commits we already have */
509
+ if (git_odb_exists(odb, &oid)) continue;
510
+
511
+ if (!git_object_lookup((git_object**)&commit, t->repo, &oid, GIT_OBJ_COMMIT)) {
512
+ const git_oid *tree_oid = git_commit_tree_id(commit);
513
+
514
+ /* Add the commit and its tree */
515
+ if ((error = git_packbuilder_insert(pack, &oid, NULL)) < 0 ||
516
+ (error = git_packbuilder_insert_tree(pack, tree_oid)) < 0) {
517
+ git_commit_free(commit);
518
+ goto cleanup;
519
+ }
520
+
521
+ git_commit_free(commit);
522
+ }
523
+ }
524
+
525
+ if ((error = git_odb_write_pack(&writepack, odb, progress_cb, progress_payload)) < 0)
526
+ goto cleanup;
527
+
528
+ /* Write the data to the ODB */
529
+ {
530
+ foreach_data data = {0};
531
+ data.stats = stats;
532
+ data.progress_cb = progress_cb;
533
+ data.progress_payload = progress_payload;
534
+ data.writepack = writepack;
535
+
536
+ if ((error = git_packbuilder_foreach(pack, foreach_cb, &data)) < 0)
537
+ goto cleanup;
538
+ }
539
+ error = writepack->commit(writepack, stats);
540
+
541
+ cleanup:
542
+ if (writepack) writepack->free(writepack);
543
+ git_packbuilder_free(pack);
544
+ git_revwalk_free(walk);
545
+ return error;
546
+ }
547
+
548
+ static int local_is_connected(git_transport *transport)
549
+ {
550
+ transport_local *t = (transport_local *)transport;
551
+
552
+ return t->connected;
553
+ }
554
+
555
+ static int local_read_flags(git_transport *transport, int *flags)
556
+ {
557
+ transport_local *t = (transport_local *)transport;
558
+
559
+ *flags = t->flags;
560
+
561
+ return 0;
562
+ }
563
+
564
+ static void local_cancel(git_transport *transport)
565
+ {
566
+ transport_local *t = (transport_local *)transport;
567
+
568
+ git_atomic_set(&t->cancelled, 1);
190
569
  }
191
570
 
192
571
  static int local_close(git_transport *transport)
193
572
  {
194
573
  transport_local *t = (transport_local *)transport;
195
574
 
196
- t->parent.connected = 0;
197
- git_repository_free(t->repo);
198
- t->repo = NULL;
575
+ t->connected = 0;
576
+
577
+ if (t->repo) {
578
+ git_repository_free(t->repo);
579
+ t->repo = NULL;
580
+ }
581
+
582
+ if (t->url) {
583
+ git__free(t->url);
584
+ t->url = NULL;
585
+ }
199
586
 
200
587
  return 0;
201
588
  }
202
589
 
203
590
  static void local_free(git_transport *transport)
204
591
  {
205
- unsigned int i;
206
- transport_local *t = (transport_local *) transport;
207
- git_vector *vec = &transport->refs;
208
- git_pkt_ref *pkt;
592
+ transport_local *t = (transport_local *)transport;
593
+ size_t i;
594
+ git_remote_head *head;
209
595
 
210
- assert(transport);
596
+ /* Close the transport, if it's still open. */
597
+ local_close(transport);
211
598
 
212
- git_vector_foreach (vec, i, pkt) {
213
- git__free(pkt->head.name);
214
- git__free(pkt);
599
+ git_vector_foreach(&t->refs, i, head) {
600
+ git__free(head->name);
601
+ git__free(head);
215
602
  }
216
- git_vector_free(vec);
217
603
 
218
- git__free(t->parent.url);
604
+ git_vector_free(&t->refs);
605
+
606
+ /* Free the transport */
219
607
  git__free(t);
220
608
  }
221
609
 
@@ -223,20 +611,28 @@ static void local_free(git_transport *transport)
223
611
  * Public API *
224
612
  **************/
225
613
 
226
- int git_transport_local(git_transport **out)
614
+ int git_transport_local(git_transport **out, git_remote *owner, void *param)
227
615
  {
228
616
  transport_local *t;
229
617
 
230
- t = git__malloc(sizeof(transport_local));
231
- GITERR_CHECK_ALLOC(t);
618
+ GIT_UNUSED(param);
232
619
 
233
- memset(t, 0x0, sizeof(transport_local));
620
+ t = git__calloc(1, sizeof(transport_local));
621
+ GITERR_CHECK_ALLOC(t);
234
622
 
235
- t->parent.own_logic = 1;
623
+ t->parent.version = GIT_TRANSPORT_VERSION;
236
624
  t->parent.connect = local_connect;
237
625
  t->parent.negotiate_fetch = local_negotiate_fetch;
626
+ t->parent.download_pack = local_download_pack;
627
+ t->parent.push = local_push;
238
628
  t->parent.close = local_close;
239
629
  t->parent.free = local_free;
630
+ t->parent.ls = local_ls;
631
+ t->parent.is_connected = local_is_connected;
632
+ t->parent.read_flags = local_read_flags;
633
+ t->parent.cancel = local_cancel;
634
+
635
+ t->owner = owner;
240
636
 
241
637
  *out = (git_transport *) t;
242
638