rugged 0.17.0.b7 → 0.18.0.b1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (310) hide show
  1. data/LICENSE +1 -1
  2. data/README.md +88 -32
  3. data/ext/rugged/extconf.rb +4 -2
  4. data/ext/rugged/rugged.c +72 -10
  5. data/ext/rugged/rugged.h +14 -10
  6. data/ext/rugged/rugged_blob.c +8 -10
  7. data/ext/rugged/rugged_branch.c +11 -14
  8. data/ext/rugged/rugged_commit.c +31 -24
  9. data/ext/rugged/rugged_config.c +2 -2
  10. data/ext/rugged/rugged_index.c +133 -198
  11. data/ext/rugged/rugged_note.c +372 -0
  12. data/ext/rugged/rugged_object.c +50 -22
  13. data/ext/rugged/rugged_reference.c +122 -130
  14. data/ext/rugged/rugged_remote.c +72 -29
  15. data/ext/rugged/rugged_repo.c +402 -20
  16. data/ext/rugged/rugged_revwalk.c +7 -3
  17. data/ext/rugged/rugged_settings.c +110 -0
  18. data/ext/rugged/rugged_signature.c +23 -7
  19. data/ext/rugged/rugged_tag.c +32 -16
  20. data/ext/rugged/rugged_tree.c +44 -15
  21. data/lib/rugged.rb +1 -0
  22. data/lib/rugged/index.rb +8 -0
  23. data/lib/rugged/remote.rb +13 -0
  24. data/lib/rugged/repository.rb +3 -3
  25. data/lib/rugged/version.rb +1 -1
  26. data/test/blob_test.rb +13 -15
  27. data/test/branch_test.rb +32 -67
  28. data/test/commit_test.rb +50 -12
  29. data/test/config_test.rb +12 -11
  30. data/test/coverage/HEAD.json +1 -1
  31. data/test/coverage/cover.rb +40 -21
  32. data/test/errors_test.rb +34 -0
  33. data/test/fixtures/alternate/objects/14/6ae76773c91e3b1d00cf7a338ec55ae58297e2 +0 -0
  34. data/test/fixtures/alternate/objects/14/9c32d47e99d0a3572ff1e70a2e0051bbf347a9 +0 -0
  35. data/test/fixtures/alternate/objects/14/fb3108588f9421bf764041e5e3ac305eb6277f +0 -0
  36. data/test/fixtures/testrepo.git/logs/refs/notes/commits +1 -0
  37. data/test/fixtures/testrepo.git/objects/44/1034f860c1d5d90e4188d11ae0d325176869a8 +1 -0
  38. data/test/fixtures/testrepo.git/objects/60/d415052a33de2150bf68757f6461df4f563ae4 +0 -0
  39. data/test/fixtures/testrepo.git/objects/68/8a8f4ef7496901d15322972f96e212a9e466cc +1 -0
  40. data/test/fixtures/testrepo.git/objects/94/eca2de348d5f672faf56b0decafa5937e3235e +0 -0
  41. data/test/fixtures/testrepo.git/objects/9b/7384fe1676186192842f5d3e129457b62db9e3 +0 -0
  42. data/test/fixtures/testrepo.git/objects/b7/4713326bc972cc15751ed504dca6f6f3b91f7a +3 -0
  43. data/test/fixtures/testrepo.git/refs/notes/commits +1 -0
  44. data/test/index_test.rb +65 -69
  45. data/test/lib_test.rb +76 -11
  46. data/test/note_test.rb +158 -0
  47. data/test/object_test.rb +8 -11
  48. data/test/reference_test.rb +77 -85
  49. data/test/remote_test.rb +86 -8
  50. data/test/repo_pack_test.rb +9 -7
  51. data/test/repo_reset_test.rb +80 -0
  52. data/test/repo_test.rb +176 -53
  53. data/test/tag_test.rb +44 -7
  54. data/test/test_helper.rb +63 -35
  55. data/test/tree_test.rb +34 -13
  56. data/test/walker_test.rb +14 -14
  57. data/vendor/libgit2/Makefile.embed +1 -1
  58. data/vendor/libgit2/deps/http-parser/http_parser.c +974 -578
  59. data/vendor/libgit2/deps/http-parser/http_parser.h +106 -70
  60. data/vendor/libgit2/deps/regex/regcomp.c +7 -6
  61. data/vendor/libgit2/deps/regex/regex_internal.c +1 -1
  62. data/vendor/libgit2/deps/regex/regex_internal.h +12 -3
  63. data/vendor/libgit2/deps/regex/regexec.c +5 -5
  64. data/vendor/libgit2/include/git2.h +5 -1
  65. data/vendor/libgit2/include/git2/attr.h +4 -2
  66. data/vendor/libgit2/include/git2/blob.h +39 -12
  67. data/vendor/libgit2/include/git2/branch.h +123 -35
  68. data/vendor/libgit2/include/git2/checkout.h +206 -48
  69. data/vendor/libgit2/include/git2/clone.h +72 -27
  70. data/vendor/libgit2/include/git2/commit.h +20 -17
  71. data/vendor/libgit2/include/git2/common.h +67 -1
  72. data/vendor/libgit2/include/git2/config.h +81 -60
  73. data/vendor/libgit2/include/git2/cred_helpers.h +53 -0
  74. data/vendor/libgit2/include/git2/diff.h +459 -150
  75. data/vendor/libgit2/include/git2/errors.h +9 -1
  76. data/vendor/libgit2/include/git2/graph.h +41 -0
  77. data/vendor/libgit2/include/git2/ignore.h +7 -6
  78. data/vendor/libgit2/include/git2/index.h +323 -97
  79. data/vendor/libgit2/include/git2/indexer.h +27 -59
  80. data/vendor/libgit2/include/git2/inttypes.h +4 -0
  81. data/vendor/libgit2/include/git2/merge.h +13 -3
  82. data/vendor/libgit2/include/git2/message.h +14 -8
  83. data/vendor/libgit2/include/git2/net.h +9 -7
  84. data/vendor/libgit2/include/git2/notes.h +88 -29
  85. data/vendor/libgit2/include/git2/object.h +16 -6
  86. data/vendor/libgit2/include/git2/odb.h +80 -17
  87. data/vendor/libgit2/include/git2/odb_backend.h +47 -11
  88. data/vendor/libgit2/include/git2/oid.h +26 -17
  89. data/vendor/libgit2/include/git2/pack.h +62 -8
  90. data/vendor/libgit2/include/git2/push.h +131 -0
  91. data/vendor/libgit2/include/git2/refdb.h +103 -0
  92. data/vendor/libgit2/include/git2/refdb_backend.h +109 -0
  93. data/vendor/libgit2/include/git2/reflog.h +30 -21
  94. data/vendor/libgit2/include/git2/refs.h +215 -193
  95. data/vendor/libgit2/include/git2/refspec.h +22 -2
  96. data/vendor/libgit2/include/git2/remote.h +158 -37
  97. data/vendor/libgit2/include/git2/repository.h +150 -31
  98. data/vendor/libgit2/include/git2/reset.h +43 -9
  99. data/vendor/libgit2/include/git2/revparse.h +48 -4
  100. data/vendor/libgit2/include/git2/revwalk.h +25 -10
  101. data/vendor/libgit2/include/git2/signature.h +20 -12
  102. data/vendor/libgit2/include/git2/stash.h +121 -0
  103. data/vendor/libgit2/include/git2/status.h +122 -53
  104. data/vendor/libgit2/include/git2/strarray.h +17 -11
  105. data/vendor/libgit2/include/git2/submodule.h +42 -7
  106. data/vendor/libgit2/include/git2/tag.h +72 -59
  107. data/vendor/libgit2/include/git2/threads.h +4 -2
  108. data/vendor/libgit2/include/git2/trace.h +68 -0
  109. data/vendor/libgit2/include/git2/transport.h +328 -0
  110. data/vendor/libgit2/include/git2/tree.h +149 -120
  111. data/vendor/libgit2/include/git2/types.h +13 -12
  112. data/vendor/libgit2/include/git2/version.h +3 -3
  113. data/vendor/libgit2/src/amiga/map.c +2 -2
  114. data/vendor/libgit2/src/attr.c +58 -48
  115. data/vendor/libgit2/src/attr.h +4 -18
  116. data/vendor/libgit2/src/attr_file.c +30 -6
  117. data/vendor/libgit2/src/attr_file.h +6 -8
  118. data/vendor/libgit2/src/attrcache.h +24 -0
  119. data/vendor/libgit2/src/blob.c +30 -7
  120. data/vendor/libgit2/src/blob.h +1 -1
  121. data/vendor/libgit2/src/branch.c +361 -68
  122. data/vendor/libgit2/src/branch.h +17 -0
  123. data/vendor/libgit2/src/bswap.h +1 -1
  124. data/vendor/libgit2/src/buf_text.c +291 -0
  125. data/vendor/libgit2/src/buf_text.h +122 -0
  126. data/vendor/libgit2/src/buffer.c +27 -101
  127. data/vendor/libgit2/src/buffer.h +54 -39
  128. data/vendor/libgit2/src/cache.c +15 -6
  129. data/vendor/libgit2/src/cache.h +1 -1
  130. data/vendor/libgit2/src/cc-compat.h +3 -1
  131. data/vendor/libgit2/src/checkout.c +1165 -222
  132. data/vendor/libgit2/src/checkout.h +24 -0
  133. data/vendor/libgit2/src/clone.c +171 -86
  134. data/vendor/libgit2/src/commit.c +44 -45
  135. data/vendor/libgit2/src/commit.h +3 -3
  136. data/vendor/libgit2/src/commit_list.c +194 -0
  137. data/vendor/libgit2/src/commit_list.h +49 -0
  138. data/vendor/libgit2/src/common.h +44 -10
  139. data/vendor/libgit2/src/compress.c +1 -1
  140. data/vendor/libgit2/src/compress.h +1 -1
  141. data/vendor/libgit2/src/config.c +211 -124
  142. data/vendor/libgit2/src/config.h +23 -4
  143. data/vendor/libgit2/src/config_cache.c +2 -2
  144. data/vendor/libgit2/src/config_file.c +129 -53
  145. data/vendor/libgit2/src/config_file.h +10 -8
  146. data/vendor/libgit2/src/crlf.c +66 -67
  147. data/vendor/libgit2/src/date.c +12 -12
  148. data/vendor/libgit2/src/delta-apply.c +14 -1
  149. data/vendor/libgit2/src/delta-apply.h +18 -1
  150. data/vendor/libgit2/src/delta.c +40 -107
  151. data/vendor/libgit2/src/delta.h +19 -17
  152. data/vendor/libgit2/src/diff.c +347 -496
  153. data/vendor/libgit2/src/diff.h +27 -1
  154. data/vendor/libgit2/src/diff_output.c +564 -249
  155. data/vendor/libgit2/src/diff_output.h +15 -8
  156. data/vendor/libgit2/src/diff_tform.c +687 -0
  157. data/vendor/libgit2/src/errors.c +27 -36
  158. data/vendor/libgit2/src/fetch.c +13 -351
  159. data/vendor/libgit2/src/fetch.h +13 -3
  160. data/vendor/libgit2/src/fetchhead.c +295 -0
  161. data/vendor/libgit2/src/fetchhead.h +34 -0
  162. data/vendor/libgit2/src/filebuf.c +42 -15
  163. data/vendor/libgit2/src/filebuf.h +4 -2
  164. data/vendor/libgit2/src/fileops.c +466 -113
  165. data/vendor/libgit2/src/fileops.h +154 -28
  166. data/vendor/libgit2/src/filter.c +3 -75
  167. data/vendor/libgit2/src/filter.h +1 -29
  168. data/vendor/libgit2/src/fnmatch.c +1 -1
  169. data/vendor/libgit2/src/fnmatch.h +1 -1
  170. data/vendor/libgit2/src/global.c +54 -10
  171. data/vendor/libgit2/src/global.h +10 -1
  172. data/vendor/libgit2/src/graph.c +178 -0
  173. data/vendor/libgit2/src/hash.c +25 -52
  174. data/vendor/libgit2/src/hash.h +21 -9
  175. data/vendor/libgit2/src/{sha1/sha1.c → hash/hash_generic.c} +20 -12
  176. data/vendor/libgit2/src/hash/hash_generic.h +24 -0
  177. data/vendor/libgit2/src/hash/hash_openssl.h +45 -0
  178. data/vendor/libgit2/src/hash/hash_win32.c +291 -0
  179. data/vendor/libgit2/src/hash/hash_win32.h +140 -0
  180. data/vendor/libgit2/src/hashsig.c +368 -0
  181. data/vendor/libgit2/src/hashsig.h +72 -0
  182. data/vendor/libgit2/src/ignore.c +22 -15
  183. data/vendor/libgit2/src/ignore.h +6 -1
  184. data/vendor/libgit2/src/index.c +770 -171
  185. data/vendor/libgit2/src/index.h +13 -5
  186. data/vendor/libgit2/src/indexer.c +286 -431
  187. data/vendor/libgit2/src/iterator.c +854 -466
  188. data/vendor/libgit2/src/iterator.h +134 -109
  189. data/vendor/libgit2/src/map.h +1 -1
  190. data/vendor/libgit2/src/merge.c +296 -0
  191. data/vendor/libgit2/src/merge.h +22 -0
  192. data/vendor/libgit2/src/message.c +1 -1
  193. data/vendor/libgit2/src/message.h +1 -1
  194. data/vendor/libgit2/src/mwindow.c +35 -30
  195. data/vendor/libgit2/src/mwindow.h +2 -2
  196. data/vendor/libgit2/src/netops.c +162 -98
  197. data/vendor/libgit2/src/netops.h +50 -15
  198. data/vendor/libgit2/src/notes.c +109 -58
  199. data/vendor/libgit2/src/notes.h +2 -1
  200. data/vendor/libgit2/src/object.c +46 -57
  201. data/vendor/libgit2/src/object.h +1 -8
  202. data/vendor/libgit2/src/odb.c +151 -40
  203. data/vendor/libgit2/src/odb.h +5 -1
  204. data/vendor/libgit2/src/odb_loose.c +4 -5
  205. data/vendor/libgit2/src/odb_pack.c +122 -80
  206. data/vendor/libgit2/src/offmap.h +65 -0
  207. data/vendor/libgit2/src/oid.c +12 -4
  208. data/vendor/libgit2/src/oidmap.h +1 -1
  209. data/vendor/libgit2/src/pack-objects.c +88 -61
  210. data/vendor/libgit2/src/pack-objects.h +8 -8
  211. data/vendor/libgit2/src/pack.c +293 -28
  212. data/vendor/libgit2/src/pack.h +49 -4
  213. data/vendor/libgit2/src/path.c +103 -14
  214. data/vendor/libgit2/src/path.h +23 -7
  215. data/vendor/libgit2/src/pathspec.c +168 -0
  216. data/vendor/libgit2/src/pathspec.h +40 -0
  217. data/vendor/libgit2/src/pool.c +29 -4
  218. data/vendor/libgit2/src/pool.h +8 -1
  219. data/vendor/libgit2/src/posix.c +26 -27
  220. data/vendor/libgit2/src/posix.h +2 -3
  221. data/vendor/libgit2/src/pqueue.c +23 -1
  222. data/vendor/libgit2/src/pqueue.h +23 -1
  223. data/vendor/libgit2/src/push.c +653 -0
  224. data/vendor/libgit2/src/push.h +51 -0
  225. data/vendor/libgit2/src/refdb.c +185 -0
  226. data/vendor/libgit2/src/refdb.h +46 -0
  227. data/vendor/libgit2/src/refdb_fs.c +1024 -0
  228. data/vendor/libgit2/src/refdb_fs.h +15 -0
  229. data/vendor/libgit2/src/reflog.c +77 -45
  230. data/vendor/libgit2/src/reflog.h +1 -3
  231. data/vendor/libgit2/src/refs.c +366 -1326
  232. data/vendor/libgit2/src/refs.h +22 -13
  233. data/vendor/libgit2/src/refspec.c +46 -7
  234. data/vendor/libgit2/src/refspec.h +11 -1
  235. data/vendor/libgit2/src/remote.c +758 -120
  236. data/vendor/libgit2/src/remote.h +10 -5
  237. data/vendor/libgit2/src/repo_template.h +6 -6
  238. data/vendor/libgit2/src/repository.c +315 -96
  239. data/vendor/libgit2/src/repository.h +5 -3
  240. data/vendor/libgit2/src/reset.c +99 -81
  241. data/vendor/libgit2/src/revparse.c +157 -84
  242. data/vendor/libgit2/src/revwalk.c +68 -470
  243. data/vendor/libgit2/src/revwalk.h +44 -0
  244. data/vendor/libgit2/src/sha1_lookup.c +1 -1
  245. data/vendor/libgit2/src/sha1_lookup.h +1 -1
  246. data/vendor/libgit2/src/signature.c +68 -200
  247. data/vendor/libgit2/src/signature.h +1 -1
  248. data/vendor/libgit2/src/stash.c +663 -0
  249. data/vendor/libgit2/src/status.c +101 -79
  250. data/vendor/libgit2/src/strmap.h +1 -1
  251. data/vendor/libgit2/src/submodule.c +67 -51
  252. data/vendor/libgit2/src/submodule.h +1 -1
  253. data/vendor/libgit2/src/tag.c +35 -29
  254. data/vendor/libgit2/src/tag.h +1 -1
  255. data/vendor/libgit2/src/thread-utils.c +1 -1
  256. data/vendor/libgit2/src/thread-utils.h +2 -2
  257. data/vendor/libgit2/src/trace.c +39 -0
  258. data/vendor/libgit2/src/trace.h +56 -0
  259. data/vendor/libgit2/src/transport.c +81 -34
  260. data/vendor/libgit2/src/transports/cred.c +60 -0
  261. data/vendor/libgit2/src/transports/cred_helpers.c +49 -0
  262. data/vendor/libgit2/src/transports/git.c +234 -127
  263. data/vendor/libgit2/src/transports/http.c +761 -433
  264. data/vendor/libgit2/src/transports/local.c +460 -64
  265. data/vendor/libgit2/src/transports/smart.c +345 -0
  266. data/vendor/libgit2/src/transports/smart.h +179 -0
  267. data/vendor/libgit2/src/{pkt.c → transports/smart_pkt.c} +131 -12
  268. data/vendor/libgit2/src/transports/smart_protocol.c +856 -0
  269. data/vendor/libgit2/src/transports/winhttp.c +1136 -0
  270. data/vendor/libgit2/src/tree-cache.c +2 -2
  271. data/vendor/libgit2/src/tree-cache.h +1 -1
  272. data/vendor/libgit2/src/tree.c +239 -166
  273. data/vendor/libgit2/src/tree.h +11 -2
  274. data/vendor/libgit2/src/tsort.c +39 -23
  275. data/vendor/libgit2/src/unix/map.c +1 -1
  276. data/vendor/libgit2/src/unix/posix.h +12 -2
  277. data/vendor/libgit2/src/unix/realpath.c +30 -0
  278. data/vendor/libgit2/src/util.c +250 -13
  279. data/vendor/libgit2/src/util.h +71 -14
  280. data/vendor/libgit2/src/vector.c +123 -60
  281. data/vendor/libgit2/src/vector.h +24 -22
  282. data/vendor/libgit2/src/win32/dir.c +1 -1
  283. data/vendor/libgit2/src/win32/dir.h +1 -1
  284. data/vendor/libgit2/src/win32/error.c +77 -0
  285. data/vendor/libgit2/src/win32/error.h +13 -0
  286. data/vendor/libgit2/src/win32/findfile.c +143 -54
  287. data/vendor/libgit2/src/win32/findfile.h +10 -6
  288. data/vendor/libgit2/src/win32/map.c +1 -1
  289. data/vendor/libgit2/src/win32/mingw-compat.h +1 -1
  290. data/vendor/libgit2/src/win32/msvc-compat.h +10 -1
  291. data/vendor/libgit2/src/win32/posix.h +10 -1
  292. data/vendor/libgit2/src/win32/posix_w32.c +132 -63
  293. data/vendor/libgit2/src/win32/precompiled.c +1 -1
  294. data/vendor/libgit2/src/win32/pthread.c +1 -1
  295. data/vendor/libgit2/src/win32/pthread.h +1 -1
  296. data/vendor/libgit2/src/win32/utf-conv.c +5 -5
  297. data/vendor/libgit2/src/win32/utf-conv.h +3 -3
  298. data/vendor/libgit2/src/win32/version.h +20 -0
  299. metadata +308 -252
  300. data/test/fixtures/testrepo.git/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 +0 -0
  301. data/test/fixtures/testrepo.git/objects/7f/043268ea43ce18e3540acaabf9e090c91965b0 +0 -0
  302. data/test/fixtures/testrepo.git/objects/a3/e05719b428a2d0ed7a55c4ce53dcc5768c6d5e +0 -0
  303. data/test/index_test.rb~ +0 -218
  304. data/vendor/libgit2/src/pkt.h +0 -91
  305. data/vendor/libgit2/src/ppc/sha1.c +0 -70
  306. data/vendor/libgit2/src/ppc/sha1.h +0 -26
  307. data/vendor/libgit2/src/protocol.c +0 -110
  308. data/vendor/libgit2/src/protocol.h +0 -21
  309. data/vendor/libgit2/src/sha1.h +0 -33
  310. data/vendor/libgit2/src/transport.h +0 -148
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (C) 2009-2012 the libgit2 contributors
2
+ * Copyright (C) the libgit2 contributors. All rights reserved.
3
3
  *
4
4
  * This file is part of libgit2, distributed under the GNU GPL v2 with
5
5
  * a Linking Exception. For full terms see the included COPYING file.
@@ -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
+ }