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
@@ -31,19 +31,18 @@ extern int git_attr_cache__get(
31
31
  git_attr_file **file,
32
32
  git_repository *repo,
33
33
  git_attr_session *attr_session,
34
- git_attr_file_source source,
35
- const char *base,
36
- const char *filename,
34
+ git_attr_file_source *source,
37
35
  git_attr_file_parser parser,
38
36
  bool allow_macros);
39
37
 
40
38
  extern bool git_attr_cache__is_cached(
41
39
  git_repository *repo,
42
- git_attr_file_source source,
43
- const char *path);
40
+ git_attr_file_source_t source_type,
41
+ const char *filename);
44
42
 
45
43
  extern int git_attr_cache__alloc_file_entry(
46
44
  git_attr_file_entry **out,
45
+ git_repository *repo,
47
46
  const char *base,
48
47
  const char *path,
49
48
  git_pool *pool);
@@ -176,20 +176,21 @@ void git_blame_free(git_blame *blame)
176
176
 
177
177
  uint32_t git_blame_get_hunk_count(git_blame *blame)
178
178
  {
179
- assert(blame);
179
+ GIT_ASSERT_ARG(blame);
180
180
  return (uint32_t)blame->hunks.length;
181
181
  }
182
182
 
183
183
  const git_blame_hunk *git_blame_get_hunk_byindex(git_blame *blame, uint32_t index)
184
184
  {
185
- assert(blame);
185
+ GIT_ASSERT_ARG_WITH_RETVAL(blame, NULL);
186
186
  return (git_blame_hunk*)git_vector_get(&blame->hunks, index);
187
187
  }
188
188
 
189
189
  const git_blame_hunk *git_blame_get_hunk_byline(git_blame *blame, size_t lineno)
190
190
  {
191
191
  size_t i, new_lineno = lineno;
192
- assert(blame);
192
+
193
+ GIT_ASSERT_ARG_WITH_RETVAL(blame, NULL);
193
194
 
194
195
  if (!git_vector_bsearch2(&i, &blame->hunks, hunk_byfinalline_search_cmp, &new_lineno)) {
195
196
  return git_blame_get_hunk_byindex(blame, (uint32_t)i);
@@ -393,7 +394,10 @@ int git_blame_file(
393
394
  git_blame_options normOptions = GIT_BLAME_OPTIONS_INIT;
394
395
  git_blame *blame = NULL;
395
396
 
396
- assert(out && repo && path);
397
+ GIT_ASSERT_ARG(out);
398
+ GIT_ASSERT_ARG(repo);
399
+ GIT_ASSERT_ARG(path);
400
+
397
401
  if ((error = normalize_options(&normOptions, options, repo)) < 0)
398
402
  goto on_error;
399
403
 
@@ -514,7 +518,9 @@ int git_blame_buffer(
514
518
 
515
519
  diffopts.context_lines = 0;
516
520
 
517
- assert(out && reference && buffer && buffer_len);
521
+ GIT_ASSERT_ARG(out);
522
+ GIT_ASSERT_ARG(reference);
523
+ GIT_ASSERT_ARG(buffer && buffer_len);
518
524
 
519
525
  blame = git_blame__alloc(reference->repository, reference->options, reference->path);
520
526
  GIT_ERROR_CHECK_ALLOC(blame);
@@ -14,11 +14,11 @@
14
14
 
15
15
  #include "filebuf.h"
16
16
  #include "filter.h"
17
- #include "buf_text.h"
18
17
 
19
18
  const void *git_blob_rawcontent(const git_blob *blob)
20
19
  {
21
- assert(blob);
20
+ GIT_ASSERT_ARG_WITH_RETVAL(blob, NULL);
21
+
22
22
  if (blob->raw)
23
23
  return blob->data.raw.data;
24
24
  else
@@ -27,7 +27,8 @@ const void *git_blob_rawcontent(const git_blob *blob)
27
27
 
28
28
  git_object_size_t git_blob_rawsize(const git_blob *blob)
29
29
  {
30
- assert(blob);
30
+ GIT_ASSERT_ARG(blob);
31
+
31
32
  if (blob->raw)
32
33
  return blob->data.raw.size;
33
34
  else
@@ -53,7 +54,9 @@ void git_blob__free(void *_blob)
53
54
  int git_blob__parse_raw(void *_blob, const char *data, size_t size)
54
55
  {
55
56
  git_blob *blob = (git_blob *) _blob;
56
- assert(blob);
57
+
58
+ GIT_ASSERT_ARG(blob);
59
+
57
60
  blob->raw = 1;
58
61
  blob->data.raw.data = data;
59
62
  blob->data.raw.size = size;
@@ -63,7 +66,9 @@ int git_blob__parse_raw(void *_blob, const char *data, size_t size)
63
66
  int git_blob__parse(void *_blob, git_odb_object *odb_obj)
64
67
  {
65
68
  git_blob *blob = (git_blob *) _blob;
66
- assert(blob);
69
+
70
+ GIT_ASSERT_ARG(blob);
71
+
67
72
  git_cached_obj_incref((git_cached_obj *)odb_obj);
68
73
  blob->raw = 0;
69
74
  blob->data.odb = odb_obj;
@@ -77,7 +82,8 @@ int git_blob_create_from_buffer(
77
82
  git_odb *odb;
78
83
  git_odb_stream *stream;
79
84
 
80
- assert(id && repo);
85
+ GIT_ASSERT_ARG(id);
86
+ GIT_ASSERT_ARG(repo);
81
87
 
82
88
  if ((error = git_repository_odb__weakptr(&odb, repo)) < 0 ||
83
89
  (error = git_odb_open_wstream(&stream, odb, len, GIT_OBJECT_BLOB)) < 0)
@@ -188,14 +194,10 @@ int git_blob__create_from_paths(
188
194
  mode_t mode;
189
195
  git_buf path = GIT_BUF_INIT;
190
196
 
191
- assert(hint_path || !try_load_filters);
197
+ GIT_ASSERT_ARG(hint_path || !try_load_filters);
192
198
 
193
199
  if (!content_path) {
194
- if (git_repository__ensure_not_bare(repo, "create blob from file") < 0)
195
- return GIT_EBAREREPO;
196
-
197
- if (git_buf_joinpath(
198
- &path, git_repository_workdir(repo), hint_path) < 0)
200
+ if (git_repository_workdir_path(&path, repo, hint_path) < 0)
199
201
  return -1;
200
202
 
201
203
  content_path = path.ptr;
@@ -331,7 +333,8 @@ int git_blob_create_from_stream(git_writestream **out, git_repository *repo, con
331
333
  git_buf path = GIT_BUF_INIT;
332
334
  blob_writestream *stream;
333
335
 
334
- assert(out && repo);
336
+ GIT_ASSERT_ARG(out);
337
+ GIT_ASSERT_ARG(repo);
335
338
 
336
339
  stream = git__calloc(1, sizeof(blob_writestream));
337
340
  GIT_ERROR_CHECK_ALLOC(stream);
@@ -391,13 +394,13 @@ int git_blob_is_binary(const git_blob *blob)
391
394
  git_buf content = GIT_BUF_INIT;
392
395
  git_object_size_t size;
393
396
 
394
- assert(blob);
397
+ GIT_ASSERT_ARG(blob);
395
398
 
396
399
  size = git_blob_rawsize(blob);
397
400
 
398
401
  git_buf_attach_notowned(&content, git_blob_rawcontent(blob),
399
402
  (size_t)min(size, GIT_FILTER_BYTES_TO_CHECK_NUL));
400
- return git_buf_text_is_binary(&content);
403
+ return git_buf_is_binary(&content);
401
404
  }
402
405
 
403
406
  int git_blob_filter_options_init(
@@ -418,15 +421,18 @@ int git_blob_filter(
418
421
  int error = 0;
419
422
  git_filter_list *fl = NULL;
420
423
  git_blob_filter_options opts = GIT_BLOB_FILTER_OPTIONS_INIT;
421
- git_filter_flag_t flags = GIT_FILTER_DEFAULT;
422
-
423
- assert(blob && path && out);
424
+ git_filter_options filter_opts = GIT_FILTER_OPTIONS_INIT;
424
425
 
425
- git_buf_sanitize(out);
426
+ GIT_ASSERT_ARG(blob);
427
+ GIT_ASSERT_ARG(path);
428
+ GIT_ASSERT_ARG(out);
426
429
 
427
430
  GIT_ERROR_CHECK_VERSION(
428
431
  given_opts, GIT_BLOB_FILTER_OPTIONS_VERSION, "git_blob_filter_options");
429
432
 
433
+ if (git_buf_sanitize(out) < 0)
434
+ return -1;
435
+
430
436
  if (given_opts != NULL)
431
437
  memcpy(&opts, given_opts, sizeof(git_blob_filter_options));
432
438
 
@@ -435,14 +441,19 @@ int git_blob_filter(
435
441
  return 0;
436
442
 
437
443
  if ((opts.flags & GIT_BLOB_FILTER_NO_SYSTEM_ATTRIBUTES) != 0)
438
- flags |= GIT_FILTER_NO_SYSTEM_ATTRIBUTES;
444
+ filter_opts.flags |= GIT_FILTER_NO_SYSTEM_ATTRIBUTES;
445
+
446
+ if ((opts.flags & GIT_BLOB_FILTER_ATTRIBUTES_FROM_HEAD) != 0)
447
+ filter_opts.flags |= GIT_FILTER_ATTRIBUTES_FROM_HEAD;
439
448
 
440
- if ((opts.flags & GIT_BLOB_FILTER_ATTTRIBUTES_FROM_HEAD) != 0)
441
- flags |= GIT_FILTER_ATTRIBUTES_FROM_HEAD;
449
+ if ((opts.flags & GIT_BLOB_FILTER_ATTRIBUTES_FROM_COMMIT) != 0) {
450
+ filter_opts.flags |= GIT_FILTER_ATTRIBUTES_FROM_COMMIT;
451
+ filter_opts.commit_id = opts.commit_id;
452
+ }
442
453
 
443
- if (!(error = git_filter_list_load(
454
+ if (!(error = git_filter_list_load_ext(
444
455
  &fl, git_blob_owner(blob), blob, path,
445
- GIT_FILTER_TO_WORKTREE, flags))) {
456
+ GIT_FILTER_TO_WORKTREE, &filter_opts))) {
446
457
 
447
458
  error = git_filter_list_apply_to_blob(out, fl, blob);
448
459
 
@@ -67,8 +67,10 @@ static int create_branch(
67
67
  int error = -1;
68
68
  int bare = git_repository_is_bare(repository);
69
69
 
70
- assert(branch_name && commit && ref_out);
71
- assert(git_object_owner((const git_object *)commit) == repository);
70
+ GIT_ASSERT_ARG(branch_name);
71
+ GIT_ASSERT_ARG(commit);
72
+ GIT_ASSERT_ARG(ref_out);
73
+ GIT_ASSERT_ARG(git_commit_owner(commit) == repository);
72
74
 
73
75
  if (!git__strcmp(branch_name, "HEAD")) {
74
76
  git_error_set(GIT_ERROR_REFERENCE, "'HEAD' is not a valid branch name");
@@ -161,6 +163,8 @@ out:
161
163
 
162
164
  int git_branch_is_checked_out(const git_reference *branch)
163
165
  {
166
+ GIT_ASSERT_ARG(branch);
167
+
164
168
  if (!git_reference_is_branch(branch))
165
169
  return 0;
166
170
  return git_repository_foreach_worktree(git_reference_owner(branch),
@@ -173,7 +177,7 @@ int git_branch_delete(git_reference *branch)
173
177
  git_buf config_section = GIT_BUF_INIT;
174
178
  int error = -1;
175
179
 
176
- assert(branch);
180
+ GIT_ASSERT_ARG(branch);
177
181
 
178
182
  if (!git_reference_is_branch(branch) && !git_reference_is_remote(branch)) {
179
183
  git_error_set(GIT_ERROR_INVALID, "reference '%s' is not a valid branch.",
@@ -288,7 +292,8 @@ int git_branch_move(
288
292
  log_message = GIT_BUF_INIT;
289
293
  int error;
290
294
 
291
- assert(branch && new_branch_name);
295
+ GIT_ASSERT_ARG(branch);
296
+ GIT_ASSERT_ARG(new_branch_name);
292
297
 
293
298
  if (!git_reference_is_branch(branch))
294
299
  return not_a_local_branch(git_reference_name(branch));
@@ -333,7 +338,10 @@ int git_branch_lookup(
333
338
  git_branch_t branch_type)
334
339
  {
335
340
  int error = -1;
336
- assert(ref_out && repo && branch_name);
341
+
342
+ GIT_ASSERT_ARG(ref_out);
343
+ GIT_ASSERT_ARG(repo);
344
+ GIT_ASSERT_ARG(branch_name);
337
345
 
338
346
  switch (branch_type) {
339
347
  case GIT_BRANCH_LOCAL:
@@ -346,7 +354,7 @@ int git_branch_lookup(
346
354
  error = retrieve_branch_reference(ref_out, repo, branch_name, true);
347
355
  break;
348
356
  default:
349
- assert(false);
357
+ GIT_ASSERT(false);
350
358
  }
351
359
  return error;
352
360
  }
@@ -357,7 +365,8 @@ int git_branch_name(
357
365
  {
358
366
  const char *branch_name;
359
367
 
360
- assert(out && ref);
368
+ GIT_ASSERT_ARG(out);
369
+ GIT_ASSERT_ARG(ref);
361
370
 
362
371
  branch_name = ref->name;
363
372
 
@@ -405,9 +414,11 @@ int git_branch_upstream_name(
405
414
  const git_refspec *refspec;
406
415
  git_config *config;
407
416
 
408
- assert(out && refname);
417
+ GIT_ASSERT_ARG(out);
418
+ GIT_ASSERT_ARG(refname);
409
419
 
410
- git_buf_sanitize(out);
420
+ if ((error = git_buf_sanitize(out)) < 0)
421
+ return error;
411
422
 
412
423
  if (!git_reference__is_branch(refname))
413
424
  return not_a_local_branch(refname);
@@ -457,7 +468,7 @@ cleanup:
457
468
  return error;
458
469
  }
459
470
 
460
- int git_branch_upstream_remote(git_buf *buf, git_repository *repo, const char *refname)
471
+ static int git_branch_upstream_with_format(git_buf *buf, git_repository *repo, const char *refname, const char *format, const char *format_name)
461
472
  {
462
473
  int error;
463
474
  git_config *cfg;
@@ -468,13 +479,12 @@ int git_branch_upstream_remote(git_buf *buf, git_repository *repo, const char *r
468
479
  if ((error = git_repository_config__weakptr(&cfg, repo)) < 0)
469
480
  return error;
470
481
 
471
- git_buf_sanitize(buf);
472
-
473
- if ((error = retrieve_upstream_configuration(buf, cfg, refname, "branch.%s.remote")) < 0)
482
+ if ((error = git_buf_sanitize(buf)) < 0 ||
483
+ (error = retrieve_upstream_configuration(buf, cfg, refname, format)) < 0)
474
484
  return error;
475
485
 
476
486
  if (git_buf_len(buf) == 0) {
477
- git_error_set(GIT_ERROR_REFERENCE, "branch '%s' does not have an upstream remote", refname);
487
+ git_error_set(GIT_ERROR_REFERENCE, "branch '%s' does not have an upstream %s", refname, format_name);
478
488
  error = GIT_ENOTFOUND;
479
489
  git_buf_clear(buf);
480
490
  }
@@ -482,6 +492,16 @@ int git_branch_upstream_remote(git_buf *buf, git_repository *repo, const char *r
482
492
  return error;
483
493
  }
484
494
 
495
+ int git_branch_upstream_remote(git_buf *buf, git_repository *repo, const char *refname)
496
+ {
497
+ return git_branch_upstream_with_format(buf, repo, refname, "branch.%s.remote", "remote");
498
+ }
499
+
500
+ int git_branch_upstream_merge(git_buf *buf, git_repository *repo, const char *refname)
501
+ {
502
+ return git_branch_upstream_with_format(buf, repo, refname, "branch.%s.merge", "merge");
503
+ }
504
+
485
505
  int git_branch_remote_name(git_buf *buf, git_repository *repo, const char *refname)
486
506
  {
487
507
  git_strarray remote_list = {0};
@@ -491,9 +511,12 @@ int git_branch_remote_name(git_buf *buf, git_repository *repo, const char *refna
491
511
  int error = 0;
492
512
  char *remote_name = NULL;
493
513
 
494
- assert(buf && repo && refname);
514
+ GIT_ASSERT_ARG(buf);
515
+ GIT_ASSERT_ARG(repo);
516
+ GIT_ASSERT_ARG(refname);
495
517
 
496
- git_buf_sanitize(buf);
518
+ if ((error = git_buf_sanitize(buf)) < 0)
519
+ return error;
497
520
 
498
521
  /* Verify that this is a remote branch */
499
522
  if (!git_reference__is_remote(refname)) {
@@ -702,7 +725,7 @@ int git_branch_is_head(
702
725
  bool is_same = false;
703
726
  int error;
704
727
 
705
- assert(branch);
728
+ GIT_ASSERT_ARG(branch);
706
729
 
707
730
  if (!git_reference_is_branch(branch))
708
731
  return false;
@@ -723,3 +746,32 @@ int git_branch_is_head(
723
746
 
724
747
  return is_same;
725
748
  }
749
+
750
+ int git_branch_name_is_valid(int *valid, const char *name)
751
+ {
752
+ git_buf ref_name = GIT_BUF_INIT;
753
+ int error = 0;
754
+
755
+ GIT_ASSERT(valid);
756
+
757
+ *valid = 0;
758
+
759
+ /*
760
+ * Discourage branch name starting with dash,
761
+ * https://github.com/git/git/commit/6348624010888b
762
+ * and discourage HEAD as branch name,
763
+ * https://github.com/git/git/commit/a625b092cc5994
764
+ */
765
+ if (!name || name[0] == '-' || !git__strcmp(name, "HEAD"))
766
+ goto done;
767
+
768
+ if ((error = git_buf_puts(&ref_name, GIT_REFS_HEADS_DIR)) < 0 ||
769
+ (error = git_buf_puts(&ref_name, name)) < 0)
770
+ goto done;
771
+
772
+ error = git_reference_name_is_valid(valid, ref_name.ptr);
773
+
774
+ done:
775
+ git_buf_dispose(&ref_name);
776
+ return error;
777
+ }
@@ -7,7 +7,6 @@
7
7
  #include "buffer.h"
8
8
  #include "posix.h"
9
9
  #include "git2/buffer.h"
10
- #include "buf_text.h"
11
10
  #include <ctype.h>
12
11
 
13
12
  /* Used as default value for git_buf->ptr so that people can always
@@ -140,13 +139,17 @@ void git_buf_free(git_buf *buf)
140
139
  }
141
140
  #endif
142
141
 
143
- void git_buf_sanitize(git_buf *buf)
142
+ int git_buf_sanitize(git_buf *buf)
144
143
  {
145
144
  if (buf->ptr == NULL) {
146
- assert(buf->size == 0 && buf->asize == 0);
145
+ GIT_ASSERT_ARG(buf->size == 0 && buf->asize == 0);
146
+
147
147
  buf->ptr = git_buf__initbuf;
148
- } else if (buf->asize > buf->size)
148
+ } else if (buf->asize > buf->size) {
149
149
  buf->ptr[buf->size] = '\0';
150
+ }
151
+
152
+ return 0;
150
153
  }
151
154
 
152
155
  void git_buf_clear(git_buf *buf)
@@ -183,16 +186,6 @@ int git_buf_set(git_buf *buf, const void *data, size_t len)
183
186
  return 0;
184
187
  }
185
188
 
186
- int git_buf_is_binary(const git_buf *buf)
187
- {
188
- return git_buf_text_is_binary(buf);
189
- }
190
-
191
- int git_buf_contains_nul(const git_buf *buf)
192
- {
193
- return git_buf_text_contains_nul(buf);
194
- }
195
-
196
189
  int git_buf_sets(git_buf *buf, const char *string)
197
190
  {
198
191
  return git_buf_set(buf, string, string ? strlen(string) : 0);
@@ -225,7 +218,7 @@ int git_buf_put(git_buf *buf, const char *data, size_t len)
225
218
  if (len) {
226
219
  size_t new_size;
227
220
 
228
- assert(data);
221
+ GIT_ASSERT_ARG(data);
229
222
 
230
223
  GIT_ERROR_CHECK_ALLOC_ADD(&new_size, buf->size, len);
231
224
  GIT_ERROR_CHECK_ALLOC_ADD(&new_size, new_size, 1);
@@ -239,7 +232,8 @@ int git_buf_put(git_buf *buf, const char *data, size_t len)
239
232
 
240
233
  int git_buf_puts(git_buf *buf, const char *string)
241
234
  {
242
- assert(string);
235
+ GIT_ASSERT_ARG(string);
236
+
243
237
  return git_buf_put(buf, string, strlen(string));
244
238
  }
245
239
 
@@ -319,7 +313,7 @@ int git_buf_decode_base64(git_buf *buf, const char *base64, size_t len)
319
313
  return -1;
320
314
  }
321
315
 
322
- assert(len % 4 == 0);
316
+ GIT_ASSERT_ARG(len % 4 == 0);
323
317
  GIT_ERROR_CHECK_ALLOC_ADD(&new_size, (len / 4 * 3), buf->size);
324
318
  GIT_ERROR_CHECK_ALLOC_ADD(&new_size, new_size, 1);
325
319
  ENSURE_SIZE(buf, new_size);
@@ -551,22 +545,26 @@ int git_buf_printf(git_buf *buf, const char *format, ...)
551
545
  return r;
552
546
  }
553
547
 
554
- void git_buf_copy_cstr(char *data, size_t datasize, const git_buf *buf)
548
+ int git_buf_copy_cstr(char *data, size_t datasize, const git_buf *buf)
555
549
  {
556
550
  size_t copylen;
557
551
 
558
- assert(data && datasize && buf);
552
+ GIT_ASSERT_ARG(data);
553
+ GIT_ASSERT_ARG(datasize);
554
+ GIT_ASSERT_ARG(buf);
559
555
 
560
556
  data[0] = '\0';
561
557
 
562
558
  if (buf->size == 0 || buf->asize <= 0)
563
- return;
559
+ return 0;
564
560
 
565
561
  copylen = buf->size;
566
562
  if (copylen > datasize - 1)
567
563
  copylen = datasize - 1;
568
564
  memmove(data, buf->ptr, copylen);
569
565
  data[copylen] = '\0';
566
+
567
+ return 0;
570
568
  }
571
569
 
572
570
  void git_buf_consume_bytes(git_buf *buf, size_t len)
@@ -760,7 +758,7 @@ int git_buf_join(
760
758
 
761
759
  /* not safe to have str_b point internally to the buffer */
762
760
  if (buf->size)
763
- assert(str_b < buf->ptr || str_b >= buf->ptr + buf->size);
761
+ GIT_ASSERT_ARG(str_b < buf->ptr || str_b >= buf->ptr + buf->size);
764
762
 
765
763
  /* figure out if we need to insert a separator */
766
764
  if (separator && strlen_a) {
@@ -810,9 +808,9 @@ int git_buf_join3(
810
808
  char *tgt;
811
809
 
812
810
  /* for this function, disallow pointers into the existing buffer */
813
- assert(str_a < buf->ptr || str_a >= buf->ptr + buf->size);
814
- assert(str_b < buf->ptr || str_b >= buf->ptr + buf->size);
815
- assert(str_c < buf->ptr || str_c >= buf->ptr + buf->size);
811
+ GIT_ASSERT(str_a < buf->ptr || str_a >= buf->ptr + buf->size);
812
+ GIT_ASSERT(str_b < buf->ptr || str_b >= buf->ptr + buf->size);
813
+ GIT_ASSERT(str_c < buf->ptr || str_c >= buf->ptr + buf->size);
816
814
 
817
815
  if (separator) {
818
816
  if (len_a > 0) {
@@ -885,7 +883,9 @@ int git_buf_splice(
885
883
  char *splice_loc;
886
884
  size_t new_size, alloc_size;
887
885
 
888
- assert(buf && where <= buf->size && nb_to_remove <= buf->size - where);
886
+ GIT_ASSERT(buf);
887
+ GIT_ASSERT(where <= buf->size);
888
+ GIT_ASSERT(nb_to_remove <= buf->size - where);
889
889
 
890
890
  splice_loc = buf->ptr + where;
891
891
 
@@ -1047,3 +1047,312 @@ invalid:
1047
1047
  git_error_set(GIT_ERROR_INVALID, "invalid quoted line");
1048
1048
  return -1;
1049
1049
  }
1050
+
1051
+ int git_buf_puts_escaped(
1052
+ git_buf *buf,
1053
+ const char *string,
1054
+ const char *esc_chars,
1055
+ const char *esc_with)
1056
+ {
1057
+ const char *scan;
1058
+ size_t total = 0, esc_len = strlen(esc_with), count, alloclen;
1059
+
1060
+ if (!string)
1061
+ return 0;
1062
+
1063
+ for (scan = string; *scan; ) {
1064
+ /* count run of non-escaped characters */
1065
+ count = strcspn(scan, esc_chars);
1066
+ total += count;
1067
+ scan += count;
1068
+ /* count run of escaped characters */
1069
+ count = strspn(scan, esc_chars);
1070
+ total += count * (esc_len + 1);
1071
+ scan += count;
1072
+ }
1073
+
1074
+ GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, total, 1);
1075
+ if (git_buf_grow_by(buf, alloclen) < 0)
1076
+ return -1;
1077
+
1078
+ for (scan = string; *scan; ) {
1079
+ count = strcspn(scan, esc_chars);
1080
+
1081
+ memmove(buf->ptr + buf->size, scan, count);
1082
+ scan += count;
1083
+ buf->size += count;
1084
+
1085
+ for (count = strspn(scan, esc_chars); count > 0; --count) {
1086
+ /* copy escape sequence */
1087
+ memmove(buf->ptr + buf->size, esc_with, esc_len);
1088
+ buf->size += esc_len;
1089
+ /* copy character to be escaped */
1090
+ buf->ptr[buf->size] = *scan;
1091
+ buf->size++;
1092
+ scan++;
1093
+ }
1094
+ }
1095
+
1096
+ buf->ptr[buf->size] = '\0';
1097
+
1098
+ return 0;
1099
+ }
1100
+
1101
+ void git_buf_unescape(git_buf *buf)
1102
+ {
1103
+ buf->size = git__unescape(buf->ptr);
1104
+ }
1105
+
1106
+ int git_buf_crlf_to_lf(git_buf *tgt, const git_buf *src)
1107
+ {
1108
+ const char *scan = src->ptr;
1109
+ const char *scan_end = src->ptr + src->size;
1110
+ const char *next = memchr(scan, '\r', src->size);
1111
+ size_t new_size;
1112
+ char *out;
1113
+
1114
+ GIT_ASSERT(tgt != src);
1115
+
1116
+ if (!next)
1117
+ return git_buf_set(tgt, src->ptr, src->size);
1118
+
1119
+ /* reduce reallocs while in the loop */
1120
+ GIT_ERROR_CHECK_ALLOC_ADD(&new_size, src->size, 1);
1121
+ if (git_buf_grow(tgt, new_size) < 0)
1122
+ return -1;
1123
+
1124
+ out = tgt->ptr;
1125
+ tgt->size = 0;
1126
+
1127
+ /* Find the next \r and copy whole chunk up to there to tgt */
1128
+ for (; next; scan = next + 1, next = memchr(scan, '\r', scan_end - scan)) {
1129
+ if (next > scan) {
1130
+ size_t copylen = (size_t)(next - scan);
1131
+ memcpy(out, scan, copylen);
1132
+ out += copylen;
1133
+ }
1134
+
1135
+ /* Do not drop \r unless it is followed by \n */
1136
+ if (next + 1 == scan_end || next[1] != '\n')
1137
+ *out++ = '\r';
1138
+ }
1139
+
1140
+ /* Copy remaining input into dest */
1141
+ if (scan < scan_end) {
1142
+ size_t remaining = (size_t)(scan_end - scan);
1143
+ memcpy(out, scan, remaining);
1144
+ out += remaining;
1145
+ }
1146
+
1147
+ tgt->size = (size_t)(out - tgt->ptr);
1148
+ tgt->ptr[tgt->size] = '\0';
1149
+
1150
+ return 0;
1151
+ }
1152
+
1153
+ int git_buf_lf_to_crlf(git_buf *tgt, const git_buf *src)
1154
+ {
1155
+ const char *start = src->ptr;
1156
+ const char *end = start + src->size;
1157
+ const char *scan = start;
1158
+ const char *next = memchr(scan, '\n', src->size);
1159
+ size_t alloclen;
1160
+
1161
+ GIT_ASSERT(tgt != src);
1162
+
1163
+ if (!next)
1164
+ return git_buf_set(tgt, src->ptr, src->size);
1165
+
1166
+ /* attempt to reduce reallocs while in the loop */
1167
+ GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, src->size, src->size >> 4);
1168
+ GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, alloclen, 1);
1169
+ if (git_buf_grow(tgt, alloclen) < 0)
1170
+ return -1;
1171
+ tgt->size = 0;
1172
+
1173
+ for (; next; scan = next + 1, next = memchr(scan, '\n', end - scan)) {
1174
+ size_t copylen = next - scan;
1175
+
1176
+ /* if we find mixed line endings, carry on */
1177
+ if (copylen && next[-1] == '\r')
1178
+ copylen--;
1179
+
1180
+ GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, copylen, 3);
1181
+ if (git_buf_grow_by(tgt, alloclen) < 0)
1182
+ return -1;
1183
+
1184
+ if (copylen) {
1185
+ memcpy(tgt->ptr + tgt->size, scan, copylen);
1186
+ tgt->size += copylen;
1187
+ }
1188
+
1189
+ tgt->ptr[tgt->size++] = '\r';
1190
+ tgt->ptr[tgt->size++] = '\n';
1191
+ }
1192
+
1193
+ tgt->ptr[tgt->size] = '\0';
1194
+ return git_buf_put(tgt, scan, end - scan);
1195
+ }
1196
+
1197
+ int git_buf_common_prefix(git_buf *buf, const git_strarray *strings)
1198
+ {
1199
+ size_t i;
1200
+ const char *str, *pfx;
1201
+
1202
+ git_buf_clear(buf);
1203
+
1204
+ if (!strings || !strings->count)
1205
+ return 0;
1206
+
1207
+ /* initialize common prefix to first string */
1208
+ if (git_buf_sets(buf, strings->strings[0]) < 0)
1209
+ return -1;
1210
+
1211
+ /* go through the rest of the strings, truncating to shared prefix */
1212
+ for (i = 1; i < strings->count; ++i) {
1213
+
1214
+ for (str = strings->strings[i], pfx = buf->ptr;
1215
+ *str && *str == *pfx; str++, pfx++)
1216
+ /* scanning */;
1217
+
1218
+ git_buf_truncate(buf, pfx - buf->ptr);
1219
+
1220
+ if (!buf->size)
1221
+ break;
1222
+ }
1223
+
1224
+ return 0;
1225
+ }
1226
+
1227
+ int git_buf_is_binary(const git_buf *buf)
1228
+ {
1229
+ const char *scan = buf->ptr, *end = buf->ptr + buf->size;
1230
+ git_buf_bom_t bom;
1231
+ int printable = 0, nonprintable = 0;
1232
+
1233
+ scan += git_buf_detect_bom(&bom, buf);
1234
+
1235
+ if (bom > GIT_BUF_BOM_UTF8)
1236
+ return 1;
1237
+
1238
+ while (scan < end) {
1239
+ unsigned char c = *scan++;
1240
+
1241
+ /* Printable characters are those above SPACE (0x1F) excluding DEL,
1242
+ * and including BS, ESC and FF.
1243
+ */
1244
+ if ((c > 0x1F && c != 127) || c == '\b' || c == '\033' || c == '\014')
1245
+ printable++;
1246
+ else if (c == '\0')
1247
+ return true;
1248
+ else if (!git__isspace(c))
1249
+ nonprintable++;
1250
+ }
1251
+
1252
+ return ((printable >> 7) < nonprintable);
1253
+ }
1254
+
1255
+ int git_buf_contains_nul(const git_buf *buf)
1256
+ {
1257
+ return (memchr(buf->ptr, '\0', buf->size) != NULL);
1258
+ }
1259
+
1260
+ int git_buf_detect_bom(git_buf_bom_t *bom, const git_buf *buf)
1261
+ {
1262
+ const char *ptr;
1263
+ size_t len;
1264
+
1265
+ *bom = GIT_BUF_BOM_NONE;
1266
+ /* need at least 2 bytes to look for any BOM */
1267
+ if (buf->size < 2)
1268
+ return 0;
1269
+
1270
+ ptr = buf->ptr;
1271
+ len = buf->size;
1272
+
1273
+ switch (*ptr++) {
1274
+ case 0:
1275
+ if (len >= 4 && ptr[0] == 0 && ptr[1] == '\xFE' && ptr[2] == '\xFF') {
1276
+ *bom = GIT_BUF_BOM_UTF32_BE;
1277
+ return 4;
1278
+ }
1279
+ break;
1280
+ case '\xEF':
1281
+ if (len >= 3 && ptr[0] == '\xBB' && ptr[1] == '\xBF') {
1282
+ *bom = GIT_BUF_BOM_UTF8;
1283
+ return 3;
1284
+ }
1285
+ break;
1286
+ case '\xFE':
1287
+ if (*ptr == '\xFF') {
1288
+ *bom = GIT_BUF_BOM_UTF16_BE;
1289
+ return 2;
1290
+ }
1291
+ break;
1292
+ case '\xFF':
1293
+ if (*ptr != '\xFE')
1294
+ break;
1295
+ if (len >= 4 && ptr[1] == 0 && ptr[2] == 0) {
1296
+ *bom = GIT_BUF_BOM_UTF32_LE;
1297
+ return 4;
1298
+ } else {
1299
+ *bom = GIT_BUF_BOM_UTF16_LE;
1300
+ return 2;
1301
+ }
1302
+ break;
1303
+ default:
1304
+ break;
1305
+ }
1306
+
1307
+ return 0;
1308
+ }
1309
+
1310
+ bool git_buf_gather_text_stats(
1311
+ git_buf_text_stats *stats, const git_buf *buf, bool skip_bom)
1312
+ {
1313
+ const char *scan = buf->ptr, *end = buf->ptr + buf->size;
1314
+ int skip;
1315
+
1316
+ memset(stats, 0, sizeof(*stats));
1317
+
1318
+ /* BOM detection */
1319
+ skip = git_buf_detect_bom(&stats->bom, buf);
1320
+ if (skip_bom)
1321
+ scan += skip;
1322
+
1323
+ /* Ignore EOF character */
1324
+ if (buf->size > 0 && end[-1] == '\032')
1325
+ end--;
1326
+
1327
+ /* Counting loop */
1328
+ while (scan < end) {
1329
+ unsigned char c = *scan++;
1330
+
1331
+ if (c > 0x1F && c != 0x7F)
1332
+ stats->printable++;
1333
+ else switch (c) {
1334
+ case '\0':
1335
+ stats->nul++;
1336
+ stats->nonprintable++;
1337
+ break;
1338
+ case '\n':
1339
+ stats->lf++;
1340
+ break;
1341
+ case '\r':
1342
+ stats->cr++;
1343
+ if (scan < end && *scan == '\n')
1344
+ stats->crlf++;
1345
+ break;
1346
+ case '\t': case '\f': case '\v': case '\b': case 0x1b: /*ESC*/
1347
+ stats->printable++;
1348
+ break;
1349
+ default:
1350
+ stats->nonprintable++;
1351
+ break;
1352
+ }
1353
+ }
1354
+
1355
+ /* Treat files with a bare CR as binary */
1356
+ return (stats->cr != stats->crlf || stats->nul > 0 ||
1357
+ ((stats->printable >> 7) < stats->nonprintable));
1358
+ }