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.
11 #include "diff_file.h"
12 #include "patch_generate.h"
17 #include "git2/sys/diff.h"
20 git_diff_format_t format
;
21 git_diff_line_cb print_cb
;
27 const char *old_prefix
;
28 const char *new_prefix
;
32 int (*strcomp
)(const char *, const char *);
35 static int diff_print_info_init__common(
39 git_diff_format_t format
,
45 pi
->payload
= payload
;
50 pi
->id_strlen
= GIT_ABBREV_DEFAULT
;
51 else if (git_repository__configmap_lookup(&pi
->id_strlen
, repo
, GIT_CONFIGMAP_ABBREV
) < 0)
55 if (pi
->id_strlen
> GIT_OID_HEXSZ
)
56 pi
->id_strlen
= GIT_OID_HEXSZ
;
58 memset(&pi
->line
, 0, sizeof(pi
->line
));
59 pi
->line
.old_lineno
= -1;
60 pi
->line
.new_lineno
= -1;
61 pi
->line
.num_lines
= 1;
66 static int diff_print_info_init_fromdiff(
70 git_diff_format_t format
,
74 git_repository
*repo
= diff
? diff
->repo
: NULL
;
76 memset(pi
, 0, sizeof(diff_print_info
));
79 pi
->flags
= diff
->opts
.flags
;
80 pi
->id_strlen
= diff
->opts
.id_abbrev
;
81 pi
->old_prefix
= diff
->opts
.old_prefix
;
82 pi
->new_prefix
= diff
->opts
.new_prefix
;
84 pi
->strcomp
= diff
->strcomp
;
87 return diff_print_info_init__common(pi
, out
, repo
, format
, cb
, payload
);
90 static int diff_print_info_init_frompatch(
94 git_diff_format_t format
,
98 GIT_ASSERT_ARG(patch
);
100 memset(pi
, 0, sizeof(diff_print_info
));
102 pi
->flags
= patch
->diff_opts
.flags
;
103 pi
->id_strlen
= patch
->diff_opts
.id_abbrev
;
104 pi
->old_prefix
= patch
->diff_opts
.old_prefix
;
105 pi
->new_prefix
= patch
->diff_opts
.new_prefix
;
107 return diff_print_info_init__common(pi
, out
, patch
->repo
, format
, cb
, payload
);
110 static char diff_pick_suffix(int mode
)
114 else if (GIT_PERMS_IS_EXEC(mode
)) /* -V536 */
115 /* in git, modes are very regular, so we must have 0100755 mode */
121 char git_diff_status_char(git_delta_t status
)
126 case GIT_DELTA_ADDED
: code
= 'A'; break;
127 case GIT_DELTA_DELETED
: code
= 'D'; break;
128 case GIT_DELTA_MODIFIED
: code
= 'M'; break;
129 case GIT_DELTA_RENAMED
: code
= 'R'; break;
130 case GIT_DELTA_COPIED
: code
= 'C'; break;
131 case GIT_DELTA_IGNORED
: code
= 'I'; break;
132 case GIT_DELTA_UNTRACKED
: code
= '?'; break;
133 case GIT_DELTA_TYPECHANGE
: code
= 'T'; break;
134 case GIT_DELTA_UNREADABLE
: code
= 'X'; break;
135 default: code
= ' '; break;
141 static int diff_print_one_name_only(
142 const git_diff_delta
*delta
, float progress
, void *data
)
144 diff_print_info
*pi
= data
;
145 git_buf
*out
= pi
->buf
;
147 GIT_UNUSED(progress
);
149 if ((pi
->flags
& GIT_DIFF_SHOW_UNMODIFIED
) == 0 &&
150 delta
->status
== GIT_DELTA_UNMODIFIED
)
154 git_buf_puts(out
, delta
->new_file
.path
);
155 git_buf_putc(out
, '\n');
156 if (git_buf_oom(out
))
159 pi
->line
.origin
= GIT_DIFF_LINE_FILE_HDR
;
160 pi
->line
.content
= git_buf_cstr(out
);
161 pi
->line
.content_len
= git_buf_len(out
);
163 return pi
->print_cb(delta
, NULL
, &pi
->line
, pi
->payload
);
166 static int diff_print_one_name_status(
167 const git_diff_delta
*delta
, float progress
, void *data
)
169 diff_print_info
*pi
= data
;
170 git_buf
*out
= pi
->buf
;
171 char old_suffix
, new_suffix
, code
= git_diff_status_char(delta
->status
);
172 int(*strcomp
)(const char *, const char *) = pi
->strcomp
?
173 pi
->strcomp
: git__strcmp
;
175 GIT_UNUSED(progress
);
177 if ((pi
->flags
& GIT_DIFF_SHOW_UNMODIFIED
) == 0 && code
== ' ')
180 old_suffix
= diff_pick_suffix(delta
->old_file
.mode
);
181 new_suffix
= diff_pick_suffix(delta
->new_file
.mode
);
185 if (delta
->old_file
.path
!= delta
->new_file
.path
&&
186 strcomp(delta
->old_file
.path
,delta
->new_file
.path
) != 0)
187 git_buf_printf(out
, "%c\t%s%c %s%c\n", code
,
188 delta
->old_file
.path
, old_suffix
, delta
->new_file
.path
, new_suffix
);
189 else if (delta
->old_file
.mode
!= delta
->new_file
.mode
&&
190 delta
->old_file
.mode
!= 0 && delta
->new_file
.mode
!= 0)
191 git_buf_printf(out
, "%c\t%s%c %s%c\n", code
,
192 delta
->old_file
.path
, old_suffix
, delta
->new_file
.path
, new_suffix
);
193 else if (old_suffix
!= ' ')
194 git_buf_printf(out
, "%c\t%s%c\n", code
, delta
->old_file
.path
, old_suffix
);
196 git_buf_printf(out
, "%c\t%s\n", code
, delta
->old_file
.path
);
197 if (git_buf_oom(out
))
200 pi
->line
.origin
= GIT_DIFF_LINE_FILE_HDR
;
201 pi
->line
.content
= git_buf_cstr(out
);
202 pi
->line
.content_len
= git_buf_len(out
);
204 return pi
->print_cb(delta
, NULL
, &pi
->line
, pi
->payload
);
207 static int diff_print_one_raw(
208 const git_diff_delta
*delta
, float progress
, void *data
)
210 diff_print_info
*pi
= data
;
211 git_buf
*out
= pi
->buf
;
213 char code
= git_diff_status_char(delta
->status
);
214 char start_oid
[GIT_OID_HEXSZ
+1], end_oid
[GIT_OID_HEXSZ
+1];
216 GIT_UNUSED(progress
);
218 if ((pi
->flags
& GIT_DIFF_SHOW_UNMODIFIED
) == 0 && code
== ' ')
223 id_abbrev
= delta
->old_file
.mode
? delta
->old_file
.id_abbrev
:
224 delta
->new_file
.id_abbrev
;
226 if (pi
->id_strlen
> id_abbrev
) {
227 git_error_set(GIT_ERROR_PATCH
,
228 "the patch input contains %d id characters (cannot print %d)",
229 id_abbrev
, pi
->id_strlen
);
233 git_oid_tostr(start_oid
, pi
->id_strlen
+ 1, &delta
->old_file
.id
);
234 git_oid_tostr(end_oid
, pi
->id_strlen
+ 1, &delta
->new_file
.id
);
237 out
, (pi
->id_strlen
<= GIT_OID_HEXSZ
) ?
238 ":%06o %06o %s... %s... %c" : ":%06o %06o %s %s %c",
239 delta
->old_file
.mode
, delta
->new_file
.mode
, start_oid
, end_oid
, code
);
241 if (delta
->similarity
> 0)
242 git_buf_printf(out
, "%03u", delta
->similarity
);
244 if (delta
->old_file
.path
!= delta
->new_file
.path
)
246 out
, "\t%s %s\n", delta
->old_file
.path
, delta
->new_file
.path
);
249 out
, "\t%s\n", delta
->old_file
.path
?
250 delta
->old_file
.path
: delta
->new_file
.path
);
252 if (git_buf_oom(out
))
255 pi
->line
.origin
= GIT_DIFF_LINE_FILE_HDR
;
256 pi
->line
.content
= git_buf_cstr(out
);
257 pi
->line
.content_len
= git_buf_len(out
);
259 return pi
->print_cb(delta
, NULL
, &pi
->line
, pi
->payload
);
262 static int diff_print_modes(
263 git_buf
*out
, const git_diff_delta
*delta
)
265 git_buf_printf(out
, "old mode %o\n", delta
->old_file
.mode
);
266 git_buf_printf(out
, "new mode %o\n", delta
->new_file
.mode
);
268 return git_buf_oom(out
) ? -1 : 0;
271 static int diff_print_oid_range(
272 git_buf
*out
, const git_diff_delta
*delta
, int id_strlen
,
275 char start_oid
[GIT_OID_HEXSZ
+1], end_oid
[GIT_OID_HEXSZ
+1];
277 if (delta
->old_file
.mode
&&
278 id_strlen
> delta
->old_file
.id_abbrev
) {
279 git_error_set(GIT_ERROR_PATCH
,
280 "the patch input contains %d id characters (cannot print %d)",
281 delta
->old_file
.id_abbrev
, id_strlen
);
285 if ((delta
->new_file
.mode
&&
286 id_strlen
> delta
->new_file
.id_abbrev
)) {
287 git_error_set(GIT_ERROR_PATCH
,
288 "the patch input contains %d id characters (cannot print %d)",
289 delta
->new_file
.id_abbrev
, id_strlen
);
293 git_oid_tostr(start_oid
, id_strlen
+ 1, &delta
->old_file
.id
);
294 git_oid_tostr(end_oid
, id_strlen
+ 1, &delta
->new_file
.id
);
296 if (delta
->old_file
.mode
== delta
->new_file
.mode
) {
298 git_buf_printf(out
, "index %s..%s %o\n",
299 start_oid
, end_oid
, delta
->old_file
.mode
);
301 if (delta
->old_file
.mode
== 0)
302 git_buf_printf(out
, "new file mode %o\n", delta
->new_file
.mode
);
303 else if (delta
->new_file
.mode
== 0)
304 git_buf_printf(out
, "deleted file mode %o\n", delta
->old_file
.mode
);
306 diff_print_modes(out
, delta
);
309 git_buf_printf(out
, "index %s..%s\n", start_oid
, end_oid
);
312 return git_buf_oom(out
) ? -1 : 0;
315 static int diff_delta_format_path(
316 git_buf
*out
, const char *prefix
, const char *filename
)
318 if (git_buf_joinpath(out
, prefix
, filename
) < 0)
321 return git_buf_quote(out
);
324 static int diff_delta_format_with_paths(
326 const git_diff_delta
*delta
,
327 const char *template,
331 if (git_oid_is_zero(&delta
->old_file
.id
))
332 oldpath
= "/dev/null";
334 if (git_oid_is_zero(&delta
->new_file
.id
))
335 newpath
= "/dev/null";
337 return git_buf_printf(out
, template, oldpath
, newpath
);
340 static int diff_delta_format_similarity_header(
342 const git_diff_delta
*delta
)
344 git_buf old_path
= GIT_BUF_INIT
, new_path
= GIT_BUF_INIT
;
348 if (delta
->similarity
> 100) {
349 git_error_set(GIT_ERROR_PATCH
, "invalid similarity %d", delta
->similarity
);
354 GIT_ASSERT(delta
->status
== GIT_DELTA_RENAMED
|| delta
->status
== GIT_DELTA_COPIED
);
355 if (delta
->status
== GIT_DELTA_RENAMED
)
360 if ((error
= git_buf_puts(&old_path
, delta
->old_file
.path
)) < 0 ||
361 (error
= git_buf_puts(&new_path
, delta
->new_file
.path
)) < 0 ||
362 (error
= git_buf_quote(&old_path
)) < 0 ||
363 (error
= git_buf_quote(&new_path
)) < 0)
367 "similarity index %d%%\n"
374 if (git_buf_oom(out
))
378 git_buf_dispose(&old_path
);
379 git_buf_dispose(&new_path
);
384 static bool delta_is_unchanged(const git_diff_delta
*delta
)
386 if (git_oid_is_zero(&delta
->old_file
.id
) &&
387 git_oid_is_zero(&delta
->new_file
.id
))
390 if (delta
->old_file
.mode
== GIT_FILEMODE_COMMIT
||
391 delta
->new_file
.mode
== GIT_FILEMODE_COMMIT
)
394 if (git_oid_equal(&delta
->old_file
.id
, &delta
->new_file
.id
))
400 int git_diff_delta__format_file_header(
402 const git_diff_delta
*delta
,
408 git_buf old_path
= GIT_BUF_INIT
, new_path
= GIT_BUF_INIT
;
409 bool unchanged
= delta_is_unchanged(delta
);
413 oldpfx
= DIFF_OLD_PREFIX_DEFAULT
;
415 newpfx
= DIFF_NEW_PREFIX_DEFAULT
;
417 id_strlen
= GIT_ABBREV_DEFAULT
;
419 if ((error
= diff_delta_format_path(
420 &old_path
, oldpfx
, delta
->old_file
.path
)) < 0 ||
421 (error
= diff_delta_format_path(
422 &new_path
, newpfx
, delta
->new_file
.path
)) < 0)
427 git_buf_printf(out
, "diff --git %s %s\n",
428 old_path
.ptr
, new_path
.ptr
);
430 if (unchanged
&& delta
->old_file
.mode
!= delta
->new_file
.mode
)
431 diff_print_modes(out
, delta
);
433 if (delta
->status
== GIT_DELTA_RENAMED
||
434 (delta
->status
== GIT_DELTA_COPIED
&& unchanged
)) {
435 if ((error
= diff_delta_format_similarity_header(out
, delta
)) < 0)
440 if ((error
= diff_print_oid_range(out
, delta
,
441 id_strlen
, print_index
)) < 0)
444 if ((delta
->flags
& GIT_DIFF_FLAG_BINARY
) == 0)
445 diff_delta_format_with_paths(out
, delta
,
446 "--- %s\n+++ %s\n", old_path
.ptr
, new_path
.ptr
);
449 if (git_buf_oom(out
))
453 git_buf_dispose(&old_path
);
454 git_buf_dispose(&new_path
);
459 static int format_binary(
461 git_diff_binary_t type
,
466 const char *typename
= type
== GIT_DIFF_BINARY_DELTA
?
468 const char *scan
, *end
;
470 git_buf_printf(pi
->buf
, "%s %" PRIuZ
"\n", typename
, inflatedlen
);
471 pi
->line
.num_lines
++;
473 for (scan
= data
, end
= data
+ datalen
; scan
< end
; ) {
474 size_t chunk_len
= end
- scan
;
479 git_buf_putc(pi
->buf
, (char)chunk_len
+ 'A' - 1);
481 git_buf_putc(pi
->buf
, (char)chunk_len
- 26 + 'a' - 1);
483 git_buf_encode_base85(pi
->buf
, scan
, chunk_len
);
484 git_buf_putc(pi
->buf
, '\n');
486 if (git_buf_oom(pi
->buf
))
490 pi
->line
.num_lines
++;
492 git_buf_putc(pi
->buf
, '\n');
494 if (git_buf_oom(pi
->buf
))
500 static int diff_print_patch_file_binary_noshow(
501 diff_print_info
*pi
, git_diff_delta
*delta
,
502 const char *old_pfx
, const char *new_pfx
)
504 git_buf old_path
= GIT_BUF_INIT
, new_path
= GIT_BUF_INIT
;
507 if ((error
= diff_delta_format_path(&old_path
, old_pfx
, delta
->old_file
.path
)) < 0 ||
508 (error
= diff_delta_format_path(&new_path
, new_pfx
, delta
->new_file
.path
)) < 0 ||
509 (error
= diff_delta_format_with_paths(pi
->buf
, delta
, "Binary files %s and %s differ\n",
510 old_path
.ptr
, new_path
.ptr
)) < 0)
513 pi
->line
.num_lines
= 1;
516 git_buf_dispose(&old_path
);
517 git_buf_dispose(&new_path
);
521 static int diff_print_patch_file_binary(
522 diff_print_info
*pi
, git_diff_delta
*delta
,
523 const char *old_pfx
, const char *new_pfx
,
524 const git_diff_binary
*binary
)
526 size_t pre_binary_size
;
529 if (delta
->status
== GIT_DELTA_UNMODIFIED
)
532 if ((pi
->flags
& GIT_DIFF_SHOW_BINARY
) == 0 || !binary
->contains_data
)
533 return diff_print_patch_file_binary_noshow(
534 pi
, delta
, old_pfx
, new_pfx
);
536 pre_binary_size
= pi
->buf
->size
;
537 git_buf_printf(pi
->buf
, "GIT binary patch\n");
538 pi
->line
.num_lines
++;
540 if ((error
= format_binary(pi
, binary
->new_file
.type
, binary
->new_file
.data
,
541 binary
->new_file
.datalen
, binary
->new_file
.inflatedlen
)) < 0 ||
542 (error
= format_binary(pi
, binary
->old_file
.type
, binary
->old_file
.data
,
543 binary
->old_file
.datalen
, binary
->old_file
.inflatedlen
)) < 0) {
544 if (error
== GIT_EBUFS
) {
546 git_buf_truncate(pi
->buf
, pre_binary_size
);
548 return diff_print_patch_file_binary_noshow(
549 pi
, delta
, old_pfx
, new_pfx
);
553 pi
->line
.num_lines
++;
557 static int diff_print_patch_file(
558 const git_diff_delta
*delta
, float progress
, void *data
)
561 diff_print_info
*pi
= data
;
563 pi
->old_prefix
? pi
->old_prefix
: DIFF_OLD_PREFIX_DEFAULT
;
565 pi
->new_prefix
? pi
->new_prefix
: DIFF_NEW_PREFIX_DEFAULT
;
567 bool binary
= (delta
->flags
& GIT_DIFF_FLAG_BINARY
) ||
568 (pi
->flags
& GIT_DIFF_FORCE_BINARY
);
569 bool show_binary
= !!(pi
->flags
& GIT_DIFF_SHOW_BINARY
);
570 int id_strlen
= pi
->id_strlen
;
571 bool print_index
= (pi
->format
!= GIT_DIFF_FORMAT_PATCH_ID
);
573 if (binary
&& show_binary
)
574 id_strlen
= delta
->old_file
.id_abbrev
? delta
->old_file
.id_abbrev
:
575 delta
->new_file
.id_abbrev
;
577 GIT_UNUSED(progress
);
579 if (S_ISDIR(delta
->new_file
.mode
) ||
580 delta
->status
== GIT_DELTA_UNMODIFIED
||
581 delta
->status
== GIT_DELTA_IGNORED
||
582 delta
->status
== GIT_DELTA_UNREADABLE
||
583 (delta
->status
== GIT_DELTA_UNTRACKED
&&
584 (pi
->flags
& GIT_DIFF_SHOW_UNTRACKED_CONTENT
) == 0))
587 if ((error
= git_diff_delta__format_file_header(pi
->buf
, delta
, oldpfx
, newpfx
,
588 id_strlen
, print_index
)) < 0)
591 pi
->line
.origin
= GIT_DIFF_LINE_FILE_HDR
;
592 pi
->line
.content
= git_buf_cstr(pi
->buf
);
593 pi
->line
.content_len
= git_buf_len(pi
->buf
);
595 return pi
->print_cb(delta
, NULL
, &pi
->line
, pi
->payload
);
598 static int diff_print_patch_binary(
599 const git_diff_delta
*delta
,
600 const git_diff_binary
*binary
,
603 diff_print_info
*pi
= data
;
604 const char *old_pfx
=
605 pi
->old_prefix
? pi
->old_prefix
: DIFF_OLD_PREFIX_DEFAULT
;
606 const char *new_pfx
=
607 pi
->new_prefix
? pi
->new_prefix
: DIFF_NEW_PREFIX_DEFAULT
;
610 git_buf_clear(pi
->buf
);
612 if ((error
= diff_print_patch_file_binary(
613 pi
, (git_diff_delta
*)delta
, old_pfx
, new_pfx
, binary
)) < 0)
616 pi
->line
.origin
= GIT_DIFF_LINE_BINARY
;
617 pi
->line
.content
= git_buf_cstr(pi
->buf
);
618 pi
->line
.content_len
= git_buf_len(pi
->buf
);
620 return pi
->print_cb(delta
, NULL
, &pi
->line
, pi
->payload
);
623 static int diff_print_patch_hunk(
624 const git_diff_delta
*d
,
625 const git_diff_hunk
*h
,
628 diff_print_info
*pi
= data
;
630 if (S_ISDIR(d
->new_file
.mode
))
633 pi
->line
.origin
= GIT_DIFF_LINE_HUNK_HDR
;
634 pi
->line
.content
= h
->header
;
635 pi
->line
.content_len
= h
->header_len
;
637 return pi
->print_cb(d
, h
, &pi
->line
, pi
->payload
);
640 static int diff_print_patch_line(
641 const git_diff_delta
*delta
,
642 const git_diff_hunk
*hunk
,
643 const git_diff_line
*line
,
646 diff_print_info
*pi
= data
;
648 if (S_ISDIR(delta
->new_file
.mode
))
651 return pi
->print_cb(delta
, hunk
, line
, pi
->payload
);
654 /* print a git_diff to an output callback */
657 git_diff_format_t format
,
658 git_diff_line_cb print_cb
,
662 git_buf buf
= GIT_BUF_INIT
;
664 git_diff_file_cb print_file
= NULL
;
665 git_diff_binary_cb print_binary
= NULL
;
666 git_diff_hunk_cb print_hunk
= NULL
;
667 git_diff_line_cb print_line
= NULL
;
670 case GIT_DIFF_FORMAT_PATCH
:
671 print_file
= diff_print_patch_file
;
672 print_binary
= diff_print_patch_binary
;
673 print_hunk
= diff_print_patch_hunk
;
674 print_line
= diff_print_patch_line
;
676 case GIT_DIFF_FORMAT_PATCH_ID
:
677 print_file
= diff_print_patch_file
;
678 print_binary
= diff_print_patch_binary
;
679 print_line
= diff_print_patch_line
;
681 case GIT_DIFF_FORMAT_PATCH_HEADER
:
682 print_file
= diff_print_patch_file
;
684 case GIT_DIFF_FORMAT_RAW
:
685 print_file
= diff_print_one_raw
;
687 case GIT_DIFF_FORMAT_NAME_ONLY
:
688 print_file
= diff_print_one_name_only
;
690 case GIT_DIFF_FORMAT_NAME_STATUS
:
691 print_file
= diff_print_one_name_status
;
694 git_error_set(GIT_ERROR_INVALID
, "unknown diff output format (%d)", format
);
698 if ((error
= diff_print_info_init_fromdiff(&pi
, &buf
, diff
, format
, print_cb
, payload
)) < 0)
701 if ((error
= git_diff_foreach(diff
, print_file
, print_binary
, print_hunk
, print_line
, &pi
)) != 0) {
702 git_error_set_after_callback_function(error
, "git_diff_print");
707 git_buf_dispose(&buf
);
711 int git_diff_print_callback__to_buf(
712 const git_diff_delta
*delta
,
713 const git_diff_hunk
*hunk
,
714 const git_diff_line
*line
,
717 git_buf
*output
= payload
;
718 GIT_UNUSED(delta
); GIT_UNUSED(hunk
);
721 git_error_set(GIT_ERROR_INVALID
, "buffer pointer must be provided");
725 if (line
->origin
== GIT_DIFF_LINE_ADDITION
||
726 line
->origin
== GIT_DIFF_LINE_DELETION
||
727 line
->origin
== GIT_DIFF_LINE_CONTEXT
)
728 git_buf_putc(output
, line
->origin
);
730 return git_buf_put(output
, line
->content
, line
->content_len
);
733 int git_diff_print_callback__to_file_handle(
734 const git_diff_delta
*delta
,
735 const git_diff_hunk
*hunk
,
736 const git_diff_line
*line
,
739 FILE *fp
= payload
? payload
: stdout
;
745 if (line
->origin
== GIT_DIFF_LINE_CONTEXT
||
746 line
->origin
== GIT_DIFF_LINE_ADDITION
||
747 line
->origin
== GIT_DIFF_LINE_DELETION
) {
748 while ((error
= fputc(line
->origin
, fp
)) == EINTR
)
751 git_error_set(GIT_ERROR_OS
, "could not write status");
756 if (fwrite(line
->content
, line
->content_len
, 1, fp
) != 1) {
757 git_error_set(GIT_ERROR_OS
, "could not write line");
764 /* print a git_diff to a git_buf */
765 int git_diff_to_buf(git_buf
*out
, git_diff
*diff
, git_diff_format_t format
)
770 GIT_ASSERT_ARG(diff
);
772 if ((error
= git_buf_sanitize(out
)) < 0)
775 return git_diff_print(diff
, format
, git_diff_print_callback__to_buf
, out
);
778 /* print a git_patch to an output callback */
781 git_diff_line_cb print_cb
,
784 git_buf temp
= GIT_BUF_INIT
;
788 GIT_ASSERT_ARG(patch
);
789 GIT_ASSERT_ARG(print_cb
);
791 if ((error
= diff_print_info_init_frompatch(&pi
, &temp
, patch
,
792 GIT_DIFF_FORMAT_PATCH
, print_cb
, payload
)) < 0)
795 if ((error
= git_patch__invoke_callbacks(patch
, diff_print_patch_file
, diff_print_patch_binary
,
796 diff_print_patch_hunk
, diff_print_patch_line
, &pi
)) < 0) {
797 git_error_set_after_callback_function(error
, "git_patch_print");
802 git_buf_dispose(&temp
);
806 /* print a git_patch to a git_buf */
807 int git_patch_to_buf(git_buf
*out
, git_patch
*patch
)
812 GIT_ASSERT_ARG(patch
);
814 if ((error
= git_buf_sanitize(out
)) < 0)
817 return git_patch_print(patch
, git_diff_print_callback__to_buf
, out
);