Commit ece5bb5e by Gregory Herrero

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>
parent 048e94ad
......@@ -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)
......
......@@ -20,6 +20,39 @@ void test_diff_patchid__simple_commit(void)
verify_patch_id(PATCH_SIMPLE_COMMIT, "06094b1948b878b7d9ff7560b4eae672a014b0ec");
}
void test_diff_patchid__deleted_file(void)
{
verify_patch_id(PATCH_DELETE_ORIGINAL, "d18507fe189f49c028b32c8c34e1ad98dd6a1aad");
verify_patch_id(PATCH_DELETED_FILE_2_HUNKS, "f31412498a17e6c3fbc635f2c5f9aa3ef4c1a9b7");
}
void test_diff_patchid__created_file(void)
{
verify_patch_id(PATCH_ADD_ORIGINAL, "a7d39379308021465ae2ce65e338c048a3110db6");
}
void test_diff_patchid__binary_file(void)
{
verify_patch_id(PATCH_ADD_BINARY_NOT_PRINTED, "2b31236b485faa30cf4dd33e4d6539829996739f");
}
void test_diff_patchid__renamed_file(void)
{
verify_patch_id(PATCH_RENAME_EXACT, "4666d50cea4976f6f727448046d43461912058fd");
verify_patch_id(PATCH_RENAME_SIMILAR, "a795087575fcb940227be524488bedd6b3d3f438");
}
void test_diff_patchid__modechange(void)
{
verify_patch_id(PATCH_MODECHANGE_UNCHANGED, "dbf3423ee98375ef1c72a79fbd29a049a2bae771");
verify_patch_id(PATCH_MODECHANGE_MODIFIED, "93aba696e1bbd2bbb73e3e3e62ed71f232137657");
}
void test_diff_patchid__shuffle_hunks(void)
{
verify_patch_id(PATCH_DELETED_FILE_2_HUNKS_SHUFFLED, "f31412498a17e6c3fbc635f2c5f9aa3ef4c1a9b7");
}
void test_diff_patchid__filename_with_spaces(void)
{
verify_patch_id(PATCH_APPEND_NO_NL, "f0ba05413beaef743b630e796153839462ee477a");
......
......@@ -385,6 +385,38 @@
"@@ -9,0 +10 @@ below it!\n" \
"+insert at end\n"
#define PATCH_DELETED_FILE_2_HUNKS \
"diff --git a/a b/a\n" \
"index 7f129fd..af431f2 100644\n" \
"--- a/a\n" \
"+++ b/a\n" \
"@@ -1 +1 @@\n" \
"-a contents 2\n" \
"+a contents\n" \
"diff --git a/c/d b/c/d\n" \
"deleted file mode 100644\n" \
"index 297efb8..0000000\n" \
"--- a/c/d\n" \
"+++ /dev/null\n" \
"@@ -1 +0,0 @@\n" \
"-c/d contents\n"
#define PATCH_DELETED_FILE_2_HUNKS_SHUFFLED \
"diff --git a/c/d b/c/d\n" \
"deleted file mode 100644\n" \
"index 297efb8..0000000\n" \
"--- a/c/d\n" \
"+++ /dev/null\n" \
"@@ -1 +0,0 @@\n" \
"-c/d contents\n" \
"diff --git a/a b/a\n" \
"index 7f129fd..af431f2 100644\n" \
"--- a/a\n" \
"+++ b/a\n" \
"@@ -1 +1 @@\n" \
"-a contents 2\n" \
"+a contents\n"
#define PATCH_SIMPLE_COMMIT \
"commit 15e119375018fba121cf58e02a9f17fe22df0df8\n" \
"Author: Edward Thomson <ethomson@edwardthomson.com>\n" \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment