rugged 0.27.10.1 → 0.28.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (297) hide show
  1. checksums.yaml +4 -4
  2. data/ext/rugged/extconf.rb +23 -2
  3. data/ext/rugged/rugged.c +48 -2
  4. data/ext/rugged/rugged.h +5 -0
  5. data/ext/rugged/rugged_allocator.c +89 -0
  6. data/ext/rugged/rugged_blob.c +3 -3
  7. data/ext/rugged/rugged_branch.c +1 -1
  8. data/ext/rugged/rugged_commit.c +8 -8
  9. data/ext/rugged/rugged_config.c +1 -1
  10. data/ext/rugged/rugged_diff.c +24 -4
  11. data/ext/rugged/rugged_note.c +1 -1
  12. data/ext/rugged/rugged_repo.c +10 -10
  13. data/ext/rugged/rugged_settings.c +1 -1
  14. data/lib/rugged/version.rb +1 -1
  15. data/vendor/libgit2/CMakeLists.txt +69 -47
  16. data/vendor/libgit2/cmake/Modules/AddCFlagIfSupported.cmake +15 -1
  17. data/vendor/libgit2/cmake/Modules/EnableWarnings.cmake +5 -8
  18. data/vendor/libgit2/cmake/Modules/FindmbedTLS.cmake +93 -0
  19. data/vendor/libgit2/deps/http-parser/CMakeLists.txt +2 -0
  20. data/vendor/libgit2/deps/http-parser/{LICENSE-MIT → COPYING} +0 -0
  21. data/vendor/libgit2/deps/regex/COPYING +502 -0
  22. data/vendor/libgit2/deps/winhttp/COPYING.GPL +993 -0
  23. data/vendor/libgit2/deps/winhttp/COPYING.LGPL +502 -0
  24. data/vendor/libgit2/deps/zlib/CMakeLists.txt +1 -0
  25. data/vendor/libgit2/deps/zlib/COPYING +27 -0
  26. data/vendor/libgit2/include/git2.h +3 -0
  27. data/vendor/libgit2/include/git2/annotated_commit.h +9 -0
  28. data/vendor/libgit2/include/git2/apply.h +129 -0
  29. data/vendor/libgit2/include/git2/attr.h +19 -8
  30. data/vendor/libgit2/include/git2/blame.h +41 -24
  31. data/vendor/libgit2/include/git2/blob.h +1 -1
  32. data/vendor/libgit2/include/git2/branch.h +1 -1
  33. data/vendor/libgit2/include/git2/buffer.h +2 -2
  34. data/vendor/libgit2/include/git2/checkout.h +20 -19
  35. data/vendor/libgit2/include/git2/cherrypick.h +6 -4
  36. data/vendor/libgit2/include/git2/clone.h +11 -9
  37. data/vendor/libgit2/include/git2/commit.h +30 -2
  38. data/vendor/libgit2/include/git2/common.h +54 -4
  39. data/vendor/libgit2/include/git2/config.h +18 -7
  40. data/vendor/libgit2/include/git2/deprecated.h +253 -0
  41. data/vendor/libgit2/include/git2/describe.h +30 -7
  42. data/vendor/libgit2/include/git2/diff.h +193 -143
  43. data/vendor/libgit2/include/git2/errors.h +54 -46
  44. data/vendor/libgit2/include/git2/ignore.h +2 -2
  45. data/vendor/libgit2/include/git2/index.h +72 -51
  46. data/vendor/libgit2/include/git2/indexer.h +30 -4
  47. data/vendor/libgit2/include/git2/mailmap.h +115 -0
  48. data/vendor/libgit2/include/git2/merge.h +29 -8
  49. data/vendor/libgit2/include/git2/net.h +1 -1
  50. data/vendor/libgit2/include/git2/notes.h +1 -1
  51. data/vendor/libgit2/include/git2/object.h +16 -16
  52. data/vendor/libgit2/include/git2/odb.h +10 -10
  53. data/vendor/libgit2/include/git2/odb_backend.h +7 -7
  54. data/vendor/libgit2/include/git2/oid.h +1 -1
  55. data/vendor/libgit2/include/git2/pack.h +2 -2
  56. data/vendor/libgit2/include/git2/proxy.h +9 -5
  57. data/vendor/libgit2/include/git2/rebase.h +7 -4
  58. data/vendor/libgit2/include/git2/refs.h +14 -15
  59. data/vendor/libgit2/include/git2/refspec.h +17 -0
  60. data/vendor/libgit2/include/git2/remote.h +92 -16
  61. data/vendor/libgit2/include/git2/repository.h +52 -37
  62. data/vendor/libgit2/include/git2/revert.h +5 -3
  63. data/vendor/libgit2/include/git2/revwalk.h +7 -7
  64. data/vendor/libgit2/include/git2/signature.h +2 -2
  65. data/vendor/libgit2/include/git2/stash.h +13 -10
  66. data/vendor/libgit2/include/git2/status.h +8 -4
  67. data/vendor/libgit2/include/git2/submodule.h +11 -10
  68. data/vendor/libgit2/include/git2/sys/alloc.h +101 -0
  69. data/vendor/libgit2/include/git2/sys/commit.h +1 -1
  70. data/vendor/libgit2/include/git2/sys/config.h +13 -13
  71. data/vendor/libgit2/include/git2/sys/filter.h +6 -6
  72. data/vendor/libgit2/include/git2/sys/index.h +3 -0
  73. data/vendor/libgit2/include/git2/sys/mempack.h +35 -35
  74. data/vendor/libgit2/include/git2/sys/merge.h +9 -4
  75. data/vendor/libgit2/include/git2/sys/odb_backend.h +19 -19
  76. data/vendor/libgit2/include/git2/sys/path.h +64 -0
  77. data/vendor/libgit2/include/git2/sys/refdb_backend.h +19 -19
  78. data/vendor/libgit2/include/git2/sys/stream.h +92 -12
  79. data/vendor/libgit2/include/git2/sys/transport.h +127 -81
  80. data/vendor/libgit2/include/git2/tag.h +2 -2
  81. data/vendor/libgit2/include/git2/trace.h +1 -1
  82. data/vendor/libgit2/include/git2/transaction.h +1 -0
  83. data/vendor/libgit2/include/git2/transport.h +47 -18
  84. data/vendor/libgit2/include/git2/tree.h +3 -3
  85. data/vendor/libgit2/include/git2/types.h +35 -28
  86. data/vendor/libgit2/include/git2/version.h +4 -4
  87. data/vendor/libgit2/include/git2/worktree.h +47 -12
  88. data/vendor/libgit2/src/CMakeLists.txt +87 -26
  89. data/vendor/libgit2/src/alloc.c +55 -0
  90. data/vendor/libgit2/src/alloc.h +40 -0
  91. data/vendor/libgit2/src/annotated_commit.c +15 -8
  92. data/vendor/libgit2/src/apply.c +490 -14
  93. data/vendor/libgit2/src/apply.h +3 -1
  94. data/vendor/libgit2/src/array.h +2 -2
  95. data/vendor/libgit2/src/attr.c +11 -11
  96. data/vendor/libgit2/src/attr_file.c +20 -15
  97. data/vendor/libgit2/src/attrcache.c +11 -11
  98. data/vendor/libgit2/src/blame.c +30 -15
  99. data/vendor/libgit2/src/blame.h +1 -0
  100. data/vendor/libgit2/src/blame_git.c +16 -13
  101. data/vendor/libgit2/src/blob.c +50 -28
  102. data/vendor/libgit2/src/blob.h +18 -1
  103. data/vendor/libgit2/src/branch.c +38 -38
  104. data/vendor/libgit2/src/buf_text.c +7 -6
  105. data/vendor/libgit2/src/buffer.c +55 -50
  106. data/vendor/libgit2/src/buffer.h +1 -1
  107. data/vendor/libgit2/src/cache.c +16 -16
  108. data/vendor/libgit2/src/cache.h +2 -2
  109. data/vendor/libgit2/src/cc-compat.h +15 -3
  110. data/vendor/libgit2/src/checkout.c +83 -74
  111. data/vendor/libgit2/src/cherrypick.c +6 -6
  112. data/vendor/libgit2/src/clone.c +20 -20
  113. data/vendor/libgit2/src/commit.c +53 -33
  114. data/vendor/libgit2/src/commit.h +1 -0
  115. data/vendor/libgit2/src/commit_list.c +6 -10
  116. data/vendor/libgit2/src/common.h +32 -30
  117. data/vendor/libgit2/src/config.c +167 -147
  118. data/vendor/libgit2/src/config.h +1 -14
  119. data/vendor/libgit2/src/config_backend.h +84 -0
  120. data/vendor/libgit2/src/config_cache.c +7 -1
  121. data/vendor/libgit2/src/config_entries.c +259 -0
  122. data/vendor/libgit2/src/config_entries.h +23 -0
  123. data/vendor/libgit2/src/config_file.c +167 -439
  124. data/vendor/libgit2/src/config_mem.c +224 -0
  125. data/vendor/libgit2/src/config_parse.c +69 -38
  126. data/vendor/libgit2/src/config_parse.h +4 -4
  127. data/vendor/libgit2/src/crlf.c +215 -186
  128. data/vendor/libgit2/src/delta.c +25 -18
  129. data/vendor/libgit2/src/describe.c +23 -23
  130. data/vendor/libgit2/src/diff.c +12 -12
  131. data/vendor/libgit2/src/diff_driver.c +14 -15
  132. data/vendor/libgit2/src/diff_file.c +10 -10
  133. data/vendor/libgit2/src/diff_generate.c +29 -23
  134. data/vendor/libgit2/src/diff_generate.h +1 -1
  135. data/vendor/libgit2/src/diff_parse.c +3 -3
  136. data/vendor/libgit2/src/diff_print.c +17 -17
  137. data/vendor/libgit2/src/diff_stats.c +22 -7
  138. data/vendor/libgit2/src/diff_tform.c +12 -12
  139. data/vendor/libgit2/src/diff_xdiff.c +15 -3
  140. data/vendor/libgit2/src/errors.c +42 -20
  141. data/vendor/libgit2/src/features.h.in +2 -1
  142. data/vendor/libgit2/src/fetch.c +3 -3
  143. data/vendor/libgit2/src/fetchhead.c +16 -16
  144. data/vendor/libgit2/src/filebuf.c +28 -28
  145. data/vendor/libgit2/src/fileops.c +54 -54
  146. data/vendor/libgit2/src/fileops.h +1 -1
  147. data/vendor/libgit2/src/filter.c +30 -30
  148. data/vendor/libgit2/src/filter.h +0 -10
  149. data/vendor/libgit2/src/global.c +36 -23
  150. data/vendor/libgit2/src/hash.h +4 -1
  151. data/vendor/libgit2/src/hash/hash_collisiondetect.h +6 -2
  152. data/vendor/libgit2/src/hash/hash_common_crypto.h +5 -1
  153. data/vendor/libgit2/src/hash/hash_generic.h +5 -1
  154. data/vendor/libgit2/src/hash/hash_mbedtls.c +38 -0
  155. data/vendor/libgit2/src/hash/hash_mbedtls.h +24 -0
  156. data/vendor/libgit2/src/hash/hash_openssl.h +8 -4
  157. data/vendor/libgit2/src/hash/hash_win32.c +13 -13
  158. data/vendor/libgit2/src/hashsig.c +4 -4
  159. data/vendor/libgit2/src/idxmap.c +25 -5
  160. data/vendor/libgit2/src/idxmap.h +4 -18
  161. data/vendor/libgit2/src/ignore.c +9 -9
  162. data/vendor/libgit2/src/index.c +280 -198
  163. data/vendor/libgit2/src/index.h +16 -0
  164. data/vendor/libgit2/src/indexer.c +311 -139
  165. data/vendor/libgit2/src/integer.h +32 -22
  166. data/vendor/libgit2/src/iterator.c +116 -49
  167. data/vendor/libgit2/src/iterator.h +15 -0
  168. data/vendor/libgit2/src/khash.h +3 -1
  169. data/vendor/libgit2/src/mailmap.c +485 -0
  170. data/vendor/libgit2/src/mailmap.h +35 -0
  171. data/vendor/libgit2/src/merge.c +89 -59
  172. data/vendor/libgit2/src/merge_driver.c +7 -7
  173. data/vendor/libgit2/src/merge_file.c +1 -1
  174. data/vendor/libgit2/src/mwindow.c +8 -8
  175. data/vendor/libgit2/src/netops.c +22 -13
  176. data/vendor/libgit2/src/netops.h +2 -0
  177. data/vendor/libgit2/src/notes.c +15 -10
  178. data/vendor/libgit2/src/object.c +118 -67
  179. data/vendor/libgit2/src/object.h +20 -9
  180. data/vendor/libgit2/src/object_api.c +8 -8
  181. data/vendor/libgit2/src/odb.c +72 -72
  182. data/vendor/libgit2/src/odb.h +7 -7
  183. data/vendor/libgit2/src/odb_loose.c +46 -46
  184. data/vendor/libgit2/src/odb_mempack.c +14 -14
  185. data/vendor/libgit2/src/odb_pack.c +14 -10
  186. data/vendor/libgit2/src/offmap.c +30 -0
  187. data/vendor/libgit2/src/offmap.h +20 -11
  188. data/vendor/libgit2/src/oid.c +6 -6
  189. data/vendor/libgit2/src/oidmap.c +20 -0
  190. data/vendor/libgit2/src/oidmap.h +9 -12
  191. data/vendor/libgit2/src/pack-objects.c +71 -63
  192. data/vendor/libgit2/src/pack-objects.h +1 -7
  193. data/vendor/libgit2/src/pack.c +58 -58
  194. data/vendor/libgit2/src/pack.h +6 -6
  195. data/vendor/libgit2/src/parse.h +1 -1
  196. data/vendor/libgit2/src/patch.c +3 -3
  197. data/vendor/libgit2/src/patch_generate.c +18 -18
  198. data/vendor/libgit2/src/patch_parse.c +13 -13
  199. data/vendor/libgit2/src/path.c +93 -225
  200. data/vendor/libgit2/src/path.h +2 -84
  201. data/vendor/libgit2/src/pathspec.c +6 -6
  202. data/vendor/libgit2/src/posix.c +3 -3
  203. data/vendor/libgit2/src/proxy.c +1 -1
  204. data/vendor/libgit2/src/push.c +27 -26
  205. data/vendor/libgit2/src/push.h +2 -1
  206. data/vendor/libgit2/src/reader.c +265 -0
  207. data/vendor/libgit2/src/reader.h +107 -0
  208. data/vendor/libgit2/src/rebase.c +49 -52
  209. data/vendor/libgit2/src/refdb.c +3 -3
  210. data/vendor/libgit2/src/refdb_fs.c +181 -103
  211. data/vendor/libgit2/src/reflog.c +3 -3
  212. data/vendor/libgit2/src/refs.c +98 -74
  213. data/vendor/libgit2/src/refs.h +5 -3
  214. data/vendor/libgit2/src/refspec.c +47 -21
  215. data/vendor/libgit2/src/refspec.h +1 -1
  216. data/vendor/libgit2/src/remote.c +219 -166
  217. data/vendor/libgit2/src/remote.h +9 -0
  218. data/vendor/libgit2/src/repository.c +173 -133
  219. data/vendor/libgit2/src/repository.h +6 -3
  220. data/vendor/libgit2/src/reset.c +8 -8
  221. data/vendor/libgit2/src/revert.c +6 -6
  222. data/vendor/libgit2/src/revparse.c +30 -30
  223. data/vendor/libgit2/src/revwalk.c +60 -30
  224. data/vendor/libgit2/src/revwalk.h +2 -1
  225. data/vendor/libgit2/src/settings.c +42 -10
  226. data/vendor/libgit2/src/signature.c +11 -11
  227. data/vendor/libgit2/src/sortedcache.c +13 -13
  228. data/vendor/libgit2/src/stash.c +91 -45
  229. data/vendor/libgit2/src/status.c +13 -13
  230. data/vendor/libgit2/src/stdalloc.c +120 -0
  231. data/vendor/libgit2/src/{streams/curl.h → stdalloc.h} +6 -6
  232. data/vendor/libgit2/src/stream.h +17 -2
  233. data/vendor/libgit2/src/streams/mbedtls.c +483 -0
  234. data/vendor/libgit2/src/streams/mbedtls.h +23 -0
  235. data/vendor/libgit2/src/streams/openssl.c +204 -114
  236. data/vendor/libgit2/src/streams/openssl.h +4 -108
  237. data/vendor/libgit2/src/streams/registry.c +118 -0
  238. data/vendor/libgit2/src/streams/registry.h +19 -0
  239. data/vendor/libgit2/src/streams/socket.c +54 -29
  240. data/vendor/libgit2/src/streams/stransport.c +57 -32
  241. data/vendor/libgit2/src/streams/stransport.h +5 -0
  242. data/vendor/libgit2/src/streams/tls.c +50 -19
  243. data/vendor/libgit2/src/streams/tls.h +12 -4
  244. data/vendor/libgit2/src/strmap.c +22 -2
  245. data/vendor/libgit2/src/strmap.h +18 -15
  246. data/vendor/libgit2/src/submodule.c +179 -155
  247. data/vendor/libgit2/src/sysdir.c +18 -18
  248. data/vendor/libgit2/src/tag.c +31 -26
  249. data/vendor/libgit2/src/tag.h +2 -1
  250. data/vendor/libgit2/src/trace.c +1 -1
  251. data/vendor/libgit2/src/trace.h +1 -1
  252. data/vendor/libgit2/src/trailer.c +6 -6
  253. data/vendor/libgit2/src/transaction.c +23 -23
  254. data/vendor/libgit2/src/transport.c +5 -5
  255. data/vendor/libgit2/src/transports/auth.c +7 -4
  256. data/vendor/libgit2/src/transports/auth.h +1 -1
  257. data/vendor/libgit2/src/transports/auth_negotiate.c +12 -11
  258. data/vendor/libgit2/src/transports/cred.c +18 -18
  259. data/vendor/libgit2/src/transports/git.c +15 -15
  260. data/vendor/libgit2/src/transports/http.c +606 -216
  261. data/vendor/libgit2/src/transports/http.h +2 -0
  262. data/vendor/libgit2/src/transports/local.c +26 -26
  263. data/vendor/libgit2/src/transports/smart.c +54 -31
  264. data/vendor/libgit2/src/transports/smart.h +1 -2
  265. data/vendor/libgit2/src/transports/smart_pkt.c +43 -40
  266. data/vendor/libgit2/src/transports/smart_protocol.c +61 -57
  267. data/vendor/libgit2/src/transports/ssh.c +34 -33
  268. data/vendor/libgit2/src/transports/winhttp.c +99 -119
  269. data/vendor/libgit2/src/tree-cache.c +5 -5
  270. data/vendor/libgit2/src/tree.c +96 -121
  271. data/vendor/libgit2/src/tree.h +1 -12
  272. data/vendor/libgit2/src/unix/map.c +2 -2
  273. data/vendor/libgit2/src/util.c +22 -6
  274. data/vendor/libgit2/src/util.h +12 -135
  275. data/vendor/libgit2/src/vector.c +4 -4
  276. data/vendor/libgit2/src/win32/dir.c +3 -3
  277. data/vendor/libgit2/src/win32/findfile.c +3 -3
  278. data/vendor/libgit2/src/win32/map.c +6 -6
  279. data/vendor/libgit2/src/win32/msvc-compat.h +6 -0
  280. data/vendor/libgit2/src/win32/path_w32.c +101 -7
  281. data/vendor/libgit2/src/win32/path_w32.h +18 -0
  282. data/vendor/libgit2/src/win32/posix_w32.c +24 -43
  283. data/vendor/libgit2/src/win32/w32_buffer.c +2 -2
  284. data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.c +96 -2
  285. data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.h +28 -75
  286. data/vendor/libgit2/src/win32/w32_stack.c +2 -2
  287. data/vendor/libgit2/src/win32/w32_util.c +1 -69
  288. data/vendor/libgit2/src/win32/w32_util.h +1 -19
  289. data/vendor/libgit2/src/worktree.c +75 -54
  290. data/vendor/libgit2/src/worktree.h +2 -0
  291. data/vendor/libgit2/src/xdiff/xdiffi.c +7 -5
  292. data/vendor/libgit2/src/xdiff/xhistogram.c +1 -1
  293. data/vendor/libgit2/src/xdiff/xmerge.c +15 -15
  294. data/vendor/libgit2/src/zstream.c +4 -4
  295. metadata +33 -7
  296. data/vendor/libgit2/src/config_file.h +0 -73
  297. data/vendor/libgit2/src/streams/curl.c +0 -385
@@ -0,0 +1,55 @@
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
+
8
+ #include "alloc.h"
9
+
10
+ #if defined(GIT_MSVC_CRTDBG)
11
+ # include "win32/w32_crtdbg_stacktrace.h"
12
+ #else
13
+ # include "stdalloc.h"
14
+ #endif
15
+
16
+ git_allocator git__allocator;
17
+
18
+ static int setup_default_allocator(void)
19
+ {
20
+ #if defined(GIT_MSVC_CRTDBG)
21
+ return git_win32_crtdbg_init_allocator(&git__allocator);
22
+ #else
23
+ return git_stdalloc_init_allocator(&git__allocator);
24
+ #endif
25
+ }
26
+
27
+ int git_allocator_global_init(void)
28
+ {
29
+ /*
30
+ * We don't want to overwrite any allocator which has been set before
31
+ * the init function is called.
32
+ */
33
+ if (git__allocator.gmalloc != NULL)
34
+ return 0;
35
+
36
+ return setup_default_allocator();
37
+ }
38
+
39
+ int git_allocator_setup(git_allocator *allocator)
40
+ {
41
+ if (!allocator)
42
+ return setup_default_allocator();
43
+
44
+ memcpy(&git__allocator, allocator, sizeof(*allocator));
45
+ return 0;
46
+ }
47
+
48
+ #if !defined(GIT_MSVC_CRTDBG)
49
+ int git_win32_crtdbg_init_allocator(git_allocator *allocator)
50
+ {
51
+ GIT_UNUSED(allocator);
52
+ git_error_set(GIT_EINVALID, "crtdbg memory allocator not available");
53
+ return -1;
54
+ }
55
+ #endif
@@ -0,0 +1,40 @@
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
+
8
+ #ifndef INCLUDE_alloc_h__
9
+ #define INCLUDE_alloc_h__
10
+
11
+ #include "git2/sys/alloc.h"
12
+
13
+ extern git_allocator git__allocator;
14
+
15
+ #define git__malloc(len) git__allocator.gmalloc(len, __FILE__, __LINE__)
16
+ #define git__calloc(nelem, elsize) git__allocator.gcalloc(nelem, elsize, __FILE__, __LINE__)
17
+ #define git__strdup(str) git__allocator.gstrdup(str, __FILE__, __LINE__)
18
+ #define git__strndup(str, n) git__allocator.gstrndup(str, n, __FILE__, __LINE__)
19
+ #define git__substrdup(str, n) git__allocator.gsubstrdup(str, n, __FILE__, __LINE__)
20
+ #define git__realloc(ptr, size) git__allocator.grealloc(ptr, size, __FILE__, __LINE__)
21
+ #define git__reallocarray(ptr, nelem, elsize) git__allocator.greallocarray(ptr, nelem, elsize, __FILE__, __LINE__)
22
+ #define git__mallocarray(nelem, elsize) git__allocator.gmallocarray(nelem, elsize, __FILE__, __LINE__)
23
+ #define git__free git__allocator.gfree
24
+
25
+ /**
26
+ * This function is being called by our global setup routines to
27
+ * initialize the standard allocator.
28
+ */
29
+ int git_allocator_global_init(void);
30
+
31
+ /**
32
+ * Switch out libgit2's global memory allocator
33
+ *
34
+ * @param allocator The new allocator that should be used. All function pointers
35
+ * of it need to be set correctly.
36
+ * @return An error code or 0.
37
+ */
38
+ int git_allocator_setup(git_allocator *allocator);
39
+
40
+ #endif
@@ -31,7 +31,7 @@ static int annotated_commit_init(
31
31
  *out = NULL;
32
32
 
33
33
  annotated_commit = git__calloc(1, sizeof(git_annotated_commit));
34
- GITERR_CHECK_ALLOC(annotated_commit);
34
+ GIT_ERROR_CHECK_ALLOC(annotated_commit);
35
35
 
36
36
  annotated_commit->type = GIT_ANNOTATED_COMMIT_REAL;
37
37
 
@@ -45,7 +45,7 @@ static int annotated_commit_init(
45
45
  description = annotated_commit->id_str;
46
46
 
47
47
  annotated_commit->description = git__strdup(description);
48
- GITERR_CHECK_ALLOC(annotated_commit->description);
48
+ GIT_ERROR_CHECK_ALLOC(annotated_commit->description);
49
49
 
50
50
  done:
51
51
  if (!error)
@@ -105,7 +105,7 @@ int git_annotated_commit_from_revspec(
105
105
  if ((error = git_revparse_single(&obj, repo, revspec)) < 0)
106
106
  return error;
107
107
 
108
- if ((error = git_object_peel(&commit, obj, GIT_OBJ_COMMIT))) {
108
+ if ((error = git_object_peel(&commit, obj, GIT_OBJECT_COMMIT))) {
109
109
  git_object_free(obj);
110
110
  return error;
111
111
  }
@@ -130,9 +130,9 @@ int git_annotated_commit_from_ref(
130
130
 
131
131
  *out = NULL;
132
132
 
133
- if ((error = git_reference_peel(&peeled, ref, GIT_OBJ_COMMIT)) < 0)
133
+ if ((error = git_reference_peel(&peeled, ref, GIT_OBJECT_COMMIT)) < 0)
134
134
  return error;
135
-
135
+
136
136
  error = annotated_commit_init_from_id(out,
137
137
  repo,
138
138
  git_object_id(peeled),
@@ -140,7 +140,7 @@ int git_annotated_commit_from_ref(
140
140
 
141
141
  if (!error) {
142
142
  (*out)->ref_name = git__strdup(git_reference_name(ref));
143
- GITERR_CHECK_ALLOC((*out)->ref_name);
143
+ GIT_ERROR_CHECK_ALLOC((*out)->ref_name);
144
144
  }
145
145
 
146
146
  git_object_free(peeled);
@@ -180,10 +180,10 @@ int git_annotated_commit_from_fetchhead(
180
180
  return -1;
181
181
 
182
182
  (*out)->ref_name = git__strdup(branch_name);
183
- GITERR_CHECK_ALLOC((*out)->ref_name);
183
+ GIT_ERROR_CHECK_ALLOC((*out)->ref_name);
184
184
 
185
185
  (*out)->remote_url = git__strdup(remote_url);
186
- GITERR_CHECK_ALLOC((*out)->remote_url);
186
+ GIT_ERROR_CHECK_ALLOC((*out)->remote_url);
187
187
 
188
188
  return 0;
189
189
  }
@@ -196,6 +196,13 @@ const git_oid *git_annotated_commit_id(
196
196
  return git_commit_id(annotated_commit->commit);
197
197
  }
198
198
 
199
+ const char *git_annotated_commit_ref(
200
+ const git_annotated_commit *annotated_commit)
201
+ {
202
+ assert(annotated_commit);
203
+ return annotated_commit->ref_name;
204
+ }
205
+
199
206
  void git_annotated_commit_free(git_annotated_commit *annotated_commit)
200
207
  {
201
208
  if (annotated_commit == NULL)
@@ -9,16 +9,23 @@
9
9
 
10
10
  #include <assert.h>
11
11
 
12
+ #include "git2/apply.h"
12
13
  #include "git2/patch.h"
13
14
  #include "git2/filter.h"
15
+ #include "git2/blob.h"
16
+ #include "git2/index.h"
17
+ #include "git2/checkout.h"
18
+ #include "git2/repository.h"
14
19
  #include "array.h"
15
20
  #include "patch.h"
16
21
  #include "fileops.h"
17
22
  #include "delta.h"
18
23
  #include "zstream.h"
24
+ #include "reader.h"
25
+ #include "index.h"
19
26
 
20
27
  #define apply_err(...) \
21
- ( giterr_set(GITERR_PATCH, __VA_ARGS__), -1 )
28
+ ( git_error_set(GIT_ERROR_PATCH, __VA_ARGS__), GIT_EAPPLYFAIL )
22
29
 
23
30
  typedef struct {
24
31
  /* The lines that we allocate ourself are allocated out of the pool.
@@ -61,7 +68,7 @@ static int patch_image_init_fromstr(
61
68
  end++;
62
69
 
63
70
  line = git_pool_mallocz(&out->pool, 1);
64
- GITERR_CHECK_ALLOC(line);
71
+ GIT_ERROR_CHECK_ALLOC(line);
65
72
 
66
73
  if (git_vector_insert(&out->lines, line) < 0)
67
74
  return -1;
@@ -131,7 +138,7 @@ static bool find_hunk_linenum(
131
138
 
132
139
  static int update_hunk(
133
140
  patch_image *image,
134
- unsigned int linenum,
141
+ size_t linenum,
135
142
  patch_image *preimage,
136
143
  patch_image *postimage)
137
144
  {
@@ -148,7 +155,7 @@ static int update_hunk(
148
155
  &image->lines, linenum, (prelen - postlen));
149
156
 
150
157
  if (error) {
151
- giterr_set_oom();
158
+ git_error_set_oom();
152
159
  return -1;
153
160
  }
154
161
 
@@ -160,15 +167,36 @@ static int update_hunk(
160
167
  return 0;
161
168
  }
162
169
 
170
+ typedef struct {
171
+ git_apply_options opts;
172
+ size_t skipped_new_lines;
173
+ size_t skipped_old_lines;
174
+ } apply_hunks_ctx;
175
+
163
176
  static int apply_hunk(
164
177
  patch_image *image,
165
178
  git_patch *patch,
166
- git_patch_hunk *hunk)
179
+ git_patch_hunk *hunk,
180
+ apply_hunks_ctx *ctx)
167
181
  {
168
182
  patch_image preimage = PATCH_IMAGE_INIT, postimage = PATCH_IMAGE_INIT;
169
183
  size_t line_num, i;
170
184
  int error = 0;
171
185
 
186
+ if (ctx->opts.hunk_cb) {
187
+ error = ctx->opts.hunk_cb(&hunk->hunk, ctx->opts.payload);
188
+
189
+ if (error) {
190
+ if (error > 0) {
191
+ ctx->skipped_new_lines += hunk->hunk.new_lines;
192
+ ctx->skipped_old_lines += hunk->hunk.old_lines;
193
+ error = 0;
194
+ }
195
+
196
+ goto done;
197
+ }
198
+ }
199
+
172
200
  for (i = 0; i < hunk->line_count; i++) {
173
201
  size_t linenum = hunk->line_start + i;
174
202
  git_diff_line *line = git_array_get(patch->lines, linenum);
@@ -191,7 +219,14 @@ static int apply_hunk(
191
219
  }
192
220
  }
193
221
 
194
- line_num = hunk->hunk.new_start ? hunk->hunk.new_start - 1 : 0;
222
+ if (hunk->hunk.new_start) {
223
+ line_num = hunk->hunk.new_start -
224
+ ctx->skipped_new_lines +
225
+ ctx->skipped_old_lines -
226
+ 1;
227
+ } else {
228
+ line_num = 0;
229
+ }
195
230
 
196
231
  if (!find_hunk_linenum(&line_num, image, &preimage, line_num)) {
197
232
  error = apply_err("hunk at line %d did not apply",
@@ -212,7 +247,8 @@ static int apply_hunks(
212
247
  git_buf *out,
213
248
  const char *source,
214
249
  size_t source_len,
215
- git_patch *patch)
250
+ git_patch *patch,
251
+ apply_hunks_ctx *ctx)
216
252
  {
217
253
  git_patch_hunk *hunk;
218
254
  git_diff_line *line;
@@ -224,7 +260,7 @@ static int apply_hunks(
224
260
  goto done;
225
261
 
226
262
  git_array_foreach(patch->hunks, i, hunk) {
227
- if ((error = apply_hunk(&image, patch, hunk)) < 0)
263
+ if ((error = apply_hunk(&image, patch, hunk, ctx)) < 0)
228
264
  goto done;
229
265
  }
230
266
 
@@ -255,7 +291,7 @@ static int apply_binary_delta(
255
291
 
256
292
  if (!error && inflated.size != binary_file->inflatedlen) {
257
293
  error = apply_err("inflated delta does not match expected length");
258
- git_buf_free(out);
294
+ git_buf_dispose(out);
259
295
  }
260
296
 
261
297
  if (error < 0)
@@ -281,7 +317,7 @@ static int apply_binary_delta(
281
317
  }
282
318
 
283
319
  done:
284
- git_buf_free(&inflated);
320
+ git_buf_dispose(&inflated);
285
321
  return error;
286
322
  }
287
323
 
@@ -321,9 +357,9 @@ static int apply_binary(
321
357
 
322
358
  done:
323
359
  if (error < 0)
324
- git_buf_free(out);
360
+ git_buf_dispose(out);
325
361
 
326
- git_buf_free(&reverse);
362
+ git_buf_dispose(&reverse);
327
363
  return error;
328
364
  }
329
365
 
@@ -333,14 +369,19 @@ int git_apply__patch(
333
369
  unsigned int *mode_out,
334
370
  const char *source,
335
371
  size_t source_len,
336
- git_patch *patch)
372
+ git_patch *patch,
373
+ const git_apply_options *given_opts)
337
374
  {
375
+ apply_hunks_ctx ctx = { GIT_APPLY_OPTIONS_INIT };
338
376
  char *filename = NULL;
339
377
  unsigned int mode = 0;
340
378
  int error = 0;
341
379
 
342
380
  assert(contents_out && filename_out && mode_out && (source || !source_len) && patch);
343
381
 
382
+ if (given_opts)
383
+ memcpy(&ctx.opts, given_opts, sizeof(git_apply_options));
384
+
344
385
  *filename_out = NULL;
345
386
  *mode_out = 0;
346
387
 
@@ -355,7 +396,7 @@ int git_apply__patch(
355
396
  if (patch->delta->flags & GIT_DIFF_FLAG_BINARY)
356
397
  error = apply_binary(contents_out, source, source_len, patch);
357
398
  else if (patch->hunks.size)
358
- error = apply_hunks(contents_out, source, source_len, patch);
399
+ error = apply_hunks(contents_out, source, source_len, patch, &ctx);
359
400
  else
360
401
  error = git_buf_put(contents_out, source, source_len);
361
402
 
@@ -377,3 +418,438 @@ done:
377
418
 
378
419
  return error;
379
420
  }
421
+
422
+ static int apply_one(
423
+ git_repository *repo,
424
+ git_reader *preimage_reader,
425
+ git_index *preimage,
426
+ git_reader *postimage_reader,
427
+ git_index *postimage,
428
+ git_diff *diff,
429
+ git_strmap *removed_paths,
430
+ size_t i,
431
+ const git_apply_options *opts)
432
+ {
433
+ git_patch *patch = NULL;
434
+ git_buf pre_contents = GIT_BUF_INIT, post_contents = GIT_BUF_INIT;
435
+ const git_diff_delta *delta;
436
+ char *filename = NULL;
437
+ unsigned int mode;
438
+ git_oid pre_id, post_id;
439
+ git_filemode_t pre_filemode;
440
+ git_index_entry pre_entry, post_entry;
441
+ bool skip_preimage = false;
442
+ size_t pos;
443
+ int error;
444
+
445
+ if ((error = git_patch_from_diff(&patch, diff, i)) < 0)
446
+ goto done;
447
+
448
+ delta = git_patch_get_delta(patch);
449
+
450
+ if (opts->delta_cb) {
451
+ error = opts->delta_cb(delta, opts->payload);
452
+
453
+ if (error) {
454
+ if (error > 0)
455
+ error = 0;
456
+
457
+ goto done;
458
+ }
459
+ }
460
+
461
+ /*
462
+ * Ensure that the file has not been deleted or renamed if we're
463
+ * applying a modification delta.
464
+ */
465
+ if (delta->status != GIT_DELTA_RENAMED &&
466
+ delta->status != GIT_DELTA_ADDED) {
467
+ pos = git_strmap_lookup_index(removed_paths, delta->old_file.path);
468
+ if (git_strmap_valid_index(removed_paths, pos)) {
469
+ error = apply_err("path '%s' has been renamed or deleted", delta->old_file.path);
470
+ goto done;
471
+ }
472
+ }
473
+
474
+ /*
475
+ * We may be applying a second delta to an already seen file. If so,
476
+ * use the already modified data in the postimage instead of the
477
+ * content from the index or working directory. (Don't do this in
478
+ * the case of a rename, which must be specified before additional
479
+ * deltas since we apply deltas to the target filename.)
480
+ */
481
+ if (delta->status != GIT_DELTA_RENAMED) {
482
+ if ((error = git_reader_read(&pre_contents, &pre_id, &pre_filemode,
483
+ postimage_reader, delta->old_file.path)) == 0) {
484
+ skip_preimage = true;
485
+ } else if (error == GIT_ENOTFOUND) {
486
+ git_error_clear();
487
+ error = 0;
488
+ } else {
489
+ goto done;
490
+ }
491
+ }
492
+
493
+ if (!skip_preimage && delta->status != GIT_DELTA_ADDED) {
494
+ error = git_reader_read(&pre_contents, &pre_id, &pre_filemode,
495
+ preimage_reader, delta->old_file.path);
496
+
497
+ /* ENOTFOUND means the preimage was not found; apply failed. */
498
+ if (error == GIT_ENOTFOUND)
499
+ error = GIT_EAPPLYFAIL;
500
+
501
+ /* When applying to BOTH, the index did not match the workdir. */
502
+ if (error == GIT_READER_MISMATCH)
503
+ error = apply_err("%s: does not match index", delta->old_file.path);
504
+
505
+ if (error < 0)
506
+ goto done;
507
+
508
+ /*
509
+ * We need to populate the preimage data structure with the
510
+ * contents that we are using as the preimage for this file.
511
+ * This allows us to apply patches to files that have been
512
+ * modified in the working directory. During checkout,
513
+ * we will use this expected preimage as the baseline, and
514
+ * limit checkout to only the paths affected by patch
515
+ * application. (Without this, we would fail to write the
516
+ * postimage contents to any file that had been modified
517
+ * from HEAD on-disk, even if the patch application succeeded.)
518
+ * Use the contents from the delta where available - some
519
+ * fields may not be available, like the old file mode (eg in
520
+ * an exact rename situation) so trust the patch parsing to
521
+ * validate and use the preimage data in that case.
522
+ */
523
+ if (preimage) {
524
+ memset(&pre_entry, 0, sizeof(git_index_entry));
525
+ pre_entry.path = delta->old_file.path;
526
+ pre_entry.mode = delta->old_file.mode ? delta->old_file.mode : pre_filemode;
527
+ git_oid_cpy(&pre_entry.id, &pre_id);
528
+
529
+ if ((error = git_index_add(preimage, &pre_entry)) < 0)
530
+ goto done;
531
+ }
532
+ }
533
+
534
+ if (delta->status != GIT_DELTA_DELETED) {
535
+ if ((error = git_apply__patch(&post_contents, &filename, &mode,
536
+ pre_contents.ptr, pre_contents.size, patch, opts)) < 0 ||
537
+ (error = git_blob_create_frombuffer(&post_id, repo,
538
+ post_contents.ptr, post_contents.size)) < 0)
539
+ goto done;
540
+
541
+ memset(&post_entry, 0, sizeof(git_index_entry));
542
+ post_entry.path = filename;
543
+ post_entry.mode = mode;
544
+ git_oid_cpy(&post_entry.id, &post_id);
545
+
546
+ if ((error = git_index_add(postimage, &post_entry)) < 0)
547
+ goto done;
548
+ }
549
+
550
+ if (delta->status == GIT_DELTA_RENAMED ||
551
+ delta->status == GIT_DELTA_DELETED)
552
+ git_strmap_insert(removed_paths, delta->old_file.path, (char *)delta->old_file.path, &error);
553
+
554
+ if (delta->status == GIT_DELTA_RENAMED ||
555
+ delta->status == GIT_DELTA_ADDED)
556
+ git_strmap_delete(removed_paths, delta->new_file.path);
557
+
558
+ done:
559
+ git_buf_dispose(&pre_contents);
560
+ git_buf_dispose(&post_contents);
561
+ git__free(filename);
562
+ git_patch_free(patch);
563
+
564
+ return error;
565
+ }
566
+
567
+ static int apply_deltas(
568
+ git_repository *repo,
569
+ git_reader *pre_reader,
570
+ git_index *preimage,
571
+ git_reader *post_reader,
572
+ git_index *postimage,
573
+ git_diff *diff,
574
+ const git_apply_options *opts)
575
+ {
576
+ git_strmap *removed_paths;
577
+ size_t i;
578
+ int error = 0;
579
+
580
+ if (git_strmap_alloc(&removed_paths) < 0)
581
+ return -1;
582
+
583
+ for (i = 0; i < git_diff_num_deltas(diff); i++) {
584
+ if ((error = apply_one(repo, pre_reader, preimage, post_reader, postimage, diff, removed_paths, i, opts)) < 0)
585
+ goto done;
586
+ }
587
+
588
+ done:
589
+ git_strmap_free(removed_paths);
590
+ return error;
591
+ }
592
+
593
+ int git_apply_to_tree(
594
+ git_index **out,
595
+ git_repository *repo,
596
+ git_tree *preimage,
597
+ git_diff *diff,
598
+ const git_apply_options *given_opts)
599
+ {
600
+ git_index *postimage = NULL;
601
+ git_reader *pre_reader = NULL, *post_reader = NULL;
602
+ git_apply_options opts = GIT_APPLY_OPTIONS_INIT;
603
+ const git_diff_delta *delta;
604
+ size_t i;
605
+ int error = 0;
606
+
607
+ assert(out && repo && preimage && diff);
608
+
609
+ *out = NULL;
610
+
611
+ if (given_opts)
612
+ memcpy(&opts, given_opts, sizeof(git_apply_options));
613
+
614
+ if ((error = git_reader_for_tree(&pre_reader, preimage)) < 0)
615
+ goto done;
616
+
617
+ /*
618
+ * put the current tree into the postimage as-is - the diff will
619
+ * replace any entries contained therein
620
+ */
621
+ if ((error = git_index_new(&postimage)) < 0 ||
622
+ (error = git_index_read_tree(postimage, preimage)) < 0 ||
623
+ (error = git_reader_for_index(&post_reader, repo, postimage)) < 0)
624
+ goto done;
625
+
626
+ /*
627
+ * Remove the old paths from the index before applying diffs -
628
+ * we need to do a full pass to remove them before adding deltas,
629
+ * in order to handle rename situations.
630
+ */
631
+ for (i = 0; i < git_diff_num_deltas(diff); i++) {
632
+ delta = git_diff_get_delta(diff, i);
633
+
634
+ if ((error = git_index_remove(postimage,
635
+ delta->old_file.path, 0)) < 0)
636
+ goto done;
637
+ }
638
+
639
+ if ((error = apply_deltas(repo, pre_reader, NULL, post_reader, postimage, diff, &opts)) < 0)
640
+ goto done;
641
+
642
+ *out = postimage;
643
+
644
+ done:
645
+ if (error < 0)
646
+ git_index_free(postimage);
647
+
648
+ git_reader_free(pre_reader);
649
+ git_reader_free(post_reader);
650
+
651
+ return error;
652
+ }
653
+
654
+ static int git_apply__to_workdir(
655
+ git_repository *repo,
656
+ git_diff *diff,
657
+ git_index *preimage,
658
+ git_index *postimage,
659
+ git_apply_location_t location,
660
+ git_apply_options *opts)
661
+ {
662
+ git_vector paths = GIT_VECTOR_INIT;
663
+ git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
664
+ const git_diff_delta *delta;
665
+ size_t i;
666
+ int error;
667
+
668
+ GIT_UNUSED(opts);
669
+
670
+ /*
671
+ * Limit checkout to the paths affected by the diff; this ensures
672
+ * that other modifications in the working directory are unaffected.
673
+ */
674
+ if ((error = git_vector_init(&paths, git_diff_num_deltas(diff), NULL)) < 0)
675
+ goto done;
676
+
677
+ for (i = 0; i < git_diff_num_deltas(diff); i++) {
678
+ delta = git_diff_get_delta(diff, i);
679
+
680
+ if ((error = git_vector_insert(&paths, (void *)delta->old_file.path)) < 0)
681
+ goto done;
682
+
683
+ if (strcmp(delta->old_file.path, delta->new_file.path) &&
684
+ (error = git_vector_insert(&paths, (void *)delta->new_file.path)) < 0)
685
+ goto done;
686
+ }
687
+
688
+ checkout_opts.checkout_strategy |= GIT_CHECKOUT_SAFE;
689
+ checkout_opts.checkout_strategy |= GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH;
690
+ checkout_opts.checkout_strategy |= GIT_CHECKOUT_DONT_WRITE_INDEX;
691
+
692
+ if (location == GIT_APPLY_LOCATION_WORKDIR)
693
+ checkout_opts.checkout_strategy |= GIT_CHECKOUT_DONT_UPDATE_INDEX;
694
+
695
+ checkout_opts.paths.strings = (char **)paths.contents;
696
+ checkout_opts.paths.count = paths.length;
697
+
698
+ checkout_opts.baseline_index = preimage;
699
+
700
+ error = git_checkout_index(repo, postimage, &checkout_opts);
701
+
702
+ done:
703
+ git_vector_free(&paths);
704
+ return error;
705
+ }
706
+
707
+ static int git_apply__to_index(
708
+ git_repository *repo,
709
+ git_diff *diff,
710
+ git_index *preimage,
711
+ git_index *postimage,
712
+ git_apply_options *opts)
713
+ {
714
+ git_index *index = NULL;
715
+ const git_diff_delta *delta;
716
+ const git_index_entry *entry;
717
+ size_t i;
718
+ int error;
719
+
720
+ GIT_UNUSED(preimage);
721
+ GIT_UNUSED(opts);
722
+
723
+ if ((error = git_repository_index(&index, repo)) < 0)
724
+ goto done;
725
+
726
+ /* Remove deleted (or renamed) paths from the index. */
727
+ for (i = 0; i < git_diff_num_deltas(diff); i++) {
728
+ delta = git_diff_get_delta(diff, i);
729
+
730
+ if (delta->status == GIT_DELTA_DELETED ||
731
+ delta->status == GIT_DELTA_RENAMED) {
732
+ if ((error = git_index_remove(index, delta->old_file.path, 0)) < 0)
733
+ goto done;
734
+ }
735
+ }
736
+
737
+ /* Then add the changes back to the index. */
738
+ for (i = 0; i < git_index_entrycount(postimage); i++) {
739
+ entry = git_index_get_byindex(postimage, i);
740
+
741
+ if ((error = git_index_add(index, entry)) < 0)
742
+ goto done;
743
+ }
744
+
745
+ done:
746
+ git_index_free(index);
747
+ return error;
748
+ }
749
+
750
+ /*
751
+ * Handle the three application options ("locations"):
752
+ *
753
+ * GIT_APPLY_LOCATION_WORKDIR: the default, emulates `git apply`.
754
+ * Applies the diff only to the workdir items and ignores the index
755
+ * entirely.
756
+ *
757
+ * GIT_APPLY_LOCATION_INDEX: emulates `git apply --cached`.
758
+ * Applies the diff only to the index items and ignores the workdir
759
+ * completely.
760
+ *
761
+ * GIT_APPLY_LOCATION_BOTH: emulates `git apply --index`.
762
+ * Applies the diff to both the index items and the working directory
763
+ * items.
764
+ */
765
+
766
+ int git_apply(
767
+ git_repository *repo,
768
+ git_diff *diff,
769
+ git_apply_location_t location,
770
+ const git_apply_options *given_opts)
771
+ {
772
+ git_indexwriter indexwriter = GIT_INDEXWRITER_INIT;
773
+ git_index *index = NULL, *preimage = NULL, *postimage = NULL;
774
+ git_reader *pre_reader = NULL, *post_reader = NULL;
775
+ git_apply_options opts = GIT_APPLY_OPTIONS_INIT;
776
+ int error = GIT_EINVALID;
777
+
778
+ assert(repo && diff);
779
+
780
+ GIT_ERROR_CHECK_VERSION(
781
+ given_opts, GIT_APPLY_OPTIONS_VERSION, "git_apply_options");
782
+
783
+ if (given_opts)
784
+ memcpy(&opts, given_opts, sizeof(git_apply_options));
785
+
786
+ /*
787
+ * by default, we apply a patch directly to the working directory;
788
+ * in `--cached` or `--index` mode, we apply to the contents already
789
+ * in the index.
790
+ */
791
+ switch (location) {
792
+ case GIT_APPLY_LOCATION_BOTH:
793
+ error = git_reader_for_workdir(&pre_reader, repo, true);
794
+ break;
795
+ case GIT_APPLY_LOCATION_INDEX:
796
+ error = git_reader_for_index(&pre_reader, repo, NULL);
797
+ break;
798
+ case GIT_APPLY_LOCATION_WORKDIR:
799
+ error = git_reader_for_workdir(&pre_reader, repo, false);
800
+ break;
801
+ default:
802
+ assert(false);
803
+ }
804
+
805
+ if (error < 0)
806
+ goto done;
807
+
808
+ /*
809
+ * Build the preimage and postimage (differences). Note that
810
+ * this is not the complete preimage or postimage, it only
811
+ * contains the files affected by the patch. We want to avoid
812
+ * having the full repo index, so we will limit our checkout
813
+ * to only write these files that were affected by the diff.
814
+ */
815
+ if ((error = git_index_new(&preimage)) < 0 ||
816
+ (error = git_index_new(&postimage)) < 0 ||
817
+ (error = git_reader_for_index(&post_reader, repo, postimage)) < 0)
818
+ goto done;
819
+
820
+ if ((error = git_repository_index(&index, repo)) < 0 ||
821
+ (error = git_indexwriter_init(&indexwriter, index)) < 0)
822
+ goto done;
823
+
824
+ if ((error = apply_deltas(repo, pre_reader, preimage, post_reader, postimage, diff, &opts)) < 0)
825
+ goto done;
826
+
827
+ switch (location) {
828
+ case GIT_APPLY_LOCATION_BOTH:
829
+ error = git_apply__to_workdir(repo, diff, preimage, postimage, location, &opts);
830
+ break;
831
+ case GIT_APPLY_LOCATION_INDEX:
832
+ error = git_apply__to_index(repo, diff, preimage, postimage, &opts);
833
+ break;
834
+ case GIT_APPLY_LOCATION_WORKDIR:
835
+ error = git_apply__to_workdir(repo, diff, preimage, postimage, location, &opts);
836
+ break;
837
+ default:
838
+ assert(false);
839
+ }
840
+
841
+ if (error < 0)
842
+ goto done;
843
+
844
+ error = git_indexwriter_commit(&indexwriter);
845
+
846
+ done:
847
+ git_indexwriter_cleanup(&indexwriter);
848
+ git_index_free(postimage);
849
+ git_index_free(preimage);
850
+ git_index_free(index);
851
+ git_reader_free(pre_reader);
852
+ git_reader_free(post_reader);
853
+
854
+ return error;
855
+ }