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
@@ -7,16 +7,143 @@
7
7
  #ifndef INCLUDE_merge_h__
8
8
  #define INCLUDE_merge_h__
9
9
 
10
- #include "git2/types.h"
11
- #include "git2/merge.h"
12
- #include "commit_list.h"
13
10
  #include "vector.h"
11
+ #include "commit_list.h"
12
+ #include "pool.h"
13
+
14
+ #include "git2/merge.h"
15
+ #include "git2/types.h"
14
16
 
15
17
  #define GIT_MERGE_MSG_FILE "MERGE_MSG"
16
18
  #define GIT_MERGE_MODE_FILE "MERGE_MODE"
17
19
 
18
- #define MERGE_CONFIG_FILE_MODE 0666
20
+ #define GIT_MERGE_TREE_RENAME_THRESHOLD 50
21
+ #define GIT_MERGE_TREE_TARGET_LIMIT 1000
22
+
23
+ /** Types of changes when files are merged from branch to branch. */
24
+ typedef enum {
25
+ /* No conflict - a change only occurs in one branch. */
26
+ GIT_MERGE_DIFF_NONE = 0,
27
+
28
+ /* Occurs when a file is modified in both branches. */
29
+ GIT_MERGE_DIFF_BOTH_MODIFIED = (1 << 0),
30
+
31
+ /* Occurs when a file is added in both branches. */
32
+ GIT_MERGE_DIFF_BOTH_ADDED = (1 << 1),
33
+
34
+ /* Occurs when a file is deleted in both branches. */
35
+ GIT_MERGE_DIFF_BOTH_DELETED = (1 << 2),
36
+
37
+ /* Occurs when a file is modified in one branch and deleted in the other. */
38
+ GIT_MERGE_DIFF_MODIFIED_DELETED = (1 << 3),
39
+
40
+ /* Occurs when a file is renamed in one branch and modified in the other. */
41
+ GIT_MERGE_DIFF_RENAMED_MODIFIED = (1 << 4),
42
+
43
+ /* Occurs when a file is renamed in one branch and deleted in the other. */
44
+ GIT_MERGE_DIFF_RENAMED_DELETED = (1 << 5),
45
+
46
+ /* Occurs when a file is renamed in one branch and a file with the same
47
+ * name is added in the other. Eg, A->B and new file B. Core git calls
48
+ * this a "rename/delete". */
49
+ GIT_MERGE_DIFF_RENAMED_ADDED = (1 << 6),
50
+
51
+ /* Occurs when both a file is renamed to the same name in the ours and
52
+ * theirs branches. Eg, A->B and A->B in both. Automergeable. */
53
+ GIT_MERGE_DIFF_BOTH_RENAMED = (1 << 7),
54
+
55
+ /* Occurs when a file is renamed to different names in the ours and theirs
56
+ * branches. Eg, A->B and A->C. */
57
+ GIT_MERGE_DIFF_BOTH_RENAMED_1_TO_2 = (1 << 8),
58
+
59
+ /* Occurs when two files are renamed to the same name in the ours and
60
+ * theirs branches. Eg, A->C and B->C. */
61
+ GIT_MERGE_DIFF_BOTH_RENAMED_2_TO_1 = (1 << 9),
62
+
63
+ /* Occurs when an item at a path in one branch is a directory, and an
64
+ * item at the same path in a different branch is a file. */
65
+ GIT_MERGE_DIFF_DIRECTORY_FILE = (1 << 10),
66
+
67
+ /* The child of a folder that is in a directory/file conflict. */
68
+ GIT_MERGE_DIFF_DF_CHILD = (1 << 11),
69
+ } git_merge_diff_type_t;
70
+
71
+
72
+ typedef struct {
73
+ git_repository *repo;
74
+ git_pool pool;
75
+
76
+ /* Vector of git_index_entry that represent the merged items that
77
+ * have been staged, either because only one side changed, or because
78
+ * the two changes were non-conflicting and mergeable. These items
79
+ * will be written as staged entries in the main index.
80
+ */
81
+ git_vector staged;
82
+
83
+ /* Vector of git_merge_diff entries that represent the conflicts that
84
+ * have not been automerged. These items will be written to high-stage
85
+ * entries in the main index.
86
+ */
87
+ git_vector conflicts;
88
+
89
+ /* Vector of git_merge_diff that have been automerged. These items
90
+ * will be written to the REUC when the index is produced.
91
+ */
92
+ git_vector resolved;
93
+ } git_merge_diff_list;
94
+
95
+ /**
96
+ * Description of changes to one file across three trees.
97
+ */
98
+ typedef struct {
99
+ git_merge_diff_type_t type;
100
+
101
+ git_index_entry ancestor_entry;
102
+
103
+ git_index_entry our_entry;
104
+ git_delta_t our_status;
105
+
106
+ git_index_entry their_entry;
107
+ git_delta_t their_status;
108
+ } git_merge_diff;
109
+
110
+ /** Internal structure for merge inputs */
111
+ struct git_merge_head {
112
+ char *ref_name;
113
+ char *remote_url;
114
+
115
+ git_oid oid;
116
+ git_commit *commit;
117
+ };
118
+
119
+ int git_merge__bases_many(
120
+ git_commit_list **out,
121
+ git_revwalk *walk,
122
+ git_commit_list_node *one,
123
+ git_vector *twos);
124
+
125
+ /*
126
+ * Three-way tree differencing
127
+ */
128
+
129
+ git_merge_diff_list *git_merge_diff_list__alloc(git_repository *repo);
130
+
131
+ int git_merge_diff_list__find_differences(git_merge_diff_list *merge_diff_list,
132
+ const git_tree *ancestor_tree,
133
+ const git_tree *ours_tree,
134
+ const git_tree *theirs_tree);
135
+
136
+ int git_merge_diff_list__find_renames(git_repository *repo, git_merge_diff_list *merge_diff_list, const git_merge_tree_opts *opts);
137
+
138
+ void git_merge_diff_list__free(git_merge_diff_list *diff_list);
139
+
140
+ /* Merge metadata setup */
19
141
 
20
- int git_merge__bases_many(git_commit_list **out, git_revwalk *walk, git_commit_list_node *one, git_vector *twos);
142
+ int git_merge__setup(
143
+ git_repository *repo,
144
+ const git_merge_head *our_head,
145
+ const git_merge_head *their_heads[],
146
+ size_t their_heads_len,
147
+ unsigned int flags);
21
148
 
22
149
  #endif
@@ -0,0 +1,174 @@
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 "common.h"
9
+ #include "repository.h"
10
+ #include "merge_file.h"
11
+
12
+ #include "git2/repository.h"
13
+ #include "git2/object.h"
14
+ #include "git2/index.h"
15
+
16
+ #include "xdiff/xdiff.h"
17
+
18
+ #define GIT_MERGE_FILE_SIDE_EXISTS(X) ((X)->mode != 0)
19
+
20
+ GIT_INLINE(const char *) merge_file_best_path(
21
+ const git_merge_file_input *ancestor,
22
+ const git_merge_file_input *ours,
23
+ const git_merge_file_input *theirs)
24
+ {
25
+ if (!GIT_MERGE_FILE_SIDE_EXISTS(ancestor)) {
26
+ if (strcmp(ours->path, theirs->path) == 0)
27
+ return ours->path;
28
+
29
+ return NULL;
30
+ }
31
+
32
+ if (strcmp(ancestor->path, ours->path) == 0)
33
+ return theirs->path;
34
+ else if(strcmp(ancestor->path, theirs->path) == 0)
35
+ return ours->path;
36
+
37
+ return NULL;
38
+ }
39
+
40
+ GIT_INLINE(int) merge_file_best_mode(
41
+ const git_merge_file_input *ancestor,
42
+ const git_merge_file_input *ours,
43
+ const git_merge_file_input *theirs)
44
+ {
45
+ /*
46
+ * If ancestor didn't exist and either ours or theirs is executable,
47
+ * assume executable. Otherwise, if any mode changed from the ancestor,
48
+ * use that one.
49
+ */
50
+ if (GIT_MERGE_FILE_SIDE_EXISTS(ancestor)) {
51
+ if (ours->mode == GIT_FILEMODE_BLOB_EXECUTABLE ||
52
+ theirs->mode == GIT_FILEMODE_BLOB_EXECUTABLE)
53
+ return GIT_FILEMODE_BLOB_EXECUTABLE;
54
+
55
+ return GIT_FILEMODE_BLOB;
56
+ }
57
+
58
+ if (ancestor->mode == ours->mode)
59
+ return theirs->mode;
60
+ else if(ancestor->mode == theirs->mode)
61
+ return ours->mode;
62
+
63
+ return 0;
64
+ }
65
+
66
+ int git_merge_file_input_from_index_entry(
67
+ git_merge_file_input *input,
68
+ git_repository *repo,
69
+ const git_index_entry *entry)
70
+ {
71
+ git_odb *odb = NULL;
72
+ int error = 0;
73
+
74
+ assert(input && repo && entry);
75
+
76
+ if (entry->mode == 0)
77
+ return 0;
78
+
79
+ if ((error = git_repository_odb(&odb, repo)) < 0 ||
80
+ (error = git_odb_read(&input->odb_object, odb, &entry->oid)) < 0)
81
+ goto done;
82
+
83
+ input->mode = entry->mode;
84
+ input->path = git__strdup(entry->path);
85
+ input->mmfile.size = git_odb_object_size(input->odb_object);
86
+ input->mmfile.ptr = (char *)git_odb_object_data(input->odb_object);
87
+
88
+ if (input->label == NULL)
89
+ input->label = entry->path;
90
+
91
+ done:
92
+ git_odb_free(odb);
93
+
94
+ return error;
95
+ }
96
+
97
+ int git_merge_file_input_from_diff_file(
98
+ git_merge_file_input *input,
99
+ git_repository *repo,
100
+ const git_diff_file *file)
101
+ {
102
+ git_odb *odb = NULL;
103
+ int error = 0;
104
+
105
+ assert(input && repo && file);
106
+
107
+ if (file->mode == 0)
108
+ return 0;
109
+
110
+ if ((error = git_repository_odb(&odb, repo)) < 0 ||
111
+ (error = git_odb_read(&input->odb_object, odb, &file->oid)) < 0)
112
+ goto done;
113
+
114
+ input->mode = file->mode;
115
+ input->path = git__strdup(file->path);
116
+ input->mmfile.size = git_odb_object_size(input->odb_object);
117
+ input->mmfile.ptr = (char *)git_odb_object_data(input->odb_object);
118
+
119
+ if (input->label == NULL)
120
+ input->label = file->path;
121
+
122
+ done:
123
+ git_odb_free(odb);
124
+
125
+ return error;
126
+ }
127
+
128
+ int git_merge_files(
129
+ git_merge_file_result *out,
130
+ git_merge_file_input *ancestor,
131
+ git_merge_file_input *ours,
132
+ git_merge_file_input *theirs,
133
+ git_merge_automerge_flags flags)
134
+ {
135
+ xmparam_t xmparam;
136
+ mmbuffer_t mmbuffer;
137
+ int xdl_result;
138
+ int error = 0;
139
+
140
+ assert(out && ancestor && ours && theirs);
141
+
142
+ memset(out, 0x0, sizeof(git_merge_file_result));
143
+
144
+ if (!GIT_MERGE_FILE_SIDE_EXISTS(ours) || !GIT_MERGE_FILE_SIDE_EXISTS(theirs))
145
+ return 0;
146
+
147
+ memset(&xmparam, 0x0, sizeof(xmparam_t));
148
+ xmparam.ancestor = ancestor->label;
149
+ xmparam.file1 = ours->label;
150
+ xmparam.file2 = theirs->label;
151
+
152
+ out->path = merge_file_best_path(ancestor, ours, theirs);
153
+ out->mode = merge_file_best_mode(ancestor, ours, theirs);
154
+
155
+ if (flags == GIT_MERGE_AUTOMERGE_FAVOR_OURS)
156
+ xmparam.favor = XDL_MERGE_FAVOR_OURS;
157
+
158
+ if (flags == GIT_MERGE_AUTOMERGE_FAVOR_THEIRS)
159
+ xmparam.favor = XDL_MERGE_FAVOR_THEIRS;
160
+
161
+ if ((xdl_result = xdl_merge(&ancestor->mmfile, &ours->mmfile,
162
+ &theirs->mmfile, &xmparam, &mmbuffer)) < 0) {
163
+ giterr_set(GITERR_MERGE, "Failed to merge files.");
164
+ error = -1;
165
+ goto done;
166
+ }
167
+
168
+ out->automergeable = (xdl_result == 0);
169
+ out->data = (unsigned char *)mmbuffer.ptr;
170
+ out->len = mmbuffer.size;
171
+
172
+ done:
173
+ return error;
174
+ }
@@ -0,0 +1,71 @@
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_filediff_h__
8
+ #define INCLUDE_filediff_h__
9
+
10
+ #include "xdiff/xdiff.h"
11
+
12
+ #include "git2/merge.h"
13
+
14
+ typedef struct {
15
+ const char *label;
16
+ char *path;
17
+ unsigned int mode;
18
+ mmfile_t mmfile;
19
+
20
+ git_odb_object *odb_object;
21
+ } git_merge_file_input;
22
+
23
+ #define GIT_MERGE_FILE_INPUT_INIT {0}
24
+
25
+ typedef struct {
26
+ bool automergeable;
27
+
28
+ const char *path;
29
+ int mode;
30
+
31
+ unsigned char *data;
32
+ size_t len;
33
+ } git_merge_file_result;
34
+
35
+ #define GIT_MERGE_FILE_RESULT_INIT {0}
36
+
37
+ int git_merge_file_input_from_index_entry(
38
+ git_merge_file_input *input,
39
+ git_repository *repo,
40
+ const git_index_entry *entry);
41
+
42
+ int git_merge_file_input_from_diff_file(
43
+ git_merge_file_input *input,
44
+ git_repository *repo,
45
+ const git_diff_file *file);
46
+
47
+ int git_merge_files(
48
+ git_merge_file_result *out,
49
+ git_merge_file_input *ancestor,
50
+ git_merge_file_input *ours,
51
+ git_merge_file_input *theirs,
52
+ git_merge_automerge_flags flags);
53
+
54
+ GIT_INLINE(void) git_merge_file_input_free(git_merge_file_input *input)
55
+ {
56
+ assert(input);
57
+ git__free(input->path);
58
+ git_odb_object_free(input->odb_object);
59
+ }
60
+
61
+ GIT_INLINE(void) git_merge_file_result_free(git_merge_file_result *filediff)
62
+ {
63
+ if (filediff == NULL)
64
+ return;
65
+
66
+ /* xdiff uses malloc() not git_malloc, so we use free(), not git_free() */
67
+ if (filediff->data != NULL)
68
+ free(filediff->data);
69
+ }
70
+
71
+ #endif
@@ -162,7 +162,7 @@ static git_mwindow *new_window(
162
162
  git_mwindow *w;
163
163
 
164
164
  w = git__malloc(sizeof(*w));
165
-
165
+
166
166
  if (w == NULL)
167
167
  return NULL;
168
168
 
@@ -13,6 +13,12 @@
13
13
  #include "iterator.h"
14
14
  #include "signature.h"
15
15
 
16
+ static int note_error_notfound(void)
17
+ {
18
+ giterr_set(GITERR_INVALID, "Note could not be found");
19
+ return GIT_ENOTFOUND;
20
+ }
21
+
16
22
  static int find_subtree_in_current_level(
17
23
  git_tree **out,
18
24
  git_repository *repo,
@@ -26,7 +32,7 @@ static int find_subtree_in_current_level(
26
32
  *out = NULL;
27
33
 
28
34
  if (parent == NULL)
29
- return GIT_ENOTFOUND;
35
+ return note_error_notfound();
30
36
 
31
37
  for (i = 0; i < git_tree_entrycount(parent); i++) {
32
38
  entry = git_tree_entry_byindex(parent, i);
@@ -44,7 +50,7 @@ static int find_subtree_in_current_level(
44
50
  return GIT_EEXISTS;
45
51
  }
46
52
 
47
- return GIT_ENOTFOUND;
53
+ return note_error_notfound();
48
54
  }
49
55
 
50
56
  static int find_subtree_r(git_tree **out, git_tree *root,
@@ -56,9 +62,8 @@ static int find_subtree_r(git_tree **out, git_tree *root,
56
62
  *out = NULL;
57
63
 
58
64
  error = find_subtree_in_current_level(&subtree, repo, root, target, *fanout);
59
- if (error == GIT_EEXISTS) {
65
+ if (error == GIT_EEXISTS)
60
66
  return git_tree_lookup(out, repo, git_tree_id(root));
61
- }
62
67
 
63
68
  if (error < 0)
64
69
  return error;
@@ -85,7 +90,8 @@ static int find_blob(git_oid *blob, git_tree *tree, const char *target)
85
90
  return 0;
86
91
  }
87
92
  }
88
- return GIT_ENOTFOUND;
93
+
94
+ return note_error_notfound();
89
95
  }
90
96
 
91
97
  static int tree_write(
@@ -316,8 +322,8 @@ static int note_new(git_note **out, git_oid *note_oid, git_blob *blob)
316
322
  return 0;
317
323
  }
318
324
 
319
- static int note_lookup(git_note **out, git_repository *repo,
320
- git_tree *tree, const char *target)
325
+ static int note_lookup(
326
+ git_note **out, git_repository *repo, git_tree *tree, const char *target)
321
327
  {
322
328
  int error, fanout = 0;
323
329
  git_oid oid;
@@ -382,6 +388,7 @@ static int note_get_default_ref(const char **out, git_repository *repo)
382
388
 
383
389
  ret = git_config_get_string(out, cfg, "core.notesRef");
384
390
  if (ret == GIT_ENOTFOUND) {
391
+ giterr_clear();
385
392
  *out = GIT_NOTES_DEFAULT_REF;
386
393
  return 0;
387
394
  }
@@ -432,12 +439,10 @@ int git_note_read(git_note **out, git_repository *repo,
432
439
  target = git_oid_allocfmt(oid);
433
440
  GITERR_CHECK_ALLOC(target);
434
441
 
435
- if ((error = retrieve_note_tree_and_commit(&tree, &commit, repo, &notes_ref)) < 0)
436
- goto cleanup;
437
-
438
- error = note_lookup(out, repo, tree, target);
442
+ if (!(error = retrieve_note_tree_and_commit(
443
+ &tree, &commit, repo, &notes_ref)))
444
+ error = note_lookup(out, repo, tree, target);
439
445
 
440
- cleanup:
441
446
  git__free(target);
442
447
  git_tree_free(tree);
443
448
  git_commit_free(commit);
@@ -489,13 +494,11 @@ int git_note_remove(git_repository *repo, const char *notes_ref,
489
494
  target = git_oid_allocfmt(oid);
490
495
  GITERR_CHECK_ALLOC(target);
491
496
 
492
- if ((error = retrieve_note_tree_and_commit(&tree, &commit, repo, &notes_ref)) < 0)
493
- goto cleanup;
497
+ if (!(error = retrieve_note_tree_and_commit(
498
+ &tree, &commit, repo, &notes_ref)))
499
+ error = note_remove(
500
+ repo, author, committer, notes_ref, tree, target, &commit);
494
501
 
495
- error = note_remove(repo, author, committer, notes_ref,
496
- tree, target, &commit);
497
-
498
- cleanup:
499
502
  git__free(target);
500
503
  git_commit_free(commit);
501
504
  git_tree_free(tree);
@@ -533,7 +536,7 @@ static int process_entry_path(
533
536
  const char* entry_path,
534
537
  git_oid *annotated_object_id)
535
538
  {
536
- int error = -1;
539
+ int error = 0;
537
540
  size_t i = 0, j = 0, len;
538
541
  git_buf buf = GIT_BUF_INIT;
539
542
 
@@ -576,30 +579,30 @@ cleanup:
576
579
  }
577
580
 
578
581
  int git_note_foreach(
579
- git_repository *repo,
580
- const char *notes_ref,
581
- git_note_foreach_cb note_cb,
582
- void *payload)
582
+ git_repository *repo,
583
+ const char *notes_ref,
584
+ git_note_foreach_cb note_cb,
585
+ void *payload)
583
586
  {
584
- int error;
585
- git_note_iterator *iter = NULL;
586
- git_oid note_id, annotated_id;
587
+ int error;
588
+ git_note_iterator *iter = NULL;
589
+ git_oid note_id, annotated_id;
587
590
 
588
- if ((error = git_note_iterator_new(&iter, repo, notes_ref)) < 0)
589
- return error;
591
+ if ((error = git_note_iterator_new(&iter, repo, notes_ref)) < 0)
592
+ return error;
590
593
 
591
- while (!(error = git_note_next(&note_id, &annotated_id, iter))) {
592
- if (note_cb(&note_id, &annotated_id, payload)) {
593
- error = GIT_EUSER;
594
- break;
595
- }
596
- }
594
+ while (!(error = git_note_next(&note_id, &annotated_id, iter))) {
595
+ if (note_cb(&note_id, &annotated_id, payload)) {
596
+ error = GIT_EUSER;
597
+ break;
598
+ }
599
+ }
597
600
 
598
- if (error == GIT_ITEROVER)
599
- error = 0;
601
+ if (error == GIT_ITEROVER)
602
+ error = 0;
600
603
 
601
- git_note_iterator_free(iter);
602
- return error;
604
+ git_note_iterator_free(iter);
605
+ return error;
603
606
  }
604
607
 
605
608
 
@@ -644,18 +647,12 @@ int git_note_next(
644
647
  const git_index_entry *item;
645
648
 
646
649
  if ((error = git_iterator_current(&item, it)) < 0)
647
- goto exit;
650
+ return error;
648
651
 
649
- if (item != NULL) {
650
- git_oid_cpy(note_id, &item->oid);
651
- error = process_entry_path(item->path, annotated_id);
652
+ git_oid_cpy(note_id, &item->oid);
652
653
 
653
- if (error >= 0)
654
- error = git_iterator_advance(NULL, it);
655
- } else {
656
- error = GIT_ITEROVER;
657
- }
654
+ if (!(error = process_entry_path(item->path, annotated_id)))
655
+ git_iterator_advance(NULL, it);
658
656
 
659
- exit:
660
657
  return error;
661
658
  }