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.
@@ -8,9 +8,9 @@
8
8
  #define INCLUDE_remote_h__
9
9
 
10
10
  #include "git2/remote.h"
11
+ #include "git2/transport.h"
11
12
 
12
13
  #include "refspec.h"
13
- #include "transport.h"
14
14
  #include "repository.h"
15
15
 
16
16
  #define GIT_REMOTE_ORIGIN "origin"
@@ -22,14 +22,19 @@ struct git_remote {
22
22
  git_vector refs;
23
23
  struct git_refspec fetch;
24
24
  struct git_refspec push;
25
+ git_cred_acquire_cb cred_acquire_cb;
26
+ void *cred_acquire_payload;
25
27
  git_transport *transport;
26
28
  git_repository *repo;
27
29
  git_remote_callbacks callbacks;
28
- unsigned int need_pack:1,
29
- download_tags:2, /* There are four possible values */
30
- check_cert:1;
30
+ git_transfer_progress stats;
31
+ unsigned int need_pack;
32
+ git_remote_autotag_option_t download_tags;
33
+ unsigned int check_cert;
34
+ unsigned int update_fetchhead;
31
35
  };
32
36
 
33
37
  const char* git_remote__urlfordirection(struct git_remote *remote, int direction);
38
+ int git_remote__get_http_proxy(git_remote *remote, bool use_ssl, char **proxy_url);
34
39
 
35
40
  #endif
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (C) 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.
@@ -11,10 +11,10 @@
11
11
  #define GIT_OBJECTS_PACK_DIR GIT_OBJECTS_DIR "pack/"
12
12
 
13
13
  #define GIT_HOOKS_DIR "hooks/"
14
- #define GIT_HOOKS_DIR_MODE 0755
14
+ #define GIT_HOOKS_DIR_MODE 0777
15
15
 
16
16
  #define GIT_HOOKS_README_FILE GIT_HOOKS_DIR "README.sample"
17
- #define GIT_HOOKS_README_MODE 0755
17
+ #define GIT_HOOKS_README_MODE 0777
18
18
  #define GIT_HOOKS_README_CONTENT \
19
19
  "#!/bin/sh\n"\
20
20
  "#\n"\
@@ -23,16 +23,16 @@
23
23
  "# more information.\n"
24
24
 
25
25
  #define GIT_INFO_DIR "info/"
26
- #define GIT_INFO_DIR_MODE 0755
26
+ #define GIT_INFO_DIR_MODE 0777
27
27
 
28
28
  #define GIT_INFO_EXCLUDE_FILE GIT_INFO_DIR "exclude"
29
- #define GIT_INFO_EXCLUDE_MODE 0644
29
+ #define GIT_INFO_EXCLUDE_MODE 0666
30
30
  #define GIT_INFO_EXCLUDE_CONTENT \
31
31
  "# File patterns to ignore; see `git help ignore` for more information.\n"\
32
32
  "# Lines that start with '#' are comments.\n"
33
33
 
34
34
  #define GIT_DESC_FILE "description"
35
- #define GIT_DESC_MODE 0644
35
+ #define GIT_DESC_MODE 0666
36
36
  #define GIT_DESC_CONTENT \
37
37
  "Unnamed repository; edit this file 'description' to name the repository.\n"
38
38
 
@@ -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.
@@ -8,6 +8,7 @@
8
8
  #include <ctype.h>
9
9
 
10
10
  #include "git2/object.h"
11
+ #include "git2/refdb.h"
11
12
 
12
13
  #include "common.h"
13
14
  #include "repository.h"
@@ -20,6 +21,7 @@
20
21
  #include "filter.h"
21
22
  #include "odb.h"
22
23
  #include "remote.h"
24
+ #include "merge.h"
23
25
 
24
26
  #define GIT_FILE_CONTENT_PREFIX "gitdir:"
25
27
 
@@ -38,6 +40,15 @@ static void drop_odb(git_repository *repo)
38
40
  }
39
41
  }
40
42
 
43
+ static void drop_refdb(git_repository *repo)
44
+ {
45
+ if (repo->_refdb != NULL) {
46
+ GIT_REFCOUNT_OWN(repo->_refdb, NULL);
47
+ git_refdb_free(repo->_refdb);
48
+ repo->_refdb = NULL;
49
+ }
50
+ }
51
+
41
52
  static void drop_config(git_repository *repo)
42
53
  {
43
54
  if (repo->_config != NULL) {
@@ -64,7 +75,6 @@ void git_repository_free(git_repository *repo)
64
75
  return;
65
76
 
66
77
  git_cache_free(&repo->objects);
67
- git_repository__refcache_free(&repo->references);
68
78
  git_attr_cache_flush(repo);
69
79
  git_submodule_config_free(repo);
70
80
 
@@ -74,6 +84,7 @@ void git_repository_free(git_repository *repo)
74
84
  drop_config(repo);
75
85
  drop_index(repo);
76
86
  drop_odb(repo);
87
+ drop_refdb(repo);
77
88
 
78
89
  git__free(repo);
79
90
  }
@@ -357,10 +368,41 @@ static int find_repo(
357
368
  return error;
358
369
  }
359
370
 
371
+ int git_repository_open_bare(
372
+ git_repository **repo_ptr,
373
+ const char *bare_path)
374
+ {
375
+ int error;
376
+ git_buf path = GIT_BUF_INIT;
377
+ git_repository *repo = NULL;
378
+
379
+ if ((error = git_path_prettify_dir(&path, bare_path, NULL)) < 0)
380
+ return error;
381
+
382
+ if (!valid_repository_path(&path)) {
383
+ git_buf_free(&path);
384
+ giterr_set(GITERR_REPOSITORY, "Path is not a repository: %s", bare_path);
385
+ return GIT_ENOTFOUND;
386
+ }
387
+
388
+ repo = repository_alloc();
389
+ GITERR_CHECK_ALLOC(repo);
390
+
391
+ repo->path_repository = git_buf_detach(&path);
392
+ GITERR_CHECK_ALLOC(repo->path_repository);
393
+
394
+ /* of course we're bare! */
395
+ repo->is_bare = 1;
396
+ repo->workdir = NULL;
397
+
398
+ *repo_ptr = repo;
399
+ return 0;
400
+ }
401
+
360
402
  int git_repository_open_ext(
361
403
  git_repository **repo_ptr,
362
404
  const char *start_path,
363
- uint32_t flags,
405
+ unsigned int flags,
364
406
  const char *ceiling_dirs)
365
407
  {
366
408
  int error;
@@ -449,37 +491,46 @@ static int load_config(
449
491
  const char *xdg_config_path,
450
492
  const char *system_config_path)
451
493
  {
494
+ int error;
452
495
  git_buf config_path = GIT_BUF_INIT;
453
496
  git_config *cfg = NULL;
454
497
 
455
498
  assert(repo && out);
456
499
 
457
- if (git_config_new(&cfg) < 0)
458
- return -1;
500
+ if ((error = git_config_new(&cfg)) < 0)
501
+ return error;
459
502
 
460
- if (git_buf_joinpath(
461
- &config_path, repo->path_repository, GIT_CONFIG_FILENAME_INREPO) < 0)
503
+ error = git_buf_joinpath(
504
+ &config_path, repo->path_repository, GIT_CONFIG_FILENAME_INREPO);
505
+ if (error < 0)
462
506
  goto on_error;
463
507
 
464
- if (git_config_add_file_ondisk(cfg, config_path.ptr, GIT_CONFIG_LEVEL_LOCAL, 0) < 0)
508
+ if ((error = git_config_add_file_ondisk(
509
+ cfg, config_path.ptr, GIT_CONFIG_LEVEL_LOCAL, 0)) < 0 &&
510
+ error != GIT_ENOTFOUND)
465
511
  goto on_error;
466
512
 
467
513
  git_buf_free(&config_path);
468
514
 
469
- if (global_config_path != NULL) {
470
- if (git_config_add_file_ondisk(cfg, global_config_path, GIT_CONFIG_LEVEL_GLOBAL, 0) < 0)
471
- goto on_error;
472
- }
515
+ if (global_config_path != NULL &&
516
+ (error = git_config_add_file_ondisk(
517
+ cfg, global_config_path, GIT_CONFIG_LEVEL_GLOBAL, 0)) < 0 &&
518
+ error != GIT_ENOTFOUND)
519
+ goto on_error;
473
520
 
474
- if (xdg_config_path != NULL) {
475
- if (git_config_add_file_ondisk(cfg, xdg_config_path, GIT_CONFIG_LEVEL_XDG, 0) < 0)
476
- goto on_error;
477
- }
521
+ if (xdg_config_path != NULL &&
522
+ (error = git_config_add_file_ondisk(
523
+ cfg, xdg_config_path, GIT_CONFIG_LEVEL_XDG, 0)) < 0 &&
524
+ error != GIT_ENOTFOUND)
525
+ goto on_error;
478
526
 
479
- if (system_config_path != NULL) {
480
- if (git_config_add_file_ondisk(cfg, system_config_path, GIT_CONFIG_LEVEL_SYSTEM, 0) < 0)
481
- goto on_error;
482
- }
527
+ if (system_config_path != NULL &&
528
+ (error = git_config_add_file_ondisk(
529
+ cfg, system_config_path, GIT_CONFIG_LEVEL_SYSTEM, 0)) < 0 &&
530
+ error != GIT_ENOTFOUND)
531
+ goto on_error;
532
+
533
+ giterr_clear(); /* clear any lingering ENOTFOUND errors */
483
534
 
484
535
  *out = cfg;
485
536
  return 0;
@@ -488,7 +539,7 @@ on_error:
488
539
  git_buf_free(&config_path);
489
540
  git_config_free(cfg);
490
541
  *out = NULL;
491
- return -1;
542
+ return error;
492
543
  }
493
544
 
494
545
  int git_repository_config__weakptr(git_config **out, git_repository *repo)
@@ -543,6 +594,7 @@ void git_repository_set_config(git_repository *repo, git_config *config)
543
594
 
544
595
  repo->_config = config;
545
596
  GIT_REFCOUNT_OWN(repo->_config, repo);
597
+ GIT_REFCOUNT_INC(repo->_config);
546
598
  }
547
599
 
548
600
  int git_repository_odb__weakptr(git_odb **out, git_repository *repo)
@@ -589,6 +641,45 @@ void git_repository_set_odb(git_repository *repo, git_odb *odb)
589
641
  GIT_REFCOUNT_INC(odb);
590
642
  }
591
643
 
644
+ int git_repository_refdb__weakptr(git_refdb **out, git_repository *repo)
645
+ {
646
+ assert(out && repo);
647
+
648
+ if (repo->_refdb == NULL) {
649
+ int res;
650
+
651
+ res = git_refdb_open(&repo->_refdb, repo);
652
+
653
+ if (res < 0)
654
+ return -1;
655
+
656
+ GIT_REFCOUNT_OWN(repo->_refdb, repo);
657
+ }
658
+
659
+ *out = repo->_refdb;
660
+ return 0;
661
+ }
662
+
663
+ int git_repository_refdb(git_refdb **out, git_repository *repo)
664
+ {
665
+ if (git_repository_refdb__weakptr(out, repo) < 0)
666
+ return -1;
667
+
668
+ GIT_REFCOUNT_INC(*out);
669
+ return 0;
670
+ }
671
+
672
+ void git_repository_set_refdb(git_repository *repo, git_refdb *refdb)
673
+ {
674
+ assert (repo && refdb);
675
+
676
+ drop_refdb(repo);
677
+
678
+ repo->_refdb = refdb;
679
+ GIT_REFCOUNT_OWN(repo->_refdb, repo);
680
+ GIT_REFCOUNT_INC(refdb);
681
+ }
682
+
592
683
  int git_repository_index__weakptr(git_index **out, git_repository *repo)
593
684
  {
594
685
  assert(out && repo);
@@ -749,6 +840,23 @@ static bool are_symlinks_supported(const char *wd_path)
749
840
  return _symlinks_supported;
750
841
  }
751
842
 
843
+ static int create_empty_file(const char *path, mode_t mode)
844
+ {
845
+ int fd;
846
+
847
+ if ((fd = p_creat(path, mode)) < 0) {
848
+ giterr_set(GITERR_OS, "Error while creating '%s'", path);
849
+ return -1;
850
+ }
851
+
852
+ if (p_close(fd) < 0) {
853
+ giterr_set(GITERR_OS, "Error while closing '%s'", path);
854
+ return -1;
855
+ }
856
+
857
+ return 0;
858
+ }
859
+
752
860
  static int repo_init_config(
753
861
  const char *repo_dir,
754
862
  const char *work_dir,
@@ -765,6 +873,12 @@ static int repo_init_config(
765
873
  if (git_buf_joinpath(&cfg_path, repo_dir, GIT_CONFIG_FILENAME_INREPO) < 0)
766
874
  return -1;
767
875
 
876
+ if (!git_path_isfile(git_buf_cstr(&cfg_path)) &&
877
+ create_empty_file(git_buf_cstr(&cfg_path), GIT_CONFIG_FILE_MODE) < 0) {
878
+ git_buf_free(&cfg_path);
879
+ return -1;
880
+ }
881
+
768
882
  if (git_config_open_ondisk(&config, git_buf_cstr(&cfg_path)) < 0) {
769
883
  git_buf_free(&cfg_path);
770
884
  return -1;
@@ -791,7 +905,7 @@ static int repo_init_config(
791
905
  SET_REPO_CONFIG(string, "core.worktree", work_dir);
792
906
  }
793
907
  else if ((opts->flags & GIT_REPOSITORY_INIT__IS_REINIT) != 0) {
794
- if (git_config_delete(config, "core.worktree") < 0)
908
+ if (git_config_delete_entry(config, "core.worktree") < 0)
795
909
  giterr_clear();
796
910
  }
797
911
  } else {
@@ -901,7 +1015,7 @@ static int repo_write_gitlink(
901
1015
  error = git_buf_printf(&buf, "%s %s", GIT_FILE_CONTENT_PREFIX, to_repo);
902
1016
 
903
1017
  if (!error)
904
- error = repo_write_template(in_dir, true, DOT_GIT, 0644, true, buf.ptr);
1018
+ error = repo_write_template(in_dir, true, DOT_GIT, 0666, true, buf.ptr);
905
1019
 
906
1020
  cleanup:
907
1021
  git_buf_free(&buf);
@@ -911,7 +1025,7 @@ cleanup:
911
1025
  static mode_t pick_dir_mode(git_repository_init_options *opts)
912
1026
  {
913
1027
  if (opts->mode == GIT_REPOSITORY_INIT_SHARED_UMASK)
914
- return 0755;
1028
+ return 0777;
915
1029
  if (opts->mode == GIT_REPOSITORY_INIT_SHARED_GROUP)
916
1030
  return (0775 | S_ISGID);
917
1031
  if (opts->mode == GIT_REPOSITORY_INIT_SHARED_ALL)
@@ -973,7 +1087,8 @@ static int repo_init_structure(
973
1087
  }
974
1088
 
975
1089
  error = git_futils_cp_r(tdir, repo_dir,
976
- GIT_CPDIR_COPY_SYMLINKS | GIT_CPDIR_CHMOD, dmode);
1090
+ GIT_CPDIR_COPY_SYMLINKS | GIT_CPDIR_CHMOD_DIRS |
1091
+ GIT_CPDIR_SIMPLE_TO_MODE, dmode);
977
1092
 
978
1093
  if (error < 0) {
979
1094
  if (strcmp(tdir, GIT_TEMPLATE_DIR) != 0)
@@ -982,6 +1097,7 @@ static int repo_init_structure(
982
1097
  /* if template was default, ignore error and use internal */
983
1098
  giterr_clear();
984
1099
  external_tpl = false;
1100
+ error = 0;
985
1101
  }
986
1102
  }
987
1103
 
@@ -1007,6 +1123,17 @@ static int repo_init_structure(
1007
1123
  return error;
1008
1124
  }
1009
1125
 
1126
+ static int mkdir_parent(git_buf *buf, uint32_t mode, bool skip2)
1127
+ {
1128
+ /* When making parent directories during repository initialization
1129
+ * don't try to set gid or grant world write access
1130
+ */
1131
+ return git_futils_mkdir(
1132
+ buf->ptr, NULL, mode & ~(S_ISGID | 0002),
1133
+ GIT_MKDIR_PATH | GIT_MKDIR_VERIFY_DIR |
1134
+ (skip2 ? GIT_MKDIR_SKIP_LAST2 : GIT_MKDIR_SKIP_LAST));
1135
+ }
1136
+
1010
1137
  static int repo_init_directories(
1011
1138
  git_buf *repo_path,
1012
1139
  git_buf *wd_path,
@@ -1014,14 +1141,36 @@ static int repo_init_directories(
1014
1141
  git_repository_init_options *opts)
1015
1142
  {
1016
1143
  int error = 0;
1017
- bool add_dotgit, has_dotgit, natural_wd;
1144
+ bool is_bare, add_dotgit, has_dotgit, natural_wd;
1018
1145
  mode_t dirmode;
1019
1146
 
1147
+ /* There are three possible rules for what we are allowed to create:
1148
+ * - MKPATH means anything we need
1149
+ * - MKDIR means just the .git directory and its parent and the workdir
1150
+ * - Neither means only the .git directory can be created
1151
+ *
1152
+ * There are 5 "segments" of path that we might need to deal with:
1153
+ * 1. The .git directory
1154
+ * 2. The parent of the .git directory
1155
+ * 3. Everything above the parent of the .git directory
1156
+ * 4. The working directory (often the same as #2)
1157
+ * 5. Everything above the working directory (often the same as #3)
1158
+ *
1159
+ * For all directories created, we start with the init_mode value for
1160
+ * permissions and then strip off bits in some cases:
1161
+ *
1162
+ * For MKPATH, we create #3 (and #5) paths without S_ISGID or S_IWOTH
1163
+ * For MKPATH and MKDIR, we create #2 (and #4) without S_ISGID
1164
+ * For all rules, we create #1 using the untouched init_mode
1165
+ */
1166
+
1020
1167
  /* set up repo path */
1021
1168
 
1169
+ is_bare = ((opts->flags & GIT_REPOSITORY_INIT_BARE) != 0);
1170
+
1022
1171
  add_dotgit =
1023
1172
  (opts->flags & GIT_REPOSITORY_INIT_NO_DOTGIT_DIR) == 0 &&
1024
- (opts->flags & GIT_REPOSITORY_INIT_BARE) == 0 &&
1173
+ !is_bare &&
1025
1174
  git__suffixcmp(given_repo, "/" DOT_GIT) != 0 &&
1026
1175
  git__suffixcmp(given_repo, "/" GIT_DIR) != 0;
1027
1176
 
@@ -1034,7 +1183,7 @@ static int repo_init_directories(
1034
1183
 
1035
1184
  /* set up workdir path */
1036
1185
 
1037
- if ((opts->flags & GIT_REPOSITORY_INIT_BARE) == 0) {
1186
+ if (!is_bare) {
1038
1187
  if (opts->workdir_path) {
1039
1188
  if (git_path_join_unrooted(
1040
1189
  wd_path, opts->workdir_path, repo_path->ptr, NULL) < 0)
@@ -1066,30 +1215,45 @@ static int repo_init_directories(
1066
1215
 
1067
1216
  dirmode = pick_dir_mode(opts);
1068
1217
 
1069
- if ((opts->flags & GIT_REPOSITORY_INIT_MKDIR) != 0 && has_dotgit) {
1070
- git_buf p = GIT_BUF_INIT;
1071
- if ((error = git_path_dirname_r(&p, repo_path->ptr)) >= 0)
1072
- error = git_futils_mkdir(p.ptr, NULL, dirmode, 0);
1073
- git_buf_free(&p);
1218
+ if ((opts->flags & GIT_REPOSITORY_INIT_MKPATH) != 0) {
1219
+ /* create path #5 */
1220
+ if (wd_path->size > 0 &&
1221
+ (error = mkdir_parent(wd_path, dirmode, false)) < 0)
1222
+ return error;
1223
+
1224
+ /* create path #3 (if not the same as #5) */
1225
+ if (!natural_wd &&
1226
+ (error = mkdir_parent(repo_path, dirmode, has_dotgit)) < 0)
1227
+ return error;
1228
+ }
1229
+
1230
+ if ((opts->flags & GIT_REPOSITORY_INIT_MKDIR) != 0 ||
1231
+ (opts->flags & GIT_REPOSITORY_INIT_MKPATH) != 0)
1232
+ {
1233
+ /* create path #4 */
1234
+ if (wd_path->size > 0 &&
1235
+ (error = git_futils_mkdir(
1236
+ wd_path->ptr, NULL, dirmode & ~S_ISGID,
1237
+ GIT_MKDIR_VERIFY_DIR)) < 0)
1238
+ return error;
1239
+
1240
+ /* create path #2 (if not the same as #4) */
1241
+ if (!natural_wd &&
1242
+ (error = git_futils_mkdir(
1243
+ repo_path->ptr, NULL, dirmode & ~S_ISGID,
1244
+ GIT_MKDIR_VERIFY_DIR | GIT_MKDIR_SKIP_LAST)) < 0)
1245
+ return error;
1074
1246
  }
1075
1247
 
1076
1248
  if ((opts->flags & GIT_REPOSITORY_INIT_MKDIR) != 0 ||
1077
1249
  (opts->flags & GIT_REPOSITORY_INIT_MKPATH) != 0 ||
1078
1250
  has_dotgit)
1079
1251
  {
1080
- uint32_t mkflag = GIT_MKDIR_CHMOD;
1081
- if ((opts->flags & GIT_REPOSITORY_INIT_MKPATH) != 0)
1082
- mkflag |= GIT_MKDIR_PATH;
1083
- error = git_futils_mkdir(repo_path->ptr, NULL, dirmode, mkflag);
1252
+ /* create path #1 */
1253
+ error = git_futils_mkdir(repo_path->ptr, NULL, dirmode,
1254
+ GIT_MKDIR_VERIFY_DIR | ((dirmode & S_ISGID) ? GIT_MKDIR_CHMOD : 0));
1084
1255
  }
1085
1256
 
1086
- if (wd_path->size > 0 &&
1087
- !natural_wd &&
1088
- ((opts->flags & GIT_REPOSITORY_INIT_MKDIR) != 0 ||
1089
- (opts->flags & GIT_REPOSITORY_INIT_MKPATH) != 0))
1090
- error = git_futils_mkdir(wd_path->ptr, NULL, dirmode & ~S_ISGID,
1091
- (opts->flags & GIT_REPOSITORY_INIT_MKPATH) ? GIT_MKDIR_PATH : 0);
1092
-
1093
1257
  /* prettify both directories now that they are created */
1094
1258
 
1095
1259
  if (!error) {
@@ -1107,8 +1271,7 @@ static int repo_init_create_origin(git_repository *repo, const char *url)
1107
1271
  int error;
1108
1272
  git_remote *remote;
1109
1273
 
1110
- if (!(error = git_remote_add(&remote, repo, GIT_REMOTE_ORIGIN, url))) {
1111
- error = git_remote_save(remote);
1274
+ if (!(error = git_remote_create(&remote, repo, GIT_REMOTE_ORIGIN, url))) {
1112
1275
  git_remote_free(remote);
1113
1276
  }
1114
1277
 
@@ -1118,9 +1281,8 @@ static int repo_init_create_origin(git_repository *repo, const char *url)
1118
1281
  int git_repository_init(
1119
1282
  git_repository **repo_out, const char *path, unsigned is_bare)
1120
1283
  {
1121
- git_repository_init_options opts;
1284
+ git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT;
1122
1285
 
1123
- memset(&opts, 0, sizeof(opts));
1124
1286
  opts.flags = GIT_REPOSITORY_INIT_MKPATH; /* don't love this default */
1125
1287
  if (is_bare)
1126
1288
  opts.flags |= GIT_REPOSITORY_INIT_BARE;
@@ -1129,14 +1291,16 @@ int git_repository_init(
1129
1291
  }
1130
1292
 
1131
1293
  int git_repository_init_ext(
1132
- git_repository **repo_out,
1294
+ git_repository **out,
1133
1295
  const char *given_repo,
1134
1296
  git_repository_init_options *opts)
1135
1297
  {
1136
1298
  int error;
1137
1299
  git_buf repo_path = GIT_BUF_INIT, wd_path = GIT_BUF_INIT;
1138
1300
 
1139
- assert(repo_out && given_repo && opts);
1301
+ assert(out && given_repo && opts);
1302
+
1303
+ GITERR_CHECK_VERSION(opts, GIT_REPOSITORY_INIT_OPTIONS_VERSION, "git_repository_init_options");
1140
1304
 
1141
1305
  error = repo_init_directories(&repo_path, &wd_path, given_repo, opts);
1142
1306
  if (error < 0)
@@ -1169,10 +1333,10 @@ int git_repository_init_ext(
1169
1333
  if (error < 0)
1170
1334
  goto cleanup;
1171
1335
 
1172
- error = git_repository_open(repo_out, git_buf_cstr(&repo_path));
1336
+ error = git_repository_open(out, git_buf_cstr(&repo_path));
1173
1337
 
1174
1338
  if (!error && opts->origin_url)
1175
- error = repo_init_create_origin(*repo_out, opts->origin_url);
1339
+ error = repo_init_create_origin(*out, opts->origin_url);
1176
1340
 
1177
1341
  cleanup:
1178
1342
  git_buf_free(&repo_path);
@@ -1198,7 +1362,7 @@ int git_repository_head_detached(git_repository *repo)
1198
1362
  return 0;
1199
1363
  }
1200
1364
 
1201
- exists = git_odb_exists(odb, git_reference_oid(ref));
1365
+ exists = git_odb_exists(odb, git_reference_target(ref));
1202
1366
 
1203
1367
  git_reference_free(ref);
1204
1368
  return exists;
@@ -1206,9 +1370,19 @@ int git_repository_head_detached(git_repository *repo)
1206
1370
 
1207
1371
  int git_repository_head(git_reference **head_out, git_repository *repo)
1208
1372
  {
1373
+ git_reference *head;
1209
1374
  int error;
1210
1375
 
1211
- error = git_reference_lookup_resolved(head_out, repo, GIT_HEAD_FILE, -1);
1376
+ if ((error = git_reference_lookup(&head, repo, GIT_HEAD_FILE)) < 0)
1377
+ return error;
1378
+
1379
+ if (git_reference_type(head) == GIT_REF_OID) {
1380
+ *head_out = head;
1381
+ return 0;
1382
+ }
1383
+
1384
+ error = git_reference_lookup_resolved(head_out, repo, git_reference_symbolic_target(head), -1);
1385
+ git_reference_free(head);
1212
1386
 
1213
1387
  return error == GIT_ENOTFOUND ? GIT_EORPHANEDHEAD : error;
1214
1388
  }
@@ -1230,36 +1404,47 @@ int git_repository_head_orphan(git_repository *repo)
1230
1404
  return 0;
1231
1405
  }
1232
1406
 
1407
+ static int at_least_one_cb(const char *refname, void *payload)
1408
+ {
1409
+ GIT_UNUSED(refname);
1410
+ GIT_UNUSED(payload);
1411
+
1412
+ return GIT_EUSER;
1413
+ }
1414
+
1415
+ static int repo_contains_no_reference(git_repository *repo)
1416
+ {
1417
+ int error;
1418
+
1419
+ error = git_reference_foreach(repo, GIT_REF_LISTALL, at_least_one_cb, NULL);
1420
+
1421
+ if (error == GIT_EUSER)
1422
+ return 0;
1423
+
1424
+ return error == 0 ? 1 : error;
1425
+ }
1426
+
1233
1427
  int git_repository_is_empty(git_repository *repo)
1234
1428
  {
1235
- git_reference *head = NULL, *branch = NULL;
1429
+ git_reference *head = NULL;
1236
1430
  int error;
1237
1431
 
1238
1432
  if (git_reference_lookup(&head, repo, GIT_HEAD_FILE) < 0)
1239
1433
  return -1;
1240
1434
 
1241
- if (git_reference_type(head) != GIT_REF_SYMBOLIC) {
1242
- git_reference_free(head);
1243
- return 0;
1244
- }
1435
+ if (!(error = git_reference_type(head) == GIT_REF_SYMBOLIC))
1436
+ goto cleanup;
1245
1437
 
1246
- if (strcmp(git_reference_target(head), GIT_REFS_HEADS_DIR "master") != 0) {
1247
- git_reference_free(head);
1248
- return 0;
1249
- }
1438
+ if (!(error = strcmp(
1439
+ git_reference_symbolic_target(head),
1440
+ GIT_REFS_HEADS_DIR "master") == 0))
1441
+ goto cleanup;
1250
1442
 
1251
- error = git_reference_resolve(&branch, head);
1443
+ error = repo_contains_no_reference(repo);
1252
1444
 
1445
+ cleanup:
1253
1446
  git_reference_free(head);
1254
- git_reference_free(branch);
1255
-
1256
- if (error == GIT_ENOTFOUND)
1257
- return 1;
1258
-
1259
- if (error < 0)
1260
- return -1;
1261
-
1262
- return 0;
1447
+ return error < 0 ? -1 : error;
1263
1448
  }
1264
1449
 
1265
1450
  const char *git_repository_path(git_repository *repo)
@@ -1302,7 +1487,7 @@ int git_repository_set_workdir(
1302
1487
 
1303
1488
  /* passthrough error means gitlink is unnecessary */
1304
1489
  if (error == GIT_PASSTHROUGH)
1305
- error = git_config_delete(config, "core.worktree");
1490
+ error = git_config_delete_entry(config, "core.worktree");
1306
1491
  else if (!error)
1307
1492
  error = git_config_set_string(config, "core.worktree", path.ptr);
1308
1493
 
@@ -1330,25 +1515,22 @@ int git_repository_is_bare(git_repository *repo)
1330
1515
 
1331
1516
  int git_repository_head_tree(git_tree **tree, git_repository *repo)
1332
1517
  {
1333
- git_oid head_oid;
1334
- git_object *obj = NULL;
1518
+ git_reference *head;
1519
+ git_object *obj;
1520
+ int error;
1335
1521
 
1336
- if (git_reference_name_to_oid(&head_oid, repo, GIT_HEAD_FILE) < 0) {
1337
- /* cannot resolve HEAD - probably brand new repo */
1338
- giterr_clear();
1339
- *tree = NULL;
1340
- return 0;
1341
- }
1522
+ if ((error = git_repository_head(&head, repo)) < 0)
1523
+ return error;
1342
1524
 
1343
- if (git_object_lookup(&obj, repo, &head_oid, GIT_OBJ_ANY) < 0 ||
1344
- git_object__resolve_to_type(&obj, GIT_OBJ_TREE) < 0)
1345
- return -1;
1525
+ if ((error = git_reference_peel(&obj, head, GIT_OBJ_TREE)) < 0)
1526
+ goto cleanup;
1346
1527
 
1347
1528
  *tree = (git_tree *)obj;
1348
- return 0;
1349
- }
1350
1529
 
1351
- #define MERGE_MSG_FILE "MERGE_MSG"
1530
+ cleanup:
1531
+ git_reference_free(head);
1532
+ return error;
1533
+ }
1352
1534
 
1353
1535
  int git_repository_message(char *buffer, size_t len, git_repository *repo)
1354
1536
  {
@@ -1356,7 +1538,7 @@ int git_repository_message(char *buffer, size_t len, git_repository *repo)
1356
1538
  struct stat st;
1357
1539
  int error;
1358
1540
 
1359
- if (git_buf_joinpath(&path, repo->path_repository, MERGE_MSG_FILE) < 0)
1541
+ if (git_buf_joinpath(&path, repo->path_repository, GIT_MERGE_MSG_FILE) < 0)
1360
1542
  return -1;
1361
1543
 
1362
1544
  if ((error = p_stat(git_buf_cstr(&path), &st)) < 0) {
@@ -1382,7 +1564,7 @@ int git_repository_message_remove(git_repository *repo)
1382
1564
  git_buf path = GIT_BUF_INIT;
1383
1565
  int error;
1384
1566
 
1385
- if (git_buf_joinpath(&path, repo->path_repository, MERGE_MSG_FILE) < 0)
1567
+ if (git_buf_joinpath(&path, repo->path_repository, GIT_MERGE_MSG_FILE) < 0)
1386
1568
  return -1;
1387
1569
 
1388
1570
  error = p_unlink(git_buf_cstr(&path));
@@ -1480,11 +1662,11 @@ int git_repository_set_head(
1480
1662
 
1481
1663
  if (!error) {
1482
1664
  if (git_reference_is_branch(ref))
1483
- error = git_reference_create_symbolic(&new_head, repo, GIT_HEAD_FILE, git_reference_name(ref), 1);
1665
+ error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE, git_reference_name(ref), 1);
1484
1666
  else
1485
- error = git_repository_set_head_detached(repo, git_reference_oid(ref));
1667
+ error = git_repository_set_head_detached(repo, git_reference_target(ref));
1486
1668
  } else if (looks_like_a_branch(refname))
1487
- error = git_reference_create_symbolic(&new_head, repo, GIT_HEAD_FILE, refname, 1);
1669
+ error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE, refname, 1);
1488
1670
 
1489
1671
  git_reference_free(ref);
1490
1672
  git_reference_free(new_head);
@@ -1508,7 +1690,7 @@ int git_repository_set_head_detached(
1508
1690
  if ((error = git_object_peel(&peeled, object, GIT_OBJ_COMMIT)) < 0)
1509
1691
  goto cleanup;
1510
1692
 
1511
- error = git_reference_create_oid(&new_head, repo, GIT_HEAD_FILE, git_object_id(peeled), 1);
1693
+ error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_object_id(peeled), 1);
1512
1694
 
1513
1695
  cleanup:
1514
1696
  git_object_free(object);
@@ -1530,10 +1712,10 @@ int git_repository_detach_head(
1530
1712
  if ((error = git_repository_head(&old_head, repo)) < 0)
1531
1713
  return error;
1532
1714
 
1533
- if ((error = git_object_lookup(&object, repo, git_reference_oid(old_head), GIT_OBJ_COMMIT)) < 0)
1715
+ if ((error = git_object_lookup(&object, repo, git_reference_target(old_head), GIT_OBJ_COMMIT)) < 0)
1534
1716
  goto cleanup;
1535
1717
 
1536
- error = git_reference_create_oid(&new_head, repo, GIT_HEAD_FILE, git_reference_oid(old_head), 1);
1718
+ error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_reference_target(old_head), 1);
1537
1719
 
1538
1720
  cleanup:
1539
1721
  git_object_free(object);
@@ -1541,3 +1723,40 @@ cleanup:
1541
1723
  git_reference_free(new_head);
1542
1724
  return error;
1543
1725
  }
1726
+
1727
+ /**
1728
+ * Loosely ported from git.git
1729
+ * https://github.com/git/git/blob/master/contrib/completion/git-prompt.sh#L198-289
1730
+ */
1731
+ int git_repository_state(git_repository *repo)
1732
+ {
1733
+ git_buf repo_path = GIT_BUF_INIT;
1734
+ int state = GIT_REPOSITORY_STATE_NONE;
1735
+
1736
+ assert(repo);
1737
+
1738
+ if (git_buf_puts(&repo_path, repo->path_repository) < 0)
1739
+ return -1;
1740
+
1741
+ if (git_path_contains_file(&repo_path, GIT_REBASE_MERGE_INTERACTIVE_FILE))
1742
+ state = GIT_REPOSITORY_STATE_REBASE_INTERACTIVE;
1743
+ else if (git_path_contains_dir(&repo_path, GIT_REBASE_MERGE_DIR))
1744
+ state = GIT_REPOSITORY_STATE_REBASE_MERGE;
1745
+ else if (git_path_contains_file(&repo_path, GIT_REBASE_APPLY_REBASING_FILE))
1746
+ state = GIT_REPOSITORY_STATE_REBASE;
1747
+ else if (git_path_contains_file(&repo_path, GIT_REBASE_APPLY_APPLYING_FILE))
1748
+ state = GIT_REPOSITORY_STATE_APPLY_MAILBOX;
1749
+ else if (git_path_contains_dir(&repo_path, GIT_REBASE_APPLY_DIR))
1750
+ state = GIT_REPOSITORY_STATE_APPLY_MAILBOX_OR_REBASE;
1751
+ else if (git_path_contains_file(&repo_path, GIT_MERGE_HEAD_FILE))
1752
+ state = GIT_REPOSITORY_STATE_MERGE;
1753
+ else if(git_path_contains_file(&repo_path, GIT_REVERT_HEAD_FILE))
1754
+ state = GIT_REPOSITORY_STATE_REVERT;
1755
+ else if(git_path_contains_file(&repo_path, GIT_CHERRY_PICK_HEAD_FILE))
1756
+ state = GIT_REPOSITORY_STATE_CHERRY_PICK;
1757
+ else if(git_path_contains_file(&repo_path, GIT_BISECT_LOG_FILE))
1758
+ state = GIT_REPOSITORY_STATE_BISECT;
1759
+
1760
+ git_buf_free(&repo_path);
1761
+ return state;
1762
+ }