diff options
author | Gregory Herrero <gregory.herrero@oracle.com> | 2019-11-07 14:10:00 +0100 |
---|---|---|
committer | Gregory Herrero <gregory.herrero@oracle.com> | 2019-11-28 14:17:50 +0100 |
commit | ece5bb5e7d6e35e50096bac3d7bf17342daaec77 (patch) | |
tree | 27f42b0b9f8fd8ac067bbfb2b780f4e72d3bae9a /src/diff.c | |
parent | 048e94adbba3c21b9ad739640cce11a8b387df48 (diff) | |
download | libgit2-ece5bb5e7d6e35e50096bac3d7bf17342daaec77.tar.gz |
diff: make patchid computation work with all types of commits.
Current implementation of patchid is not computing a correct patchid
when given a patch where, for example, a new file is added or removed.
Some more corner cases need to be handled to have same behavior as git
patch-id command.
Add some more tests to cover those corner cases.
Signed-off-by: Gregory Herrero <gregory.herrero@oracle.com>
Diffstat (limited to 'src/diff.c')
-rw-r--r-- | src/diff.c | 82 |
1 files changed, 21 insertions, 61 deletions
diff --git a/src/diff.c b/src/diff.c index 15a32ed48..47f49d949 100644 --- a/src/diff.c +++ b/src/diff.c @@ -426,81 +426,38 @@ static void strip_spaces(git_buf *buf) git_buf_truncate(buf, len); } -static int file_cb( +int git_diff_patchid_print_callback__to_buf( const git_diff_delta *delta, - float progress, + const git_diff_hunk *hunk, + const git_diff_line *line, void *payload) { struct patch_id_args *args = (struct patch_id_args *) payload; git_buf buf = GIT_BUF_INIT; - int error; - - GIT_UNUSED(progress); + int error = 0; - if (!args->first_file && - (error = flush_hunk(&args->result, &args->ctx)) < 0) - goto out; - args->first_file = 0; - - if ((error = git_buf_printf(&buf, - "diff--gita/%sb/%s---a/%s+++b/%s", - delta->old_file.path, - delta->new_file.path, - delta->old_file.path, - delta->new_file.path)) < 0) + if (line->origin == GIT_DIFF_LINE_CONTEXT_EOFNL || + line->origin == GIT_DIFF_LINE_ADD_EOFNL || + line->origin == GIT_DIFF_LINE_DEL_EOFNL) goto out; - strip_spaces(&buf); - - if ((error = git_hash_update(&args->ctx, buf.ptr, buf.size)) < 0) + if ((error = git_diff_print_callback__to_buf(delta, hunk, + line, &buf)) < 0) goto out; -out: - git_buf_dispose(&buf); - return error; -} - -static int patchid_line_cb( - const git_diff_delta *delta, - const git_diff_hunk *hunk, - const git_diff_line *line, - void *payload) -{ - struct patch_id_args *args = (struct patch_id_args *) payload; - git_buf buf = GIT_BUF_INIT; - int error; - - GIT_UNUSED(delta); - GIT_UNUSED(hunk); - - switch (line->origin) { - case GIT_DIFF_LINE_ADDITION: - git_buf_putc(&buf, '+'); - break; - case GIT_DIFF_LINE_DELETION: - git_buf_putc(&buf, '-'); - break; - case GIT_DIFF_LINE_CONTEXT: - break; - case GIT_DIFF_LINE_CONTEXT_EOFNL: - case GIT_DIFF_LINE_ADD_EOFNL: - case GIT_DIFF_LINE_DEL_EOFNL: - /* - * Ignore EOF without newlines for patch IDs as whitespace is - * not supposed to be significant. - */ - return 0; - default: - git_error_set(GIT_ERROR_PATCH, "invalid line origin for patch"); - return -1; - } - - git_buf_put(&buf, line->content, line->content_len); strip_spaces(&buf); + if (line->origin == GIT_DIFF_LINE_FILE_HDR && + !args->first_file && + (error = flush_hunk(&args->result, &args->ctx) < 0)) + goto out; + if ((error = git_hash_update(&args->ctx, buf.ptr, buf.size)) < 0) goto out; + if (line->origin == GIT_DIFF_LINE_FILE_HDR && args->first_file) + args->first_file = 0; + out: git_buf_dispose(&buf); return error; @@ -526,7 +483,10 @@ int git_diff_patchid(git_oid *out, git_diff *diff, git_diff_patchid_options *opt if ((error = git_hash_ctx_init(&args.ctx)) < 0) goto out; - if ((error = git_diff_foreach(diff, file_cb, NULL, NULL, patchid_line_cb, &args)) < 0) + if ((error = git_diff_print(diff, + GIT_DIFF_FORMAT_PATCH_ID, + git_diff_patchid_print_callback__to_buf, + &args)) < 0) goto out; if ((error = (flush_hunk(&args.result, &args.ctx))) < 0) |