rugged 0.18.0.gh.de28323 → 0.19.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (283) hide show
  1. data/README.md +9 -4
  2. data/Rakefile +1 -1
  3. data/ext/rugged/extconf.rb +10 -0
  4. data/ext/rugged/rugged.c +153 -86
  5. data/ext/rugged/rugged.h +44 -33
  6. data/ext/rugged/rugged_blob.c +288 -60
  7. data/ext/rugged/rugged_branch.c +82 -57
  8. data/ext/rugged/rugged_commit.c +83 -86
  9. data/ext/rugged/rugged_config.c +68 -68
  10. data/ext/rugged/rugged_diff.c +509 -0
  11. data/ext/rugged/rugged_diff_delta.c +94 -0
  12. data/ext/rugged/rugged_diff_hunk.c +100 -0
  13. data/ext/rugged/rugged_diff_line.c +79 -0
  14. data/ext/rugged/rugged_diff_patch.c +169 -0
  15. data/ext/rugged/rugged_index.c +539 -8
  16. data/ext/rugged/rugged_note.c +74 -80
  17. data/ext/rugged/rugged_object.c +63 -8
  18. data/ext/rugged/rugged_reference.c +231 -145
  19. data/ext/rugged/rugged_remote.c +509 -53
  20. data/ext/rugged/rugged_repo.c +572 -236
  21. data/ext/rugged/rugged_revwalk.c +59 -36
  22. data/ext/rugged/rugged_settings.c +7 -9
  23. data/ext/rugged/rugged_signature.c +7 -11
  24. data/ext/rugged/rugged_tag.c +93 -39
  25. data/ext/rugged/rugged_tree.c +321 -58
  26. data/lib/rugged.rb +1 -0
  27. data/lib/rugged/commit.rb +16 -1
  28. data/lib/rugged/console.rb +9 -0
  29. data/lib/rugged/diff.rb +19 -0
  30. data/lib/rugged/diff/delta.rb +54 -0
  31. data/lib/rugged/diff/hunk.rb +23 -0
  32. data/lib/rugged/diff/line.rb +29 -0
  33. data/lib/rugged/diff/patch.rb +28 -0
  34. data/lib/rugged/repository.rb +36 -39
  35. data/lib/rugged/version.rb +1 -1
  36. data/test/blob_test.rb +308 -1
  37. data/test/branch_test.rb +7 -0
  38. data/test/commit_test.rb +7 -10
  39. data/test/coverage/cover.rb +9 -1
  40. data/test/diff_test.rb +777 -0
  41. data/test/fixtures/archive.tar.gz +0 -0
  42. data/test/fixtures/attr/attr0 +1 -0
  43. data/test/fixtures/attr/attr1 +29 -0
  44. data/test/fixtures/attr/attr2 +21 -0
  45. data/test/fixtures/attr/attr3 +4 -0
  46. data/test/fixtures/attr/binfile +1 -0
  47. data/test/fixtures/attr/dir/file +0 -0
  48. data/test/fixtures/attr/file +1 -0
  49. data/test/fixtures/attr/gitattributes +29 -0
  50. data/test/fixtures/attr/gitignore +2 -0
  51. data/test/fixtures/attr/ign +1 -0
  52. data/test/fixtures/attr/macro_bad +1 -0
  53. data/test/fixtures/attr/macro_test +1 -0
  54. data/test/fixtures/attr/root_test1 +1 -0
  55. data/test/fixtures/attr/root_test2 +6 -0
  56. data/test/fixtures/attr/root_test3 +19 -0
  57. data/test/fixtures/attr/root_test4.txt +14 -0
  58. data/test/fixtures/attr/sub/abc +37 -0
  59. data/test/fixtures/attr/sub/dir/file +0 -0
  60. data/test/fixtures/attr/sub/file +1 -0
  61. data/test/fixtures/attr/sub/ign/file +1 -0
  62. data/test/fixtures/attr/sub/ign/sub/file +1 -0
  63. data/test/fixtures/attr/sub/sub/dir +0 -0
  64. data/test/fixtures/attr/sub/sub/file +1 -0
  65. data/test/fixtures/attr/sub/sub/subsub.txt +1 -0
  66. data/test/fixtures/attr/sub/subdir_test1 +2 -0
  67. data/test/fixtures/attr/sub/subdir_test2.txt +1 -0
  68. data/test/fixtures/diff/another.txt +38 -0
  69. data/test/fixtures/diff/readme.txt +36 -0
  70. data/test/fixtures/mergedrepo/conflicts-one.txt +5 -0
  71. data/test/fixtures/mergedrepo/conflicts-two.txt +5 -0
  72. data/test/fixtures/mergedrepo/one.txt +10 -0
  73. data/test/fixtures/mergedrepo/two.txt +12 -0
  74. data/test/fixtures/status/current_file +1 -0
  75. data/test/fixtures/status/ignored_file +1 -0
  76. data/test/fixtures/status/modified_file +2 -0
  77. data/test/fixtures/status/new_file +1 -0
  78. data/test/fixtures/status/staged_changes +2 -0
  79. data/test/fixtures/status/staged_changes_modified_file +3 -0
  80. data/test/fixtures/status/staged_delete_modified_file +1 -0
  81. data/test/fixtures/status/staged_new_file +1 -0
  82. data/test/fixtures/status/staged_new_file_modified_file +2 -0
  83. data/test/fixtures/status/subdir.txt +2 -0
  84. data/test/fixtures/status/subdir/current_file +1 -0
  85. data/test/fixtures/status/subdir/modified_file +2 -0
  86. data/test/fixtures/status/subdir/new_file +1 -0
  87. data/test/fixtures/status//350/277/231 +1 -0
  88. data/test/fixtures/testrepo.git/config +5 -0
  89. data/test/fixtures/testrepo.git/objects/77/71329dfa3002caf8c61a0ceb62a31d09023f37 +0 -0
  90. data/test/fixtures/text_file.md +464 -0
  91. data/test/fixtures/unsymlinked.git/HEAD +1 -0
  92. data/test/fixtures/unsymlinked.git/config +6 -0
  93. data/test/fixtures/unsymlinked.git/description +1 -0
  94. data/test/fixtures/unsymlinked.git/info/exclude +2 -0
  95. data/test/fixtures/unsymlinked.git/objects/08/8b64704e0d6b8bd061dea879418cb5442a3fbf +0 -0
  96. data/test/fixtures/unsymlinked.git/objects/13/a5e939bca25940c069fd2169d993dba328e30b +0 -0
  97. data/test/fixtures/unsymlinked.git/objects/19/bf568e59e3a0b363cafb4106226e62d4a4c41c +0 -0
  98. data/test/fixtures/unsymlinked.git/objects/58/1fadd35b4cf320d102a152f918729011604773 +0 -0
  99. data/test/fixtures/unsymlinked.git/objects/5c/87b6791e8b13da658a14d1ef7e09b5dc3bac8c +0 -0
  100. data/test/fixtures/unsymlinked.git/objects/6f/e5f5398af85fb3de8a6aba0339b6d3bfa26a27 +0 -0
  101. data/test/fixtures/unsymlinked.git/objects/7f/ccd75616ec188b8f1b23d67506a334cc34a49d +0 -0
  102. data/test/fixtures/unsymlinked.git/objects/80/6999882bf91d24241e4077906b9017605eb1f3 +0 -0
  103. data/test/fixtures/unsymlinked.git/objects/83/7d176303c5005505ec1e4a30231c40930c0230 +0 -0
  104. data/test/fixtures/unsymlinked.git/objects/a8/595ccca04f40818ae0155c8f9c77a230e597b6 +2 -0
  105. data/test/fixtures/unsymlinked.git/objects/cf/8f1cf5cce859c438d6cc067284cb5e161206e7 +0 -0
  106. data/test/fixtures/unsymlinked.git/objects/d5/278d05c8607ec420bfee4cf219fbc0eeebfd6a +0 -0
  107. data/test/fixtures/unsymlinked.git/objects/f4/e16fb76536591a41454194058d048d8e4dd2e9 +0 -0
  108. data/test/fixtures/unsymlinked.git/objects/f9/e65619d93fdf2673882e0a261c5e93b1a84006 +0 -0
  109. data/test/fixtures/unsymlinked.git/refs/heads/exe-file +1 -0
  110. data/test/fixtures/unsymlinked.git/refs/heads/master +1 -0
  111. data/test/fixtures/unsymlinked.git/refs/heads/reg-file +1 -0
  112. data/test/index_test.rb +120 -0
  113. data/test/reference_test.rb +38 -3
  114. data/test/remote_test.rb +224 -3
  115. data/test/repo_reset_test.rb +2 -0
  116. data/test/repo_test.rb +147 -10
  117. data/test/test_helper.rb +5 -2
  118. data/vendor/libgit2/include/git2/attr.h +3 -3
  119. data/vendor/libgit2/include/git2/blob.h +11 -17
  120. data/vendor/libgit2/include/git2/branch.h +3 -2
  121. data/vendor/libgit2/include/git2/checkout.h +7 -0
  122. data/vendor/libgit2/include/git2/clone.h +3 -0
  123. data/vendor/libgit2/include/git2/commit.h +61 -66
  124. data/vendor/libgit2/include/git2/common.h +73 -42
  125. data/vendor/libgit2/include/git2/config.h +57 -71
  126. data/vendor/libgit2/include/git2/cred_helpers.h +2 -2
  127. data/vendor/libgit2/include/git2/diff.h +179 -30
  128. data/vendor/libgit2/include/git2/errors.h +3 -3
  129. data/vendor/libgit2/include/git2/index.h +225 -146
  130. data/vendor/libgit2/include/git2/indexer.h +2 -22
  131. data/vendor/libgit2/include/git2/inttypes.h +9 -9
  132. data/vendor/libgit2/include/git2/merge.h +123 -5
  133. data/vendor/libgit2/include/git2/odb.h +59 -38
  134. data/vendor/libgit2/include/git2/odb_backend.h +45 -104
  135. data/vendor/libgit2/include/git2/oid.h +30 -19
  136. data/vendor/libgit2/include/git2/pack.h +21 -3
  137. data/vendor/libgit2/include/git2/refdb.h +0 -35
  138. data/vendor/libgit2/include/git2/refs.h +93 -31
  139. data/vendor/libgit2/include/git2/refspec.h +17 -0
  140. data/vendor/libgit2/include/git2/remote.h +60 -20
  141. data/vendor/libgit2/include/git2/repository.h +48 -70
  142. data/vendor/libgit2/include/git2/reset.h +3 -3
  143. data/vendor/libgit2/include/git2/revparse.h +22 -0
  144. data/vendor/libgit2/include/git2/stash.h +1 -1
  145. data/vendor/libgit2/include/git2/status.h +131 -56
  146. data/vendor/libgit2/include/git2/strarray.h +2 -2
  147. data/vendor/libgit2/include/git2/submodule.h +16 -16
  148. data/vendor/libgit2/include/git2/sys/commit.h +46 -0
  149. data/vendor/libgit2/include/git2/sys/config.h +71 -0
  150. data/vendor/libgit2/include/git2/sys/index.h +179 -0
  151. data/vendor/libgit2/include/git2/sys/odb_backend.h +86 -0
  152. data/vendor/libgit2/include/git2/sys/refdb_backend.h +158 -0
  153. data/vendor/libgit2/include/git2/sys/refs.h +38 -0
  154. data/vendor/libgit2/include/git2/sys/repository.h +106 -0
  155. data/vendor/libgit2/include/git2/tag.h +44 -18
  156. data/vendor/libgit2/include/git2/trace.h +1 -2
  157. data/vendor/libgit2/include/git2/transport.h +74 -0
  158. data/vendor/libgit2/include/git2/tree.h +12 -22
  159. data/vendor/libgit2/include/git2/types.h +33 -0
  160. data/vendor/libgit2/include/git2/version.h +2 -2
  161. data/vendor/libgit2/src/array.h +66 -0
  162. data/vendor/libgit2/src/attr.c +26 -13
  163. data/vendor/libgit2/src/attr_file.c +3 -2
  164. data/vendor/libgit2/src/attr_file.h +3 -3
  165. data/vendor/libgit2/src/attrcache.h +4 -4
  166. data/vendor/libgit2/src/blob.c +13 -9
  167. data/vendor/libgit2/src/blob.h +2 -2
  168. data/vendor/libgit2/src/branch.c +67 -49
  169. data/vendor/libgit2/src/cache.c +224 -54
  170. data/vendor/libgit2/src/cache.h +33 -20
  171. data/vendor/libgit2/src/checkout.c +145 -85
  172. data/vendor/libgit2/src/clone.c +62 -50
  173. data/vendor/libgit2/src/commit.c +74 -40
  174. data/vendor/libgit2/src/commit.h +2 -3
  175. data/vendor/libgit2/src/commit_list.c +14 -8
  176. data/vendor/libgit2/src/config.c +119 -36
  177. data/vendor/libgit2/src/config.h +3 -0
  178. data/vendor/libgit2/src/config_cache.c +24 -7
  179. data/vendor/libgit2/src/config_file.c +9 -6
  180. data/vendor/libgit2/src/crlf.c +4 -2
  181. data/vendor/libgit2/src/date.c +3 -3
  182. data/vendor/libgit2/src/delta.c +1 -1
  183. data/vendor/libgit2/src/diff.c +681 -303
  184. data/vendor/libgit2/src/diff.h +34 -2
  185. data/vendor/libgit2/src/diff_driver.c +405 -0
  186. data/vendor/libgit2/src/diff_driver.h +49 -0
  187. data/vendor/libgit2/src/diff_file.c +447 -0
  188. data/vendor/libgit2/src/diff_file.h +58 -0
  189. data/vendor/libgit2/src/diff_patch.c +995 -0
  190. data/vendor/libgit2/src/diff_patch.h +46 -0
  191. data/vendor/libgit2/src/diff_print.c +430 -0
  192. data/vendor/libgit2/src/diff_tform.c +464 -203
  193. data/vendor/libgit2/src/diff_xdiff.c +166 -0
  194. data/vendor/libgit2/src/diff_xdiff.h +28 -0
  195. data/vendor/libgit2/src/fetch.c +11 -4
  196. data/vendor/libgit2/src/fileops.c +85 -61
  197. data/vendor/libgit2/src/fileops.h +4 -0
  198. data/vendor/libgit2/src/global.c +10 -2
  199. data/vendor/libgit2/src/global.h +0 -8
  200. data/vendor/libgit2/src/hash/hash_generic.h +3 -3
  201. data/vendor/libgit2/src/hash/hash_win32.h +4 -4
  202. data/vendor/libgit2/src/hashsig.c +0 -1
  203. data/vendor/libgit2/src/ignore.c +68 -28
  204. data/vendor/libgit2/src/ignore.h +10 -1
  205. data/vendor/libgit2/src/index.c +666 -84
  206. data/vendor/libgit2/src/index.h +6 -0
  207. data/vendor/libgit2/src/indexer.c +10 -28
  208. data/vendor/libgit2/src/iterator.c +427 -283
  209. data/vendor/libgit2/src/iterator.h +58 -4
  210. data/vendor/libgit2/src/merge.c +1892 -32
  211. data/vendor/libgit2/src/merge.h +132 -5
  212. data/vendor/libgit2/src/merge_file.c +174 -0
  213. data/vendor/libgit2/src/merge_file.h +71 -0
  214. data/vendor/libgit2/src/mwindow.c +1 -1
  215. data/vendor/libgit2/src/notes.c +45 -48
  216. data/vendor/libgit2/src/object.c +89 -127
  217. data/vendor/libgit2/src/object.h +0 -1
  218. data/vendor/libgit2/src/object_api.c +129 -0
  219. data/vendor/libgit2/src/odb.c +156 -59
  220. data/vendor/libgit2/src/odb.h +5 -2
  221. data/vendor/libgit2/src/odb_loose.c +31 -17
  222. data/vendor/libgit2/src/odb_pack.c +39 -43
  223. data/vendor/libgit2/src/oid.c +62 -27
  224. data/vendor/libgit2/src/oid.h +33 -0
  225. data/vendor/libgit2/src/oidmap.h +4 -6
  226. data/vendor/libgit2/src/pack-objects.c +54 -22
  227. data/vendor/libgit2/src/pack.c +98 -56
  228. data/vendor/libgit2/src/pack.h +3 -1
  229. data/vendor/libgit2/src/pathspec.c +26 -1
  230. data/vendor/libgit2/src/pathspec.h +14 -0
  231. data/vendor/libgit2/src/pool.c +5 -0
  232. data/vendor/libgit2/src/posix.c +2 -2
  233. data/vendor/libgit2/src/posix.h +3 -0
  234. data/vendor/libgit2/src/push.c +13 -10
  235. data/vendor/libgit2/src/refdb.c +82 -62
  236. data/vendor/libgit2/src/refdb.h +16 -16
  237. data/vendor/libgit2/src/refdb_fs.c +386 -133
  238. data/vendor/libgit2/src/reflog.c +3 -1
  239. data/vendor/libgit2/src/refs.c +247 -221
  240. data/vendor/libgit2/src/refs.h +2 -1
  241. data/vendor/libgit2/src/refspec.c +18 -1
  242. data/vendor/libgit2/src/refspec.h +3 -1
  243. data/vendor/libgit2/src/remote.c +434 -253
  244. data/vendor/libgit2/src/remote.h +5 -3
  245. data/vendor/libgit2/src/repository.c +197 -111
  246. data/vendor/libgit2/src/repository.h +26 -5
  247. data/vendor/libgit2/src/reset.c +1 -1
  248. data/vendor/libgit2/src/revparse.c +84 -79
  249. data/vendor/libgit2/src/revwalk.c +1 -1
  250. data/vendor/libgit2/src/signature.c +22 -10
  251. data/vendor/libgit2/src/stash.c +5 -2
  252. data/vendor/libgit2/src/status.c +311 -107
  253. data/vendor/libgit2/src/status.h +23 -0
  254. data/vendor/libgit2/src/submodule.c +21 -13
  255. data/vendor/libgit2/src/tag.c +42 -31
  256. data/vendor/libgit2/src/tag.h +2 -3
  257. data/vendor/libgit2/src/thread-utils.h +105 -3
  258. data/vendor/libgit2/src/trace.c +1 -2
  259. data/vendor/libgit2/src/trace.h +3 -3
  260. data/vendor/libgit2/src/transport.c +18 -6
  261. data/vendor/libgit2/src/transports/cred.c +103 -1
  262. data/vendor/libgit2/src/transports/local.c +19 -9
  263. data/vendor/libgit2/src/transports/smart_protocol.c +32 -12
  264. data/vendor/libgit2/src/transports/ssh.c +519 -0
  265. data/vendor/libgit2/src/transports/winhttp.c +3 -1
  266. data/vendor/libgit2/src/tree.c +26 -28
  267. data/vendor/libgit2/src/tree.h +3 -3
  268. data/vendor/libgit2/src/unix/posix.h +2 -0
  269. data/vendor/libgit2/src/util.c +43 -6
  270. data/vendor/libgit2/src/util.h +40 -12
  271. data/vendor/libgit2/src/vector.c +3 -5
  272. data/vendor/libgit2/src/vector.h +9 -0
  273. data/vendor/libgit2/src/win32/dir.c +1 -1
  274. data/vendor/libgit2/src/win32/error.c +2 -0
  275. data/vendor/libgit2/src/win32/findfile.c +3 -6
  276. data/vendor/libgit2/src/win32/posix_w32.c +85 -59
  277. data/vendor/libgit2/src/win32/pthread.c +16 -8
  278. data/vendor/libgit2/src/win32/pthread.h +7 -4
  279. metadata +407 -306
  280. data/test/coverage/HEAD.json +0 -1
  281. data/vendor/libgit2/include/git2/refdb_backend.h +0 -109
  282. data/vendor/libgit2/src/diff_output.c +0 -1819
  283. data/vendor/libgit2/src/diff_output.h +0 -93
@@ -0,0 +1,49 @@
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
+ #ifndef INCLUDE_diff_driver_h__
8
+ #define INCLUDE_diff_driver_h__
9
+
10
+ #include "common.h"
11
+ #include "buffer.h"
12
+
13
+ typedef struct git_diff_driver_registry git_diff_driver_registry;
14
+
15
+ git_diff_driver_registry *git_diff_driver_registry_new(void);
16
+ void git_diff_driver_registry_free(git_diff_driver_registry *);
17
+
18
+ typedef struct git_diff_driver git_diff_driver;
19
+
20
+ int git_diff_driver_lookup(git_diff_driver **, git_repository *, const char *);
21
+ void git_diff_driver_free(git_diff_driver *);
22
+
23
+ /* diff option flags to force off and on for this driver */
24
+ void git_diff_driver_update_options(uint32_t *option_flags, git_diff_driver *);
25
+
26
+ /* returns -1 meaning "unknown", 0 meaning not binary, 1 meaning binary */
27
+ int git_diff_driver_content_is_binary(
28
+ git_diff_driver *, const char *content, size_t content_len);
29
+
30
+ typedef long (*git_diff_find_context_fn)(
31
+ const char *, long, char *, long, void *);
32
+
33
+ typedef int (*git_diff_find_context_line)(
34
+ git_diff_driver *, const char *, size_t);
35
+
36
+ typedef struct {
37
+ git_diff_driver *driver;
38
+ git_diff_find_context_line match_line;
39
+ git_buf line;
40
+ } git_diff_find_context_payload;
41
+
42
+ void git_diff_find_context_init(
43
+ git_diff_find_context_fn *findfn_out,
44
+ git_diff_find_context_payload *payload_out,
45
+ git_diff_driver *driver);
46
+
47
+ void git_diff_find_context_clear(git_diff_find_context_payload *);
48
+
49
+ #endif
@@ -0,0 +1,447 @@
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 "common.h"
8
+ #include "git2/blob.h"
9
+ #include "git2/submodule.h"
10
+ #include "diff.h"
11
+ #include "diff_file.h"
12
+ #include "odb.h"
13
+ #include "fileops.h"
14
+ #include "filter.h"
15
+
16
+ #define DIFF_MAX_FILESIZE 0x20000000
17
+
18
+ static bool diff_file_content_binary_by_size(git_diff_file_content *fc)
19
+ {
20
+ /* if we have diff opts, check max_size vs file size */
21
+ if ((fc->file->flags & DIFF_FLAGS_KNOWN_BINARY) == 0 &&
22
+ fc->opts_max_size > 0 &&
23
+ fc->file->size > fc->opts_max_size)
24
+ fc->file->flags |= GIT_DIFF_FLAG_BINARY;
25
+
26
+ return ((fc->file->flags & GIT_DIFF_FLAG_BINARY) != 0);
27
+ }
28
+
29
+ static void diff_file_content_binary_by_content(git_diff_file_content *fc)
30
+ {
31
+ if ((fc->file->flags & DIFF_FLAGS_KNOWN_BINARY) != 0)
32
+ return;
33
+
34
+ switch (git_diff_driver_content_is_binary(
35
+ fc->driver, fc->map.data, fc->map.len)) {
36
+ case 0: fc->file->flags |= GIT_DIFF_FLAG_NOT_BINARY; break;
37
+ case 1: fc->file->flags |= GIT_DIFF_FLAG_BINARY; break;
38
+ default: break;
39
+ }
40
+ }
41
+
42
+ static int diff_file_content_init_common(
43
+ git_diff_file_content *fc, const git_diff_options *opts)
44
+ {
45
+ fc->opts_flags = opts ? opts->flags : GIT_DIFF_NORMAL;
46
+
47
+ if (opts && opts->max_size >= 0)
48
+ fc->opts_max_size = opts->max_size ?
49
+ opts->max_size : DIFF_MAX_FILESIZE;
50
+
51
+ if (fc->src == GIT_ITERATOR_TYPE_EMPTY)
52
+ fc->src = GIT_ITERATOR_TYPE_TREE;
53
+
54
+ if (!fc->driver &&
55
+ git_diff_driver_lookup(&fc->driver, fc->repo, fc->file->path) < 0)
56
+ return -1;
57
+
58
+ /* give driver a chance to modify options */
59
+ git_diff_driver_update_options(&fc->opts_flags, fc->driver);
60
+
61
+ /* make sure file is conceivable mmap-able */
62
+ if ((git_off_t)((size_t)fc->file->size) != fc->file->size)
63
+ fc->file->flags |= GIT_DIFF_FLAG_BINARY;
64
+ /* check if user is forcing text diff the file */
65
+ else if (fc->opts_flags & GIT_DIFF_FORCE_TEXT) {
66
+ fc->file->flags &= ~GIT_DIFF_FLAG_BINARY;
67
+ fc->file->flags |= GIT_DIFF_FLAG_NOT_BINARY;
68
+ }
69
+ /* check if user is forcing binary diff the file */
70
+ else if (fc->opts_flags & GIT_DIFF_FORCE_BINARY) {
71
+ fc->file->flags &= ~GIT_DIFF_FLAG_NOT_BINARY;
72
+ fc->file->flags |= GIT_DIFF_FLAG_BINARY;
73
+ }
74
+
75
+ diff_file_content_binary_by_size(fc);
76
+
77
+ if ((fc->flags & GIT_DIFF_FLAG__NO_DATA) != 0) {
78
+ fc->flags |= GIT_DIFF_FLAG__LOADED;
79
+ fc->map.len = 0;
80
+ fc->map.data = "";
81
+ }
82
+
83
+ if ((fc->flags & GIT_DIFF_FLAG__LOADED) != 0)
84
+ diff_file_content_binary_by_content(fc);
85
+
86
+ return 0;
87
+ }
88
+
89
+ int git_diff_file_content__init_from_diff(
90
+ git_diff_file_content *fc,
91
+ git_diff_list *diff,
92
+ size_t delta_index,
93
+ bool use_old)
94
+ {
95
+ git_diff_delta *delta = git_vector_get(&diff->deltas, delta_index);
96
+ bool has_data = true;
97
+
98
+ memset(fc, 0, sizeof(*fc));
99
+ fc->repo = diff->repo;
100
+ fc->file = use_old ? &delta->old_file : &delta->new_file;
101
+ fc->src = use_old ? diff->old_src : diff->new_src;
102
+
103
+ if (git_diff_driver_lookup(&fc->driver, fc->repo, fc->file->path) < 0)
104
+ return -1;
105
+
106
+ switch (delta->status) {
107
+ case GIT_DELTA_ADDED:
108
+ has_data = !use_old; break;
109
+ case GIT_DELTA_DELETED:
110
+ has_data = use_old; break;
111
+ case GIT_DELTA_UNTRACKED:
112
+ has_data = !use_old &&
113
+ (diff->opts.flags & GIT_DIFF_INCLUDE_UNTRACKED_CONTENT) != 0;
114
+ break;
115
+ case GIT_DELTA_MODIFIED:
116
+ case GIT_DELTA_COPIED:
117
+ case GIT_DELTA_RENAMED:
118
+ break;
119
+ default:
120
+ has_data = false;
121
+ break;
122
+ }
123
+
124
+ if (!has_data)
125
+ fc->flags |= GIT_DIFF_FLAG__NO_DATA;
126
+
127
+ return diff_file_content_init_common(fc, &diff->opts);
128
+ }
129
+
130
+ int git_diff_file_content__init_from_blob(
131
+ git_diff_file_content *fc,
132
+ git_repository *repo,
133
+ const git_diff_options *opts,
134
+ const git_blob *blob,
135
+ git_diff_file *as_file)
136
+ {
137
+ memset(fc, 0, sizeof(*fc));
138
+ fc->repo = repo;
139
+ fc->file = as_file;
140
+ fc->blob = blob;
141
+
142
+ if (!blob) {
143
+ fc->flags |= GIT_DIFF_FLAG__NO_DATA;
144
+ } else {
145
+ fc->flags |= GIT_DIFF_FLAG__LOADED;
146
+ fc->file->flags |= GIT_DIFF_FLAG_VALID_OID;
147
+ fc->file->size = git_blob_rawsize(blob);
148
+ fc->file->mode = GIT_FILEMODE_BLOB;
149
+ git_oid_cpy(&fc->file->oid, git_blob_id(blob));
150
+
151
+ fc->map.len = (size_t)fc->file->size;
152
+ fc->map.data = (char *)git_blob_rawcontent(blob);
153
+ }
154
+
155
+ return diff_file_content_init_common(fc, opts);
156
+ }
157
+
158
+ int git_diff_file_content__init_from_raw(
159
+ git_diff_file_content *fc,
160
+ git_repository *repo,
161
+ const git_diff_options *opts,
162
+ const char *buf,
163
+ size_t buflen,
164
+ git_diff_file *as_file)
165
+ {
166
+ memset(fc, 0, sizeof(*fc));
167
+ fc->repo = repo;
168
+ fc->file = as_file;
169
+
170
+ if (!buf) {
171
+ fc->flags |= GIT_DIFF_FLAG__NO_DATA;
172
+ } else {
173
+ fc->flags |= GIT_DIFF_FLAG__LOADED;
174
+ fc->file->flags |= GIT_DIFF_FLAG_VALID_OID;
175
+ fc->file->size = buflen;
176
+ fc->file->mode = GIT_FILEMODE_BLOB;
177
+ git_odb_hash(&fc->file->oid, buf, buflen, GIT_OBJ_BLOB);
178
+
179
+ fc->map.len = buflen;
180
+ fc->map.data = (char *)buf;
181
+ }
182
+
183
+ return diff_file_content_init_common(fc, opts);
184
+ }
185
+
186
+ static int diff_file_content_commit_to_str(
187
+ git_diff_file_content *fc, bool check_status)
188
+ {
189
+ char oid[GIT_OID_HEXSZ+1];
190
+ git_buf content = GIT_BUF_INIT;
191
+ const char *status = "";
192
+
193
+ if (check_status) {
194
+ int error = 0;
195
+ git_submodule *sm = NULL;
196
+ unsigned int sm_status = 0;
197
+ const git_oid *sm_head;
198
+
199
+ if ((error = git_submodule_lookup(&sm, fc->repo, fc->file->path)) < 0 ||
200
+ (error = git_submodule_status(&sm_status, sm)) < 0) {
201
+ /* GIT_EEXISTS means a "submodule" that has not been git added */
202
+ if (error == GIT_EEXISTS)
203
+ error = 0;
204
+ return error;
205
+ }
206
+
207
+ /* update OID if we didn't have it previously */
208
+ if ((fc->file->flags & GIT_DIFF_FLAG_VALID_OID) == 0 &&
209
+ ((sm_head = git_submodule_wd_id(sm)) != NULL ||
210
+ (sm_head = git_submodule_head_id(sm)) != NULL))
211
+ {
212
+ git_oid_cpy(&fc->file->oid, sm_head);
213
+ fc->file->flags |= GIT_DIFF_FLAG_VALID_OID;
214
+ }
215
+
216
+ if (GIT_SUBMODULE_STATUS_IS_WD_DIRTY(sm_status))
217
+ status = "-dirty";
218
+ }
219
+
220
+ git_oid_tostr(oid, sizeof(oid), &fc->file->oid);
221
+ if (git_buf_printf(&content, "Subproject commit %s%s\n", oid, status) < 0)
222
+ return -1;
223
+
224
+ fc->map.len = git_buf_len(&content);
225
+ fc->map.data = git_buf_detach(&content);
226
+ fc->flags |= GIT_DIFF_FLAG__FREE_DATA;
227
+
228
+ return 0;
229
+ }
230
+
231
+ static int diff_file_content_load_blob(git_diff_file_content *fc)
232
+ {
233
+ int error = 0;
234
+ git_odb_object *odb_obj = NULL;
235
+
236
+ if (git_oid_iszero(&fc->file->oid))
237
+ return 0;
238
+
239
+ if (fc->file->mode == GIT_FILEMODE_COMMIT)
240
+ return diff_file_content_commit_to_str(fc, false);
241
+
242
+ /* if we don't know size, try to peek at object header first */
243
+ if (!fc->file->size) {
244
+ git_odb *odb;
245
+ size_t len;
246
+ git_otype type;
247
+
248
+ if (!(error = git_repository_odb__weakptr(&odb, fc->repo))) {
249
+ error = git_odb__read_header_or_object(
250
+ &odb_obj, &len, &type, odb, &fc->file->oid);
251
+ git_odb_free(odb);
252
+ }
253
+ if (error)
254
+ return error;
255
+
256
+ fc->file->size = len;
257
+ }
258
+
259
+ if (diff_file_content_binary_by_size(fc))
260
+ return 0;
261
+
262
+ if (odb_obj != NULL) {
263
+ error = git_object__from_odb_object(
264
+ (git_object **)&fc->blob, fc->repo, odb_obj, GIT_OBJ_BLOB);
265
+ git_odb_object_free(odb_obj);
266
+ } else {
267
+ error = git_blob_lookup(
268
+ (git_blob **)&fc->blob, fc->repo, &fc->file->oid);
269
+ }
270
+
271
+ if (!error) {
272
+ fc->flags |= GIT_DIFF_FLAG__FREE_BLOB;
273
+ fc->map.data = (void *)git_blob_rawcontent(fc->blob);
274
+ fc->map.len = (size_t)git_blob_rawsize(fc->blob);
275
+ }
276
+
277
+ return error;
278
+ }
279
+
280
+ static int diff_file_content_load_workdir_symlink(
281
+ git_diff_file_content *fc, git_buf *path)
282
+ {
283
+ ssize_t alloc_len, read_len;
284
+
285
+ /* link path on disk could be UTF-16, so prepare a buffer that is
286
+ * big enough to handle some UTF-8 data expansion
287
+ */
288
+ alloc_len = (ssize_t)(fc->file->size * 2) + 1;
289
+
290
+ fc->map.data = git__calloc(alloc_len, sizeof(char));
291
+ GITERR_CHECK_ALLOC(fc->map.data);
292
+
293
+ fc->flags |= GIT_DIFF_FLAG__FREE_DATA;
294
+
295
+ read_len = p_readlink(git_buf_cstr(path), fc->map.data, alloc_len);
296
+ if (read_len < 0) {
297
+ giterr_set(GITERR_OS, "Failed to read symlink '%s'", fc->file->path);
298
+ return -1;
299
+ }
300
+
301
+ fc->map.len = read_len;
302
+ return 0;
303
+ }
304
+
305
+ static int diff_file_content_load_workdir_file(
306
+ git_diff_file_content *fc, git_buf *path)
307
+ {
308
+ int error = 0;
309
+ git_vector filters = GIT_VECTOR_INIT;
310
+ git_buf raw = GIT_BUF_INIT, filtered = GIT_BUF_INIT;
311
+ git_file fd = git_futils_open_ro(git_buf_cstr(path));
312
+
313
+ if (fd < 0)
314
+ return fd;
315
+
316
+ if (!fc->file->size &&
317
+ !(fc->file->size = git_futils_filesize(fd)))
318
+ goto cleanup;
319
+
320
+ if (diff_file_content_binary_by_size(fc))
321
+ goto cleanup;
322
+
323
+ if ((error = git_filters_load(
324
+ &filters, fc->repo, fc->file->path, GIT_FILTER_TO_ODB)) < 0)
325
+ goto cleanup;
326
+ /* error >= is a filter count */
327
+
328
+ if (error == 0) {
329
+ if (!(error = git_futils_mmap_ro(
330
+ &fc->map, fd, 0, (size_t)fc->file->size)))
331
+ fc->flags |= GIT_DIFF_FLAG__UNMAP_DATA;
332
+ else /* fall through to try readbuffer below */
333
+ giterr_clear();
334
+ }
335
+
336
+ if (error != 0) {
337
+ error = git_futils_readbuffer_fd(&raw, fd, (size_t)fc->file->size);
338
+ if (error < 0)
339
+ goto cleanup;
340
+
341
+ if (!filters.length)
342
+ git_buf_swap(&filtered, &raw);
343
+ else
344
+ error = git_filters_apply(&filtered, &raw, &filters);
345
+
346
+ if (!error) {
347
+ fc->map.len = git_buf_len(&filtered);
348
+ fc->map.data = git_buf_detach(&filtered);
349
+ fc->flags |= GIT_DIFF_FLAG__FREE_DATA;
350
+ }
351
+
352
+ git_buf_free(&raw);
353
+ git_buf_free(&filtered);
354
+ }
355
+
356
+ cleanup:
357
+ git_filters_free(&filters);
358
+ p_close(fd);
359
+
360
+ return error;
361
+ }
362
+
363
+ static int diff_file_content_load_workdir(git_diff_file_content *fc)
364
+ {
365
+ int error = 0;
366
+ git_buf path = GIT_BUF_INIT;
367
+
368
+ if (fc->file->mode == GIT_FILEMODE_COMMIT)
369
+ return diff_file_content_commit_to_str(fc, true);
370
+
371
+ if (fc->file->mode == GIT_FILEMODE_TREE)
372
+ return 0;
373
+
374
+ if (git_buf_joinpath(
375
+ &path, git_repository_workdir(fc->repo), fc->file->path) < 0)
376
+ return -1;
377
+
378
+ if (S_ISLNK(fc->file->mode))
379
+ error = diff_file_content_load_workdir_symlink(fc, &path);
380
+ else
381
+ error = diff_file_content_load_workdir_file(fc, &path);
382
+
383
+ /* once data is loaded, update OID if we didn't have it previously */
384
+ if (!error && (fc->file->flags & GIT_DIFF_FLAG_VALID_OID) == 0) {
385
+ error = git_odb_hash(
386
+ &fc->file->oid, fc->map.data, fc->map.len, GIT_OBJ_BLOB);
387
+ fc->file->flags |= GIT_DIFF_FLAG_VALID_OID;
388
+ }
389
+
390
+ git_buf_free(&path);
391
+ return error;
392
+ }
393
+
394
+ int git_diff_file_content__load(git_diff_file_content *fc)
395
+ {
396
+ int error = 0;
397
+
398
+ if ((fc->flags & GIT_DIFF_FLAG__LOADED) != 0)
399
+ return 0;
400
+
401
+ if ((fc->file->flags & GIT_DIFF_FLAG_BINARY) != 0)
402
+ return 0;
403
+
404
+ if (fc->src == GIT_ITERATOR_TYPE_WORKDIR)
405
+ error = diff_file_content_load_workdir(fc);
406
+ else
407
+ error = diff_file_content_load_blob(fc);
408
+ if (error)
409
+ return error;
410
+
411
+ fc->flags |= GIT_DIFF_FLAG__LOADED;
412
+
413
+ diff_file_content_binary_by_content(fc);
414
+
415
+ return 0;
416
+ }
417
+
418
+ void git_diff_file_content__unload(git_diff_file_content *fc)
419
+ {
420
+ if (fc->flags & GIT_DIFF_FLAG__FREE_DATA) {
421
+ git__free(fc->map.data);
422
+ fc->map.data = "";
423
+ fc->map.len = 0;
424
+ fc->flags &= ~GIT_DIFF_FLAG__FREE_DATA;
425
+ }
426
+ else if (fc->flags & GIT_DIFF_FLAG__UNMAP_DATA) {
427
+ git_futils_mmap_free(&fc->map);
428
+ fc->map.data = "";
429
+ fc->map.len = 0;
430
+ fc->flags &= ~GIT_DIFF_FLAG__UNMAP_DATA;
431
+ }
432
+
433
+ if (fc->flags & GIT_DIFF_FLAG__FREE_BLOB) {
434
+ git_blob_free((git_blob *)fc->blob);
435
+ fc->blob = NULL;
436
+ fc->flags &= ~GIT_DIFF_FLAG__FREE_BLOB;
437
+ }
438
+
439
+ fc->flags &= ~GIT_DIFF_FLAG__LOADED;
440
+ }
441
+
442
+ void git_diff_file_content__clear(git_diff_file_content *fc)
443
+ {
444
+ git_diff_file_content__unload(fc);
445
+
446
+ /* for now, nothing else to do */
447
+ }