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
@@ -0,0 +1,24 @@
1
+ /*
2
+ * Copyright (C) the libgit2 contributors. All rights reserved.
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_attrcache_h__
8
+ #define INCLUDE_attrcache_h__
9
+
10
+ #include "pool.h"
11
+ #include "strmap.h"
12
+
13
+ typedef struct {
14
+ int initialized;
15
+ git_pool pool;
16
+ git_strmap *files; /* hash path to git_attr_file of rules */
17
+ git_strmap *macros; /* hash name to vector<git_attr_assignment> */
18
+ const char *cfg_attr_file; /* cached value of core.attributesfile */
19
+ const char *cfg_excl_file; /* cached value of core.excludesfile */
20
+ } git_attr_cache;
21
+
22
+ extern int git_attr_cache__init(git_repository *repo);
23
+
24
+ #endif
@@ -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.
@@ -12,17 +12,18 @@
12
12
  #include "common.h"
13
13
  #include "blob.h"
14
14
  #include "filter.h"
15
+ #include "buf_text.h"
15
16
 
16
- const void *git_blob_rawcontent(git_blob *blob)
17
+ const void *git_blob_rawcontent(const git_blob *blob)
17
18
  {
18
19
  assert(blob);
19
20
  return blob->odb_object->raw.data;
20
21
  }
21
22
 
22
- size_t git_blob_rawsize(git_blob *blob)
23
+ git_off_t git_blob_rawsize(const git_blob *blob)
23
24
  {
24
25
  assert(blob);
25
- return blob->odb_object->raw.len;
26
+ return (git_off_t)blob->odb_object->raw.len;
26
27
  }
27
28
 
28
29
  int git_blob__getbuf(git_buf *buffer, git_blob *blob)
@@ -205,7 +206,7 @@ static int blob_create_internal(git_oid *oid, git_repository *repo, const char *
205
206
  return error;
206
207
  }
207
208
 
208
- int git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *path)
209
+ int git_blob_create_fromworkdir(git_oid *oid, git_repository *repo, const char *path)
209
210
  {
210
211
  git_buf full_path = GIT_BUF_INIT;
211
212
  const char *workdir;
@@ -221,7 +222,9 @@ int git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *pat
221
222
  return -1;
222
223
  }
223
224
 
224
- error = blob_create_internal(oid, repo, git_buf_cstr(&full_path), git_buf_cstr(&full_path), true);
225
+ error = blob_create_internal(
226
+ oid, repo, git_buf_cstr(&full_path),
227
+ git_buf_cstr(&full_path) + strlen(workdir), true);
225
228
 
226
229
  git_buf_free(&full_path);
227
230
  return error;
@@ -231,13 +234,21 @@ int git_blob_create_fromdisk(git_oid *oid, git_repository *repo, const char *pat
231
234
  {
232
235
  int error;
233
236
  git_buf full_path = GIT_BUF_INIT;
237
+ const char *workdir, *hintpath;
234
238
 
235
239
  if ((error = git_path_prettify(&full_path, path, NULL)) < 0) {
236
240
  git_buf_free(&full_path);
237
241
  return error;
238
242
  }
239
243
 
240
- error = blob_create_internal(oid, repo, git_buf_cstr(&full_path), git_buf_cstr(&full_path), true);
244
+ hintpath = git_buf_cstr(&full_path);
245
+ workdir = git_repository_workdir(repo);
246
+
247
+ if (workdir && !git__prefixcmp(hintpath, workdir))
248
+ hintpath += strlen(workdir);
249
+
250
+ error = blob_create_internal(
251
+ oid, repo, git_buf_cstr(&full_path), hintpath, true);
241
252
 
242
253
  git_buf_free(&full_path);
243
254
  return error;
@@ -296,3 +307,15 @@ cleanup:
296
307
  git__free(content);
297
308
  return error;
298
309
  }
310
+
311
+ int git_blob_is_binary(git_blob *blob)
312
+ {
313
+ git_buf content;
314
+
315
+ assert(blob);
316
+
317
+ content.ptr = blob->odb_object->raw.data;
318
+ content.size = min(blob->odb_object->raw.len, 4000);
319
+
320
+ return git_buf_text_is_binary(&content);
321
+ }
@@ -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.
@@ -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,6 +10,7 @@
10
10
  #include "tag.h"
11
11
  #include "config.h"
12
12
  #include "refspec.h"
13
+ #include "refs.h"
13
14
 
14
15
  #include "git2/branch.h"
15
16
 
@@ -44,47 +45,38 @@ cleanup:
44
45
  return error;
45
46
  }
46
47
 
47
- static int create_error_invalid(const char *msg)
48
+ static int not_a_local_branch(const char *reference_name)
48
49
  {
49
- giterr_set(GITERR_INVALID, "Cannot create branch - %s", msg);
50
- return -1;
51
- }
52
-
53
- static int not_a_local_branch(git_reference *ref)
54
- {
55
- giterr_set(GITERR_INVALID, "Reference '%s' is not a local branch.", git_reference_name(ref));
50
+ giterr_set(
51
+ GITERR_INVALID,
52
+ "Reference '%s' is not a local branch.", reference_name);
56
53
  return -1;
57
54
  }
58
55
 
59
56
  int git_branch_create(
60
- git_reference **ref_out,
61
- git_repository *repository,
62
- const char *branch_name,
63
- const git_object *target,
64
- int force)
57
+ git_reference **ref_out,
58
+ git_repository *repository,
59
+ const char *branch_name,
60
+ const git_commit *commit,
61
+ int force)
65
62
  {
66
- git_object *commit = NULL;
67
63
  git_reference *branch = NULL;
68
64
  git_buf canonical_branch_name = GIT_BUF_INIT;
69
65
  int error = -1;
70
66
 
71
- assert(branch_name && target && ref_out);
72
- assert(git_object_owner(target) == repository);
73
-
74
- if (git_object_peel(&commit, (git_object *)target, GIT_OBJ_COMMIT) < 0)
75
- return create_error_invalid("The given target does not resolve to a commit");
67
+ assert(branch_name && commit && ref_out);
68
+ assert(git_object_owner((const git_object *)commit) == repository);
76
69
 
77
70
  if (git_buf_joinpath(&canonical_branch_name, GIT_REFS_HEADS_DIR, branch_name) < 0)
78
71
  goto cleanup;
79
72
 
80
- error = git_reference_create_oid(&branch, repository,
81
- git_buf_cstr(&canonical_branch_name), git_object_id(commit), force);
73
+ error = git_reference_create(&branch, repository,
74
+ git_buf_cstr(&canonical_branch_name), git_commit_id(commit), force);
82
75
 
83
76
  if (!error)
84
77
  *ref_out = branch;
85
78
 
86
79
  cleanup:
87
- git_object_free(commit);
88
80
  git_buf_free(&canonical_branch_name);
89
81
  return error;
90
82
  }
@@ -92,6 +84,8 @@ cleanup:
92
84
  int git_branch_delete(git_reference *branch)
93
85
  {
94
86
  int is_head;
87
+ git_buf config_section = GIT_BUF_INIT;
88
+ int error = -1;
95
89
 
96
90
  assert(branch);
97
91
 
@@ -110,14 +104,27 @@ int git_branch_delete(git_reference *branch)
110
104
  return -1;
111
105
  }
112
106
 
113
- return git_reference_delete(branch);
107
+ if (git_buf_printf(&config_section, "branch.%s", git_reference_name(branch) + strlen(GIT_REFS_HEADS_DIR)) < 0)
108
+ goto on_error;
109
+
110
+ if (git_config_rename_section(
111
+ git_reference_owner(branch),
112
+ git_buf_cstr(&config_section),
113
+ NULL) < 0)
114
+ goto on_error;
115
+
116
+ if (git_reference_delete(branch) < 0)
117
+ goto on_error;
118
+
119
+ error = 0;
120
+
121
+ on_error:
122
+ git_buf_free(&config_section);
123
+ return error;
114
124
  }
115
125
 
116
126
  typedef struct {
117
- int (*branch_cb)(
118
- const char *branch_name,
119
- git_branch_t branch_type,
120
- void *payload);
127
+ git_branch_foreach_cb branch_cb;
121
128
  void *callback_payload;
122
129
  unsigned int branch_type;
123
130
  } branch_foreach_filter;
@@ -138,14 +145,10 @@ static int branch_foreach_cb(const char *branch_name, void *payload)
138
145
  }
139
146
 
140
147
  int git_branch_foreach(
141
- git_repository *repo,
142
- unsigned int list_flags,
143
- int (*branch_cb)(
144
- const char *branch_name,
145
- git_branch_t branch_type,
146
- void *payload),
147
- void *payload
148
- )
148
+ git_repository *repo,
149
+ unsigned int list_flags,
150
+ git_branch_foreach_cb branch_cb,
151
+ void *payload)
149
152
  {
150
153
  branch_foreach_filter filter;
151
154
 
@@ -157,52 +160,89 @@ int git_branch_foreach(
157
160
  }
158
161
 
159
162
  int git_branch_move(
163
+ git_reference **out,
160
164
  git_reference *branch,
161
165
  const char *new_branch_name,
162
166
  int force)
163
167
  {
164
- git_buf new_reference_name = GIT_BUF_INIT;
168
+ git_buf new_reference_name = GIT_BUF_INIT,
169
+ old_config_section = GIT_BUF_INIT,
170
+ new_config_section = GIT_BUF_INIT;
165
171
  int error;
166
172
 
167
173
  assert(branch && new_branch_name);
168
174
 
169
175
  if (!git_reference_is_branch(branch))
170
- return not_a_local_branch(branch);
171
-
172
- if ((error = git_buf_joinpath(&new_reference_name, GIT_REFS_HEADS_DIR, new_branch_name)) < 0)
173
- goto cleanup;
174
-
175
- error = git_reference_rename(branch, git_buf_cstr(&new_reference_name), force);
176
-
177
- cleanup:
176
+ return not_a_local_branch(git_reference_name(branch));
177
+
178
+ if ((error = git_buf_joinpath(&new_reference_name, GIT_REFS_HEADS_DIR, new_branch_name)) < 0 ||
179
+ (error = git_buf_printf(&old_config_section, "branch.%s", git_reference_name(branch) + strlen(GIT_REFS_HEADS_DIR))) < 0 ||
180
+ (error = git_buf_printf(&new_config_section, "branch.%s", new_branch_name)) < 0)
181
+ goto done;
182
+
183
+ if ((error = git_config_rename_section(git_reference_owner(branch),
184
+ git_buf_cstr(&old_config_section),
185
+ git_buf_cstr(&new_config_section))) < 0)
186
+ goto done;
187
+
188
+ if ((error = git_reference_rename(out, branch, git_buf_cstr(&new_reference_name), force)) < 0)
189
+ goto done;
190
+
191
+ done:
178
192
  git_buf_free(&new_reference_name);
193
+ git_buf_free(&old_config_section);
194
+ git_buf_free(&new_config_section);
179
195
 
180
196
  return error;
181
197
  }
182
198
 
183
199
  int git_branch_lookup(
184
- git_reference **ref_out,
185
- git_repository *repo,
186
- const char *branch_name,
187
- git_branch_t branch_type)
200
+ git_reference **ref_out,
201
+ git_repository *repo,
202
+ const char *branch_name,
203
+ git_branch_t branch_type)
188
204
  {
189
205
  assert(ref_out && repo && branch_name);
190
206
 
191
207
  return retrieve_branch_reference(ref_out, repo, branch_name, branch_type == GIT_BRANCH_REMOTE);
192
208
  }
193
209
 
194
- static int retrieve_tracking_configuration(
195
- const char **out, git_reference *branch, const char *format)
210
+ int git_branch_name(const char **out, git_reference *ref)
211
+ {
212
+ const char *branch_name;
213
+
214
+ assert(out && ref);
215
+
216
+ branch_name = ref->name;
217
+
218
+ if (git_reference_is_branch(ref)) {
219
+ branch_name += strlen(GIT_REFS_HEADS_DIR);
220
+ } else if (git_reference_is_remote(ref)) {
221
+ branch_name += strlen(GIT_REFS_REMOTES_DIR);
222
+ } else {
223
+ giterr_set(GITERR_INVALID,
224
+ "Reference '%s' is neither a local nor a remote branch.", ref->name);
225
+ return -1;
226
+ }
227
+ *out = branch_name;
228
+ return 0;
229
+ }
230
+
231
+ static int retrieve_upstream_configuration(
232
+ const char **out,
233
+ git_repository *repo,
234
+ const char *canonical_branch_name,
235
+ const char *format)
196
236
  {
197
237
  git_config *config;
198
238
  git_buf buf = GIT_BUF_INIT;
199
239
  int error;
200
240
 
201
- if (git_repository_config__weakptr(&config, git_reference_owner(branch)) < 0)
241
+ if (git_repository_config__weakptr(&config, repo) < 0)
202
242
  return -1;
203
243
 
204
244
  if (git_buf_printf(&buf, format,
205
- git_reference_name(branch) + strlen(GIT_REFS_HEADS_DIR)) < 0)
245
+ canonical_branch_name + strlen(GIT_REFS_HEADS_DIR)) < 0)
206
246
  return -1;
207
247
 
208
248
  error = git_config_get_string(out, config, git_buf_cstr(&buf));
@@ -210,9 +250,10 @@ static int retrieve_tracking_configuration(
210
250
  return error;
211
251
  }
212
252
 
213
- int git_branch_tracking(
214
- git_reference **tracking_out,
215
- git_reference *branch)
253
+ int git_branch_upstream__name(
254
+ git_buf *tracking_name,
255
+ git_repository *repo,
256
+ const char *canonical_branch_name)
216
257
  {
217
258
  const char *remote_name, *merge_name;
218
259
  git_buf buf = GIT_BUF_INIT;
@@ -220,19 +261,26 @@ int git_branch_tracking(
220
261
  git_remote *remote = NULL;
221
262
  const git_refspec *refspec;
222
263
 
223
- assert(tracking_out && branch);
264
+ assert(tracking_name && canonical_branch_name);
224
265
 
225
- if (!git_reference_is_branch(branch))
226
- return not_a_local_branch(branch);
266
+ if (!git_reference__is_branch(canonical_branch_name))
267
+ return not_a_local_branch(canonical_branch_name);
227
268
 
228
- if ((error = retrieve_tracking_configuration(&remote_name, branch, "branch.%s.remote")) < 0)
229
- goto cleanup;
269
+ if ((error = retrieve_upstream_configuration(
270
+ &remote_name, repo, canonical_branch_name, "branch.%s.remote")) < 0)
271
+ goto cleanup;
230
272
 
231
- if ((error = retrieve_tracking_configuration(&merge_name, branch, "branch.%s.merge")) < 0)
273
+ if ((error = retrieve_upstream_configuration(
274
+ &merge_name, repo, canonical_branch_name, "branch.%s.merge")) < 0)
275
+ goto cleanup;
276
+
277
+ if (!*remote_name || !*merge_name) {
278
+ error = GIT_ENOTFOUND;
232
279
  goto cleanup;
280
+ }
233
281
 
234
282
  if (strcmp(".", remote_name) != 0) {
235
- if ((error = git_remote_load(&remote, git_reference_owner(branch), remote_name)) < 0)
283
+ if ((error = git_remote_load(&remote, repo, remote_name)) < 0)
236
284
  goto cleanup;
237
285
 
238
286
  refspec = git_remote_fetchspec(remote);
@@ -249,10 +297,7 @@ int git_branch_tracking(
249
297
  if (git_buf_sets(&buf, merge_name) < 0)
250
298
  goto cleanup;
251
299
 
252
- error = git_reference_lookup(
253
- tracking_out,
254
- git_reference_owner(branch),
255
- git_buf_cstr(&buf));
300
+ error = git_buf_set(tracking_name, git_buf_cstr(&buf), git_buf_len(&buf));
256
301
 
257
302
  cleanup:
258
303
  git_remote_free(remote);
@@ -260,6 +305,254 @@ cleanup:
260
305
  return error;
261
306
  }
262
307
 
308
+ static int remote_name(git_buf *buf, git_repository *repo, const char *canonical_branch_name)
309
+ {
310
+ git_strarray remote_list = {0};
311
+ size_t i;
312
+ git_remote *remote;
313
+ const git_refspec *fetchspec;
314
+ int error = 0;
315
+ char *remote_name = NULL;
316
+
317
+ assert(buf && repo && canonical_branch_name);
318
+
319
+ /* Verify that this is a remote branch */
320
+ if (!git_reference__is_remote(canonical_branch_name)) {
321
+ giterr_set(GITERR_INVALID, "Reference '%s' is not a remote branch.",
322
+ canonical_branch_name);
323
+ error = GIT_ERROR;
324
+ goto cleanup;
325
+ }
326
+
327
+ /* Get the remotes */
328
+ if ((error = git_remote_list(&remote_list, repo)) < 0)
329
+ goto cleanup;
330
+
331
+ /* Find matching remotes */
332
+ for (i = 0; i < remote_list.count; i++) {
333
+ if ((error = git_remote_load(&remote, repo, remote_list.strings[i])) < 0)
334
+ continue;
335
+
336
+ fetchspec = git_remote_fetchspec(remote);
337
+
338
+ /* Defensivly check that we have a fetchspec */
339
+ if (fetchspec &&
340
+ git_refspec_dst_matches(fetchspec, canonical_branch_name)) {
341
+ /* If we have not already set out yet, then set
342
+ * it to the matching remote name. Otherwise
343
+ * multiple remotes match this reference, and it
344
+ * is ambiguous. */
345
+ if (!remote_name) {
346
+ remote_name = remote_list.strings[i];
347
+ } else {
348
+ git_remote_free(remote);
349
+ error = GIT_EAMBIGUOUS;
350
+ goto cleanup;
351
+ }
352
+ }
353
+
354
+ git_remote_free(remote);
355
+ }
356
+
357
+ if (remote_name) {
358
+ git_buf_clear(buf);
359
+ error = git_buf_puts(buf, remote_name);
360
+ } else {
361
+ error = GIT_ENOTFOUND;
362
+ }
363
+
364
+ cleanup:
365
+ git_strarray_free(&remote_list);
366
+ return error;
367
+ }
368
+
369
+ int git_branch_remote_name(char *buffer, size_t buffer_len, git_repository *repo, const char *refname)
370
+ {
371
+ int ret;
372
+ git_buf buf = GIT_BUF_INIT;
373
+
374
+ if ((ret = remote_name(&buf, repo, refname)) < 0)
375
+ return ret;
376
+
377
+ if (buffer)
378
+ git_buf_copy_cstr(buffer, buffer_len, &buf);
379
+
380
+ ret = git_buf_len(&buf) + 1;
381
+ git_buf_free(&buf);
382
+
383
+ return ret;
384
+ }
385
+
386
+ int git_branch_upstream_name(
387
+ char *tracking_branch_name_out,
388
+ size_t buffer_size,
389
+ git_repository *repo,
390
+ const char *canonical_branch_name)
391
+ {
392
+ git_buf buf = GIT_BUF_INIT;
393
+ int error;
394
+
395
+ assert(canonical_branch_name);
396
+
397
+ if (tracking_branch_name_out && buffer_size)
398
+ *tracking_branch_name_out = '\0';
399
+
400
+ if ((error = git_branch_upstream__name(
401
+ &buf, repo, canonical_branch_name)) < 0)
402
+ goto cleanup;
403
+
404
+ if (tracking_branch_name_out && buf.size + 1 > buffer_size) { /* +1 for NUL byte */
405
+ giterr_set(
406
+ GITERR_INVALID,
407
+ "Buffer too short to hold the tracked reference name.");
408
+ error = -1;
409
+ goto cleanup;
410
+ }
411
+
412
+ if (tracking_branch_name_out)
413
+ git_buf_copy_cstr(tracking_branch_name_out, buffer_size, &buf);
414
+
415
+ error = (int)buf.size + 1;
416
+
417
+ cleanup:
418
+ git_buf_free(&buf);
419
+ return (int)error;
420
+ }
421
+
422
+ int git_branch_upstream(
423
+ git_reference **tracking_out,
424
+ git_reference *branch)
425
+ {
426
+ int error;
427
+ git_buf tracking_name = GIT_BUF_INIT;
428
+
429
+ if ((error = git_branch_upstream__name(&tracking_name,
430
+ git_reference_owner(branch), git_reference_name(branch))) < 0)
431
+ return error;
432
+
433
+ error = git_reference_lookup(
434
+ tracking_out,
435
+ git_reference_owner(branch),
436
+ git_buf_cstr(&tracking_name));
437
+
438
+ git_buf_free(&tracking_name);
439
+ return error;
440
+ }
441
+
442
+ static int unset_upstream(git_config *config, const char *shortname)
443
+ {
444
+ git_buf buf = GIT_BUF_INIT;
445
+
446
+ if (git_buf_printf(&buf, "branch.%s.remote", shortname) < 0)
447
+ return -1;
448
+
449
+ if (git_config_delete_entry(config, git_buf_cstr(&buf)) < 0)
450
+ goto on_error;
451
+
452
+ git_buf_clear(&buf);
453
+ if (git_buf_printf(&buf, "branch.%s.merge", shortname) < 0)
454
+ goto on_error;
455
+
456
+ if (git_config_delete_entry(config, git_buf_cstr(&buf)) < 0)
457
+ goto on_error;
458
+
459
+ git_buf_free(&buf);
460
+ return 0;
461
+
462
+ on_error:
463
+ git_buf_free(&buf);
464
+ return -1;
465
+ }
466
+
467
+ int git_branch_set_upstream(git_reference *branch, const char *upstream_name)
468
+ {
469
+ git_buf key = GIT_BUF_INIT, value = GIT_BUF_INIT;
470
+ git_reference *upstream;
471
+ git_repository *repo;
472
+ git_remote *remote = NULL;
473
+ git_config *config;
474
+ const char *name, *shortname;
475
+ int local;
476
+ const git_refspec *fetchspec;
477
+
478
+ name = git_reference_name(branch);
479
+ if (!git_reference__is_branch(name))
480
+ return not_a_local_branch(name);
481
+
482
+ if (git_repository_config__weakptr(&config, git_reference_owner(branch)) < 0)
483
+ return -1;
484
+
485
+ shortname = name + strlen(GIT_REFS_HEADS_DIR);
486
+
487
+ if (upstream_name == NULL)
488
+ return unset_upstream(config, shortname);
489
+
490
+ repo = git_reference_owner(branch);
491
+
492
+ /* First we need to figure out whether it's a branch or remote-tracking */
493
+ if (git_branch_lookup(&upstream, repo, upstream_name, GIT_BRANCH_LOCAL) == 0)
494
+ local = 1;
495
+ else if (git_branch_lookup(&upstream, repo, upstream_name, GIT_BRANCH_REMOTE) == 0)
496
+ local = 0;
497
+ else
498
+ return GIT_ENOTFOUND;
499
+
500
+ /*
501
+ * If it's local, the remote is "." and the branch name is
502
+ * simply the refname. Otherwise we need to figure out what
503
+ * the remote-tracking branch's name on the remote is and use
504
+ * that.
505
+ */
506
+ if (local)
507
+ git_buf_puts(&value, ".");
508
+ else
509
+ remote_name(&value, repo, git_reference_name(upstream));
510
+
511
+ if (git_buf_printf(&key, "branch.%s.remote", shortname) < 0)
512
+ goto on_error;
513
+
514
+ if (git_config_set_string(config, git_buf_cstr(&key), git_buf_cstr(&value)) < 0)
515
+ goto on_error;
516
+
517
+ if (local) {
518
+ if (git_buf_puts(&value, git_reference_name(branch)) < 0)
519
+ goto on_error;
520
+ } else {
521
+ /* Get the remoe-tracking branch's refname in its repo */
522
+ if (git_remote_load(&remote, repo, git_buf_cstr(&value)) < 0)
523
+ goto on_error;
524
+
525
+ fetchspec = git_remote_fetchspec(remote);
526
+ git_buf_clear(&value);
527
+ if (git_refspec_transform_l(&value, fetchspec, git_reference_name(upstream)) < 0)
528
+ goto on_error;
529
+
530
+ git_remote_free(remote);
531
+ remote = NULL;
532
+ }
533
+
534
+ git_buf_clear(&key);
535
+ if (git_buf_printf(&key, "branch.%s.merge", shortname) < 0)
536
+ goto on_error;
537
+
538
+ if (git_config_set_string(config, git_buf_cstr(&key), git_buf_cstr(&value)) < 0)
539
+ goto on_error;
540
+
541
+ git_reference_free(upstream);
542
+ git_buf_free(&key);
543
+ git_buf_free(&value);
544
+
545
+ return 0;
546
+
547
+ on_error:
548
+ git_reference_free(upstream);
549
+ git_buf_free(&key);
550
+ git_buf_free(&value);
551
+ git_remote_free(remote);
552
+
553
+ return -1;
554
+ }
555
+
263
556
  int git_branch_is_head(
264
557
  git_reference *branch)
265
558
  {
@@ -274,7 +567,7 @@ int git_branch_is_head(
274
567
 
275
568
  error = git_repository_head(&head, git_reference_owner(branch));
276
569
 
277
- if (error == GIT_EORPHANEDHEAD)
570
+ if (error == GIT_EORPHANEDHEAD || error == GIT_ENOTFOUND)
278
571
  return false;
279
572
 
280
573
  if (error < 0)