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.
@@ -27,14 +27,16 @@ struct git_tree {
27
27
 
28
28
  struct git_treebuilder {
29
29
  git_vector entries;
30
+ size_t entrycount; /* vector may contain "removed" entries */
30
31
  };
31
32
 
32
-
33
33
  GIT_INLINE(bool) git_tree_entry__is_tree(const struct git_tree_entry *e)
34
34
  {
35
35
  return (S_ISDIR(e->attr) && !S_ISGITLINK(e->attr));
36
36
  }
37
37
 
38
+ extern int git_tree_entry_icmp(const git_tree_entry *e1, const git_tree_entry *e2);
39
+
38
40
  void git_tree__free(git_tree *tree);
39
41
  int git_tree__parse(git_tree *tree, git_odb_object *obj);
40
42
 
@@ -47,6 +49,13 @@ int git_tree__parse(git_tree *tree, git_odb_object *obj);
47
49
  */
48
50
  int git_tree__prefix_position(git_tree *tree, const char *prefix);
49
51
 
52
+
53
+ /**
54
+ * Write a tree to the given repository
55
+ */
56
+ int git_tree__write_index(
57
+ git_oid *oid, git_index *index, git_repository *repo);
58
+
50
59
  /**
51
60
  * Obsolete mode kept for compatibility reasons
52
61
  */
@@ -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.
@@ -23,9 +23,8 @@
23
23
  # define MIN(x,y) (((x) < (y) ? (x) : (y)))
24
24
  #endif
25
25
 
26
- typedef int (*cmp_ptr_t)(const void *, const void *);
27
-
28
- static int binsearch(void **dst, const void *x, size_t size, cmp_ptr_t cmp)
26
+ static int binsearch(
27
+ void **dst, const void *x, size_t size, git__sort_r_cmp cmp, void *payload)
29
28
  {
30
29
  int l, c, r;
31
30
  void *lx, *cx;
@@ -38,12 +37,12 @@ static int binsearch(void **dst, const void *x, size_t size, cmp_ptr_t cmp)
38
37
  lx = dst[l];
39
38
 
40
39
  /* check for beginning conditions */
41
- if (cmp(x, lx) < 0)
40
+ if (cmp(x, lx, payload) < 0)
42
41
  return 0;
43
42
 
44
- else if (cmp(x, lx) == 0) {
43
+ else if (cmp(x, lx, payload) == 0) {
45
44
  int i = 1;
46
- while (cmp(x, dst[i]) == 0)
45
+ while (cmp(x, dst[i], payload) == 0)
47
46
  i++;
48
47
  return i;
49
48
  }
@@ -51,7 +50,7 @@ static int binsearch(void **dst, const void *x, size_t size, cmp_ptr_t cmp)
51
50
  /* guaranteed not to be >= rx */
52
51
  cx = dst[c];
53
52
  while (1) {
54
- const int val = cmp(x, cx);
53
+ const int val = cmp(x, cx, payload);
55
54
  if (val < 0) {
56
55
  if (c - l <= 1) return c;
57
56
  r = c;
@@ -62,7 +61,7 @@ static int binsearch(void **dst, const void *x, size_t size, cmp_ptr_t cmp)
62
61
  } else {
63
62
  do {
64
63
  cx = dst[++c];
65
- } while (cmp(x, cx) == 0);
64
+ } while (cmp(x, cx, payload) == 0);
66
65
  return c;
67
66
  }
68
67
  c = l + ((r - l) >> 1);
@@ -71,7 +70,8 @@ static int binsearch(void **dst, const void *x, size_t size, cmp_ptr_t cmp)
71
70
  }
72
71
 
73
72
  /* Binary insertion sort, but knowing that the first "start" entries are sorted. Used in timsort. */
74
- static void bisort(void **dst, size_t start, size_t size, cmp_ptr_t cmp)
73
+ static void bisort(
74
+ void **dst, size_t start, size_t size, git__sort_r_cmp cmp, void *payload)
75
75
  {
76
76
  size_t i;
77
77
  void *x;
@@ -80,12 +80,12 @@ static void bisort(void **dst, size_t start, size_t size, cmp_ptr_t cmp)
80
80
  for (i = start; i < size; i++) {
81
81
  int j;
82
82
  /* If this entry is already correct, just move along */
83
- if (cmp(dst[i - 1], dst[i]) <= 0)
83
+ if (cmp(dst[i - 1], dst[i], payload) <= 0)
84
84
  continue;
85
85
 
86
86
  /* Else we need to find the right place, shift everything over, and squeeze in */
87
87
  x = dst[i];
88
- location = binsearch(dst, x, i, cmp);
88
+ location = binsearch(dst, x, i, cmp, payload);
89
89
  for (j = (int)i - 1; j >= location; j--) {
90
90
  dst[j + 1] = dst[j];
91
91
  }
@@ -102,7 +102,8 @@ struct tsort_run {
102
102
 
103
103
  struct tsort_store {
104
104
  size_t alloc;
105
- cmp_ptr_t cmp;
105
+ git__sort_r_cmp cmp;
106
+ void *payload;
106
107
  void **storage;
107
108
  };
108
109
 
@@ -118,7 +119,8 @@ static void reverse_elements(void **dst, ssize_t start, ssize_t end)
118
119
  }
119
120
  }
120
121
 
121
- static ssize_t count_run(void **dst, ssize_t start, ssize_t size, struct tsort_store *store)
122
+ static ssize_t count_run(
123
+ void **dst, ssize_t start, ssize_t size, struct tsort_store *store)
122
124
  {
123
125
  ssize_t curr = start + 2;
124
126
 
@@ -126,7 +128,7 @@ static ssize_t count_run(void **dst, ssize_t start, ssize_t size, struct tsort_s
126
128
  return 1;
127
129
 
128
130
  if (start >= size - 2) {
129
- if (store->cmp(dst[size - 2], dst[size - 1]) > 0) {
131
+ if (store->cmp(dst[size - 2], dst[size - 1], store->payload) > 0) {
130
132
  void *tmp = dst[size - 1];
131
133
  dst[size - 1] = dst[size - 2];
132
134
  dst[size - 2] = tmp;
@@ -135,13 +137,15 @@ static ssize_t count_run(void **dst, ssize_t start, ssize_t size, struct tsort_s
135
137
  return 2;
136
138
  }
137
139
 
138
- if (store->cmp(dst[start], dst[start + 1]) <= 0) {
139
- while (curr < size - 1 && store->cmp(dst[curr - 1], dst[curr]) <= 0)
140
+ if (store->cmp(dst[start], dst[start + 1], store->payload) <= 0) {
141
+ while (curr < size - 1 &&
142
+ store->cmp(dst[curr - 1], dst[curr], store->payload) <= 0)
140
143
  curr++;
141
144
 
142
145
  return curr - start;
143
146
  } else {
144
- while (curr < size - 1 && store->cmp(dst[curr - 1], dst[curr]) > 0)
147
+ while (curr < size - 1 &&
148
+ store->cmp(dst[curr - 1], dst[curr], store->payload) > 0)
145
149
  curr++;
146
150
 
147
151
  /* reverse in-place */
@@ -219,7 +223,7 @@ static void merge(void **dst, const struct tsort_run *stack, ssize_t stack_curr,
219
223
 
220
224
  for (k = curr; k < curr + A + B; k++) {
221
225
  if ((i < A) && (j < curr + A + B)) {
222
- if (store->cmp(storage[i], dst[j]) <= 0)
226
+ if (store->cmp(storage[i], dst[j], store->payload) <= 0)
223
227
  dst[k] = storage[i++];
224
228
  else
225
229
  dst[k] = dst[j++];
@@ -235,7 +239,7 @@ static void merge(void **dst, const struct tsort_run *stack, ssize_t stack_curr,
235
239
 
236
240
  for (k = curr + A + B - 1; k >= curr; k--) {
237
241
  if ((i >= 0) && (j >= curr)) {
238
- if (store->cmp(dst[j], storage[i]) > 0)
242
+ if (store->cmp(dst[j], storage[i], store->payload) > 0)
239
243
  dst[k] = dst[j--];
240
244
  else
241
245
  dst[k] = storage[i--];
@@ -307,7 +311,7 @@ static ssize_t collapse(void **dst, struct tsort_run *stack, ssize_t stack_curr,
307
311
  if (run < minrun) run = minrun;\
308
312
  if (run > (ssize_t)size - curr) run = size - curr;\
309
313
  if (run > len) {\
310
- bisort(&dst[curr], len, run, cmp);\
314
+ bisort(&dst[curr], len, run, cmp, payload);\
311
315
  len = run;\
312
316
  }\
313
317
  run_stack[stack_curr].start = curr;\
@@ -329,7 +333,8 @@ static ssize_t collapse(void **dst, struct tsort_run *stack, ssize_t stack_curr,
329
333
  }\
330
334
  while (0)
331
335
 
332
- void git__tsort(void **dst, size_t size, cmp_ptr_t cmp)
336
+ void git__tsort_r(
337
+ void **dst, size_t size, git__sort_r_cmp cmp, void *payload)
333
338
  {
334
339
  struct tsort_store _store, *store = &_store;
335
340
  struct tsort_run run_stack[128];
@@ -340,7 +345,7 @@ void git__tsort(void **dst, size_t size, cmp_ptr_t cmp)
340
345
  ssize_t minrun;
341
346
 
342
347
  if (size < 64) {
343
- bisort(dst, 1, size, cmp);
348
+ bisort(dst, 1, size, cmp, payload);
344
349
  return;
345
350
  }
346
351
 
@@ -351,6 +356,7 @@ void git__tsort(void **dst, size_t size, cmp_ptr_t cmp)
351
356
  store->alloc = 0;
352
357
  store->storage = NULL;
353
358
  store->cmp = cmp;
359
+ store->payload = payload;
354
360
 
355
361
  PUSH_NEXT();
356
362
  PUSH_NEXT();
@@ -365,3 +371,13 @@ void git__tsort(void **dst, size_t size, cmp_ptr_t cmp)
365
371
  PUSH_NEXT();
366
372
  }
367
373
  }
374
+
375
+ static int tsort_r_cmp(const void *a, const void *b, void *payload)
376
+ {
377
+ return ((git__tsort_cmp)payload)(a, b);
378
+ }
379
+
380
+ void git__tsort(void **dst, size_t size, git__tsort_cmp cmp)
381
+ {
382
+ git__tsort_r(dst, size, tsort_r_cmp, cmp);
383
+ }
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (C) 2009-2012 the libgit2 contributors
2
+ * Copyright (C) the libgit2 contributors. All rights reserved.
3
3
  *
4
4
  * This file is part of libgit2, distributed under the GNU GPL v2 with
5
5
  * a Linking Exception. For full terms see the included COPYING file.
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (C) 2009-2012 the libgit2 contributors
2
+ * Copyright (C) the libgit2 contributors. All rights reserved.
3
3
  *
4
4
  * This file is part of libgit2, distributed under the GNU GPL v2 with
5
5
  * a Linking Exception. For full terms see the included COPYING file.
@@ -8,6 +8,7 @@
8
8
  #define INCLUDE_posix__w32_h__
9
9
 
10
10
  #include <stdio.h>
11
+ #include <sys/param.h>
11
12
 
12
13
  #define p_lstat(p,b) lstat(p,b)
13
14
  #define p_readlink(a, b, c) readlink(a, b, c)
@@ -16,10 +17,19 @@
16
17
  #define p_unlink(p) unlink(p)
17
18
  #define p_mkdir(p,m) mkdir(p, m)
18
19
  #define p_fsync(fd) fsync(fd)
19
- #define p_realpath(p, po) realpath(p, po)
20
+
21
+ /* The OpenBSD realpath function behaves differently */
22
+ #if !defined(__OpenBSD__)
23
+ # define p_realpath(p, po) realpath(p, po)
24
+ #endif
25
+
20
26
  #define p_vsnprintf(b, c, f, a) vsnprintf(b, c, f, a)
21
27
  #define p_snprintf(b, c, f, ...) snprintf(b, c, f, __VA_ARGS__)
22
28
  #define p_mkstemp(p) mkstemp(p)
23
29
  #define p_setenv(n,v,o) setenv(n,v,o)
30
+ #define p_inet_pton(a, b, c) inet_pton(a, b, c)
31
+
32
+ /* see win32/posix.h for explanation about why this exists */
33
+ #define p_lstat_posixly(p,b) lstat(p,b)
24
34
 
25
35
  #endif
@@ -0,0 +1,30 @@
1
+ /*
2
+ * Copyright (C) the libgit2 contributors. All rights reserved.
3
+ *
4
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
5
+ * a Linking Exception. For full terms see the included COPYING file.
6
+ */
7
+ #include <git2/common.h>
8
+
9
+ #ifdef __OpenBSD__
10
+
11
+ #include <limits.h>
12
+ #include <stdlib.h>
13
+ #include <fcntl.h>
14
+ #include <unistd.h>
15
+
16
+ char *p_realpath(const char *pathname, char *resolved)
17
+ {
18
+ char *ret;
19
+
20
+ if ((ret = realpath(pathname, resolved)) == NULL)
21
+ return NULL;
22
+
23
+ /* Figure out if the file exists */
24
+ if (!access(ret, F_OK))
25
+ return ret;
26
+
27
+ return NULL;
28
+ }
29
+
30
+ #endif
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (C) 2009-2012 the libgit2 contributors
2
+ * Copyright (C) the libgit2 contributors. All rights reserved.
3
3
  *
4
4
  * This file is part of libgit2, distributed under the GNU GPL v2 with
5
5
  * a Linking Exception. For full terms see the included COPYING file.
@@ -10,6 +10,7 @@
10
10
  #include <stdio.h>
11
11
  #include <ctype.h>
12
12
  #include "posix.h"
13
+ #include "fileops.h"
13
14
 
14
15
  #ifdef _MSC_VER
15
16
  # include <Shlwapi.h>
@@ -34,6 +35,79 @@ int git_libgit2_capabilities()
34
35
  ;
35
36
  }
36
37
 
38
+ /* Declarations for tuneable settings */
39
+ extern size_t git_mwindow__window_size;
40
+ extern size_t git_mwindow__mapped_limit;
41
+ extern size_t git_odb__cache_size;
42
+
43
+ static int config_level_to_futils_dir(int config_level)
44
+ {
45
+ int val = -1;
46
+
47
+ switch (config_level) {
48
+ case GIT_CONFIG_LEVEL_SYSTEM: val = GIT_FUTILS_DIR_SYSTEM; break;
49
+ case GIT_CONFIG_LEVEL_XDG: val = GIT_FUTILS_DIR_XDG; break;
50
+ case GIT_CONFIG_LEVEL_GLOBAL: val = GIT_FUTILS_DIR_GLOBAL; break;
51
+ default:
52
+ giterr_set(
53
+ GITERR_INVALID, "Invalid config path selector %d", config_level);
54
+ }
55
+
56
+ return val;
57
+ }
58
+
59
+ int git_libgit2_opts(int key, ...)
60
+ {
61
+ int error = 0;
62
+ va_list ap;
63
+
64
+ va_start(ap, key);
65
+
66
+ switch (key) {
67
+ case GIT_OPT_SET_MWINDOW_SIZE:
68
+ git_mwindow__window_size = va_arg(ap, size_t);
69
+ break;
70
+
71
+ case GIT_OPT_GET_MWINDOW_SIZE:
72
+ *(va_arg(ap, size_t *)) = git_mwindow__window_size;
73
+ break;
74
+
75
+ case GIT_OPT_SET_MWINDOW_MAPPED_LIMIT:
76
+ git_mwindow__mapped_limit = va_arg(ap, size_t);
77
+ break;
78
+
79
+ case GIT_OPT_GET_MWINDOW_MAPPED_LIMIT:
80
+ *(va_arg(ap, size_t *)) = git_mwindow__mapped_limit;
81
+ break;
82
+
83
+ case GIT_OPT_GET_SEARCH_PATH:
84
+ if ((error = config_level_to_futils_dir(va_arg(ap, int))) >= 0) {
85
+ char *out = va_arg(ap, char *);
86
+ size_t outlen = va_arg(ap, size_t);
87
+
88
+ error = git_futils_dirs_get_str(out, outlen, error);
89
+ }
90
+ break;
91
+
92
+ case GIT_OPT_SET_SEARCH_PATH:
93
+ if ((error = config_level_to_futils_dir(va_arg(ap, int))) >= 0)
94
+ error = git_futils_dirs_set(error, va_arg(ap, const char *));
95
+ break;
96
+
97
+ case GIT_OPT_GET_ODB_CACHE_SIZE:
98
+ *(va_arg(ap, size_t *)) = git_odb__cache_size;
99
+ break;
100
+
101
+ case GIT_OPT_SET_ODB_CACHE_SIZE:
102
+ git_odb__cache_size = va_arg(ap, size_t);
103
+ break;
104
+ }
105
+
106
+ va_end(ap);
107
+
108
+ return error;
109
+ }
110
+
37
111
  void git_strarray_free(git_strarray *array)
38
112
  {
39
113
  size_t i;
@@ -41,6 +115,8 @@ void git_strarray_free(git_strarray *array)
41
115
  git__free(array->strings[i]);
42
116
 
43
117
  git__free(array->strings);
118
+
119
+ memset(array, 0, sizeof(*array));
44
120
  }
45
121
 
46
122
  int git_strarray_copy(git_strarray *tgt, const git_strarray *src)
@@ -58,8 +134,10 @@ int git_strarray_copy(git_strarray *tgt, const git_strarray *src)
58
134
  GITERR_CHECK_ALLOC(tgt->strings);
59
135
 
60
136
  for (i = 0; i < src->count; ++i) {
61
- tgt->strings[tgt->count] = git__strdup(src->strings[i]);
137
+ if (!src->strings[i])
138
+ continue;
62
139
 
140
+ tgt->strings[tgt->count] = git__strdup(src->strings[i]);
63
141
  if (!tgt->strings[tgt->count]) {
64
142
  git_strarray_free(tgt);
65
143
  memset(tgt, 0, sizeof(*tgt));
@@ -174,6 +252,42 @@ int git__strtol32(int32_t *result, const char *nptr, const char **endptr, int ba
174
252
  return error;
175
253
  }
176
254
 
255
+ int git__strcmp(const char *a, const char *b)
256
+ {
257
+ while (*a && *b && *a == *b)
258
+ ++a, ++b;
259
+ return (int)(*(const unsigned char *)a) - (int)(*(const unsigned char *)b);
260
+ }
261
+
262
+ int git__strcasecmp(const char *a, const char *b)
263
+ {
264
+ while (*a && *b && tolower(*a) == tolower(*b))
265
+ ++a, ++b;
266
+ return (tolower(*a) - tolower(*b));
267
+ }
268
+
269
+ int git__strncmp(const char *a, const char *b, size_t sz)
270
+ {
271
+ while (sz && *a && *b && *a == *b)
272
+ --sz, ++a, ++b;
273
+ if (!sz)
274
+ return 0;
275
+ return (int)(*(const unsigned char *)a) - (int)(*(const unsigned char *)b);
276
+ }
277
+
278
+ int git__strncasecmp(const char *a, const char *b, size_t sz)
279
+ {
280
+ int al, bl;
281
+
282
+ do {
283
+ al = (unsigned char)tolower(*a);
284
+ bl = (unsigned char)tolower(*b);
285
+ ++a, ++b;
286
+ } while (--sz && al && al == bl);
287
+
288
+ return al - bl;
289
+ }
290
+
177
291
  void git__strntolower(char *str, size_t len)
178
292
  {
179
293
  size_t i;
@@ -238,6 +352,24 @@ char *git__strtok(char **end, const char *sep)
238
352
  return NULL;
239
353
  }
240
354
 
355
+ /* Similar to strtok, but does not collapse repeated tokens. */
356
+ char *git__strsep(char **end, const char *sep)
357
+ {
358
+ char *start = *end, *ptr = *end;
359
+
360
+ while (*ptr && !strchr(sep, *ptr))
361
+ ++ptr;
362
+
363
+ if (*ptr) {
364
+ *end = ptr + 1;
365
+ *ptr = '\0';
366
+
367
+ return start;
368
+ }
369
+
370
+ return NULL;
371
+ }
372
+
241
373
  void git__hexdump(const char *buffer, size_t len)
242
374
  {
243
375
  static const size_t LINE_WIDTH = 16;
@@ -384,6 +516,30 @@ uint32_t git__hash(const void *key, int len, uint32_t seed)
384
516
  *
385
517
  * Copyright (c) 1990 Regents of the University of California.
386
518
  * All rights reserved.
519
+ * Redistribution and use in source and binary forms, with or without
520
+ * modification, are permitted provided that the following conditions
521
+ * are met:
522
+ * 1. Redistributions of source code must retain the above copyright
523
+ * notice, this list of conditions and the following disclaimer.
524
+ * 2. Redistributions in binary form must reproduce the above copyright
525
+ * notice, this list of conditions and the following disclaimer in the
526
+ * documentation and/or other materials provided with the distribution.
527
+ * 3. [rescinded 22 July 1999]
528
+ * 4. Neither the name of the University nor the names of its contributors
529
+ * may be used to endorse or promote products derived from this software
530
+ * without specific prior written permission.
531
+ *
532
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
533
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
534
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
535
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
536
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
537
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
538
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
539
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
540
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
541
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
542
+ * SUCH DAMAGE.
387
543
  */
388
544
  int git__bsearch(
389
545
  void **array,
@@ -392,11 +548,11 @@ int git__bsearch(
392
548
  int (*compare)(const void *, const void *),
393
549
  size_t *position)
394
550
  {
395
- unsigned int lim;
551
+ size_t lim;
396
552
  int cmp = -1;
397
553
  void **part, **base = array;
398
554
 
399
- for (lim = (unsigned int)array_len; lim != 0; lim >>= 1) {
555
+ for (lim = array_len; lim != 0; lim >>= 1) {
400
556
  part = base + (lim >> 1);
401
557
  cmp = (*compare)(key, *part);
402
558
  if (cmp == 0) {
@@ -412,12 +568,43 @@ int git__bsearch(
412
568
  if (position)
413
569
  *position = (base - array);
414
570
 
415
- return (cmp == 0) ? 0 : -1;
571
+ return (cmp == 0) ? 0 : GIT_ENOTFOUND;
572
+ }
573
+
574
+ int git__bsearch_r(
575
+ void **array,
576
+ size_t array_len,
577
+ const void *key,
578
+ int (*compare_r)(const void *, const void *, void *),
579
+ void *payload,
580
+ size_t *position)
581
+ {
582
+ size_t lim;
583
+ int cmp = -1;
584
+ void **part, **base = array;
585
+
586
+ for (lim = array_len; lim != 0; lim >>= 1) {
587
+ part = base + (lim >> 1);
588
+ cmp = (*compare_r)(key, *part, payload);
589
+ if (cmp == 0) {
590
+ base = part;
591
+ break;
592
+ }
593
+ if (cmp > 0) { /* key > p; take right partition */
594
+ base = part + 1;
595
+ lim--;
596
+ } /* else take left partition */
597
+ }
598
+
599
+ if (position)
600
+ *position = (base - array);
601
+
602
+ return (cmp == 0) ? 0 : GIT_ENOTFOUND;
416
603
  }
417
604
 
418
605
  /**
419
606
  * A strcmp wrapper
420
- *
607
+ *
421
608
  * We don't want direct pointers to the CRT on Windows, we may
422
609
  * get stdcall conflicts.
423
610
  */
@@ -432,12 +619,8 @@ int git__strcmp_cb(const void *a, const void *b)
432
619
  int git__parse_bool(int *out, const char *value)
433
620
  {
434
621
  /* A missing value means true */
435
- if (value == NULL) {
436
- *out = 1;
437
- return 0;
438
- }
439
-
440
- if (!strcasecmp(value, "true") ||
622
+ if (value == NULL ||
623
+ !strcasecmp(value, "true") ||
441
624
  !strcasecmp(value, "yes") ||
442
625
  !strcasecmp(value, "on")) {
443
626
  *out = 1;
@@ -445,7 +628,8 @@ int git__parse_bool(int *out, const char *value)
445
628
  }
446
629
  if (!strcasecmp(value, "false") ||
447
630
  !strcasecmp(value, "no") ||
448
- !strcasecmp(value, "off")) {
631
+ !strcasecmp(value, "off") ||
632
+ value[0] == '\0') {
449
633
  *out = 0;
450
634
  return 0;
451
635
  }
@@ -470,3 +654,56 @@ size_t git__unescape(char *str)
470
654
 
471
655
  return (pos - str);
472
656
  }
657
+
658
+ #if defined(GIT_WIN32) || defined(BSD)
659
+ typedef struct {
660
+ git__sort_r_cmp cmp;
661
+ void *payload;
662
+ } git__qsort_r_glue;
663
+
664
+ static int GIT_STDLIB_CALL git__qsort_r_glue_cmp(
665
+ void *payload, const void *a, const void *b)
666
+ {
667
+ git__qsort_r_glue *glue = payload;
668
+ return glue->cmp(a, b, glue->payload);
669
+ }
670
+ #endif
671
+
672
+ void git__qsort_r(
673
+ void *els, size_t nel, size_t elsize, git__sort_r_cmp cmp, void *payload)
674
+ {
675
+ #if defined(__MINGW32__) || defined(__OpenBSD__)
676
+ git__insertsort_r(els, nel, elsize, NULL, cmp, payload);
677
+ #elif defined(GIT_WIN32)
678
+ git__qsort_r_glue glue = { cmp, payload };
679
+ qsort_s(els, nel, elsize, git__qsort_r_glue_cmp, &glue);
680
+ #elif defined(BSD)
681
+ git__qsort_r_glue glue = { cmp, payload };
682
+ qsort_r(els, nel, elsize, &glue, git__qsort_r_glue_cmp);
683
+ #else
684
+ qsort_r(els, nel, elsize, cmp, payload);
685
+ #endif
686
+ }
687
+
688
+ void git__insertsort_r(
689
+ void *els, size_t nel, size_t elsize, void *swapel,
690
+ git__sort_r_cmp cmp, void *payload)
691
+ {
692
+ uint8_t *base = els;
693
+ uint8_t *end = base + nel * elsize;
694
+ uint8_t *i, *j;
695
+ bool freeswap = !swapel;
696
+
697
+ if (freeswap)
698
+ swapel = git__malloc(elsize);
699
+
700
+ for (i = base + elsize; i < end; i += elsize)
701
+ for (j = i; j > base && cmp(j, j - elsize, payload) < 0; j -= elsize) {
702
+ memcpy(swapel, j, elsize);
703
+ memcpy(j, j - elsize, elsize);
704
+ memcpy(j - elsize, swapel, elsize);
705
+ }
706
+
707
+ if (freeswap)
708
+ git__free(swapel);
709
+ }