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,509 @@
1
+ /*
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2012 GitHub, Inc
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in
14
+ * all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ * THE SOFTWARE.
23
+ */
24
+
25
+ #include "rugged.h"
26
+
27
+ extern VALUE rb_mRugged;
28
+ VALUE rb_cRuggedDiff;
29
+
30
+ static void rb_git_diff__free(git_diff_list *diff)
31
+ {
32
+ git_diff_list_free(diff);
33
+ }
34
+
35
+ VALUE rugged_diff_new(VALUE klass, VALUE owner, git_diff_list *diff)
36
+ {
37
+ VALUE rb_diff = Data_Wrap_Struct(klass, NULL, rb_git_diff__free, diff);
38
+ rugged_set_owner(rb_diff, owner);
39
+ return rb_diff;
40
+ }
41
+
42
+ /**
43
+ * The caller has to free the returned git_diff_options pathspec strings array.
44
+ */
45
+ void rugged_parse_diff_options(git_diff_options *opts, VALUE rb_options)
46
+ {
47
+ if (!NIL_P(rb_options)) {
48
+ VALUE rb_value;
49
+ Check_Type(rb_options, T_HASH);
50
+
51
+ rb_value = rb_hash_aref(rb_options, CSTR2SYM("max_size"));
52
+ if (!NIL_P(rb_value)) {
53
+ Check_Type(rb_value, T_FIXNUM);
54
+ opts->max_size = FIX2INT(rb_value);
55
+ }
56
+
57
+ rb_value = rb_hash_aref(rb_options, CSTR2SYM("context_lines"));
58
+ if (!NIL_P(rb_value)) {
59
+ Check_Type(rb_value, T_FIXNUM);
60
+ opts->context_lines = FIX2INT(rb_value);
61
+ }
62
+
63
+ rb_value = rb_hash_aref(rb_options, CSTR2SYM("interhunk_lines"));
64
+ if (!NIL_P(rb_value)) {
65
+ Check_Type(rb_value, T_FIXNUM);
66
+ opts->interhunk_lines = FIX2INT(rb_value);
67
+ }
68
+
69
+ if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("reverse")))) {
70
+ opts->flags |= GIT_DIFF_REVERSE;
71
+ }
72
+
73
+ if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("force_text")))) {
74
+ opts->flags |= GIT_DIFF_FORCE_TEXT;
75
+ }
76
+
77
+ if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("ignore_whitespace")))) {
78
+ opts->flags |= GIT_DIFF_IGNORE_WHITESPACE;
79
+ }
80
+
81
+ if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("ignore_whitespace_change")))) {
82
+ opts->flags |= GIT_DIFF_IGNORE_WHITESPACE_CHANGE;
83
+ }
84
+
85
+ if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("ignore_whitespace_eol")))) {
86
+ opts->flags |= GIT_DIFF_IGNORE_WHITESPACE_EOL;
87
+ }
88
+
89
+ if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("ignore_submodules")))) {
90
+ opts->flags |= GIT_DIFF_IGNORE_SUBMODULES;
91
+ }
92
+
93
+ if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("patience")))) {
94
+ opts->flags |= GIT_DIFF_PATIENCE;
95
+ }
96
+
97
+ if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("include_ignored")))) {
98
+ opts->flags |= GIT_DIFF_INCLUDE_IGNORED;
99
+ }
100
+
101
+ if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("include_untracked")))) {
102
+ opts->flags |= GIT_DIFF_INCLUDE_UNTRACKED;
103
+ }
104
+
105
+ if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("include_unmodified")))) {
106
+ opts->flags |= GIT_DIFF_INCLUDE_UNMODIFIED;
107
+ }
108
+
109
+ if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("recurse_untracked_dirs")))) {
110
+ opts->flags |= GIT_DIFF_RECURSE_UNTRACKED_DIRS;
111
+ }
112
+
113
+ if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("disable_pathspec_match")))) {
114
+ opts->flags |= GIT_DIFF_DISABLE_PATHSPEC_MATCH;
115
+ }
116
+
117
+ if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("include_untracked_content")))) {
118
+ opts->flags |= GIT_DIFF_INCLUDE_UNTRACKED_CONTENT ;
119
+ }
120
+
121
+ if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("skip_binary_check")))) {
122
+ opts->flags |= GIT_DIFF_SKIP_BINARY_CHECK;
123
+ }
124
+
125
+ if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("include_typechange")))) {
126
+ opts->flags |= GIT_DIFF_INCLUDE_TYPECHANGE;
127
+ }
128
+
129
+ if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("include_typechange_trees")))) {
130
+ opts->flags |= GIT_DIFF_INCLUDE_TYPECHANGE_TREES;
131
+ }
132
+
133
+ if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("ignore_filemode")))) {
134
+ opts->flags |= GIT_DIFF_IGNORE_FILEMODE;
135
+ }
136
+
137
+ if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("recurse_ignored_dirs")))) {
138
+ opts->flags |= GIT_DIFF_RECURSE_IGNORED_DIRS;
139
+ }
140
+
141
+ rb_value = rb_hash_aref(rb_options, CSTR2SYM("paths"));
142
+ if (!NIL_P(rb_value)) {
143
+ int i;
144
+ Check_Type(rb_value, T_ARRAY);
145
+
146
+ for (i = 0; i < RARRAY_LEN(rb_value); ++i)
147
+ Check_Type(rb_ary_entry(rb_value, i), T_STRING);
148
+
149
+ opts->pathspec.count = RARRAY_LEN(rb_value);
150
+ opts->pathspec.strings = xmalloc(opts->pathspec.count * sizeof(char *));
151
+
152
+ for (i = 0; i < RARRAY_LEN(rb_value); ++i) {
153
+ VALUE rb_path = rb_ary_entry(rb_value, i);
154
+ opts->pathspec.strings[i] = StringValueCStr(rb_path);
155
+ }
156
+ }
157
+ }
158
+ }
159
+
160
+ static int diff_print_cb(
161
+ const git_diff_delta *delta,
162
+ const git_diff_range *range,
163
+ char line_origin,
164
+ const char *content,
165
+ size_t content_len,
166
+ void *payload)
167
+ {
168
+ VALUE rb_str = (VALUE)payload;
169
+
170
+ rb_str_cat(rb_str, content, content_len);
171
+
172
+ return GIT_OK;
173
+ }
174
+
175
+ /*
176
+ * call-seq:
177
+ * diff.patch -> patch
178
+ * diff.patch(:compact => true) -> compact_patch
179
+ *
180
+ * Return a string containing the diff in patch form.
181
+ */
182
+ static VALUE rb_git_diff_patch(int argc, VALUE *argv, VALUE self)
183
+ {
184
+ git_diff_list *diff;
185
+ VALUE rb_str = rb_str_new(NULL, 0);
186
+ VALUE rb_opts;
187
+
188
+ rb_scan_args(argc, argv, "00:", &rb_opts);
189
+
190
+ Data_Get_Struct(self, git_diff_list, diff);
191
+
192
+ if (!NIL_P(rb_opts)) {
193
+ if (rb_hash_aref(rb_opts, CSTR2SYM("compact")) == Qtrue)
194
+ git_diff_print_compact(diff, diff_print_cb, (void*)rb_str);
195
+ else
196
+ git_diff_print_patch(diff, diff_print_cb, (void*)rb_str);
197
+ } else {
198
+ git_diff_print_patch(diff, diff_print_cb, (void*)rb_str);
199
+ }
200
+
201
+ return rb_str;
202
+ }
203
+
204
+ static int diff_write_cb(
205
+ const git_diff_delta *delta,
206
+ const git_diff_range *range,
207
+ char line_origin,
208
+ const char *content,
209
+ size_t content_len,
210
+ void *payload)
211
+ {
212
+ VALUE rb_io = (VALUE)payload, str = rb_str_new(content, content_len);
213
+
214
+ rb_io_write(rb_io, str);
215
+
216
+ return GIT_OK;
217
+ }
218
+
219
+ /*
220
+ * call-seq:
221
+ * diff.write_patch(io) -> nil
222
+ * diff.write_patch(io, :compact => true) -> nil
223
+ *
224
+ * Write a patch directly to an object which responds to "write".
225
+ */
226
+ static VALUE rb_git_diff_write_patch(int argc, VALUE *argv, VALUE self)
227
+ {
228
+ git_diff_list *diff;
229
+ VALUE rb_io, rb_opts;
230
+
231
+ rb_scan_args(argc, argv, "10:", &rb_io, &rb_opts);
232
+
233
+ if (!rb_respond_to(rb_io, rb_intern("write")))
234
+ rb_raise(rb_eArgError, "Expected io to respond to \"write\"");
235
+
236
+ Data_Get_Struct(self, git_diff_list, diff);
237
+
238
+ if (!NIL_P(rb_opts)) {
239
+ if (rb_hash_aref(rb_opts, CSTR2SYM("compact")) == Qtrue)
240
+ git_diff_print_compact(diff, diff_write_cb, (void*)rb_io);
241
+ else
242
+ git_diff_print_patch(diff, diff_write_cb, (void*)rb_io);
243
+ } else {
244
+ git_diff_print_patch(diff, diff_write_cb, (void*)rb_io);
245
+ }
246
+
247
+ return Qnil;
248
+ }
249
+
250
+ /*
251
+ * call-seq:
252
+ * diff.merge!(other_diff) -> self
253
+ *
254
+ * Merges all diff information from +other_diff+.
255
+ */
256
+ static VALUE rb_git_diff_merge(VALUE self, VALUE rb_other)
257
+ {
258
+ git_diff_list *diff;
259
+ git_diff_list *other;
260
+ int error;
261
+
262
+ if (!rb_obj_is_kind_of(rb_other, rb_cRuggedDiff))
263
+ rb_raise(rb_eTypeError, "A Rugged::Diff instance is required");
264
+
265
+ Data_Get_Struct(self, git_diff_list, diff);
266
+ Data_Get_Struct(rb_other, git_diff_list, other);
267
+
268
+ error = git_diff_merge(diff, other);
269
+ rugged_exception_check(error);
270
+
271
+ return self;
272
+ }
273
+
274
+ /*
275
+ * call-seq:
276
+ * diff.find_similar!([options]) -> self
277
+ *
278
+ * Detects entries in the diff that look like renames or copies (based on the
279
+ * given options) and replaces them with actual rename or copy entries.
280
+ *
281
+ * Additionally, modified files can be broken into add/delete pairs if the
282
+ * amount of changes are above a specific threshold (see +:break_rewrite_threshold+).
283
+ *
284
+ * By default, similarity will be measured without leading whitespace. You
285
+ * you can use the +:dont_ignore_whitespace+ to disable this.
286
+ *
287
+ * The following options can be passed in the +options+ Hash:
288
+ *
289
+ * :rename_threshold ::
290
+ * An integer specifying the similarity to consider a file renamed (default 50).
291
+ *
292
+ * :rename_from_rewrite_threshold ::
293
+ * An integer specifying the similarity of modified to be eligible
294
+ * rename source (default 50).
295
+ *
296
+ * :copy_threshold ::
297
+ * An integer specifying the similarity to consider a file a copy (default 50).
298
+ *
299
+ * :break_rewrite_threshold ::
300
+ * An integer specifying the similarity to split modify into delete/add pair (default 60).
301
+ *
302
+ * :rename_limit ::
303
+ * An integer specifying the maximum amount of similarity sources to examine
304
+ * (a la diff's +-l+ option or the +diff.renameLimit+ config) (default 200).
305
+ *
306
+ * :renames ::
307
+ * If true, looking for renames will be enabled (+--find-renames+).
308
+ *
309
+ * :renames_from_rewrites ::
310
+ * If true, the "old side" of modified files will be considered for renames (+--break-rewrites=N+).
311
+ *
312
+ * :copies ::
313
+ * If true, looking for copies will be enabled (+--find-copies+).
314
+ *
315
+ * :copies_from_unmodified ::
316
+ * If true, unmodified files will be considered as copy sources (+--find-copies-harder+).
317
+ *
318
+ * :break_rewrites ::
319
+ * If true, larger rewrites will be split into delete/add pairs (+--break-rewrites=/M+).
320
+ *
321
+ * :all ::
322
+ * If true, enables all finding features.
323
+ *
324
+ * :ignore_whitespace ::
325
+ * If true, similarity will be measured with all whitespace ignored.
326
+ *
327
+ * :dont_ignore_whitespace ::
328
+ * If true, similarity will be measured without ignoring any whitespace.
329
+ *
330
+ */
331
+ static VALUE rb_git_diff_find_similar(int argc, VALUE *argv, VALUE self)
332
+ {
333
+ git_diff_list *diff;
334
+ git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT;
335
+ VALUE rb_options;
336
+ int error;
337
+
338
+ Data_Get_Struct(self, git_diff_list, diff);
339
+
340
+ rb_scan_args(argc, argv, "00:", &rb_options);
341
+
342
+ if (!NIL_P(rb_options)) {
343
+ VALUE rb_value = rb_hash_aref(rb_options, CSTR2SYM("rename_threshold"));
344
+ if (!NIL_P(rb_value)) {
345
+ Check_Type(rb_value, T_FIXNUM);
346
+ opts.rename_threshold = FIX2INT(rb_value);
347
+ }
348
+
349
+ rb_value = rb_hash_aref(rb_options, CSTR2SYM("rename_from_rewrite_threshold"));
350
+ if (!NIL_P(rb_value)) {
351
+ Check_Type(rb_value, T_FIXNUM);
352
+ opts.rename_from_rewrite_threshold = FIX2INT(rb_value);
353
+ }
354
+
355
+ rb_value = rb_hash_aref(rb_options, CSTR2SYM("copy_threshold"));
356
+ if (!NIL_P(rb_value)) {
357
+ Check_Type(rb_value, T_FIXNUM);
358
+ opts.copy_threshold = FIX2INT(rb_value);
359
+ }
360
+
361
+ rb_value = rb_hash_aref(rb_options, CSTR2SYM("break_rewrite_threshold"));
362
+ if (!NIL_P(rb_value)) {
363
+ Check_Type(rb_value, T_FIXNUM);
364
+ opts.break_rewrite_threshold = FIX2INT(rb_value);
365
+ }
366
+
367
+ rb_value = rb_hash_aref(rb_options, CSTR2SYM("rename_limit"));
368
+ if (!NIL_P(rb_value)) {
369
+ Check_Type(rb_value, T_FIXNUM);
370
+ opts.rename_limit = FIX2INT(rb_value);
371
+ }
372
+
373
+ if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("renames")))) {
374
+ opts.flags |= GIT_DIFF_FIND_RENAMES;
375
+ }
376
+
377
+ if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("renames_from_rewrites")))) {
378
+ opts.flags |= GIT_DIFF_FIND_RENAMES_FROM_REWRITES;
379
+ }
380
+
381
+ if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("copies")))) {
382
+ opts.flags |= GIT_DIFF_FIND_COPIES;
383
+ }
384
+
385
+ if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("copies_from_unmodified")))) {
386
+ opts.flags |= GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED;
387
+ }
388
+
389
+ if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("break_rewrites")))) {
390
+ opts.flags |= GIT_DIFF_FIND_AND_BREAK_REWRITES;
391
+ }
392
+
393
+ if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("all")))) {
394
+ opts.flags |= GIT_DIFF_FIND_ALL;
395
+ }
396
+
397
+ if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("ignore_whitespace")))) {
398
+ opts.flags |= GIT_DIFF_FIND_IGNORE_WHITESPACE;
399
+ }
400
+
401
+ if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("dont_ignore_whitespace")))) {
402
+ opts.flags |= GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE;
403
+ }
404
+ }
405
+
406
+ error = git_diff_find_similar(diff, &opts);
407
+ rugged_exception_check(error);
408
+
409
+ return self;
410
+ }
411
+
412
+ /*
413
+ * call-seq:
414
+ * diff.each_patch { |patch| } -> self
415
+ * diff.each_patch -> enumerator
416
+ *
417
+ * If given a block, yields each patch that is part of the diff.
418
+ * If no block is given, an enumerator will be returned.
419
+ */
420
+ static VALUE rb_git_diff_each_patch(VALUE self)
421
+ {
422
+ git_diff_list *diff;
423
+ git_diff_patch *patch;
424
+ int error = 0, d, delta_count;
425
+
426
+ if (!rb_block_given_p()) {
427
+ return rb_funcall(self, rb_intern("to_enum"), 1, CSTR2SYM("each_patch"), self);
428
+ }
429
+
430
+ Data_Get_Struct(self, git_diff_list, diff);
431
+
432
+ delta_count = git_diff_num_deltas(diff);
433
+ for (d = 0; d < delta_count; ++d) {
434
+ error = git_diff_get_patch(&patch, NULL, diff, d);
435
+ if (error) break;
436
+
437
+ rb_yield(rugged_diff_patch_new(self, patch));
438
+ }
439
+
440
+ rugged_exception_check(error);
441
+
442
+ return self;
443
+ }
444
+
445
+ /*
446
+ * call-seq:
447
+ * diff.each_delta { |delta| } -> self
448
+ * diff.each_delta -> enumerator
449
+ *
450
+ * If given a block, yields each delta that is part of the diff.
451
+ * If no block is given, an enumerator will be returned.
452
+ *
453
+ * This method should be preferred over #each_patch if you're not interested
454
+ * in the actual line-by-line changes of the diff.
455
+ */
456
+ static VALUE rb_git_diff_each_delta(VALUE self)
457
+ {
458
+ git_diff_list *diff;
459
+ const git_diff_delta *delta;
460
+ int error = 0, d, delta_count;
461
+
462
+ if (!rb_block_given_p()) {
463
+ return rb_funcall(self, rb_intern("to_enum"), 1, CSTR2SYM("each_delta"), self);
464
+ }
465
+
466
+ Data_Get_Struct(self, git_diff_list, diff);
467
+
468
+ delta_count = git_diff_num_deltas(diff);
469
+ for (d = 0; d < delta_count; ++d) {
470
+ error = git_diff_get_patch(NULL, &delta, diff, d);
471
+ if (error) break;
472
+
473
+ rb_yield(rugged_diff_delta_new(self, delta));
474
+ }
475
+
476
+ rugged_exception_check(error);
477
+
478
+ return self;
479
+ }
480
+
481
+ /*
482
+ * call-seq: diff.size -> int
483
+ *
484
+ * Returns the number of deltas/patches in this diff.
485
+ */
486
+ static VALUE rb_git_diff_size(VALUE self)
487
+ {
488
+ git_diff_list *diff;
489
+
490
+ Data_Get_Struct(self, git_diff_list, diff);
491
+
492
+ return INT2FIX(git_diff_num_deltas(diff));
493
+ }
494
+
495
+ void Init_rugged_diff(void)
496
+ {
497
+ rb_cRuggedDiff = rb_define_class_under(rb_mRugged, "Diff", rb_cObject);
498
+
499
+ rb_define_method(rb_cRuggedDiff, "patch", rb_git_diff_patch, -1);
500
+ rb_define_method(rb_cRuggedDiff, "write_patch", rb_git_diff_write_patch, -1);
501
+
502
+ rb_define_method(rb_cRuggedDiff, "find_similar!", rb_git_diff_find_similar, -1);
503
+ rb_define_method(rb_cRuggedDiff, "merge!", rb_git_diff_merge, 1);
504
+
505
+ rb_define_method(rb_cRuggedDiff, "size", rb_git_diff_size, 0);
506
+
507
+ rb_define_method(rb_cRuggedDiff, "each_patch", rb_git_diff_each_patch, 0);
508
+ rb_define_method(rb_cRuggedDiff, "each_delta", rb_git_diff_each_delta, 0);
509
+ }