mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-28 15:58:29 +00:00
Don't try to merge binary files
This commit is contained in:
parent
c1d648c5c6
commit
6b92c99bcb
@ -70,7 +70,8 @@ typedef struct {
|
||||
|
||||
int name_collision:1,
|
||||
directoryfile:1,
|
||||
one_to_two:1;
|
||||
one_to_two:1,
|
||||
binary:1;
|
||||
} checkout_conflictdata;
|
||||
|
||||
static int checkout_notify(
|
||||
@ -681,6 +682,40 @@ GIT_INLINE(bool) conflict_pathspec_match(
|
||||
return false;
|
||||
}
|
||||
|
||||
GIT_INLINE(int) checkout_conflict_detect_binary(git_repository *repo, checkout_conflictdata *conflict)
|
||||
{
|
||||
git_blob *ancestor_blob = NULL, *our_blob = NULL, *their_blob = NULL;
|
||||
int error = 0;
|
||||
|
||||
if (conflict->ancestor) {
|
||||
if ((error = git_blob_lookup(&ancestor_blob, repo, &conflict->ancestor->oid)) < 0)
|
||||
goto done;
|
||||
|
||||
conflict->binary = git_blob_is_binary(ancestor_blob);
|
||||
}
|
||||
|
||||
if (!conflict->binary && conflict->ours) {
|
||||
if ((error = git_blob_lookup(&our_blob, repo, &conflict->ours->oid)) < 0)
|
||||
goto done;
|
||||
|
||||
conflict->binary = git_blob_is_binary(our_blob);
|
||||
}
|
||||
|
||||
if (!conflict->binary && conflict->theirs) {
|
||||
if ((error = git_blob_lookup(&their_blob, repo, &conflict->theirs->oid)) < 0)
|
||||
goto done;
|
||||
|
||||
conflict->binary = git_blob_is_binary(their_blob);
|
||||
}
|
||||
|
||||
done:
|
||||
git_blob_free(ancestor_blob);
|
||||
git_blob_free(our_blob);
|
||||
git_blob_free(their_blob);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int checkout_conflicts_load(checkout_data *data, git_iterator *workdir, git_vector *pathspec)
|
||||
{
|
||||
git_index_conflict_iterator *iterator = NULL;
|
||||
@ -705,6 +740,9 @@ static int checkout_conflicts_load(checkout_data *data, git_iterator *workdir, g
|
||||
conflict->ours = ours;
|
||||
conflict->theirs = theirs;
|
||||
|
||||
if ((error = checkout_conflict_detect_binary(data->repo, conflict)) < 0)
|
||||
goto done;
|
||||
|
||||
git_vector_insert(&data->conflicts, conflict);
|
||||
}
|
||||
|
||||
@ -1706,6 +1744,7 @@ static int checkout_create_conflicts(checkout_data *data)
|
||||
int error = 0;
|
||||
|
||||
git_vector_foreach(&data->conflicts, i, conflict) {
|
||||
|
||||
/* Both deleted: nothing to do */
|
||||
if (conflict->ours == NULL && conflict->theirs == NULL)
|
||||
error = 0;
|
||||
@ -1749,7 +1788,11 @@ static int checkout_create_conflicts(checkout_data *data)
|
||||
else if (S_ISLNK(conflict->theirs->mode))
|
||||
error = checkout_write_entry(data, conflict, conflict->ours);
|
||||
|
||||
else
|
||||
/* If any side is binary, write the ours side */
|
||||
else if (conflict->binary)
|
||||
error = checkout_write_entry(data, conflict, conflict->ours);
|
||||
|
||||
else if (!error)
|
||||
error = checkout_write_merge(data, conflict);
|
||||
|
||||
if (error)
|
||||
|
43
src/merge.c
43
src/merge.c
@ -551,6 +551,10 @@ static int merge_conflict_resolve_automerge(
|
||||
strcmp(conflict->ancestor_entry.path, conflict->their_entry.path) != 0)
|
||||
return 0;
|
||||
|
||||
/* Reject binary conflicts */
|
||||
if (conflict->binary)
|
||||
return 0;
|
||||
|
||||
if ((error = git_repository_odb(&odb, diff_list->repo)) < 0 ||
|
||||
(error = git_merge_file_input_from_index_entry(&ancestor, diff_list->repo, &conflict->ancestor_entry)) < 0 ||
|
||||
(error = git_merge_file_input_from_index_entry(&ours, diff_list->repo, &conflict->our_entry)) < 0 ||
|
||||
@ -1150,6 +1154,44 @@ GIT_INLINE(int) merge_diff_detect_type(
|
||||
return 0;
|
||||
}
|
||||
|
||||
GIT_INLINE(int) merge_diff_detect_binary(
|
||||
git_repository *repo,
|
||||
git_merge_diff *conflict)
|
||||
{
|
||||
git_blob *ancestor_blob = NULL, *our_blob = NULL, *their_blob = NULL;
|
||||
int error = 0;
|
||||
|
||||
if (GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->ancestor_entry)) {
|
||||
if ((error = git_blob_lookup(&ancestor_blob, repo, &conflict->ancestor_entry.oid)) < 0)
|
||||
goto done;
|
||||
|
||||
conflict->binary = git_blob_is_binary(ancestor_blob);
|
||||
}
|
||||
|
||||
if (!conflict->binary &&
|
||||
GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry)) {
|
||||
if ((error = git_blob_lookup(&our_blob, repo, &conflict->our_entry.oid)) < 0)
|
||||
goto done;
|
||||
|
||||
conflict->binary = git_blob_is_binary(our_blob);
|
||||
}
|
||||
|
||||
if (!conflict->binary &&
|
||||
GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry)) {
|
||||
if ((error = git_blob_lookup(&their_blob, repo, &conflict->their_entry.oid)) < 0)
|
||||
goto done;
|
||||
|
||||
conflict->binary = git_blob_is_binary(their_blob);
|
||||
}
|
||||
|
||||
done:
|
||||
git_blob_free(ancestor_blob);
|
||||
git_blob_free(our_blob);
|
||||
git_blob_free(their_blob);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
GIT_INLINE(int) index_entry_dup(
|
||||
git_index_entry *out,
|
||||
git_pool *pool,
|
||||
@ -1221,6 +1263,7 @@ static int merge_diff_list_insert_conflict(
|
||||
if ((conflict = merge_diff_from_index_entries(diff_list, tree_items)) == NULL ||
|
||||
merge_diff_detect_type(conflict) < 0 ||
|
||||
merge_diff_detect_df_conflict(merge_df_data, conflict) < 0 ||
|
||||
merge_diff_detect_binary(diff_list->repo, conflict) < 0 ||
|
||||
git_vector_insert(&diff_list->conflicts, conflict) < 0)
|
||||
return -1;
|
||||
|
||||
|
@ -106,6 +106,8 @@ typedef struct {
|
||||
|
||||
git_index_entry their_entry;
|
||||
git_delta_t their_status;
|
||||
|
||||
int binary:1;
|
||||
} git_merge_diff;
|
||||
|
||||
/** Internal structure for merge inputs */
|
||||
|
@ -489,3 +489,40 @@ void test_merge_workdir_simple__unrelated_with_conflicts(void)
|
||||
git_merge_result_free(result);
|
||||
}
|
||||
|
||||
void test_merge_workdir_simple__binary(void)
|
||||
{
|
||||
git_oid our_oid, their_oid, our_file_oid;
|
||||
git_commit *our_commit;
|
||||
git_merge_head *their_head;
|
||||
git_merge_result *result;
|
||||
const git_index_entry *binary_entry;
|
||||
git_merge_opts opts = GIT_MERGE_OPTS_INIT;
|
||||
|
||||
struct merge_index_entry merge_index_entries[] = {
|
||||
{ 0100644, "1c51d885170f57a0c4e8c69ff6363d91a5b51f85", 1, "binary" },
|
||||
{ 0100644, "23ed141a6ae1e798b2f721afedbe947c119111ba", 2, "binary" },
|
||||
{ 0100644, "836b8b82b26cab22eaaed8820877c76d6c8bca19", 3, "binary" },
|
||||
};
|
||||
|
||||
cl_git_pass(git_oid_fromstr(&our_oid, "cc338e4710c9b257106b8d16d82f86458d5beaf1"));
|
||||
cl_git_pass(git_oid_fromstr(&their_oid, "ad01aebfdf2ac13145efafe3f9fcf798882f1730"));
|
||||
|
||||
cl_git_pass(git_commit_lookup(&our_commit, repo, &our_oid));
|
||||
cl_git_pass(git_reset(repo, (git_object *)our_commit, GIT_RESET_HARD));
|
||||
|
||||
cl_git_pass(git_merge_head_from_oid(&their_head, repo, &their_oid));
|
||||
|
||||
cl_git_pass(git_merge(&result, repo, (const git_merge_head **)&their_head, 1, &opts));
|
||||
|
||||
cl_assert(merge_test_index(repo_index, merge_index_entries, 3));
|
||||
|
||||
cl_git_pass(git_index_add_bypath(repo_index, "binary"));
|
||||
cl_assert((binary_entry = git_index_get_bypath(repo_index, "binary", 0)) != NULL);
|
||||
|
||||
cl_git_pass(git_oid_fromstr(&our_file_oid, "23ed141a6ae1e798b2f721afedbe947c119111ba"));
|
||||
cl_assert(git_oid_cmp(&binary_entry->oid, &our_file_oid) == 0);
|
||||
|
||||
git_merge_head_free(their_head);
|
||||
git_merge_result_free(result);
|
||||
git_commit_free(our_commit);
|
||||
}
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user