rugged 0.24.6.1 → 0.25.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (213) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/ext/rugged/extconf.rb +9 -2
  4. data/ext/rugged/rugged.c +85 -21
  5. data/ext/rugged/rugged.h +7 -21
  6. data/ext/rugged/rugged_backend.c +3 -20
  7. data/ext/rugged/rugged_blame.c +7 -24
  8. data/ext/rugged/rugged_blob.c +136 -59
  9. data/ext/rugged/rugged_branch.c +3 -20
  10. data/ext/rugged/rugged_branch_collection.c +3 -20
  11. data/ext/rugged/rugged_commit.c +251 -101
  12. data/ext/rugged/rugged_config.c +3 -20
  13. data/ext/rugged/rugged_cred.c +3 -20
  14. data/ext/rugged/rugged_diff.c +3 -20
  15. data/ext/rugged/rugged_diff_delta.c +3 -20
  16. data/ext/rugged/rugged_diff_hunk.c +3 -20
  17. data/ext/rugged/rugged_diff_line.c +3 -20
  18. data/ext/rugged/rugged_index.c +46 -229
  19. data/ext/rugged/rugged_note.c +3 -20
  20. data/ext/rugged/rugged_object.c +3 -20
  21. data/ext/rugged/rugged_patch.c +192 -34
  22. data/ext/rugged/rugged_rebase.c +90 -48
  23. data/ext/rugged/rugged_reference.c +4 -21
  24. data/ext/rugged/rugged_reference_collection.c +3 -20
  25. data/ext/rugged/rugged_remote.c +70 -42
  26. data/ext/rugged/rugged_remote_collection.c +3 -20
  27. data/ext/rugged/rugged_repo.c +50 -59
  28. data/ext/rugged/rugged_revwalk.c +4 -21
  29. data/ext/rugged/rugged_settings.c +3 -20
  30. data/ext/rugged/rugged_signature.c +3 -20
  31. data/ext/rugged/rugged_submodule.c +4 -21
  32. data/ext/rugged/rugged_submodule_collection.c +3 -20
  33. data/ext/rugged/rugged_tag.c +3 -20
  34. data/ext/rugged/rugged_tag_collection.c +3 -20
  35. data/ext/rugged/rugged_tree.c +189 -184
  36. data/lib/rugged/attributes.rb +5 -0
  37. data/lib/rugged/blob.rb +5 -0
  38. data/lib/rugged/branch.rb +6 -1
  39. data/lib/rugged/commit.rb +5 -0
  40. data/lib/rugged/console.rb +5 -0
  41. data/lib/rugged/credentials.rb +5 -0
  42. data/lib/rugged/diff/delta.rb +5 -0
  43. data/lib/rugged/diff/hunk.rb +5 -0
  44. data/lib/rugged/diff/line.rb +5 -0
  45. data/lib/rugged/diff.rb +5 -0
  46. data/lib/rugged/index.rb +120 -0
  47. data/lib/rugged/object.rb +5 -0
  48. data/lib/rugged/patch.rb +5 -0
  49. data/lib/rugged/reference.rb +5 -0
  50. data/lib/rugged/remote.rb +5 -0
  51. data/lib/rugged/repository.rb +9 -4
  52. data/lib/rugged/submodule_collection.rb +5 -0
  53. data/lib/rugged/tag.rb +5 -0
  54. data/lib/rugged/tree.rb +156 -1
  55. data/lib/rugged/version.rb +6 -1
  56. data/lib/rugged/walker.rb +5 -0
  57. data/lib/rugged.rb +5 -0
  58. data/vendor/libgit2/CMakeLists.txt +12 -2
  59. data/vendor/libgit2/include/git2/blob.h +39 -28
  60. data/vendor/libgit2/include/git2/commit.h +76 -0
  61. data/vendor/libgit2/include/git2/common.h +21 -1
  62. data/vendor/libgit2/include/git2/describe.h +5 -2
  63. data/vendor/libgit2/include/git2/diff.h +62 -7
  64. data/vendor/libgit2/include/git2/errors.h +2 -1
  65. data/vendor/libgit2/include/git2/index.h +25 -0
  66. data/vendor/libgit2/include/git2/merge.h +10 -1
  67. data/vendor/libgit2/include/git2/odb.h +47 -1
  68. data/vendor/libgit2/include/git2/pack.h +4 -4
  69. data/vendor/libgit2/include/git2/patch.h +1 -1
  70. data/vendor/libgit2/include/git2/proxy.h +92 -0
  71. data/vendor/libgit2/include/git2/refs.h +11 -0
  72. data/vendor/libgit2/include/git2/remote.h +21 -8
  73. data/vendor/libgit2/include/git2/repository.h +20 -1
  74. data/vendor/libgit2/include/git2/revwalk.h +4 -6
  75. data/vendor/libgit2/include/git2/signature.h +13 -0
  76. data/vendor/libgit2/include/git2/submodule.h +11 -3
  77. data/vendor/libgit2/include/git2/sys/merge.h +177 -0
  78. data/vendor/libgit2/include/git2/sys/odb_backend.h +11 -0
  79. data/vendor/libgit2/include/git2/sys/remote.h +16 -0
  80. data/vendor/libgit2/include/git2/sys/stream.h +2 -1
  81. data/vendor/libgit2/include/git2/sys/time.h +31 -0
  82. data/vendor/libgit2/include/git2/sys/transport.h +3 -1
  83. data/vendor/libgit2/include/git2/tag.h +9 -0
  84. data/vendor/libgit2/include/git2/transaction.h +9 -0
  85. data/vendor/libgit2/include/git2/tree.h +55 -0
  86. data/vendor/libgit2/include/git2/version.h +4 -4
  87. data/vendor/libgit2/include/git2.h +1 -0
  88. data/vendor/libgit2/src/annotated_commit.c +99 -80
  89. data/vendor/libgit2/src/annotated_commit.h +5 -2
  90. data/vendor/libgit2/src/apply.c +377 -0
  91. data/vendor/libgit2/src/apply.h +21 -0
  92. data/vendor/libgit2/src/array.h +0 -1
  93. data/vendor/libgit2/src/blob.c +71 -39
  94. data/vendor/libgit2/src/branch.c +7 -5
  95. data/vendor/libgit2/src/buffer.c +252 -20
  96. data/vendor/libgit2/src/buffer.h +8 -0
  97. data/vendor/libgit2/src/checkout.c +69 -42
  98. data/vendor/libgit2/src/clone.c +0 -8
  99. data/vendor/libgit2/src/commit.c +193 -49
  100. data/vendor/libgit2/src/commit_list.c +8 -3
  101. data/vendor/libgit2/src/commit_list.h +1 -0
  102. data/vendor/libgit2/src/common.h +2 -1
  103. data/vendor/libgit2/src/config.c +3 -3
  104. data/vendor/libgit2/src/config_file.c +20 -10
  105. data/vendor/libgit2/src/crlf.c +1 -0
  106. data/vendor/libgit2/src/curl_stream.c +106 -6
  107. data/vendor/libgit2/src/delta.c +238 -62
  108. data/vendor/libgit2/src/delta.h +79 -58
  109. data/vendor/libgit2/src/describe.c +1 -1
  110. data/vendor/libgit2/src/diff.c +32 -1554
  111. data/vendor/libgit2/src/diff.h +14 -122
  112. data/vendor/libgit2/src/diff_driver.c +4 -6
  113. data/vendor/libgit2/src/diff_file.c +3 -0
  114. data/vendor/libgit2/src/diff_generate.c +1613 -0
  115. data/vendor/libgit2/src/diff_generate.h +123 -0
  116. data/vendor/libgit2/src/diff_parse.c +101 -0
  117. data/vendor/libgit2/src/diff_parse.h +18 -0
  118. data/vendor/libgit2/src/diff_print.c +263 -144
  119. data/vendor/libgit2/src/diff_stats.c +21 -12
  120. data/vendor/libgit2/src/diff_tform.c +1 -0
  121. data/vendor/libgit2/src/diff_tform.h +22 -0
  122. data/vendor/libgit2/src/diff_xdiff.c +9 -9
  123. data/vendor/libgit2/src/diff_xdiff.h +5 -5
  124. data/vendor/libgit2/src/fetchhead.c +8 -8
  125. data/vendor/libgit2/src/filebuf.c +6 -1
  126. data/vendor/libgit2/src/filebuf.h +1 -0
  127. data/vendor/libgit2/src/fileops.c +22 -1
  128. data/vendor/libgit2/src/fileops.h +8 -2
  129. data/vendor/libgit2/src/fnmatch.c +18 -5
  130. data/vendor/libgit2/src/global.c +21 -4
  131. data/vendor/libgit2/src/global.h +6 -0
  132. data/vendor/libgit2/src/graph.c +1 -1
  133. data/vendor/libgit2/src/index.c +159 -46
  134. data/vendor/libgit2/src/index.h +2 -0
  135. data/vendor/libgit2/src/iterator.c +1573 -1468
  136. data/vendor/libgit2/src/iterator.h +52 -69
  137. data/vendor/libgit2/src/merge.c +163 -64
  138. data/vendor/libgit2/src/merge.h +61 -2
  139. data/vendor/libgit2/src/merge_driver.c +397 -0
  140. data/vendor/libgit2/src/merge_driver.h +60 -0
  141. data/vendor/libgit2/src/merge_file.c +11 -49
  142. data/vendor/libgit2/src/netops.c +12 -10
  143. data/vendor/libgit2/src/object_api.c +19 -1
  144. data/vendor/libgit2/src/odb.c +228 -52
  145. data/vendor/libgit2/src/odb_loose.c +19 -1
  146. data/vendor/libgit2/src/odb_mempack.c +1 -1
  147. data/vendor/libgit2/src/odb_pack.c +27 -1
  148. data/vendor/libgit2/src/openssl_stream.c +4 -5
  149. data/vendor/libgit2/src/pack-objects.c +105 -76
  150. data/vendor/libgit2/src/pack-objects.h +13 -12
  151. data/vendor/libgit2/src/pack.c +16 -10
  152. data/vendor/libgit2/src/pack.h +2 -0
  153. data/vendor/libgit2/src/patch.c +216 -0
  154. data/vendor/libgit2/src/patch.h +66 -0
  155. data/vendor/libgit2/src/{diff_patch.c → patch_generate.c} +203 -376
  156. data/vendor/libgit2/src/patch_generate.h +68 -0
  157. data/vendor/libgit2/src/patch_parse.c +1159 -0
  158. data/vendor/libgit2/src/patch_parse.h +56 -0
  159. data/vendor/libgit2/src/path.c +38 -2
  160. data/vendor/libgit2/src/path.h +18 -0
  161. data/vendor/libgit2/src/pathspec.c +1 -1
  162. data/vendor/libgit2/src/pool.h +5 -0
  163. data/vendor/libgit2/src/pqueue.c +12 -5
  164. data/vendor/libgit2/src/pqueue.h +1 -0
  165. data/vendor/libgit2/src/proxy.c +32 -0
  166. data/vendor/libgit2/src/proxy.h +14 -0
  167. data/vendor/libgit2/src/push.c +1 -1
  168. data/vendor/libgit2/src/rebase.c +63 -36
  169. data/vendor/libgit2/src/refdb.c +4 -2
  170. data/vendor/libgit2/src/refdb_fs.c +82 -54
  171. data/vendor/libgit2/src/refs.c +13 -1
  172. data/vendor/libgit2/src/remote.c +20 -81
  173. data/vendor/libgit2/src/repository.c +212 -29
  174. data/vendor/libgit2/src/reset.c +1 -1
  175. data/vendor/libgit2/src/revparse.c +1 -1
  176. data/vendor/libgit2/src/revwalk.c +260 -184
  177. data/vendor/libgit2/src/settings.c +11 -3
  178. data/vendor/libgit2/src/signature.c +27 -2
  179. data/vendor/libgit2/src/sortedcache.c +14 -5
  180. data/vendor/libgit2/src/stash.c +1 -0
  181. data/vendor/libgit2/src/status.c +1 -0
  182. data/vendor/libgit2/src/stransport_stream.c +4 -2
  183. data/vendor/libgit2/src/stream.h +2 -2
  184. data/vendor/libgit2/src/submodule.c +16 -4
  185. data/vendor/libgit2/src/sysdir.c +1 -1
  186. data/vendor/libgit2/src/transport.c +3 -5
  187. data/vendor/libgit2/src/transports/http.c +38 -13
  188. data/vendor/libgit2/src/transports/local.c +4 -1
  189. data/vendor/libgit2/src/transports/smart.c +6 -0
  190. data/vendor/libgit2/src/transports/smart.h +1 -0
  191. data/vendor/libgit2/src/transports/smart_pkt.c +5 -13
  192. data/vendor/libgit2/src/transports/smart_protocol.c +22 -7
  193. data/vendor/libgit2/src/transports/winhttp.c +144 -11
  194. data/vendor/libgit2/src/tree.c +267 -2
  195. data/vendor/libgit2/src/unix/posix.h +10 -0
  196. data/vendor/libgit2/src/unix/pthread.h +2 -0
  197. data/vendor/libgit2/src/util.c +25 -2
  198. data/vendor/libgit2/src/util.h +10 -0
  199. data/vendor/libgit2/src/varint.c +44 -0
  200. data/vendor/libgit2/src/varint.h +15 -0
  201. data/vendor/libgit2/src/vector.c +58 -0
  202. data/vendor/libgit2/src/vector.h +8 -0
  203. data/vendor/libgit2/src/win32/posix.h +3 -0
  204. data/vendor/libgit2/src/win32/thread.c +18 -0
  205. data/vendor/libgit2/src/win32/thread.h +2 -0
  206. data/vendor/libgit2/src/win32/w32_util.h +1 -1
  207. data/vendor/libgit2/src/zstream.c +37 -8
  208. data/vendor/libgit2/src/zstream.h +8 -1
  209. metadata +100 -82
  210. data/vendor/libgit2/Makefile.embed +0 -60
  211. data/vendor/libgit2/src/delta-apply.c +0 -166
  212. data/vendor/libgit2/src/delta-apply.h +0 -62
  213. data/vendor/libgit2/src/diff_patch.h +0 -83
@@ -6,7 +6,8 @@
6
6
  */
7
7
  #include "common.h"
8
8
  #include "diff.h"
9
- #include "diff_patch.h"
9
+ #include "diff_file.h"
10
+ #include "patch_generate.h"
10
11
  #include "fileops.h"
11
12
  #include "zstream.h"
12
13
  #include "blob.h"
@@ -14,19 +15,19 @@
14
15
  #include "git2/sys/diff.h"
15
16
 
16
17
  typedef struct {
17
- git_diff *diff;
18
18
  git_diff_format_t format;
19
19
  git_diff_line_cb print_cb;
20
20
  void *payload;
21
+
21
22
  git_buf *buf;
22
- uint32_t flags;
23
- int oid_strlen;
24
23
  git_diff_line line;
25
- unsigned int
26
- content_loaded : 1,
27
- content_allocated : 1;
28
- git_diff_file_content *ofile;
29
- git_diff_file_content *nfile;
24
+
25
+ const char *old_prefix;
26
+ const char *new_prefix;
27
+ uint32_t flags;
28
+ int id_strlen;
29
+
30
+ int (*strcomp)(const char *, const char *);
30
31
  } diff_print_info;
31
32
 
32
33
  static int diff_print_info_init__common(
@@ -42,17 +43,15 @@ static int diff_print_info_init__common(
42
43
  pi->payload = payload;
43
44
  pi->buf = out;
44
45
 
45
- if (!pi->oid_strlen) {
46
+ if (!pi->id_strlen) {
46
47
  if (!repo)
47
- pi->oid_strlen = GIT_ABBREV_DEFAULT;
48
- else if (git_repository__cvar(&pi->oid_strlen, repo, GIT_CVAR_ABBREV) < 0)
48
+ pi->id_strlen = GIT_ABBREV_DEFAULT;
49
+ else if (git_repository__cvar(&pi->id_strlen, repo, GIT_CVAR_ABBREV) < 0)
49
50
  return -1;
50
51
  }
51
52
 
52
- pi->oid_strlen += 1; /* for NUL byte */
53
-
54
- if (pi->oid_strlen > GIT_OID_HEXSZ + 1)
55
- pi->oid_strlen = GIT_OID_HEXSZ + 1;
53
+ if (pi->id_strlen > GIT_OID_HEXSZ)
54
+ pi->id_strlen = GIT_OID_HEXSZ;
56
55
 
57
56
  memset(&pi->line, 0, sizeof(pi->line));
58
57
  pi->line.old_lineno = -1;
@@ -74,11 +73,13 @@ static int diff_print_info_init_fromdiff(
74
73
 
75
74
  memset(pi, 0, sizeof(diff_print_info));
76
75
 
77
- pi->diff = diff;
78
-
79
76
  if (diff) {
80
77
  pi->flags = diff->opts.flags;
81
- pi->oid_strlen = diff->opts.id_abbrev;
78
+ pi->id_strlen = diff->opts.id_abbrev;
79
+ pi->old_prefix = diff->opts.old_prefix;
80
+ pi->new_prefix = diff->opts.new_prefix;
81
+
82
+ pi->strcomp = diff->strcomp;
82
83
  }
83
84
 
84
85
  return diff_print_info_init__common(pi, out, repo, format, cb, payload);
@@ -92,24 +93,16 @@ static int diff_print_info_init_frompatch(
92
93
  git_diff_line_cb cb,
93
94
  void *payload)
94
95
  {
95
- git_repository *repo;
96
-
97
96
  assert(patch);
98
97
 
99
- repo = patch->diff ? patch->diff->repo : NULL;
100
-
101
98
  memset(pi, 0, sizeof(diff_print_info));
102
99
 
103
- pi->diff = patch->diff;
104
-
105
100
  pi->flags = patch->diff_opts.flags;
106
- pi->oid_strlen = patch->diff_opts.id_abbrev;
107
-
108
- pi->content_loaded = 1;
109
- pi->ofile = &patch->ofile;
110
- pi->nfile = &patch->nfile;
101
+ pi->id_strlen = patch->diff_opts.id_abbrev;
102
+ pi->old_prefix = patch->diff_opts.old_prefix;
103
+ pi->new_prefix = patch->diff_opts.new_prefix;
111
104
 
112
- return diff_print_info_init__common(pi, out, repo, format, cb, payload);
105
+ return diff_print_info_init__common(pi, out, patch->repo, format, cb, payload);
113
106
  }
114
107
 
115
108
  static char diff_pick_suffix(int mode)
@@ -173,8 +166,8 @@ static int diff_print_one_name_status(
173
166
  diff_print_info *pi = data;
174
167
  git_buf *out = pi->buf;
175
168
  char old_suffix, new_suffix, code = git_diff_status_char(delta->status);
176
- int (*strcomp)(const char *, const char *) =
177
- pi->diff ? pi->diff->strcomp : git__strcmp;
169
+ int(*strcomp)(const char *, const char *) = pi->strcomp ?
170
+ pi->strcomp : git__strcmp;
178
171
 
179
172
  GIT_UNUSED(progress);
180
173
 
@@ -213,6 +206,7 @@ static int diff_print_one_raw(
213
206
  {
214
207
  diff_print_info *pi = data;
215
208
  git_buf *out = pi->buf;
209
+ int id_abbrev;
216
210
  char code = git_diff_status_char(delta->status);
217
211
  char start_oid[GIT_OID_HEXSZ+1], end_oid[GIT_OID_HEXSZ+1];
218
212
 
@@ -223,11 +217,21 @@ static int diff_print_one_raw(
223
217
 
224
218
  git_buf_clear(out);
225
219
 
226
- git_oid_tostr(start_oid, pi->oid_strlen, &delta->old_file.id);
227
- git_oid_tostr(end_oid, pi->oid_strlen, &delta->new_file.id);
220
+ id_abbrev = delta->old_file.mode ? delta->old_file.id_abbrev :
221
+ delta->new_file.id_abbrev;
222
+
223
+ if (pi->id_strlen > id_abbrev) {
224
+ giterr_set(GITERR_PATCH,
225
+ "The patch input contains %d id characters (cannot print %d)",
226
+ id_abbrev, pi->id_strlen);
227
+ return -1;
228
+ }
229
+
230
+ git_oid_tostr(start_oid, pi->id_strlen + 1, &delta->old_file.id);
231
+ git_oid_tostr(end_oid, pi->id_strlen + 1, &delta->new_file.id);
228
232
 
229
233
  git_buf_printf(
230
- out, (pi->oid_strlen <= GIT_OID_HEXSZ) ?
234
+ out, (pi->id_strlen <= GIT_OID_HEXSZ) ?
231
235
  ":%06o %06o %s... %s... %c" : ":%06o %06o %s %s %c",
232
236
  delta->old_file.mode, delta->new_file.mode, start_oid, end_oid, code);
233
237
 
@@ -252,53 +256,140 @@ static int diff_print_one_raw(
252
256
  return pi->print_cb(delta, NULL, &pi->line, pi->payload);
253
257
  }
254
258
 
259
+ static int diff_print_modes(
260
+ git_buf *out, const git_diff_delta *delta)
261
+ {
262
+ git_buf_printf(out, "old mode %o\n", delta->old_file.mode);
263
+ git_buf_printf(out, "new mode %o\n", delta->new_file.mode);
264
+
265
+ return git_buf_oom(out) ? -1 : 0;
266
+ }
267
+
255
268
  static int diff_print_oid_range(
256
- git_buf *out, const git_diff_delta *delta, int oid_strlen)
269
+ git_buf *out, const git_diff_delta *delta, int id_strlen)
257
270
  {
258
271
  char start_oid[GIT_OID_HEXSZ+1], end_oid[GIT_OID_HEXSZ+1];
259
272
 
260
- git_oid_tostr(start_oid, oid_strlen, &delta->old_file.id);
261
- git_oid_tostr(end_oid, oid_strlen, &delta->new_file.id);
273
+ if (delta->old_file.mode &&
274
+ id_strlen > delta->old_file.id_abbrev) {
275
+ giterr_set(GITERR_PATCH,
276
+ "The patch input contains %d id characters (cannot print %d)",
277
+ delta->old_file.id_abbrev, id_strlen);
278
+ return -1;
279
+ }
280
+
281
+ if ((delta->new_file.mode &&
282
+ id_strlen > delta->new_file.id_abbrev)) {
283
+ giterr_set(GITERR_PATCH,
284
+ "The patch input contains %d id characters (cannot print %d)",
285
+ delta->new_file.id_abbrev, id_strlen);
286
+ return -1;
287
+ }
288
+
289
+ git_oid_tostr(start_oid, id_strlen + 1, &delta->old_file.id);
290
+ git_oid_tostr(end_oid, id_strlen + 1, &delta->new_file.id);
262
291
 
263
- /* TODO: Match git diff more closely */
264
292
  if (delta->old_file.mode == delta->new_file.mode) {
265
293
  git_buf_printf(out, "index %s..%s %o\n",
266
294
  start_oid, end_oid, delta->old_file.mode);
267
295
  } else {
268
- if (delta->old_file.mode == 0) {
296
+ if (delta->old_file.mode == 0)
269
297
  git_buf_printf(out, "new file mode %o\n", delta->new_file.mode);
270
- } else if (delta->new_file.mode == 0) {
298
+ else if (delta->new_file.mode == 0)
271
299
  git_buf_printf(out, "deleted file mode %o\n", delta->old_file.mode);
272
- } else {
273
- git_buf_printf(out, "old mode %o\n", delta->old_file.mode);
274
- git_buf_printf(out, "new mode %o\n", delta->new_file.mode);
275
- }
300
+ else
301
+ diff_print_modes(out, delta);
302
+
276
303
  git_buf_printf(out, "index %s..%s\n", start_oid, end_oid);
277
304
  }
278
305
 
279
306
  return git_buf_oom(out) ? -1 : 0;
280
307
  }
281
308
 
309
+ static int diff_delta_format_path(
310
+ git_buf *out, const char *prefix, const char *filename)
311
+ {
312
+ if (git_buf_joinpath(out, prefix, filename) < 0)
313
+ return -1;
314
+
315
+ return git_buf_quote(out);
316
+ }
317
+
282
318
  static int diff_delta_format_with_paths(
283
319
  git_buf *out,
284
320
  const git_diff_delta *delta,
285
- const char *oldpfx,
286
- const char *newpfx,
287
- const char *template)
321
+ const char *template,
322
+ const char *oldpath,
323
+ const char *newpath)
288
324
  {
289
- const char *oldpath = delta->old_file.path;
290
- const char *newpath = delta->new_file.path;
291
-
292
- if (git_oid_iszero(&delta->old_file.id)) {
293
- oldpfx = "";
325
+ if (git_oid_iszero(&delta->old_file.id))
294
326
  oldpath = "/dev/null";
295
- }
296
- if (git_oid_iszero(&delta->new_file.id)) {
297
- newpfx = "";
327
+
328
+ if (git_oid_iszero(&delta->new_file.id))
298
329
  newpath = "/dev/null";
330
+
331
+ return git_buf_printf(out, template, oldpath, newpath);
332
+ }
333
+
334
+ int diff_delta_format_similarity_header(
335
+ git_buf *out,
336
+ const git_diff_delta *delta)
337
+ {
338
+ git_buf old_path = GIT_BUF_INIT, new_path = GIT_BUF_INIT;
339
+ const char *type;
340
+ int error = 0;
341
+
342
+ if (delta->similarity > 100) {
343
+ giterr_set(GITERR_PATCH, "invalid similarity %d", delta->similarity);
344
+ error = -1;
345
+ goto done;
299
346
  }
300
347
 
301
- return git_buf_printf(out, template, oldpfx, oldpath, newpfx, newpath);
348
+ if (delta->status == GIT_DELTA_RENAMED)
349
+ type = "rename";
350
+ else if (delta->status == GIT_DELTA_COPIED)
351
+ type = "copy";
352
+ else
353
+ abort();
354
+
355
+ if ((error = git_buf_puts(&old_path, delta->old_file.path)) < 0 ||
356
+ (error = git_buf_puts(&new_path, delta->new_file.path)) < 0 ||
357
+ (error = git_buf_quote(&old_path)) < 0 ||
358
+ (error = git_buf_quote(&new_path)) < 0)
359
+ goto done;
360
+
361
+ git_buf_printf(out,
362
+ "similarity index %d%%\n"
363
+ "%s from %s\n"
364
+ "%s to %s\n",
365
+ delta->similarity,
366
+ type, old_path.ptr,
367
+ type, new_path.ptr);
368
+
369
+ if (git_buf_oom(out))
370
+ error = -1;
371
+
372
+ done:
373
+ git_buf_free(&old_path);
374
+ git_buf_free(&new_path);
375
+
376
+ return error;
377
+ }
378
+
379
+ static bool delta_is_unchanged(const git_diff_delta *delta)
380
+ {
381
+ if (git_oid_iszero(&delta->old_file.id) &&
382
+ git_oid_iszero(&delta->new_file.id))
383
+ return true;
384
+
385
+ if (delta->old_file.mode == GIT_FILEMODE_COMMIT ||
386
+ delta->new_file.mode == GIT_FILEMODE_COMMIT)
387
+ return false;
388
+
389
+ if (git_oid_equal(&delta->old_file.id, &delta->new_file.id))
390
+ return true;
391
+
392
+ return false;
302
393
  }
303
394
 
304
395
  int git_diff_delta__format_file_header(
@@ -306,27 +397,56 @@ int git_diff_delta__format_file_header(
306
397
  const git_diff_delta *delta,
307
398
  const char *oldpfx,
308
399
  const char *newpfx,
309
- int oid_strlen)
400
+ int id_strlen)
310
401
  {
402
+ git_buf old_path = GIT_BUF_INIT, new_path = GIT_BUF_INIT;
403
+ bool unchanged = delta_is_unchanged(delta);
404
+ int error = 0;
405
+
311
406
  if (!oldpfx)
312
407
  oldpfx = DIFF_OLD_PREFIX_DEFAULT;
313
408
  if (!newpfx)
314
409
  newpfx = DIFF_NEW_PREFIX_DEFAULT;
315
- if (!oid_strlen)
316
- oid_strlen = GIT_ABBREV_DEFAULT + 1;
410
+ if (!id_strlen)
411
+ id_strlen = GIT_ABBREV_DEFAULT;
412
+
413
+ if ((error = diff_delta_format_path(
414
+ &old_path, oldpfx, delta->old_file.path)) < 0 ||
415
+ (error = diff_delta_format_path(
416
+ &new_path, newpfx, delta->new_file.path)) < 0)
417
+ goto done;
317
418
 
318
419
  git_buf_clear(out);
319
420
 
320
- git_buf_printf(out, "diff --git %s%s %s%s\n",
321
- oldpfx, delta->old_file.path, newpfx, delta->new_file.path);
421
+ git_buf_printf(out, "diff --git %s %s\n",
422
+ old_path.ptr, new_path.ptr);
322
423
 
323
- GITERR_CHECK_ERROR(diff_print_oid_range(out, delta, oid_strlen));
424
+ if (delta->status == GIT_DELTA_RENAMED ||
425
+ (delta->status == GIT_DELTA_COPIED && unchanged)) {
426
+ if ((error = diff_delta_format_similarity_header(out, delta)) < 0)
427
+ goto done;
428
+ }
324
429
 
325
- if ((delta->flags & GIT_DIFF_FLAG_BINARY) == 0)
326
- diff_delta_format_with_paths(
327
- out, delta, oldpfx, newpfx, "--- %s%s\n+++ %s%s\n");
430
+ if (!unchanged) {
431
+ if ((error = diff_print_oid_range(out, delta, id_strlen)) < 0)
432
+ goto done;
328
433
 
329
- return git_buf_oom(out) ? -1 : 0;
434
+ if ((delta->flags & GIT_DIFF_FLAG_BINARY) == 0)
435
+ diff_delta_format_with_paths(out, delta,
436
+ "--- %s\n+++ %s\n", old_path.ptr, new_path.ptr);
437
+ }
438
+
439
+ if (unchanged && delta->old_file.mode != delta->new_file.mode)
440
+ diff_print_modes(out, delta);
441
+
442
+ if (git_buf_oom(out))
443
+ error = -1;
444
+
445
+ done:
446
+ git_buf_free(&old_path);
447
+ git_buf_free(&new_path);
448
+
449
+ return error;
330
450
  }
331
451
 
332
452
  static int format_binary(
@@ -367,37 +487,29 @@ static int format_binary(
367
487
  return 0;
368
488
  }
369
489
 
370
- static int diff_print_load_content(
371
- diff_print_info *pi,
372
- git_diff_delta *delta)
490
+ static int diff_print_patch_file_binary_noshow(
491
+ diff_print_info *pi, git_diff_delta *delta,
492
+ const char *old_pfx, const char *new_pfx)
373
493
  {
374
- git_diff_file_content *ofile, *nfile;
494
+ git_buf old_path = GIT_BUF_INIT, new_path = GIT_BUF_INIT;
375
495
  int error;
376
496
 
377
- assert(pi->diff);
378
-
379
- ofile = git__calloc(1, sizeof(git_diff_file_content));
380
- nfile = git__calloc(1, sizeof(git_diff_file_content));
381
-
382
- GITERR_CHECK_ALLOC(ofile);
383
- GITERR_CHECK_ALLOC(nfile);
497
+ if ((error = diff_delta_format_path(
498
+ &old_path, old_pfx, delta->old_file.path)) < 0 ||
499
+ (error = diff_delta_format_path(
500
+ &new_path, new_pfx, delta->new_file.path)) < 0)
501
+ goto done;
384
502
 
385
- if ((error = git_diff_file_content__init_from_diff(
386
- ofile, pi->diff, delta, true)) < 0 ||
387
- (error = git_diff_file_content__init_from_diff(
388
- nfile, pi->diff, delta, true)) < 0) {
389
-
390
- git__free(ofile);
391
- git__free(nfile);
392
- return error;
393
- }
503
+ pi->line.num_lines = 1;
504
+ error = diff_delta_format_with_paths(
505
+ pi->buf, delta, "Binary files %s and %s differ\n",
506
+ old_path.ptr, new_path.ptr);
394
507
 
395
- pi->content_loaded = 1;
396
- pi->content_allocated = 1;
397
- pi->ofile = ofile;
398
- pi->nfile = nfile;
508
+ done:
509
+ git_buf_free(&old_path);
510
+ git_buf_free(&new_path);
399
511
 
400
- return 0;
512
+ return error;
401
513
  }
402
514
 
403
515
  static int diff_print_patch_file_binary(
@@ -408,12 +520,12 @@ static int diff_print_patch_file_binary(
408
520
  size_t pre_binary_size;
409
521
  int error;
410
522
 
411
- if ((pi->flags & GIT_DIFF_SHOW_BINARY) == 0)
412
- goto noshow;
523
+ if (delta->status == GIT_DELTA_UNMODIFIED)
524
+ return 0;
413
525
 
414
- if (!pi->content_loaded &&
415
- (error = diff_print_load_content(pi, delta)) < 0)
416
- return error;
526
+ if ((pi->flags & GIT_DIFF_SHOW_BINARY) == 0 || !binary->contains_data)
527
+ return diff_print_patch_file_binary_noshow(
528
+ pi, delta, old_pfx, new_pfx);
417
529
 
418
530
  pre_binary_size = pi->buf->size;
419
531
  git_buf_printf(pi->buf, "GIT binary patch\n");
@@ -427,18 +539,14 @@ static int diff_print_patch_file_binary(
427
539
  if (error == GIT_EBUFS) {
428
540
  giterr_clear();
429
541
  git_buf_truncate(pi->buf, pre_binary_size);
430
- goto noshow;
542
+
543
+ return diff_print_patch_file_binary_noshow(
544
+ pi, delta, old_pfx, new_pfx);
431
545
  }
432
546
  }
433
547
 
434
548
  pi->line.num_lines++;
435
549
  return error;
436
-
437
- noshow:
438
- pi->line.num_lines = 1;
439
- return diff_delta_format_with_paths(
440
- pi->buf, delta, old_pfx, new_pfx,
441
- "Binary files %s%s and %s%s differ\n");
442
550
  }
443
551
 
444
552
  static int diff_print_patch_file(
@@ -447,15 +555,18 @@ static int diff_print_patch_file(
447
555
  int error;
448
556
  diff_print_info *pi = data;
449
557
  const char *oldpfx =
450
- pi->diff ? pi->diff->opts.old_prefix : DIFF_OLD_PREFIX_DEFAULT;
558
+ pi->old_prefix ? pi->old_prefix : DIFF_OLD_PREFIX_DEFAULT;
451
559
  const char *newpfx =
452
- pi->diff ? pi->diff->opts.new_prefix : DIFF_NEW_PREFIX_DEFAULT;
560
+ pi->new_prefix ? pi->new_prefix : DIFF_NEW_PREFIX_DEFAULT;
453
561
 
454
562
  bool binary = (delta->flags & GIT_DIFF_FLAG_BINARY) ||
455
563
  (pi->flags & GIT_DIFF_FORCE_BINARY);
456
564
  bool show_binary = !!(pi->flags & GIT_DIFF_SHOW_BINARY);
457
- int oid_strlen = binary && show_binary ?
458
- GIT_OID_HEXSZ + 1 : pi->oid_strlen;
565
+ int id_strlen = pi->id_strlen;
566
+
567
+ if (binary && show_binary)
568
+ id_strlen = delta->old_file.id_abbrev ? delta->old_file.id_abbrev :
569
+ delta->new_file.id_abbrev;
459
570
 
460
571
  GIT_UNUSED(progress);
461
572
 
@@ -468,7 +579,7 @@ static int diff_print_patch_file(
468
579
  return 0;
469
580
 
470
581
  if ((error = git_diff_delta__format_file_header(
471
- pi->buf, delta, oldpfx, newpfx, oid_strlen)) < 0)
582
+ pi->buf, delta, oldpfx, newpfx, id_strlen)) < 0)
472
583
  return error;
473
584
 
474
585
  pi->line.origin = GIT_DIFF_LINE_FILE_HDR;
@@ -485,9 +596,9 @@ static int diff_print_patch_binary(
485
596
  {
486
597
  diff_print_info *pi = data;
487
598
  const char *old_pfx =
488
- pi->diff ? pi->diff->opts.old_prefix : DIFF_OLD_PREFIX_DEFAULT;
599
+ pi->old_prefix ? pi->old_prefix : DIFF_OLD_PREFIX_DEFAULT;
489
600
  const char *new_pfx =
490
- pi->diff ? pi->diff->opts.new_prefix : DIFF_NEW_PREFIX_DEFAULT;
601
+ pi->new_prefix ? pi->new_prefix : DIFF_NEW_PREFIX_DEFAULT;
491
602
  int error;
492
603
 
493
604
  git_buf_clear(pi->buf);
@@ -582,43 +693,11 @@ int git_diff_print(
582
693
  giterr_set_after_callback_function(error, "git_diff_print");
583
694
  }
584
695
 
585
- git__free(pi.nfile);
586
- git__free(pi.ofile);
587
-
588
696
  git_buf_free(&buf);
589
697
 
590
698
  return error;
591
699
  }
592
700
 
593
- /* print a git_patch to an output callback */
594
- int git_patch_print(
595
- git_patch *patch,
596
- git_diff_line_cb print_cb,
597
- void *payload)
598
- {
599
- int error;
600
- git_buf temp = GIT_BUF_INIT;
601
- diff_print_info pi;
602
-
603
- assert(patch && print_cb);
604
-
605
- if (!(error = diff_print_info_init_frompatch(
606
- &pi, &temp, patch,
607
- GIT_DIFF_FORMAT_PATCH, print_cb, payload)))
608
- {
609
- error = git_patch__invoke_callbacks(
610
- patch, diff_print_patch_file, diff_print_patch_binary,
611
- diff_print_patch_hunk, diff_print_patch_line, &pi);
612
-
613
- if (error) /* make sure error message is set */
614
- giterr_set_after_callback_function(error, "git_patch_print");
615
- }
616
-
617
- git_buf_free(&temp);
618
-
619
- return error;
620
- }
621
-
622
701
  int git_diff_print_callback__to_buf(
623
702
  const git_diff_delta *delta,
624
703
  const git_diff_hunk *hunk,
@@ -659,6 +738,46 @@ int git_diff_print_callback__to_file_handle(
659
738
  return 0;
660
739
  }
661
740
 
741
+ /* print a git_diff to a git_buf */
742
+ int git_diff_to_buf(git_buf *out, git_diff *diff, git_diff_format_t format)
743
+ {
744
+ assert(out && diff);
745
+ git_buf_sanitize(out);
746
+ return git_diff_print(
747
+ diff, format, git_diff_print_callback__to_buf, out);
748
+ }
749
+
750
+ /* print a git_patch to an output callback */
751
+ int git_patch_print(
752
+ git_patch *patch,
753
+ git_diff_line_cb print_cb,
754
+ void *payload)
755
+ {
756
+ int error;
757
+ git_buf temp = GIT_BUF_INIT;
758
+ diff_print_info pi;
759
+
760
+ assert(patch && print_cb);
761
+
762
+ if (!(error = diff_print_info_init_frompatch(
763
+ &pi, &temp, patch,
764
+ GIT_DIFF_FORMAT_PATCH, print_cb, payload)))
765
+ {
766
+ error = git_patch__invoke_callbacks(
767
+ patch,
768
+ diff_print_patch_file, diff_print_patch_binary,
769
+ diff_print_patch_hunk, diff_print_patch_line,
770
+ &pi);
771
+
772
+ if (error) /* make sure error message is set */
773
+ giterr_set_after_callback_function(error, "git_patch_print");
774
+ }
775
+
776
+ git_buf_free(&temp);
777
+
778
+ return error;
779
+ }
780
+
662
781
  /* print a git_patch to a git_buf */
663
782
  int git_patch_to_buf(git_buf *out, git_patch *patch)
664
783
  {
@@ -7,7 +7,7 @@
7
7
  #include "common.h"
8
8
  #include "vector.h"
9
9
  #include "diff.h"
10
- #include "diff_patch.h"
10
+ #include "patch_generate.h"
11
11
 
12
12
  #define DIFF_RENAME_FILE_SEPARATOR " => "
13
13
  #define STATS_FULL_MIN_SCALE 7
@@ -190,8 +190,9 @@ int git_diff_get_stats(
190
190
  break;
191
191
 
192
192
  /* keep a count of renames because it will affect formatting */
193
- delta = git_patch_get_delta(patch);
193
+ delta = patch->delta;
194
194
 
195
+ /* TODO ugh */
195
196
  namelen = strlen(delta->new_file.path);
196
197
  if (strcmp(delta->old_file.path, delta->new_file.path) != 0) {
197
198
  namelen += strlen(delta->old_file.path);
@@ -299,15 +300,24 @@ int git_diff_stats_to_buf(
299
300
  }
300
301
 
301
302
  if (format & GIT_DIFF_STATS_FULL || format & GIT_DIFF_STATS_SHORT) {
302
- error = git_buf_printf(
303
- out, " %" PRIuZ " file%s changed, %" PRIuZ
304
- " insertion%s(+), %" PRIuZ " deletion%s(-)\n",
305
- stats->files_changed, stats->files_changed != 1 ? "s" : "",
306
- stats->insertions, stats->insertions != 1 ? "s" : "",
307
- stats->deletions, stats->deletions != 1 ? "s" : "");
308
-
309
- if (error < 0)
310
- return error;
303
+ git_buf_printf(
304
+ out, " %" PRIuZ " file%s changed",
305
+ stats->files_changed, stats->files_changed != 1 ? "s" : "");
306
+
307
+ if (stats->insertions || stats->deletions == 0)
308
+ git_buf_printf(
309
+ out, ", %" PRIuZ " insertion%s(+)",
310
+ stats->insertions, stats->insertions != 1 ? "s" : "");
311
+
312
+ if (stats->deletions || stats->insertions == 0)
313
+ git_buf_printf(
314
+ out, ", %" PRIuZ " deletion%s(-)",
315
+ stats->deletions, stats->deletions != 1 ? "s" : "");
316
+
317
+ git_buf_putc(out, '\n');
318
+
319
+ if (git_buf_oom(out))
320
+ return -1;
311
321
  }
312
322
 
313
323
  if (format & GIT_DIFF_STATS_INCLUDE_SUMMARY) {
@@ -333,4 +343,3 @@ void git_diff_stats_free(git_diff_stats *stats)
333
343
  git__free(stats->filestats);
334
344
  git__free(stats);
335
345
  }
336
-
@@ -11,6 +11,7 @@
11
11
  #include "git2/sys/hashsig.h"
12
12
 
13
13
  #include "diff.h"
14
+ #include "diff_generate.h"
14
15
  #include "path.h"
15
16
  #include "fileops.h"
16
17
  #include "config.h"
@@ -0,0 +1,22 @@
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_tform_h__
8
+ #define INCLUDE_diff_tform_h__
9
+
10
+ extern int git_diff_find_similar__hashsig_for_file(
11
+ void **out, const git_diff_file *f, const char *path, void *p);
12
+
13
+ extern int git_diff_find_similar__hashsig_for_buf(
14
+ void **out, const git_diff_file *f, const char *buf, size_t len, void *p);
15
+
16
+ extern void git_diff_find_similar__hashsig_free(void *sig, void *payload);
17
+
18
+ extern int git_diff_find_similar__calc_similarity(
19
+ int *score, void *siga, void *sigb, void *payload);
20
+
21
+ #endif
22
+