mirror of
https://git.proxmox.com/git/libgit2
synced 2025-06-04 15:22:13 +00:00
Honor UPDATE_ONLY bit when checking out conflicts
This commit is contained in:
parent
6f8cc7bb6a
commit
cfae7f85fb
@ -851,7 +851,7 @@ static void report_progress(
|
|||||||
data->opts.progress_payload);
|
data->opts.progress_payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int checkout_safe_for_update_only(const char *path, mode_t expected_mode)
|
int git_checkout__safe_for_update_only(const char *path, mode_t expected_mode)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
@ -921,7 +921,7 @@ static int checkout_blob(
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if ((data->strategy & GIT_CHECKOUT_UPDATE_ONLY) != 0) {
|
if ((data->strategy & GIT_CHECKOUT_UPDATE_ONLY) != 0) {
|
||||||
int rval = checkout_safe_for_update_only(
|
int rval = git_checkout__safe_for_update_only(
|
||||||
git_buf_cstr(&data->path), file->mode);
|
git_buf_cstr(&data->path), file->mode);
|
||||||
if (rval <= 0)
|
if (rval <= 0)
|
||||||
return rval;
|
return rval;
|
||||||
|
@ -40,6 +40,10 @@ extern int git_checkout_iterator(
|
|||||||
git_iterator *target,
|
git_iterator *target,
|
||||||
const git_checkout_opts *opts);
|
const git_checkout_opts *opts);
|
||||||
|
|
||||||
|
int git_checkout__safe_for_update_only(
|
||||||
|
const char *path,
|
||||||
|
mode_t expected_mode);
|
||||||
|
|
||||||
int git_checkout__write_content(
|
int git_checkout__write_content(
|
||||||
checkout_data *data,
|
checkout_data *data,
|
||||||
const git_oid *oid,
|
const git_oid *oid,
|
||||||
|
@ -410,6 +410,7 @@ static int checkout_write_entry(
|
|||||||
{
|
{
|
||||||
const char *hint_path = NULL, *suffix;
|
const char *hint_path = NULL, *suffix;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
int error;
|
||||||
|
|
||||||
assert (side == conflict->ours || side == conflict->theirs);
|
assert (side == conflict->ours || side == conflict->theirs);
|
||||||
|
|
||||||
@ -434,6 +435,10 @@ static int checkout_write_entry(
|
|||||||
hint_path = side->path;
|
hint_path = side->path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((data->strategy & GIT_CHECKOUT_UPDATE_ONLY) != 0 &&
|
||||||
|
(error = git_checkout__safe_for_update_only(git_buf_cstr(&data->path), side->mode)) <= 0)
|
||||||
|
return error;
|
||||||
|
|
||||||
return git_checkout__write_content(data,
|
return git_checkout__write_content(data,
|
||||||
&side->oid, git_buf_cstr(&data->path), hint_path, side->mode, &st);
|
&side->oid, git_buf_cstr(&data->path), hint_path, side->mode, &st);
|
||||||
}
|
}
|
||||||
@ -528,8 +533,14 @@ static int checkout_write_merge(
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((error = checkout_merge_path(&path_workdir, data, conflict, &result)) < 0 ||
|
if ((error = checkout_merge_path(&path_workdir, data, conflict, &result)) < 0)
|
||||||
(error = git_futils_mkpath2file(path_workdir.ptr, 0755)) < 0 ||
|
goto done;
|
||||||
|
|
||||||
|
if ((data->strategy & GIT_CHECKOUT_UPDATE_ONLY) != 0 &&
|
||||||
|
(error = git_checkout__safe_for_update_only(git_buf_cstr(&path_workdir), result.mode)) <= 0)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
if ((error = git_futils_mkpath2file(path_workdir.ptr, 0755)) < 0 ||
|
||||||
(error = git_filebuf_open(&output, path_workdir.ptr, GIT_FILEBUF_DO_NOT_BUFFER)) < 0 ||
|
(error = git_filebuf_open(&output, path_workdir.ptr, GIT_FILEBUF_DO_NOT_BUFFER)) < 0 ||
|
||||||
(error = git_filebuf_write(&output, result.data, result.len)) < 0 ||
|
(error = git_filebuf_write(&output, result.data, result.len)) < 0 ||
|
||||||
(error = git_filebuf_commit(&output, result.mode)) < 0)
|
(error = git_filebuf_commit(&output, result.mode)) < 0)
|
||||||
|
@ -82,7 +82,9 @@ static void create_index(struct checkout_index_entry *entries, size_t entries_le
|
|||||||
|
|
||||||
for (i = 0; i < entries_len; i++) {
|
for (i = 0; i < entries_len; i++) {
|
||||||
git_buf_joinpath(&path, TEST_REPO_PATH, entries[i].path);
|
git_buf_joinpath(&path, TEST_REPO_PATH, entries[i].path);
|
||||||
p_unlink(git_buf_cstr(&path));
|
|
||||||
|
if (entries[i].stage == 3 && (i == 0 || strcmp(entries[i-1].path, entries[i].path) != 0 || entries[i-1].stage != 2))
|
||||||
|
p_unlink(git_buf_cstr(&path));
|
||||||
|
|
||||||
git_index_remove_bypath(g_index, entries[i].path);
|
git_index_remove_bypath(g_index, entries[i].path);
|
||||||
}
|
}
|
||||||
@ -203,6 +205,7 @@ void test_checkout_conflict__ignored(void)
|
|||||||
opts.checkout_strategy |= GIT_CHECKOUT_SKIP_UNMERGED;
|
opts.checkout_strategy |= GIT_CHECKOUT_SKIP_UNMERGED;
|
||||||
|
|
||||||
create_conflicting_index();
|
create_conflicting_index();
|
||||||
|
cl_git_pass(p_unlink(TEST_REPO_PATH "/conflicting.txt"));
|
||||||
|
|
||||||
cl_git_pass(git_checkout_index(g_repo, g_index, &opts));
|
cl_git_pass(git_checkout_index(g_repo, g_index, &opts));
|
||||||
|
|
||||||
@ -974,3 +977,48 @@ void test_checkout_conflict__name_mangled_file_exists_in_workdir(void)
|
|||||||
ensure_workdir("directory_file-one~ours_0", 0100644, CONFLICTING_OURS_OID);
|
ensure_workdir("directory_file-one~ours_0", 0100644, CONFLICTING_OURS_OID);
|
||||||
ensure_workdir("directory_file-two~theirs_0", 0100644, CONFLICTING_THEIRS_OID);
|
ensure_workdir("directory_file-two~theirs_0", 0100644, CONFLICTING_THEIRS_OID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_checkout_conflict__update_only(void)
|
||||||
|
{
|
||||||
|
git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;
|
||||||
|
|
||||||
|
struct checkout_index_entry checkout_index_entries[] = {
|
||||||
|
{ 0100644, AUTOMERGEABLE_ANCESTOR_OID, 1, "automergeable.txt" },
|
||||||
|
{ 0100644, AUTOMERGEABLE_OURS_OID, 2, "automergeable.txt" },
|
||||||
|
{ 0100644, AUTOMERGEABLE_THEIRS_OID, 3, "automergeable.txt" },
|
||||||
|
|
||||||
|
{ 0100644, CONFLICTING_ANCESTOR_OID, 1, "modify-delete" },
|
||||||
|
{ 0100644, CONFLICTING_THEIRS_OID, 3, "modify-delete" },
|
||||||
|
|
||||||
|
{ 0100644, CONFLICTING_ANCESTOR_OID, 1, "directory_file-one" },
|
||||||
|
{ 0100644, CONFLICTING_OURS_OID, 2, "directory_file-one" },
|
||||||
|
{ 0100644, CONFLICTING_THEIRS_OID, 0, "directory_file-one/file" },
|
||||||
|
|
||||||
|
{ 0100644, CONFLICTING_ANCESTOR_OID, 1, "directory_file-two" },
|
||||||
|
{ 0100644, CONFLICTING_OURS_OID, 0, "directory_file-two/file" },
|
||||||
|
{ 0100644, CONFLICTING_THEIRS_OID, 3, "directory_file-two" },
|
||||||
|
};
|
||||||
|
|
||||||
|
opts.checkout_strategy |= GIT_CHECKOUT_UPDATE_ONLY;
|
||||||
|
|
||||||
|
create_index(checkout_index_entries, 3);
|
||||||
|
git_index_write(g_index);
|
||||||
|
|
||||||
|
cl_git_pass(p_mkdir("merge-resolve/directory_file-two", 0777));
|
||||||
|
cl_git_rewritefile("merge-resolve/directory_file-two/file", CONFLICTING_OURS_FILE);
|
||||||
|
|
||||||
|
cl_git_pass(git_checkout_index(g_repo, g_index, &opts));
|
||||||
|
|
||||||
|
ensure_workdir_contents("automergeable.txt", AUTOMERGEABLE_MERGED_FILE);
|
||||||
|
ensure_workdir("directory_file-two/file", 0100644, CONFLICTING_OURS_OID);
|
||||||
|
|
||||||
|
cl_assert(!git_path_exists("merge-resolve/modify-delete"));
|
||||||
|
cl_assert(!git_path_exists("merge-resolve/test-one.txt"));
|
||||||
|
cl_assert(!git_path_exists("merge-resolve/test-one-side-one.txt"));
|
||||||
|
cl_assert(!git_path_exists("merge-resolve/test-one-side-two.txt"));
|
||||||
|
cl_assert(!git_path_exists("merge-resolve/test-one.txt~ours"));
|
||||||
|
cl_assert(!git_path_exists("merge-resolve/test-one.txt~theirs"));
|
||||||
|
cl_assert(!git_path_exists("merge-resolve/directory_file-one/file"));
|
||||||
|
cl_assert(!git_path_exists("merge-resolve/directory_file-one~ours"));
|
||||||
|
cl_assert(!git_path_exists("merge-resolve/directory_file-two~theirs"));
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user