rugged 1.1.1 → 1.2.0

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 (277) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -0
  3. data/README.md +1 -1
  4. data/ext/rugged/rugged.c +7 -4
  5. data/ext/rugged/rugged_object.c +1 -1
  6. data/ext/rugged/rugged_repo.c +3 -3
  7. data/lib/rugged/repository.rb +2 -2
  8. data/lib/rugged/version.rb +1 -1
  9. data/vendor/libgit2/CMakeLists.txt +11 -6
  10. data/vendor/libgit2/COPYING +109 -1
  11. data/vendor/libgit2/cmake/Findfutimens.cmake +14 -0
  12. data/vendor/libgit2/cmake/SelectHTTPSBackend.cmake +4 -0
  13. data/vendor/libgit2/cmake/SelectHashes.cmake +1 -0
  14. data/vendor/libgit2/deps/chromium-zlib/CMakeLists.txt +101 -0
  15. data/vendor/libgit2/deps/ntlmclient/CMakeLists.txt +17 -5
  16. data/vendor/libgit2/deps/ntlmclient/crypt.h +14 -9
  17. data/vendor/libgit2/deps/ntlmclient/crypt_commoncrypto.c +20 -20
  18. data/vendor/libgit2/deps/ntlmclient/crypt_commoncrypto.h +3 -3
  19. data/vendor/libgit2/deps/ntlmclient/crypt_mbedtls.c +37 -36
  20. data/vendor/libgit2/deps/ntlmclient/crypt_mbedtls.h +4 -3
  21. data/vendor/libgit2/deps/ntlmclient/crypt_openssl.c +178 -51
  22. data/vendor/libgit2/deps/ntlmclient/crypt_openssl.h +74 -5
  23. data/vendor/libgit2/deps/ntlmclient/ntlm.c +150 -118
  24. data/vendor/libgit2/deps/ntlmclient/ntlm.h +13 -9
  25. data/vendor/libgit2/deps/ntlmclient/ntlmclient.h +16 -3
  26. data/vendor/libgit2/deps/ntlmclient/unicode.h +10 -4
  27. data/vendor/libgit2/deps/ntlmclient/unicode_builtin.c +16 -27
  28. data/vendor/libgit2/deps/ntlmclient/unicode_builtin.h +20 -0
  29. data/vendor/libgit2/deps/ntlmclient/unicode_iconv.c +28 -52
  30. data/vendor/libgit2/deps/ntlmclient/unicode_iconv.h +22 -0
  31. data/vendor/libgit2/include/git2/attr.h +89 -0
  32. data/vendor/libgit2/include/git2/blame.h +93 -42
  33. data/vendor/libgit2/include/git2/blob.h +14 -2
  34. data/vendor/libgit2/include/git2/branch.h +25 -0
  35. data/vendor/libgit2/include/git2/cert.h +42 -5
  36. data/vendor/libgit2/include/git2/checkout.h +28 -12
  37. data/vendor/libgit2/include/git2/commit.h +35 -19
  38. data/vendor/libgit2/include/git2/common.h +14 -4
  39. data/vendor/libgit2/include/git2/deprecated.h +206 -6
  40. data/vendor/libgit2/include/git2/diff.h +34 -19
  41. data/vendor/libgit2/include/git2/errors.h +6 -6
  42. data/vendor/libgit2/include/git2/filter.h +57 -17
  43. data/vendor/libgit2/include/git2/graph.h +20 -2
  44. data/vendor/libgit2/include/git2/index.h +2 -2
  45. data/vendor/libgit2/include/git2/odb.h +29 -0
  46. data/vendor/libgit2/include/git2/patch.h +8 -0
  47. data/vendor/libgit2/include/git2/rebase.h +25 -1
  48. data/vendor/libgit2/include/git2/refs.h +6 -2
  49. data/vendor/libgit2/include/git2/remote.h +59 -6
  50. data/vendor/libgit2/include/git2/revparse.h +5 -5
  51. data/vendor/libgit2/include/git2/status.h +115 -59
  52. data/vendor/libgit2/include/git2/submodule.h +9 -0
  53. data/vendor/libgit2/include/git2/sys/commit_graph.h +174 -0
  54. data/vendor/libgit2/include/git2/sys/filter.h +49 -28
  55. data/vendor/libgit2/include/git2/sys/midx.h +74 -0
  56. data/vendor/libgit2/include/git2/sys/odb_backend.h +7 -0
  57. data/vendor/libgit2/include/git2/sys/transport.h +1 -0
  58. data/vendor/libgit2/include/git2/tag.h +12 -0
  59. data/vendor/libgit2/include/git2/tree.h +0 -14
  60. data/vendor/libgit2/include/git2/types.h +9 -0
  61. data/vendor/libgit2/include/git2/version.h +4 -4
  62. data/vendor/libgit2/include/git2/worktree.h +1 -0
  63. data/vendor/libgit2/src/CMakeLists.txt +25 -4
  64. data/vendor/libgit2/src/alloc.c +21 -8
  65. data/vendor/libgit2/src/allocators/failalloc.c +92 -0
  66. data/vendor/libgit2/src/allocators/failalloc.h +23 -0
  67. data/vendor/libgit2/src/allocators/stdalloc.c +41 -10
  68. data/vendor/libgit2/src/allocators/win32_leakcheck.c +118 -0
  69. data/vendor/libgit2/src/allocators/{win32_crtdbg.h → win32_leakcheck.h} +3 -3
  70. data/vendor/libgit2/src/annotated_commit.c +21 -9
  71. data/vendor/libgit2/src/apply.c +16 -7
  72. data/vendor/libgit2/src/array.h +11 -11
  73. data/vendor/libgit2/src/attr.c +181 -74
  74. data/vendor/libgit2/src/attr_file.c +84 -39
  75. data/vendor/libgit2/src/attr_file.h +32 -11
  76. data/vendor/libgit2/src/attrcache.c +42 -37
  77. data/vendor/libgit2/src/attrcache.h +4 -5
  78. data/vendor/libgit2/src/blame.c +11 -5
  79. data/vendor/libgit2/src/blob.c +35 -24
  80. data/vendor/libgit2/src/branch.c +69 -17
  81. data/vendor/libgit2/src/buffer.c +334 -25
  82. data/vendor/libgit2/src/buffer.h +153 -2
  83. data/vendor/libgit2/src/cache.c +2 -2
  84. data/vendor/libgit2/src/cache.h +7 -7
  85. data/vendor/libgit2/src/cc-compat.h +10 -2
  86. data/vendor/libgit2/src/checkout.c +48 -26
  87. data/vendor/libgit2/src/cherrypick.c +6 -2
  88. data/vendor/libgit2/src/clone.c +41 -47
  89. data/vendor/libgit2/src/commit.c +41 -28
  90. data/vendor/libgit2/src/commit_graph.c +1209 -0
  91. data/vendor/libgit2/src/commit_graph.h +162 -0
  92. data/vendor/libgit2/src/commit_list.c +46 -0
  93. data/vendor/libgit2/src/commit_list.h +2 -0
  94. data/vendor/libgit2/src/common.h +25 -2
  95. data/vendor/libgit2/src/config.c +37 -15
  96. data/vendor/libgit2/src/config_cache.c +5 -3
  97. data/vendor/libgit2/src/config_file.c +16 -8
  98. data/vendor/libgit2/src/config_parse.c +4 -6
  99. data/vendor/libgit2/src/crlf.c +16 -6
  100. data/vendor/libgit2/src/date.c +4 -3
  101. data/vendor/libgit2/src/delta.c +1 -1
  102. data/vendor/libgit2/src/describe.c +6 -3
  103. data/vendor/libgit2/src/diff.c +11 -8
  104. data/vendor/libgit2/src/diff_driver.c +21 -17
  105. data/vendor/libgit2/src/diff_file.c +2 -6
  106. data/vendor/libgit2/src/diff_generate.c +46 -17
  107. data/vendor/libgit2/src/diff_print.c +19 -6
  108. data/vendor/libgit2/src/diff_stats.c +7 -5
  109. data/vendor/libgit2/src/diff_tform.c +9 -8
  110. data/vendor/libgit2/src/diff_xdiff.c +4 -2
  111. data/vendor/libgit2/src/diff_xdiff.h +1 -1
  112. data/vendor/libgit2/src/errors.c +24 -19
  113. data/vendor/libgit2/src/features.h.in +5 -1
  114. data/vendor/libgit2/src/fetch.c +5 -2
  115. data/vendor/libgit2/src/fetchhead.c +8 -4
  116. data/vendor/libgit2/src/filebuf.c +9 -7
  117. data/vendor/libgit2/src/filter.c +206 -110
  118. data/vendor/libgit2/src/filter.h +24 -5
  119. data/vendor/libgit2/src/futils.c +5 -5
  120. data/vendor/libgit2/src/futils.h +1 -1
  121. data/vendor/libgit2/src/graph.c +64 -9
  122. data/vendor/libgit2/src/hash/sha1/collisiondetect.c +3 -3
  123. data/vendor/libgit2/src/hash/sha1/common_crypto.c +3 -3
  124. data/vendor/libgit2/src/hash/sha1/generic.h +1 -1
  125. data/vendor/libgit2/src/hash/sha1/mbedtls.c +12 -12
  126. data/vendor/libgit2/src/hash/sha1/openssl.c +3 -3
  127. data/vendor/libgit2/src/hash/sha1/sha1dc/sha1.c +0 -2
  128. data/vendor/libgit2/src/hash/sha1/win32.c +15 -11
  129. data/vendor/libgit2/src/hash.c +16 -13
  130. data/vendor/libgit2/src/hash.h +1 -1
  131. data/vendor/libgit2/src/hashsig.c +23 -10
  132. data/vendor/libgit2/src/ident.c +13 -3
  133. data/vendor/libgit2/src/ignore.c +35 -19
  134. data/vendor/libgit2/src/index.c +106 -70
  135. data/vendor/libgit2/src/index.h +1 -1
  136. data/vendor/libgit2/src/indexer.c +31 -29
  137. data/vendor/libgit2/src/integer.h +64 -2
  138. data/vendor/libgit2/src/iterator.c +36 -24
  139. data/vendor/libgit2/src/iterator.h +1 -1
  140. data/vendor/libgit2/src/khash.h +2 -11
  141. data/vendor/libgit2/src/{settings.c → libgit2.c} +117 -50
  142. data/vendor/libgit2/src/libgit2.h +15 -0
  143. data/vendor/libgit2/src/mailmap.c +23 -10
  144. data/vendor/libgit2/src/map.h +3 -3
  145. data/vendor/libgit2/src/merge.c +70 -30
  146. data/vendor/libgit2/src/merge.h +2 -1
  147. data/vendor/libgit2/src/merge_driver.c +19 -13
  148. data/vendor/libgit2/src/merge_file.c +11 -3
  149. data/vendor/libgit2/src/message.c +3 -1
  150. data/vendor/libgit2/src/midx.c +471 -10
  151. data/vendor/libgit2/src/midx.h +28 -1
  152. data/vendor/libgit2/src/mwindow.c +103 -59
  153. data/vendor/libgit2/src/mwindow.h +3 -3
  154. data/vendor/libgit2/src/net.c +127 -3
  155. data/vendor/libgit2/src/net.h +16 -2
  156. data/vendor/libgit2/src/netops.c +6 -4
  157. data/vendor/libgit2/src/netops.h +2 -2
  158. data/vendor/libgit2/src/notes.c +10 -10
  159. data/vendor/libgit2/src/object.c +22 -14
  160. data/vendor/libgit2/src/odb.c +285 -48
  161. data/vendor/libgit2/src/odb.h +16 -2
  162. data/vendor/libgit2/src/odb_loose.c +28 -18
  163. data/vendor/libgit2/src/odb_mempack.c +1 -1
  164. data/vendor/libgit2/src/odb_pack.c +391 -114
  165. data/vendor/libgit2/src/oid.c +5 -4
  166. data/vendor/libgit2/src/pack-objects.c +54 -48
  167. data/vendor/libgit2/src/pack.c +329 -119
  168. data/vendor/libgit2/src/pack.h +25 -7
  169. data/vendor/libgit2/src/patch.c +14 -7
  170. data/vendor/libgit2/src/patch_generate.c +2 -2
  171. data/vendor/libgit2/src/patch_parse.c +2 -1
  172. data/vendor/libgit2/src/path.c +98 -53
  173. data/vendor/libgit2/src/path.h +79 -6
  174. data/vendor/libgit2/src/pathspec.c +8 -8
  175. data/vendor/libgit2/src/pool.c +13 -7
  176. data/vendor/libgit2/src/posix.c +11 -3
  177. data/vendor/libgit2/src/reader.c +10 -6
  178. data/vendor/libgit2/src/rebase.c +93 -49
  179. data/vendor/libgit2/src/refdb.c +30 -13
  180. data/vendor/libgit2/src/refdb_fs.c +121 -69
  181. data/vendor/libgit2/src/reflog.c +19 -14
  182. data/vendor/libgit2/src/refs.c +76 -41
  183. data/vendor/libgit2/src/refspec.c +32 -12
  184. data/vendor/libgit2/src/remote.c +272 -102
  185. data/vendor/libgit2/src/remote.h +2 -1
  186. data/vendor/libgit2/src/repository.c +176 -103
  187. data/vendor/libgit2/src/repository.h +12 -1
  188. data/vendor/libgit2/src/reset.c +7 -6
  189. data/vendor/libgit2/src/revert.c +6 -2
  190. data/vendor/libgit2/src/revparse.c +14 -9
  191. data/vendor/libgit2/src/revwalk.c +32 -15
  192. data/vendor/libgit2/src/runtime.c +162 -0
  193. data/vendor/libgit2/src/runtime.h +62 -0
  194. data/vendor/libgit2/src/settings.h +11 -0
  195. data/vendor/libgit2/src/signature.c +6 -5
  196. data/vendor/libgit2/src/sortedcache.h +10 -8
  197. data/vendor/libgit2/src/stash.c +3 -1
  198. data/vendor/libgit2/src/status.c +7 -4
  199. data/vendor/libgit2/src/strarray.c +2 -1
  200. data/vendor/libgit2/src/streams/mbedtls.c +14 -17
  201. data/vendor/libgit2/src/streams/mbedtls.h +1 -1
  202. data/vendor/libgit2/src/streams/openssl.c +101 -201
  203. data/vendor/libgit2/src/streams/openssl.h +9 -1
  204. data/vendor/libgit2/src/streams/openssl_dynamic.c +309 -0
  205. data/vendor/libgit2/src/streams/openssl_dynamic.h +348 -0
  206. data/vendor/libgit2/src/streams/openssl_legacy.c +203 -0
  207. data/vendor/libgit2/src/streams/openssl_legacy.h +63 -0
  208. data/vendor/libgit2/src/streams/registry.c +5 -6
  209. data/vendor/libgit2/src/streams/socket.c +6 -2
  210. data/vendor/libgit2/src/streams/stransport.c +6 -3
  211. data/vendor/libgit2/src/streams/tls.c +5 -3
  212. data/vendor/libgit2/src/submodule.c +128 -62
  213. data/vendor/libgit2/src/submodule.h +9 -9
  214. data/vendor/libgit2/src/sysdir.c +4 -6
  215. data/vendor/libgit2/src/tag.c +47 -11
  216. data/vendor/libgit2/src/thread.c +140 -0
  217. data/vendor/libgit2/src/thread.h +479 -0
  218. data/vendor/libgit2/src/threadstate.c +83 -0
  219. data/vendor/libgit2/src/threadstate.h +24 -0
  220. data/vendor/libgit2/src/trace.c +2 -2
  221. data/vendor/libgit2/src/trace.h +17 -13
  222. data/vendor/libgit2/src/transaction.c +19 -8
  223. data/vendor/libgit2/src/transport.c +3 -3
  224. data/vendor/libgit2/src/transports/auth.c +1 -1
  225. data/vendor/libgit2/src/transports/auth_negotiate.c +11 -4
  226. data/vendor/libgit2/src/transports/auth_ntlm.c +10 -6
  227. data/vendor/libgit2/src/transports/credential.c +15 -7
  228. data/vendor/libgit2/src/transports/git.c +1 -3
  229. data/vendor/libgit2/src/transports/http.c +19 -17
  230. data/vendor/libgit2/src/transports/http.h +1 -0
  231. data/vendor/libgit2/src/transports/httpclient.c +53 -26
  232. data/vendor/libgit2/src/transports/httpclient.h +1 -1
  233. data/vendor/libgit2/src/transports/local.c +3 -3
  234. data/vendor/libgit2/src/transports/smart.c +12 -7
  235. data/vendor/libgit2/src/transports/smart.h +1 -1
  236. data/vendor/libgit2/src/transports/smart_protocol.c +11 -5
  237. data/vendor/libgit2/src/transports/ssh.c +51 -17
  238. data/vendor/libgit2/src/transports/winhttp.c +41 -31
  239. data/vendor/libgit2/src/tree.c +100 -77
  240. data/vendor/libgit2/src/tree.h +1 -0
  241. data/vendor/libgit2/src/tsort.c +0 -2
  242. data/vendor/libgit2/src/unix/map.c +3 -1
  243. data/vendor/libgit2/src/unix/pthread.h +2 -1
  244. data/vendor/libgit2/src/utf8.c +150 -0
  245. data/vendor/libgit2/src/utf8.h +52 -0
  246. data/vendor/libgit2/src/util.c +53 -129
  247. data/vendor/libgit2/src/util.h +33 -39
  248. data/vendor/libgit2/src/vector.c +23 -19
  249. data/vendor/libgit2/src/vector.h +4 -2
  250. data/vendor/libgit2/src/win32/findfile.c +4 -2
  251. data/vendor/libgit2/src/win32/map.c +1 -1
  252. data/vendor/libgit2/src/win32/msvc-compat.h +9 -1
  253. data/vendor/libgit2/src/win32/path_w32.c +22 -24
  254. data/vendor/libgit2/src/win32/path_w32.h +0 -1
  255. data/vendor/libgit2/src/win32/posix_w32.c +7 -1
  256. data/vendor/libgit2/src/win32/precompiled.h +0 -1
  257. data/vendor/libgit2/src/win32/reparse.h +4 -4
  258. data/vendor/libgit2/src/win32/thread.c +24 -15
  259. data/vendor/libgit2/src/win32/thread.h +1 -1
  260. data/vendor/libgit2/src/win32/w32_buffer.c +3 -3
  261. data/vendor/libgit2/src/win32/w32_common.h +18 -9
  262. data/vendor/libgit2/src/win32/{w32_crtdbg_stacktrace.c → w32_leakcheck.c} +269 -33
  263. data/vendor/libgit2/src/win32/w32_leakcheck.h +222 -0
  264. data/vendor/libgit2/src/win32/w32_util.h +6 -6
  265. data/vendor/libgit2/src/worktree.c +27 -16
  266. data/vendor/libgit2/src/zstream.c +1 -1
  267. metadata +32 -16
  268. data/vendor/libgit2/src/allocators/win32_crtdbg.c +0 -118
  269. data/vendor/libgit2/src/buf_text.c +0 -316
  270. data/vendor/libgit2/src/buf_text.h +0 -122
  271. data/vendor/libgit2/src/global.c +0 -363
  272. data/vendor/libgit2/src/global.h +0 -41
  273. data/vendor/libgit2/src/thread-utils.c +0 -58
  274. data/vendor/libgit2/src/thread-utils.h +0 -369
  275. data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.h +0 -127
  276. data/vendor/libgit2/src/win32/w32_stack.c +0 -188
  277. data/vendor/libgit2/src/win32/w32_stack.h +0 -140
@@ -12,8 +12,11 @@
12
12
 
13
13
  #include <ctype.h>
14
14
 
15
+ #include "git2/sys/midx.h"
16
+
15
17
  #include "map.h"
16
18
  #include "mwindow.h"
19
+ #include "odb.h"
17
20
 
18
21
  /*
19
22
  * A multi-pack-index file.
@@ -49,6 +52,9 @@ typedef struct git_midx_file {
49
52
 
50
53
  /* The trailer of the file. Contains the SHA1-checksum of the whole file. */
51
54
  git_oid checksum;
55
+
56
+ /* something like ".git/objects/pack/multi-pack-index". */
57
+ git_buf filename;
52
58
  } git_midx_file;
53
59
 
54
60
  /*
@@ -63,15 +69,36 @@ typedef struct git_midx_entry {
63
69
  git_oid sha1;
64
70
  } git_midx_entry;
65
71
 
72
+ /*
73
+ * A writer for `multi-pack-index` files.
74
+ */
75
+ struct git_midx_writer {
76
+ /*
77
+ * The path of the directory where the .pack/.idx files are stored. The
78
+ * `multi-pack-index` file will be written to the same directory.
79
+ */
80
+ git_buf pack_dir;
81
+
82
+ /* The list of `git_pack_file`s. */
83
+ git_vector packs;
84
+ };
85
+
66
86
  int git_midx_open(
67
87
  git_midx_file **idx_out,
68
88
  const char *path);
89
+ bool git_midx_needs_refresh(
90
+ const git_midx_file *idx,
91
+ const char *path);
69
92
  int git_midx_entry_find(
70
93
  git_midx_entry *e,
71
94
  git_midx_file *idx,
72
95
  const git_oid *short_oid,
73
96
  size_t len);
74
- void git_midx_close(git_midx_file *idx);
97
+ int git_midx_foreach_entry(
98
+ git_midx_file *idx,
99
+ git_odb_foreach_cb cb,
100
+ void *data);
101
+ int git_midx_close(git_midx_file *idx);
75
102
  void git_midx_free(git_midx_file *idx);
76
103
 
77
104
  /* This is exposed for use in the fuzzers. */
@@ -10,7 +10,7 @@
10
10
  #include "vector.h"
11
11
  #include "futils.h"
12
12
  #include "map.h"
13
- #include "global.h"
13
+ #include "runtime.h"
14
14
  #include "strmap.h"
15
15
  #include "pack.h"
16
16
 
@@ -20,7 +20,7 @@
20
20
  : 32 * 1024 * 1024)
21
21
 
22
22
  #define DEFAULT_MAPPED_LIMIT \
23
- ((1024 * 1024) * (sizeof(void*) >= 8 ? 8192ULL : 256UL))
23
+ ((1024 * 1024) * (sizeof(void*) >= 8 ? UINT64_C(8192) : UINT64_C(256)))
24
24
 
25
25
  /* default is unlimited */
26
26
  #define DEFAULT_FILE_LIMIT 0
@@ -29,26 +29,36 @@ size_t git_mwindow__window_size = DEFAULT_WINDOW_SIZE;
29
29
  size_t git_mwindow__mapped_limit = DEFAULT_MAPPED_LIMIT;
30
30
  size_t git_mwindow__file_limit = DEFAULT_FILE_LIMIT;
31
31
 
32
- /* Whenever you want to read or modify this, grab git__mwindow_mutex */
32
+ /* Mutex to control access to `git_mwindow__mem_ctl` and `git__pack_cache`. */
33
+ git_mutex git__mwindow_mutex;
34
+
35
+ /* Whenever you want to read or modify this, grab `git__mwindow_mutex` */
33
36
  git_mwindow_ctl git_mwindow__mem_ctl;
34
37
 
35
38
  /* Global list of mwindow files, to open packs once across repos */
36
39
  git_strmap *git__pack_cache = NULL;
37
40
 
38
- static void git_mwindow_files_free(void)
41
+ static void git_mwindow_global_shutdown(void)
39
42
  {
40
43
  git_strmap *tmp = git__pack_cache;
41
44
 
45
+ git_mutex_free(&git__mwindow_mutex);
46
+
42
47
  git__pack_cache = NULL;
43
48
  git_strmap_free(tmp);
44
49
  }
45
50
 
46
51
  int git_mwindow_global_init(void)
47
52
  {
48
- assert(!git__pack_cache);
53
+ int error;
49
54
 
50
- git__on_shutdown(git_mwindow_files_free);
51
- return git_strmap_new(&git__pack_cache);
55
+ GIT_ASSERT(!git__pack_cache);
56
+
57
+ if ((error = git_mutex_init(&git__mwindow_mutex)) < 0 ||
58
+ (error = git_strmap_new(&git__pack_cache)) < 0)
59
+ return error;
60
+
61
+ return git_runtime_shutdown_register(git_mwindow_global_shutdown);
52
62
  }
53
63
 
54
64
  int git_mwindow_get_pack(struct git_pack_file **out, const char *path)
@@ -69,7 +79,7 @@ int git_mwindow_get_pack(struct git_pack_file **out, const char *path)
69
79
  git__free(packname);
70
80
 
71
81
  if (pack != NULL) {
72
- git_atomic_inc(&pack->refcount);
82
+ git_atomic32_inc(&pack->refcount);
73
83
  git_mutex_unlock(&git__mwindow_mutex);
74
84
  *out = pack;
75
85
  return 0;
@@ -81,60 +91,49 @@ int git_mwindow_get_pack(struct git_pack_file **out, const char *path)
81
91
  return error;
82
92
  }
83
93
 
84
- git_atomic_inc(&pack->refcount);
94
+ git_atomic32_inc(&pack->refcount);
85
95
 
86
96
  error = git_strmap_set(git__pack_cache, pack->pack_name, pack);
87
97
  git_mutex_unlock(&git__mwindow_mutex);
88
-
89
98
  if (error < 0) {
90
- git_packfile_free(pack);
91
- return -1;
99
+ git_packfile_free(pack, false);
100
+ return error;
92
101
  }
93
102
 
94
103
  *out = pack;
95
104
  return 0;
96
105
  }
97
106
 
98
- void git_mwindow_put_pack(struct git_pack_file *pack)
107
+ int git_mwindow_put_pack(struct git_pack_file *pack)
99
108
  {
100
- int count;
109
+ int count, error;
110
+ struct git_pack_file *pack_to_delete = NULL;
101
111
 
102
- if (git_mutex_lock(&git__mwindow_mutex) < 0)
103
- return;
112
+ if ((error = git_mutex_lock(&git__mwindow_mutex)) < 0)
113
+ return error;
104
114
 
105
115
  /* put before get would be a corrupted state */
106
- assert(git__pack_cache);
116
+ GIT_ASSERT(git__pack_cache);
107
117
 
108
118
  /* if we cannot find it, the state is corrupted */
109
- assert(git_strmap_exists(git__pack_cache, pack->pack_name));
119
+ GIT_ASSERT(git_strmap_exists(git__pack_cache, pack->pack_name));
110
120
 
111
- count = git_atomic_dec(&pack->refcount);
121
+ count = git_atomic32_dec(&pack->refcount);
112
122
  if (count == 0) {
113
123
  git_strmap_delete(git__pack_cache, pack->pack_name);
114
- git_packfile_free(pack);
124
+ pack_to_delete = pack;
115
125
  }
116
-
117
126
  git_mutex_unlock(&git__mwindow_mutex);
118
- return;
119
- }
127
+ git_packfile_free(pack_to_delete, false);
120
128
 
121
- void git_mwindow_free_all(git_mwindow_file *mwf)
122
- {
123
- if (git_mutex_lock(&git__mwindow_mutex)) {
124
- git_error_set(GIT_ERROR_THREAD, "unable to lock mwindow mutex");
125
- return;
126
- }
127
-
128
- git_mwindow_free_all_locked(mwf);
129
-
130
- git_mutex_unlock(&git__mwindow_mutex);
129
+ return 0;
131
130
  }
132
131
 
133
132
  /*
134
133
  * Free all the windows in a sequence, typically because we're done
135
- * with the file
134
+ * with the file. Needs to hold the git__mwindow_mutex.
136
135
  */
137
- void git_mwindow_free_all_locked(git_mwindow_file *mwf)
136
+ static int git_mwindow_free_all_locked(git_mwindow_file *mwf)
138
137
  {
139
138
  git_mwindow_ctl *ctl = &git_mwindow__mem_ctl;
140
139
  size_t i;
@@ -156,7 +155,7 @@ void git_mwindow_free_all_locked(git_mwindow_file *mwf)
156
155
 
157
156
  while (mwf->windows) {
158
157
  git_mwindow *w = mwf->windows;
159
- assert(w->inuse_cnt == 0);
158
+ GIT_ASSERT(w->inuse_cnt == 0);
160
159
 
161
160
  ctl->mapped -= w->window_map.len;
162
161
  ctl->open_windows--;
@@ -166,6 +165,24 @@ void git_mwindow_free_all_locked(git_mwindow_file *mwf)
166
165
  mwf->windows = w->next;
167
166
  git__free(w);
168
167
  }
168
+
169
+ return 0;
170
+ }
171
+
172
+ int git_mwindow_free_all(git_mwindow_file *mwf)
173
+ {
174
+ int error;
175
+
176
+ if (git_mutex_lock(&git__mwindow_mutex)) {
177
+ git_error_set(GIT_ERROR_THREAD, "unable to lock mwindow mutex");
178
+ return -1;
179
+ }
180
+
181
+ error = git_mwindow_free_all_locked(mwf);
182
+
183
+ git_mutex_unlock(&git__mwindow_mutex);
184
+
185
+ return error;
169
186
  }
170
187
 
171
188
  /*
@@ -200,8 +217,8 @@ static bool git_mwindow_scan_recently_used(
200
217
  git_mwindow *lru_window = NULL, *lru_last = NULL;
201
218
  bool found = false;
202
219
 
203
- assert(mwf);
204
- assert(out_window);
220
+ GIT_ASSERT_ARG(mwf);
221
+ GIT_ASSERT_ARG(out_window);
205
222
 
206
223
  lru_window = *out_window;
207
224
  if (out_last)
@@ -240,9 +257,9 @@ static bool git_mwindow_scan_recently_used(
240
257
 
241
258
  /*
242
259
  * Close the least recently used window (that is currently not being used) out
243
- * of all the files. Called under lock from new_window.
260
+ * of all the files. Called under lock from new_window_locked.
244
261
  */
245
- static int git_mwindow_close_lru_window(void)
262
+ static int git_mwindow_close_lru_window_locked(void)
246
263
  {
247
264
  git_mwindow_ctl *ctl = &git_mwindow__mem_ctl;
248
265
  git_mwindow_file *cur;
@@ -276,13 +293,13 @@ static int git_mwindow_close_lru_window(void)
276
293
  }
277
294
 
278
295
  /*
279
- * Close the file that does not have any open windows AND whose
296
+ * Finds the file that does not have any open windows AND whose
280
297
  * most-recently-used window is the least-recently used one across all
281
298
  * currently open files.
282
299
  *
283
- * Called under lock from new_window.
300
+ * Called under lock from new_window_locked.
284
301
  */
285
- static int git_mwindow_close_lru_file(void)
302
+ static int git_mwindow_find_lru_file_locked(git_mwindow_file **out)
286
303
  {
287
304
  git_mwindow_ctl *ctl = &git_mwindow__mem_ctl;
288
305
  git_mwindow_file *lru_file = NULL, *current_file = NULL;
@@ -306,15 +323,12 @@ static int git_mwindow_close_lru_file(void)
306
323
  return -1;
307
324
  }
308
325
 
309
- git_mwindow_free_all_locked(lru_file);
310
- p_close(lru_file->fd);
311
- lru_file->fd = -1;
312
-
326
+ *out = lru_file;
313
327
  return 0;
314
328
  }
315
329
 
316
330
  /* This gets called under lock from git_mwindow_open */
317
- static git_mwindow *new_window(
331
+ static git_mwindow *new_window_locked(
318
332
  git_file fd,
319
333
  off64_t size,
320
334
  off64_t offset)
@@ -324,12 +338,11 @@ static git_mwindow *new_window(
324
338
  off64_t len;
325
339
  git_mwindow *w;
326
340
 
327
- w = git__malloc(sizeof(*w));
341
+ w = git__calloc(1, sizeof(*w));
328
342
 
329
343
  if (w == NULL)
330
344
  return NULL;
331
345
 
332
- memset(w, 0x0, sizeof(*w));
333
346
  w->offset = (offset / walign) * walign;
334
347
 
335
348
  len = size - w->offset;
@@ -339,7 +352,7 @@ static git_mwindow *new_window(
339
352
  ctl->mapped += (size_t)len;
340
353
 
341
354
  while (git_mwindow__mapped_limit < ctl->mapped &&
342
- git_mwindow_close_lru_window() == 0) /* nop */;
355
+ git_mwindow_close_lru_window_locked() == 0) /* nop */;
343
356
 
344
357
  /*
345
358
  * We treat `mapped_limit` as a soft limit. If we can't find a
@@ -353,7 +366,7 @@ static git_mwindow *new_window(
353
366
  * we're below our soft limits, so free up what we can and try again.
354
367
  */
355
368
 
356
- while (git_mwindow_close_lru_window() == 0)
369
+ while (git_mwindow_close_lru_window_locked() == 0)
357
370
  /* nop */;
358
371
 
359
372
  if (git_futils_mmap_ro(&w->window_map, fd, w->offset, (size_t)len) < 0) {
@@ -409,7 +422,7 @@ unsigned char *git_mwindow_open(
409
422
  * one.
410
423
  */
411
424
  if (!w) {
412
- w = new_window(mwf->fd, mwf->size, offset);
425
+ w = new_window_locked(mwf->fd, mwf->size, offset);
413
426
  if (w == NULL) {
414
427
  git_mutex_unlock(&git__mwindow_mutex);
415
428
  return NULL;
@@ -437,8 +450,11 @@ unsigned char *git_mwindow_open(
437
450
 
438
451
  int git_mwindow_file_register(git_mwindow_file *mwf)
439
452
  {
453
+ git_vector closed_files = GIT_VECTOR_INIT;
440
454
  git_mwindow_ctl *ctl = &git_mwindow__mem_ctl;
441
- int ret;
455
+ int error;
456
+ size_t i;
457
+ git_mwindow_file *closed_file = NULL;
442
458
 
443
459
  if (git_mutex_lock(&git__mwindow_mutex)) {
444
460
  git_error_set(GIT_ERROR_THREAD, "unable to lock mwindow mutex");
@@ -446,20 +462,48 @@ int git_mwindow_file_register(git_mwindow_file *mwf)
446
462
  }
447
463
 
448
464
  if (ctl->windowfiles.length == 0 &&
449
- git_vector_init(&ctl->windowfiles, 8, NULL) < 0) {
465
+ (error = git_vector_init(&ctl->windowfiles, 8, NULL)) < 0) {
450
466
  git_mutex_unlock(&git__mwindow_mutex);
451
- return -1;
467
+ goto cleanup;
452
468
  }
453
469
 
454
470
  if (git_mwindow__file_limit) {
471
+ git_mwindow_file *lru_file;
455
472
  while (git_mwindow__file_limit <= ctl->windowfiles.length &&
456
- git_mwindow_close_lru_file() == 0) /* nop */;
473
+ git_mwindow_find_lru_file_locked(&lru_file) == 0) {
474
+ if ((error = git_vector_insert(&closed_files, lru_file)) < 0) {
475
+ /*
476
+ * Exceeding the file limit seems preferrable to being open to
477
+ * data races that can end up corrupting the heap.
478
+ */
479
+ break;
480
+ }
481
+ git_mwindow_free_all_locked(lru_file);
482
+ }
457
483
  }
458
484
 
459
- ret = git_vector_insert(&ctl->windowfiles, mwf);
485
+ error = git_vector_insert(&ctl->windowfiles, mwf);
460
486
  git_mutex_unlock(&git__mwindow_mutex);
487
+ if (error < 0)
488
+ goto cleanup;
489
+
490
+ /*
491
+ * Once we have released the global windowfiles lock, we can close each
492
+ * individual file. Before doing so, acquire that file's lock to avoid
493
+ * closing a file that is currently being used.
494
+ */
495
+ git_vector_foreach(&closed_files, i, closed_file) {
496
+ error = git_mutex_lock(&closed_file->lock);
497
+ if (error < 0)
498
+ continue;
499
+ p_close(closed_file->fd);
500
+ closed_file->fd = -1;
501
+ git_mutex_unlock(&closed_file->lock);
502
+ }
461
503
 
462
- return ret;
504
+ cleanup:
505
+ git_vector_free(&closed_files);
506
+ return error;
463
507
  }
464
508
 
465
509
  void git_mwindow_file_deregister(git_mwindow_file *mwf)
@@ -22,6 +22,7 @@ typedef struct git_mwindow {
22
22
  } git_mwindow;
23
23
 
24
24
  typedef struct git_mwindow_file {
25
+ git_mutex lock; /* protects updates to fd */
25
26
  git_mwindow *windows;
26
27
  int fd;
27
28
  off64_t size;
@@ -38,8 +39,7 @@ typedef struct git_mwindow_ctl {
38
39
  } git_mwindow_ctl;
39
40
 
40
41
  int git_mwindow_contains(git_mwindow *win, off64_t offset);
41
- void git_mwindow_free_all(git_mwindow_file *mwf); /* locks */
42
- void git_mwindow_free_all_locked(git_mwindow_file *mwf); /* run under lock */
42
+ int git_mwindow_free_all(git_mwindow_file *mwf); /* locks */
43
43
  unsigned char *git_mwindow_open(git_mwindow_file *mwf, git_mwindow **cursor, off64_t offset, size_t extra, unsigned int *left);
44
44
  int git_mwindow_file_register(git_mwindow_file *mwf);
45
45
  void git_mwindow_file_deregister(git_mwindow_file *mwf);
@@ -49,6 +49,6 @@ extern int git_mwindow_global_init(void);
49
49
 
50
50
  struct git_pack_file; /* just declaration to avoid cyclical includes */
51
51
  int git_mwindow_get_pack(struct git_pack_file **out, const char *path);
52
- void git_mwindow_put_pack(struct git_pack_file *pack);
52
+ int git_mwindow_put_pack(struct git_pack_file *pack);
53
53
 
54
54
  #endif
@@ -14,7 +14,7 @@
14
14
  #include "posix.h"
15
15
  #include "buffer.h"
16
16
  #include "http_parser.h"
17
- #include "global.h"
17
+ #include "runtime.h"
18
18
 
19
19
  #define DEFAULT_PORT_HTTP "80"
20
20
  #define DEFAULT_PORT_HTTPS "443"
@@ -35,6 +35,46 @@ static const char *default_port_for_scheme(const char *scheme)
35
35
  return NULL;
36
36
  }
37
37
 
38
+ int git_net_url_dup(git_net_url *out, git_net_url *in)
39
+ {
40
+ if (in->scheme) {
41
+ out->scheme = git__strdup(in->scheme);
42
+ GIT_ERROR_CHECK_ALLOC(out->scheme);
43
+ }
44
+
45
+ if (in->host) {
46
+ out->host = git__strdup(in->host);
47
+ GIT_ERROR_CHECK_ALLOC(out->host);
48
+ }
49
+
50
+ if (in->port) {
51
+ out->port = git__strdup(in->port);
52
+ GIT_ERROR_CHECK_ALLOC(out->port);
53
+ }
54
+
55
+ if (in->path) {
56
+ out->path = git__strdup(in->path);
57
+ GIT_ERROR_CHECK_ALLOC(out->path);
58
+ }
59
+
60
+ if (in->query) {
61
+ out->query = git__strdup(in->query);
62
+ GIT_ERROR_CHECK_ALLOC(out->query);
63
+ }
64
+
65
+ if (in->username) {
66
+ out->username = git__strdup(in->username);
67
+ GIT_ERROR_CHECK_ALLOC(out->username);
68
+ }
69
+
70
+ if (in->password) {
71
+ out->password = git__strdup(in->password);
72
+ GIT_ERROR_CHECK_ALLOC(out->password);
73
+ }
74
+
75
+ return 0;
76
+ }
77
+
38
78
  int git_net_url_parse(git_net_url *url, const char *given)
39
79
  {
40
80
  struct http_parser_url u = {0};
@@ -281,7 +321,8 @@ int git_net_url_apply_redirect(
281
321
  git_net_url tmp = GIT_NET_URL_INIT;
282
322
  int error = 0;
283
323
 
284
- assert(url && redirect_location);
324
+ GIT_ASSERT(url);
325
+ GIT_ASSERT(redirect_location);
285
326
 
286
327
  if (redirect_location[0] == '/') {
287
328
  git__free(url->path);
@@ -334,7 +375,7 @@ bool git_net_url_valid(git_net_url *url)
334
375
  return (url->host && url->port && url->path);
335
376
  }
336
377
 
337
- int git_net_url_is_default_port(git_net_url *url)
378
+ bool git_net_url_is_default_port(git_net_url *url)
338
379
  {
339
380
  const char *default_port;
340
381
 
@@ -344,6 +385,11 @@ int git_net_url_is_default_port(git_net_url *url)
344
385
  return false;
345
386
  }
346
387
 
388
+ bool git_net_url_is_ipv6(git_net_url *url)
389
+ {
390
+ return (strchr(url->host, ':') != NULL);
391
+ }
392
+
347
393
  void git_net_url_swap(git_net_url *a, git_net_url *b)
348
394
  {
349
395
  git_net_url tmp = GIT_NET_URL_INIT;
@@ -355,6 +401,10 @@ void git_net_url_swap(git_net_url *a, git_net_url *b)
355
401
 
356
402
  int git_net_url_fmt(git_buf *buf, git_net_url *url)
357
403
  {
404
+ GIT_ASSERT_ARG(url);
405
+ GIT_ASSERT_ARG(url->scheme);
406
+ GIT_ASSERT_ARG(url->host);
407
+
358
408
  git_buf_puts(buf, url->scheme);
359
409
  git_buf_puts(buf, "://");
360
410
 
@@ -398,6 +448,80 @@ int git_net_url_fmt_path(git_buf *buf, git_net_url *url)
398
448
  return git_buf_oom(buf) ? -1 : 0;
399
449
  }
400
450
 
451
+ static bool matches_pattern(
452
+ git_net_url *url,
453
+ const char *pattern,
454
+ size_t pattern_len)
455
+ {
456
+ const char *domain, *port = NULL, *colon;
457
+ size_t host_len, domain_len, port_len = 0, wildcard = 0;
458
+
459
+ GIT_UNUSED(url);
460
+ GIT_UNUSED(pattern);
461
+
462
+ if (!pattern_len)
463
+ return false;
464
+ else if (pattern_len == 1 && pattern[0] == '*')
465
+ return true;
466
+ else if (pattern_len > 1 && pattern[0] == '*' && pattern[1] == '.')
467
+ wildcard = 2;
468
+ else if (pattern[0] == '.')
469
+ wildcard = 1;
470
+
471
+ domain = pattern + wildcard;
472
+ domain_len = pattern_len - wildcard;
473
+
474
+ if ((colon = memchr(domain, ':', domain_len)) != NULL) {
475
+ domain_len = colon - domain;
476
+ port = colon + 1;
477
+ port_len = pattern_len - wildcard - domain_len - 1;
478
+ }
479
+
480
+ /* A pattern's port *must* match if it's specified */
481
+ if (port_len && git__strlcmp(url->port, port, port_len) != 0)
482
+ return false;
483
+
484
+ /* No wildcard? Host must match exactly. */
485
+ if (!wildcard)
486
+ return !git__strlcmp(url->host, domain, domain_len);
487
+
488
+ /* Wildcard: ensure there's (at least) a suffix match */
489
+ if ((host_len = strlen(url->host)) < domain_len ||
490
+ memcmp(url->host + (host_len - domain_len), domain, domain_len))
491
+ return false;
492
+
493
+ /* The pattern is *.domain and the host is simply domain */
494
+ if (host_len == domain_len)
495
+ return true;
496
+
497
+ /* The pattern is *.domain and the host is foo.domain */
498
+ return (url->host[host_len - domain_len - 1] == '.');
499
+ }
500
+
501
+ bool git_net_url_matches_pattern(git_net_url *url, const char *pattern)
502
+ {
503
+ return matches_pattern(url, pattern, strlen(pattern));
504
+ }
505
+
506
+ bool git_net_url_matches_pattern_list(
507
+ git_net_url *url,
508
+ const char *pattern_list)
509
+ {
510
+ const char *pattern, *pattern_end, *sep;
511
+
512
+ for (pattern = pattern_list;
513
+ pattern && *pattern;
514
+ pattern = sep ? sep + 1 : NULL) {
515
+ sep = strchr(pattern, ',');
516
+ pattern_end = sep ? sep : strchr(pattern, '\0');
517
+
518
+ if (matches_pattern(url, pattern, (pattern_end - pattern)))
519
+ return true;
520
+ }
521
+
522
+ return false;
523
+ }
524
+
401
525
  void git_net_url_dispose(git_net_url *url)
402
526
  {
403
527
  if (url->username)