2 * Copyright (C) the libgit2 contributors. All rights reserved.
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.
12 #include "diff_file.h"
13 #include "patch_generate.h"
18 #include "git2/sys/diff.h"
21 git_diff_format_t format
;
22 git_diff_line_cb print_cb
;
28 const char *old_prefix
;
29 const char *new_prefix
;
33 int (*strcomp
)(const char *, const char *);
36 static int diff_print_info_init__common(
40 git_diff_format_t format
,
46 pi
->payload
= payload
;
51 pi
->id_strlen
= GIT_ABBREV_DEFAULT
;
52 else if (git_repository__configmap_lookup(&pi
->id_strlen
, repo
, GIT_CONFIGMAP_ABBREV
) < 0)
56 if (pi
->id_strlen
> GIT_OID_HEXSZ
)
57 pi
->id_strlen
= GIT_OID_HEXSZ
;
59 memset(&pi
->line
, 0, sizeof(pi
->line
));
60 pi
->line
.old_lineno
= -1;
61 pi
->line
.new_lineno
= -1;
62 pi
->line
.num_lines
= 1;
67 static int diff_print_info_init_fromdiff(
71 git_diff_format_t format
,
75 git_repository
*repo
= diff
? diff
->repo
: NULL
;
77 memset(pi
, 0, sizeof(diff_print_info
));
80 pi
->flags
= diff
->opts
.flags
;
81 pi
->id_strlen
= diff
->opts
.id_abbrev
;
82 pi
->old_prefix
= diff
->opts
.old_prefix
;
83 pi
->new_prefix
= diff
->opts
.new_prefix
;
85 pi
->strcomp
= diff
->strcomp
;
88 return diff_print_info_init__common(pi
, out
, repo
, format
, cb
, payload
);
91 static int diff_print_info_init_frompatch(
95 git_diff_format_t format
,
99 GIT_ASSERT_ARG(patch
);
101 memset(pi
, 0, sizeof(diff_print_info
));
103 pi
->flags
= patch
->diff_opts
.flags
;
104 pi
->id_strlen
= patch
->diff_opts
.id_abbrev
;
105 pi
->old_prefix
= patch
->diff_opts
.old_prefix
;
106 pi
->new_prefix
= patch
->diff_opts
.new_prefix
;
108 return diff_print_info_init__common(pi
, out
, patch
->repo
, format
, cb
, payload
);
111 static char diff_pick_suffix(int mode
)
115 else if (GIT_PERMS_IS_EXEC(mode
)) /* -V536 */
116 /* in git, modes are very regular, so we must have 0100755 mode */
122 char git_diff_status_char(git_delta_t status
)
127 case GIT_DELTA_ADDED
: code
= 'A'; break;
128 case GIT_DELTA_DELETED
: code
= 'D'; break;
129 case GIT_DELTA_MODIFIED
: code
= 'M'; break;
130 case GIT_DELTA_RENAMED
: code
= 'R'; break;
131 case GIT_DELTA_COPIED
: code
= 'C'; break;
132 case GIT_DELTA_IGNORED
: code
= 'I'; break;
133 case GIT_DELTA_UNTRACKED
: code
= '?'; break;
134 case GIT_DELTA_TYPECHANGE
: code
= 'T'; break;
135 case GIT_DELTA_UNREADABLE
: code
= 'X'; break;
136 default: code
= ' '; break;
142 static int diff_print_one_name_only(
143 const git_diff_delta
*delta
, float progress
, void *data
)
145 diff_print_info
*pi
= data
;
146 git_str
*out
= pi
->buf
;
148 GIT_UNUSED(progress
);
150 if ((pi
->flags
& GIT_DIFF_SHOW_UNMODIFIED
) == 0 &&
151 delta
->status
== GIT_DELTA_UNMODIFIED
)
155 git_str_puts(out
, delta
->new_file
.path
);
156 git_str_putc(out
, '\n');
157 if (git_str_oom(out
))
160 pi
->line
.origin
= GIT_DIFF_LINE_FILE_HDR
;
161 pi
->line
.content
= git_str_cstr(out
);
162 pi
->line
.content_len
= git_str_len(out
);
164 return pi
->print_cb(delta
, NULL
, &pi
->line
, pi
->payload
);
167 static int diff_print_one_name_status(
168 const git_diff_delta
*delta
, float progress
, void *data
)
170 diff_print_info
*pi
= data
;
171 git_str
*out
= pi
->buf
;
172 char old_suffix
, new_suffix
, code
= git_diff_status_char(delta
->status
);
173 int(*strcomp
)(const char *, const char *) = pi
->strcomp
?
174 pi
->strcomp
: git__strcmp
;
176 GIT_UNUSED(progress
);
178 if ((pi
->flags
& GIT_DIFF_SHOW_UNMODIFIED
) == 0 && code
== ' ')
181 old_suffix
= diff_pick_suffix(delta
->old_file
.mode
);
182 new_suffix
= diff_pick_suffix(delta
->new_file
.mode
);
186 if (delta
->old_file
.path
!= delta
->new_file
.path
&&
187 strcomp(delta
->old_file
.path
,delta
->new_file
.path
) != 0)
188 git_str_printf(out
, "%c\t%s%c %s%c\n", code
,
189 delta
->old_file
.path
, old_suffix
, delta
->new_file
.path
, new_suffix
);
190 else if (delta
->old_file
.mode
!= delta
->new_file
.mode
&&
191 delta
->old_file
.mode
!= 0 && delta
->new_file
.mode
!= 0)
192 git_str_printf(out
, "%c\t%s%c %s%c\n", code
,
193 delta
->old_file
.path
, old_suffix
, delta
->new_file
.path
, new_suffix
);
194 else if (old_suffix
!= ' ')
195 git_str_printf(out
, "%c\t%s%c\n", code
, delta
->old_file
.path
, old_suffix
);
197 git_str_printf(out
, "%c\t%s\n", code
, delta
->old_file
.path
);
198 if (git_str_oom(out
))
201 pi
->line
.origin
= GIT_DIFF_LINE_FILE_HDR
;
202 pi
->line
.content
= git_str_cstr(out
);
203 pi
->line
.content_len
= git_str_len(out
);
205 return pi
->print_cb(delta
, NULL
, &pi
->line
, pi
->payload
);
208 static int diff_print_one_raw(
209 const git_diff_delta
*delta
, float progress
, void *data
)
211 diff_print_info
*pi
= data
;
212 git_str
*out
= pi
->buf
;
214 char code
= git_diff_status_char(delta
->status
);
215 char start_oid
[GIT_OID_HEXSZ
+1], end_oid
[GIT_OID_HEXSZ
+1];
217 GIT_UNUSED(progress
);
219 if ((pi
->flags
& GIT_DIFF_SHOW_UNMODIFIED
) == 0 && code
== ' ')
224 id_abbrev
= delta
->old_file
.mode
? delta
->old_file
.id_abbrev
:
225 delta
->new_file
.id_abbrev
;
227 if (pi
->id_strlen
> id_abbrev
) {
228 git_error_set(GIT_ERROR_PATCH
,
229 "the patch input contains %d id characters (cannot print %d)",
230 id_abbrev
, pi
->id_strlen
);
234 git_oid_tostr(start_oid
, pi
->id_strlen
+ 1, &delta
->old_file
.id
);
235 git_oid_tostr(end_oid
, pi
->id_strlen
+ 1, &delta
->new_file
.id
);
238 out
, (pi
->id_strlen
<= GIT_OID_HEXSZ
) ?
239 ":%06o %06o %s... %s... %c" : ":%06o %06o %s %s %c",
240 delta
->old_file
.mode
, delta
->new_file
.mode
, start_oid
, end_oid
, code
);
242 if (delta
->similarity
> 0)
243 git_str_printf(out
, "%03u", delta
->similarity
);
245 if (delta
->old_file
.path
!= delta
->new_file
.path
)
247 out
, "\t%s %s\n", delta
->old_file
.path
, delta
->new_file
.path
);
250 out
, "\t%s\n", delta
->old_file
.path
?
251 delta
->old_file
.path
: delta
->new_file
.path
);
253 if (git_str_oom(out
))
256 pi
->line
.origin
= GIT_DIFF_LINE_FILE_HDR
;
257 pi
->line
.content
= git_str_cstr(out
);
258 pi
->line
.content_len
= git_str_len(out
);
260 return pi
->print_cb(delta
, NULL
, &pi
->line
, pi
->payload
);
263 static int diff_print_modes(
264 git_str
*out
, const git_diff_delta
*delta
)
266 git_str_printf(out
, "old mode %o\n", delta
->old_file
.mode
);
267 git_str_printf(out
, "new mode %o\n", delta
->new_file
.mode
);
269 return git_str_oom(out
) ? -1 : 0;
272 static int diff_print_oid_range(
273 git_str
*out
, const git_diff_delta
*delta
, int id_strlen
,
276 char start_oid
[GIT_OID_HEXSZ
+1], end_oid
[GIT_OID_HEXSZ
+1];
278 if (delta
->old_file
.mode
&&
279 id_strlen
> delta
->old_file
.id_abbrev
) {
280 git_error_set(GIT_ERROR_PATCH
,
281 "the patch input contains %d id characters (cannot print %d)",
282 delta
->old_file
.id_abbrev
, id_strlen
);
286 if ((delta
->new_file
.mode
&&
287 id_strlen
> delta
->new_file
.id_abbrev
)) {
288 git_error_set(GIT_ERROR_PATCH
,
289 "the patch input contains %d id characters (cannot print %d)",
290 delta
->new_file
.id_abbrev
, id_strlen
);
294 git_oid_tostr(start_oid
, id_strlen
+ 1, &delta
->old_file
.id
);
295 git_oid_tostr(end_oid
, id_strlen
+ 1, &delta
->new_file
.id
);
297 if (delta
->old_file
.mode
== delta
->new_file
.mode
) {
299 git_str_printf(out
, "index %s..%s %o\n",
300 start_oid
, end_oid
, delta
->old_file
.mode
);
302 if (delta
->old_file
.mode
== 0)
303 git_str_printf(out
, "new file mode %o\n", delta
->new_file
.mode
);
304 else if (delta
->new_file
.mode
== 0)
305 git_str_printf(out
, "deleted file mode %o\n", delta
->old_file
.mode
);
307 diff_print_modes(out
, delta
);
310 git_str_printf(out
, "index %s..%s\n", start_oid
, end_oid
);
313 return git_str_oom(out
) ? -1 : 0;
316 static int diff_delta_format_path(
317 git_str
*out
, const char *prefix
, const char *filename
)
320 /* don't prefix "/dev/null" */
321 return git_str_puts(out
, "/dev/null");
324 if (git_str_joinpath(out
, prefix
, filename
) < 0)
327 return git_str_quote(out
);
330 static int diff_delta_format_with_paths(
332 const git_diff_delta
*delta
,
333 const char *template,
337 if (git_oid_is_zero(&delta
->old_file
.id
))
338 oldpath
= "/dev/null";
340 if (git_oid_is_zero(&delta
->new_file
.id
))
341 newpath
= "/dev/null";
343 return git_str_printf(out
, template, oldpath
, newpath
);
346 static int diff_delta_format_similarity_header(
348 const git_diff_delta
*delta
)
350 git_str old_path
= GIT_STR_INIT
, new_path
= GIT_STR_INIT
;
354 if (delta
->similarity
> 100) {
355 git_error_set(GIT_ERROR_PATCH
, "invalid similarity %d", delta
->similarity
);
360 GIT_ASSERT(delta
->status
== GIT_DELTA_RENAMED
|| delta
->status
== GIT_DELTA_COPIED
);
361 if (delta
->status
== GIT_DELTA_RENAMED
)
366 if ((error
= git_str_puts(&old_path
, delta
->old_file
.path
)) < 0 ||
367 (error
= git_str_puts(&new_path
, delta
->new_file
.path
)) < 0 ||
368 (error
= git_str_quote(&old_path
)) < 0 ||
369 (error
= git_str_quote(&new_path
)) < 0)
373 "similarity index %d%%\n"
380 if (git_str_oom(out
))
384 git_str_dispose(&old_path
);
385 git_str_dispose(&new_path
);
390 static bool delta_is_unchanged(const git_diff_delta
*delta
)
392 if (git_oid_is_zero(&delta
->old_file
.id
) &&
393 git_oid_is_zero(&delta
->new_file
.id
))
396 if (delta
->old_file
.mode
== GIT_FILEMODE_COMMIT
||
397 delta
->new_file
.mode
== GIT_FILEMODE_COMMIT
)
400 if (git_oid_equal(&delta
->old_file
.id
, &delta
->new_file
.id
))
406 int git_diff_delta__format_file_header(
408 const git_diff_delta
*delta
,
414 git_str old_path
= GIT_STR_INIT
, new_path
= GIT_STR_INIT
;
415 bool unchanged
= delta_is_unchanged(delta
);
419 oldpfx
= DIFF_OLD_PREFIX_DEFAULT
;
421 newpfx
= DIFF_NEW_PREFIX_DEFAULT
;
423 id_strlen
= GIT_ABBREV_DEFAULT
;
425 if ((error
= diff_delta_format_path(
426 &old_path
, oldpfx
, delta
->old_file
.path
)) < 0 ||
427 (error
= diff_delta_format_path(
428 &new_path
, newpfx
, delta
->new_file
.path
)) < 0)
433 git_str_printf(out
, "diff --git %s %s\n",
434 old_path
.ptr
, new_path
.ptr
);
436 if (unchanged
&& delta
->old_file
.mode
!= delta
->new_file
.mode
)
437 diff_print_modes(out
, delta
);
439 if (delta
->status
== GIT_DELTA_RENAMED
||
440 (delta
->status
== GIT_DELTA_COPIED
&& unchanged
)) {
441 if ((error
= diff_delta_format_similarity_header(out
, delta
)) < 0)
446 if ((error
= diff_print_oid_range(out
, delta
,
447 id_strlen
, print_index
)) < 0)
450 if ((delta
->flags
& GIT_DIFF_FLAG_BINARY
) == 0)
451 diff_delta_format_with_paths(out
, delta
,
452 "--- %s\n+++ %s\n", old_path
.ptr
, new_path
.ptr
);
455 if (git_str_oom(out
))
459 git_str_dispose(&old_path
);
460 git_str_dispose(&new_path
);
465 static int format_binary(
467 git_diff_binary_t type
,
472 const char *typename
= type
== GIT_DIFF_BINARY_DELTA
?
474 const char *scan
, *end
;
476 git_str_printf(pi
->buf
, "%s %" PRIuZ
"\n", typename
, inflatedlen
);
477 pi
->line
.num_lines
++;
479 for (scan
= data
, end
= data
+ datalen
; scan
< end
; ) {
480 size_t chunk_len
= end
- scan
;
485 git_str_putc(pi
->buf
, (char)chunk_len
+ 'A' - 1);
487 git_str_putc(pi
->buf
, (char)chunk_len
- 26 + 'a' - 1);
489 git_str_encode_base85(pi
->buf
, scan
, chunk_len
);
490 git_str_putc(pi
->buf
, '\n');
492 if (git_str_oom(pi
->buf
))
496 pi
->line
.num_lines
++;
498 git_str_putc(pi
->buf
, '\n');
500 if (git_str_oom(pi
->buf
))
506 static int diff_print_patch_file_binary_noshow(
507 diff_print_info
*pi
, git_diff_delta
*delta
,
508 const char *old_pfx
, const char *new_pfx
)
510 git_str old_path
= GIT_STR_INIT
, new_path
= GIT_STR_INIT
;
513 if ((error
= diff_delta_format_path(&old_path
, old_pfx
, delta
->old_file
.path
)) < 0 ||
514 (error
= diff_delta_format_path(&new_path
, new_pfx
, delta
->new_file
.path
)) < 0 ||
515 (error
= diff_delta_format_with_paths(pi
->buf
, delta
, "Binary files %s and %s differ\n",
516 old_path
.ptr
, new_path
.ptr
)) < 0)
519 pi
->line
.num_lines
= 1;
522 git_str_dispose(&old_path
);
523 git_str_dispose(&new_path
);
527 static int diff_print_patch_file_binary(
528 diff_print_info
*pi
, git_diff_delta
*delta
,
529 const char *old_pfx
, const char *new_pfx
,
530 const git_diff_binary
*binary
)
532 size_t pre_binary_size
;
535 if (delta
->status
== GIT_DELTA_UNMODIFIED
)
538 if ((pi
->flags
& GIT_DIFF_SHOW_BINARY
) == 0 || !binary
->contains_data
)
539 return diff_print_patch_file_binary_noshow(
540 pi
, delta
, old_pfx
, new_pfx
);
542 pre_binary_size
= pi
->buf
->size
;
543 git_str_printf(pi
->buf
, "GIT binary patch\n");
544 pi
->line
.num_lines
++;
546 if ((error
= format_binary(pi
, binary
->new_file
.type
, binary
->new_file
.data
,
547 binary
->new_file
.datalen
, binary
->new_file
.inflatedlen
)) < 0 ||
548 (error
= format_binary(pi
, binary
->old_file
.type
, binary
->old_file
.data
,
549 binary
->old_file
.datalen
, binary
->old_file
.inflatedlen
)) < 0) {
550 if (error
== GIT_EBUFS
) {
552 git_str_truncate(pi
->buf
, pre_binary_size
);
554 return diff_print_patch_file_binary_noshow(
555 pi
, delta
, old_pfx
, new_pfx
);
559 pi
->line
.num_lines
++;
563 static int diff_print_patch_file(
564 const git_diff_delta
*delta
, float progress
, void *data
)
567 diff_print_info
*pi
= data
;
569 pi
->old_prefix
? pi
->old_prefix
: DIFF_OLD_PREFIX_DEFAULT
;
571 pi
->new_prefix
? pi
->new_prefix
: DIFF_NEW_PREFIX_DEFAULT
;
573 bool binary
= (delta
->flags
& GIT_DIFF_FLAG_BINARY
) ||
574 (pi
->flags
& GIT_DIFF_FORCE_BINARY
);
575 bool show_binary
= !!(pi
->flags
& GIT_DIFF_SHOW_BINARY
);
576 int id_strlen
= pi
->id_strlen
;
577 bool print_index
= (pi
->format
!= GIT_DIFF_FORMAT_PATCH_ID
);
579 if (binary
&& show_binary
)
580 id_strlen
= delta
->old_file
.id_abbrev
? delta
->old_file
.id_abbrev
:
581 delta
->new_file
.id_abbrev
;
583 GIT_UNUSED(progress
);
585 if (S_ISDIR(delta
->new_file
.mode
) ||
586 delta
->status
== GIT_DELTA_UNMODIFIED
||
587 delta
->status
== GIT_DELTA_IGNORED
||
588 delta
->status
== GIT_DELTA_UNREADABLE
||
589 (delta
->status
== GIT_DELTA_UNTRACKED
&&
590 (pi
->flags
& GIT_DIFF_SHOW_UNTRACKED_CONTENT
) == 0))
593 if ((error
= git_diff_delta__format_file_header(pi
->buf
, delta
, oldpfx
, newpfx
,
594 id_strlen
, print_index
)) < 0)
597 pi
->line
.origin
= GIT_DIFF_LINE_FILE_HDR
;
598 pi
->line
.content
= git_str_cstr(pi
->buf
);
599 pi
->line
.content_len
= git_str_len(pi
->buf
);
601 return pi
->print_cb(delta
, NULL
, &pi
->line
, pi
->payload
);
604 static int diff_print_patch_binary(
605 const git_diff_delta
*delta
,
606 const git_diff_binary
*binary
,
609 diff_print_info
*pi
= data
;
610 const char *old_pfx
=
611 pi
->old_prefix
? pi
->old_prefix
: DIFF_OLD_PREFIX_DEFAULT
;
612 const char *new_pfx
=
613 pi
->new_prefix
? pi
->new_prefix
: DIFF_NEW_PREFIX_DEFAULT
;
616 git_str_clear(pi
->buf
);
618 if ((error
= diff_print_patch_file_binary(
619 pi
, (git_diff_delta
*)delta
, old_pfx
, new_pfx
, binary
)) < 0)
622 pi
->line
.origin
= GIT_DIFF_LINE_BINARY
;
623 pi
->line
.content
= git_str_cstr(pi
->buf
);
624 pi
->line
.content_len
= git_str_len(pi
->buf
);
626 return pi
->print_cb(delta
, NULL
, &pi
->line
, pi
->payload
);
629 static int diff_print_patch_hunk(
630 const git_diff_delta
*d
,
631 const git_diff_hunk
*h
,
634 diff_print_info
*pi
= data
;
636 if (S_ISDIR(d
->new_file
.mode
))
639 pi
->line
.origin
= GIT_DIFF_LINE_HUNK_HDR
;
640 pi
->line
.content
= h
->header
;
641 pi
->line
.content_len
= h
->header_len
;
643 return pi
->print_cb(d
, h
, &pi
->line
, pi
->payload
);
646 static int diff_print_patch_line(
647 const git_diff_delta
*delta
,
648 const git_diff_hunk
*hunk
,
649 const git_diff_line
*line
,
652 diff_print_info
*pi
= data
;
654 if (S_ISDIR(delta
->new_file
.mode
))
657 return pi
->print_cb(delta
, hunk
, line
, pi
->payload
);
660 /* print a git_diff to an output callback */
663 git_diff_format_t format
,
664 git_diff_line_cb print_cb
,
668 git_str buf
= GIT_STR_INIT
;
670 git_diff_file_cb print_file
= NULL
;
671 git_diff_binary_cb print_binary
= NULL
;
672 git_diff_hunk_cb print_hunk
= NULL
;
673 git_diff_line_cb print_line
= NULL
;
676 case GIT_DIFF_FORMAT_PATCH
:
677 print_file
= diff_print_patch_file
;
678 print_binary
= diff_print_patch_binary
;
679 print_hunk
= diff_print_patch_hunk
;
680 print_line
= diff_print_patch_line
;
682 case GIT_DIFF_FORMAT_PATCH_ID
:
683 print_file
= diff_print_patch_file
;
684 print_binary
= diff_print_patch_binary
;
685 print_line
= diff_print_patch_line
;
687 case GIT_DIFF_FORMAT_PATCH_HEADER
:
688 print_file
= diff_print_patch_file
;
690 case GIT_DIFF_FORMAT_RAW
:
691 print_file
= diff_print_one_raw
;
693 case GIT_DIFF_FORMAT_NAME_ONLY
:
694 print_file
= diff_print_one_name_only
;
696 case GIT_DIFF_FORMAT_NAME_STATUS
:
697 print_file
= diff_print_one_name_status
;
700 git_error_set(GIT_ERROR_INVALID
, "unknown diff output format (%d)", format
);
704 if ((error
= diff_print_info_init_fromdiff(&pi
, &buf
, diff
, format
, print_cb
, payload
)) < 0)
707 if ((error
= git_diff_foreach(diff
, print_file
, print_binary
, print_hunk
, print_line
, &pi
)) != 0) {
708 git_error_set_after_callback_function(error
, "git_diff_print");
713 git_str_dispose(&buf
);
717 int git_diff_print_callback__to_buf(
718 const git_diff_delta
*delta
,
719 const git_diff_hunk
*hunk
,
720 const git_diff_line
*line
,
723 git_str
*output
= payload
;
724 GIT_UNUSED(delta
); GIT_UNUSED(hunk
);
727 git_error_set(GIT_ERROR_INVALID
, "buffer pointer must be provided");
731 if (line
->origin
== GIT_DIFF_LINE_ADDITION
||
732 line
->origin
== GIT_DIFF_LINE_DELETION
||
733 line
->origin
== GIT_DIFF_LINE_CONTEXT
)
734 git_str_putc(output
, line
->origin
);
736 return git_str_put(output
, line
->content
, line
->content_len
);
739 int git_diff_print_callback__to_file_handle(
740 const git_diff_delta
*delta
,
741 const git_diff_hunk
*hunk
,
742 const git_diff_line
*line
,
745 FILE *fp
= payload
? payload
: stdout
;
751 if (line
->origin
== GIT_DIFF_LINE_CONTEXT
||
752 line
->origin
== GIT_DIFF_LINE_ADDITION
||
753 line
->origin
== GIT_DIFF_LINE_DELETION
) {
754 while ((error
= fputc(line
->origin
, fp
)) == EINTR
)
757 git_error_set(GIT_ERROR_OS
, "could not write status");
762 if (fwrite(line
->content
, line
->content_len
, 1, fp
) != 1) {
763 git_error_set(GIT_ERROR_OS
, "could not write line");
770 /* print a git_diff to a git_str */
771 int git_diff_to_buf(git_buf
*out
, git_diff
*diff
, git_diff_format_t format
)
773 git_str str
= GIT_STR_INIT
;
777 GIT_ASSERT_ARG(diff
);
779 if ((error
= git_buf_tostr(&str
, out
)) < 0 ||
780 (error
= git_diff_print(diff
, format
, git_diff_print_callback__to_buf
, &str
)) < 0)
783 error
= git_buf_fromstr(out
, &str
);
786 git_str_dispose(&str
);
790 /* print a git_patch to an output callback */
793 git_diff_line_cb print_cb
,
796 git_str temp
= GIT_STR_INIT
;
800 GIT_ASSERT_ARG(patch
);
801 GIT_ASSERT_ARG(print_cb
);
803 if ((error
= diff_print_info_init_frompatch(&pi
, &temp
, patch
,
804 GIT_DIFF_FORMAT_PATCH
, print_cb
, payload
)) < 0)
807 if ((error
= git_patch__invoke_callbacks(patch
, diff_print_patch_file
, diff_print_patch_binary
,
808 diff_print_patch_hunk
, diff_print_patch_line
, &pi
)) < 0) {
809 git_error_set_after_callback_function(error
, "git_patch_print");
814 git_str_dispose(&temp
);
818 /* print a git_patch to a git_str */
819 int git_patch_to_buf(git_buf
*out
, git_patch
*patch
)
821 GIT_BUF_WRAP_PRIVATE(out
, git_patch__to_buf
, patch
);
824 int git_patch__to_buf(git_str
*out
, git_patch
*patch
)
827 GIT_ASSERT_ARG(patch
);
829 return git_patch_print(patch
, git_diff_print_callback__to_buf
, out
);