mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-06 00:13:18 +00:00
Merge pull request #1815 from libgit2/ntk/topic/stream_write/check_before_overwriting
Ask the odbbackend if the object exists before overwriting it
This commit is contained in:
commit
97affdf213
@ -92,6 +92,10 @@ struct git_odb_stream {
|
||||
/**
|
||||
* Store the contents of the stream as an object with the id
|
||||
* specified in `oid`.
|
||||
*
|
||||
* This method will *not* be invoked by libgit2 if the object pointed at
|
||||
* by `oid` already exists in any backend. Libgit2 will however take care
|
||||
* of properly disposing the stream through a call to `free()`.
|
||||
*/
|
||||
int (*finalize_write)(git_odb_stream *stream, const git_oid *oid);
|
||||
|
||||
|
@ -900,6 +900,10 @@ int git_odb_stream_write(git_odb_stream *stream, const char *buffer, size_t len)
|
||||
int git_odb_stream_finalize_write(git_oid *out, git_odb_stream *stream)
|
||||
{
|
||||
git_hash_final(out, stream->hash_ctx);
|
||||
|
||||
if (git_odb_exists(stream->backend->odb, out))
|
||||
return 0;
|
||||
|
||||
return stream->finalize_write(stream, out);
|
||||
}
|
||||
|
||||
|
@ -781,13 +781,6 @@ static int loose_backend__stream_fwrite(git_odb_stream *_stream, const git_oid *
|
||||
if (object_file_name(&final_path, backend, oid) < 0 ||
|
||||
object_mkdir(&final_path, backend) < 0)
|
||||
error = -1;
|
||||
/*
|
||||
* Don't try to add an existing object to the repository. This
|
||||
* is what git does and allows us to sidestep the fact that
|
||||
* we're not allowed to overwrite a read-only file on Windows.
|
||||
*/
|
||||
else if (git_path_exists(final_path.ptr) == true)
|
||||
git_filebuf_cleanup(&stream->fbuf);
|
||||
else
|
||||
error = git_filebuf_commit_at(
|
||||
&stream->fbuf, final_path.ptr, GIT_OBJECT_FILE_MODE);
|
||||
|
@ -41,14 +41,46 @@ void test_object_blob_fromchunks__can_create_a_blob_from_a_in_memory_chunk_provi
|
||||
|
||||
cl_git_pass(git_oid_fromstr(&expected_oid, "321cbdf08803c744082332332838df6bd160f8f9"));
|
||||
|
||||
cl_git_fail(git_object_lookup(&blob, repo, &expected_oid, GIT_OBJ_ANY));
|
||||
cl_git_fail_with(
|
||||
git_object_lookup(&blob, repo, &expected_oid, GIT_OBJ_ANY),
|
||||
GIT_ENOTFOUND);
|
||||
|
||||
cl_git_pass(git_blob_create_fromchunks(&oid, repo, NULL, text_chunked_source_cb, &howmany));
|
||||
|
||||
cl_git_pass(git_object_lookup(&blob, repo, &expected_oid, GIT_OBJ_ANY));
|
||||
cl_assert(git_oid_cmp(&expected_oid, git_object_id(blob)) == 0);
|
||||
|
||||
git_object_free(blob);
|
||||
}
|
||||
|
||||
void test_object_blob_fromchunks__doesnot_overwrite_an_already_existing_object(void)
|
||||
{
|
||||
git_buf path = GIT_BUF_INIT;
|
||||
git_buf content = GIT_BUF_INIT;
|
||||
git_oid expected_oid, oid;
|
||||
int howmany = 7;
|
||||
|
||||
cl_git_pass(git_oid_fromstr(&expected_oid, "321cbdf08803c744082332332838df6bd160f8f9"));
|
||||
|
||||
cl_git_pass(git_blob_create_fromchunks(&oid, repo, NULL, text_chunked_source_cb, &howmany));
|
||||
|
||||
/* Let's replace the content of the blob file storage with something else... */
|
||||
cl_git_pass(git_buf_joinpath(&path, git_repository_path(repo), "objects/32/1cbdf08803c744082332332838df6bd160f8f9"));
|
||||
cl_git_pass(p_unlink(git_buf_cstr(&path)));
|
||||
cl_git_mkfile(git_buf_cstr(&path), "boom");
|
||||
|
||||
/* ...request a creation of the same blob... */
|
||||
howmany = 7;
|
||||
cl_git_pass(git_blob_create_fromchunks(&oid, repo, NULL, text_chunked_source_cb, &howmany));
|
||||
|
||||
/* ...and ensure the content of the faked blob file hasn't been altered */
|
||||
cl_git_pass(git_futils_readbuffer(&content, git_buf_cstr(&path)));
|
||||
cl_assert(!git__strcmp("boom", git_buf_cstr(&content)));
|
||||
|
||||
git_buf_free(&path);
|
||||
git_buf_free(&content);
|
||||
}
|
||||
|
||||
#define GITATTR "* text=auto\n" \
|
||||
"*.txt text\n" \
|
||||
"*.data binary\n"
|
||||
|
Loading…
Reference in New Issue
Block a user