mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-29 12:24:11 +00:00
Merge pull request #671 from nulltoken/topic/blob_create_fromdisk
Add git_blob_create_fromdisk()
This commit is contained in:
commit
e49cb1687e
@ -103,6 +103,18 @@ GIT_EXTERN(size_t) git_blob_rawsize(git_blob *blob);
|
|||||||
*/
|
*/
|
||||||
GIT_EXTERN(int) git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *path);
|
GIT_EXTERN(int) git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a file from the filesystem and write its content
|
||||||
|
* to the Object Database as a loose blob
|
||||||
|
*
|
||||||
|
* @param oid return the id of the written blob
|
||||||
|
* @param repo repository where the blob will be written.
|
||||||
|
* this repository can be bare or not
|
||||||
|
* @param path file from which the blob will be created
|
||||||
|
* @return GIT_SUCCESS or an error code
|
||||||
|
*/
|
||||||
|
GIT_EXTERN(int) git_blob_create_fromdisk(git_oid *oid, git_repository *repo, const char *path);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write an in-memory buffer to the ODB as a blob
|
* Write an in-memory buffer to the ODB as a blob
|
||||||
|
56
src/blob.c
56
src/blob.c
@ -148,30 +148,20 @@ static int write_symlink(
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
int git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *path)
|
static int blob_create_internal(git_oid *oid, git_repository *repo, const char *path)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
git_buf full_path = GIT_BUF_INIT;
|
|
||||||
git_off_t size;
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
const char *workdir;
|
|
||||||
git_odb *odb = NULL;
|
git_odb *odb = NULL;
|
||||||
|
git_off_t size;
|
||||||
|
|
||||||
workdir = git_repository_workdir(repo);
|
if ((error = git_path_lstat(path, &st)) < 0 || (error = git_repository_odb__weakptr(&odb, repo)) < 0)
|
||||||
assert(workdir); /* error to call this on bare repo */
|
|
||||||
|
|
||||||
if ((error = git_buf_joinpath(&full_path, workdir, path)) < 0 ||
|
|
||||||
(error = git_path_lstat(full_path.ptr, &st)) < 0 ||
|
|
||||||
(error = git_repository_odb__weakptr(&odb, repo)) < 0)
|
|
||||||
{
|
|
||||||
git_buf_free(&full_path);
|
|
||||||
return error;
|
return error;
|
||||||
}
|
|
||||||
|
|
||||||
size = st.st_size;
|
size = st.st_size;
|
||||||
|
|
||||||
if (S_ISLNK(st.st_mode)) {
|
if (S_ISLNK(st.st_mode)) {
|
||||||
error = write_symlink(oid, odb, full_path.ptr, (size_t)size);
|
error = write_symlink(oid, odb, path, (size_t)size);
|
||||||
} else {
|
} else {
|
||||||
git_vector write_filters = GIT_VECTOR_INIT;
|
git_vector write_filters = GIT_VECTOR_INIT;
|
||||||
int filter_count;
|
int filter_count;
|
||||||
@ -186,10 +176,10 @@ int git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *pat
|
|||||||
} else if (filter_count == 0) {
|
} else if (filter_count == 0) {
|
||||||
/* No filters need to be applied to the document: we can stream
|
/* No filters need to be applied to the document: we can stream
|
||||||
* directly from disk */
|
* directly from disk */
|
||||||
error = write_file_stream(oid, odb, full_path.ptr, size);
|
error = write_file_stream(oid, odb, path, size);
|
||||||
} else {
|
} else {
|
||||||
/* We need to apply one or more filters */
|
/* We need to apply one or more filters */
|
||||||
error = write_file_filtered(oid, odb, full_path.ptr, &write_filters);
|
error = write_file_filtered(oid, odb, path, &write_filters);
|
||||||
}
|
}
|
||||||
|
|
||||||
git_filters_free(&write_filters);
|
git_filters_free(&write_filters);
|
||||||
@ -209,7 +199,41 @@ int git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *pat
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
int git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *path)
|
||||||
|
{
|
||||||
|
git_buf full_path = GIT_BUF_INIT;
|
||||||
|
const char *workdir;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
workdir = git_repository_workdir(repo);
|
||||||
|
assert(workdir); /* error to call this on bare repo */
|
||||||
|
|
||||||
|
if (git_buf_joinpath(&full_path, workdir, path) < 0) {
|
||||||
|
git_buf_free(&full_path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = blob_create_internal(oid, repo, git_buf_cstr(&full_path));
|
||||||
|
|
||||||
git_buf_free(&full_path);
|
git_buf_free(&full_path);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int git_blob_create_fromdisk(git_oid *oid, git_repository *repo, const char *path)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
git_buf full_path = GIT_BUF_INIT;
|
||||||
|
|
||||||
|
if ((error = git_path_prettify(&full_path, path, NULL)) < 0) {
|
||||||
|
git_buf_free(&full_path);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = blob_create_internal(oid, repo, git_buf_cstr(&full_path));
|
||||||
|
|
||||||
|
git_buf_free(&full_path);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
69
tests-clar/object/blob/write.c
Normal file
69
tests-clar/object/blob/write.c
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
#include "clar_libgit2.h"
|
||||||
|
#include "buffer.h"
|
||||||
|
#include "posix.h"
|
||||||
|
#include "path.h"
|
||||||
|
#include "fileops.h"
|
||||||
|
|
||||||
|
static git_repository *repo;
|
||||||
|
|
||||||
|
#define WORKDIR "empty_standard_repo"
|
||||||
|
#define BARE_REPO "testrepo.git"
|
||||||
|
#define ELSEWHERE "elsewhere"
|
||||||
|
|
||||||
|
typedef int (*blob_creator_fn)(
|
||||||
|
git_oid *,
|
||||||
|
git_repository *,
|
||||||
|
const char *);
|
||||||
|
|
||||||
|
void test_object_blob_write__cleanup(void)
|
||||||
|
{
|
||||||
|
cl_git_sandbox_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void assert_blob_creation(const char *path_to_file, const char *blob_from_path, blob_creator_fn creator)
|
||||||
|
{
|
||||||
|
git_oid oid;
|
||||||
|
cl_git_mkfile(path_to_file, "1..2...3... Can you hear me?\n");
|
||||||
|
|
||||||
|
cl_must_pass(creator(&oid, repo, blob_from_path));
|
||||||
|
cl_assert(git_oid_streq(&oid, "da5e4f20c91c81b44a7e298f3d3fb3fe2f178e32") == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_object_blob_write__can_create_a_blob_in_a_standard_repo_from_a_file_located_in_the_working_directory(void)
|
||||||
|
{
|
||||||
|
repo = cl_git_sandbox_init(WORKDIR);
|
||||||
|
|
||||||
|
assert_blob_creation(WORKDIR "/test.txt", "test.txt", &git_blob_create_fromfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_object_blob_write__can_create_a_blob_in_a_standard_repo_from_a_absolute_filepath_pointing_outside_of_the_working_directory(void)
|
||||||
|
{
|
||||||
|
git_buf full_path = GIT_BUF_INIT;
|
||||||
|
|
||||||
|
repo = cl_git_sandbox_init(WORKDIR);
|
||||||
|
|
||||||
|
cl_must_pass(p_mkdir(ELSEWHERE, 0777));
|
||||||
|
cl_must_pass(git_path_prettify_dir(&full_path, ELSEWHERE, NULL));
|
||||||
|
cl_must_pass(git_buf_puts(&full_path, "test.txt"));
|
||||||
|
|
||||||
|
assert_blob_creation(ELSEWHERE "/test.txt", git_buf_cstr(&full_path), &git_blob_create_fromdisk);
|
||||||
|
|
||||||
|
git_buf_free(&full_path);
|
||||||
|
cl_must_pass(git_futils_rmdir_r(ELSEWHERE, GIT_DIRREMOVAL_FILES_AND_DIRS));
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_object_blob_write__can_create_a_blob_in_a_bare_repo_from_a_absolute_filepath(void)
|
||||||
|
{
|
||||||
|
git_buf full_path = GIT_BUF_INIT;
|
||||||
|
|
||||||
|
repo = cl_git_sandbox_init(BARE_REPO);
|
||||||
|
|
||||||
|
cl_must_pass(p_mkdir(ELSEWHERE, 0777));
|
||||||
|
cl_must_pass(git_path_prettify_dir(&full_path, ELSEWHERE, NULL));
|
||||||
|
cl_must_pass(git_buf_puts(&full_path, "test.txt"));
|
||||||
|
|
||||||
|
assert_blob_creation(ELSEWHERE "/test.txt", git_buf_cstr(&full_path), &git_blob_create_fromdisk);
|
||||||
|
|
||||||
|
git_buf_free(&full_path);
|
||||||
|
cl_must_pass(git_futils_rmdir_r(ELSEWHERE, GIT_DIRREMOVAL_FILES_AND_DIRS));
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user