mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-03 00:22:21 +00:00
Implement git_odb_write()
Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk> Signed-off-by: Andreas Ericsson <ae@op5.se>
This commit is contained in:
parent
ca481fc4f1
commit
e17a3f5673
@ -95,6 +95,18 @@ GIT_EXTERN(int) git_odb__read_packed(git_obj *out, git_odb *db, const git_oid *i
|
||||
*/
|
||||
GIT_EXTERN(int) git_odb__read_loose(git_obj *out, git_odb *db, const git_oid *id);
|
||||
|
||||
/**
|
||||
* Write an object to the database.
|
||||
*
|
||||
* @param id identity of the object written.
|
||||
* @param db database to which the object should be written.
|
||||
* @param obj object descriptor for the object to write.
|
||||
* @return
|
||||
* - GIT_SUCCESS if the object was written;
|
||||
* - GIT_ERROR otherwise.
|
||||
*/
|
||||
GIT_EXTERN(int) git_odb_write(git_oid *id, git_odb *db, git_obj *obj);
|
||||
|
||||
/**
|
||||
* Release all memory used by the obj structure.
|
||||
*
|
||||
|
173
src/odb.c
173
src/odb.c
@ -85,6 +85,11 @@ struct git_odb {
|
||||
/** Alternate databases to search. */
|
||||
git_odb **alternates;
|
||||
size_t n_alternates;
|
||||
|
||||
/** loose object zlib compression level. */
|
||||
int object_zlib_level;
|
||||
/** loose object file fsync flag. */
|
||||
int fsync_object_files;
|
||||
};
|
||||
|
||||
typedef struct { /* object header data */
|
||||
@ -158,13 +163,12 @@ static int format_object_header(char *hdr, size_t n, git_obj *obj)
|
||||
return len+1;
|
||||
}
|
||||
|
||||
int git_obj_hash(git_oid *id, git_obj *obj)
|
||||
static int hash_obj(git_oid *id, char *hdr, size_t n, int *len, git_obj *obj)
|
||||
{
|
||||
git_buf_vec vec[2];
|
||||
char hdr[64];
|
||||
int hdrlen;
|
||||
|
||||
assert(id && obj);
|
||||
assert(id && hdr && len && obj);
|
||||
|
||||
if (!git_obj__loose_object_type(obj->type))
|
||||
return GIT_ERROR;
|
||||
@ -172,9 +176,11 @@ int git_obj_hash(git_oid *id, git_obj *obj)
|
||||
if (!obj->data && obj->len != 0)
|
||||
return GIT_ERROR;
|
||||
|
||||
if ((hdrlen = format_object_header(hdr, sizeof(hdr), obj)) < 0)
|
||||
if ((hdrlen = format_object_header(hdr, n, obj)) < 0)
|
||||
return GIT_ERROR;
|
||||
|
||||
*len = hdrlen;
|
||||
|
||||
vec[0].data = hdr;
|
||||
vec[0].len = hdrlen;
|
||||
vec[1].data = obj->data;
|
||||
@ -185,6 +191,16 @@ int git_obj_hash(git_oid *id, git_obj *obj)
|
||||
return GIT_SUCCESS;
|
||||
}
|
||||
|
||||
int git_obj_hash(git_oid *id, git_obj *obj)
|
||||
{
|
||||
char hdr[64];
|
||||
int hdrlen;
|
||||
|
||||
assert(id && obj);
|
||||
|
||||
return hash_obj(id, hdr, sizeof(hdr), &hdrlen, obj);
|
||||
}
|
||||
|
||||
static size_t object_file_name(char *name, size_t n, char *dir, const git_oid *id)
|
||||
{
|
||||
size_t len = strlen(dir);
|
||||
@ -483,6 +499,125 @@ static int inflate_disk_obj(git_obj *out, gitfo_buf *obj)
|
||||
return GIT_SUCCESS;
|
||||
}
|
||||
|
||||
static int make_temp_file(git_file *fd, char *tmp, size_t n, char *file)
|
||||
{
|
||||
char *template = "/tmp_obj_XXXXXX";
|
||||
size_t tmplen = strlen(template);
|
||||
size_t dirlen;
|
||||
|
||||
if ((dirlen = git__dirname(tmp, n, file)) < 0)
|
||||
return GIT_ERROR;
|
||||
|
||||
if ((dirlen + tmplen) >= n)
|
||||
return GIT_ERROR;
|
||||
|
||||
strcpy(tmp + dirlen, (dirlen) ? template : template + 1);
|
||||
|
||||
*fd = gitfo_mkstemp(tmp);
|
||||
if (*fd < 0 && dirlen) {
|
||||
/* create directory if it doesn't exist */
|
||||
tmp[dirlen] = '\0';
|
||||
if ((gitfo_exists(tmp) < 0) && gitfo_mkdir(tmp, 0755))
|
||||
return GIT_ERROR;
|
||||
/* try again */
|
||||
strcpy(tmp + dirlen, template);
|
||||
*fd = gitfo_mkstemp(tmp);
|
||||
}
|
||||
if (*fd < 0)
|
||||
return GIT_ERROR;
|
||||
|
||||
return GIT_SUCCESS;
|
||||
}
|
||||
|
||||
static int deflate_buf(z_stream *s, void *in, size_t len, int flush)
|
||||
{
|
||||
int status = Z_OK;
|
||||
|
||||
set_stream_input(s, in, len);
|
||||
while (status == Z_OK) {
|
||||
status = deflate(s, flush);
|
||||
if (s->avail_in == 0)
|
||||
break;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static int deflate_obj(gitfo_buf *buf, char *hdr, int hdrlen, git_obj *obj, int level)
|
||||
{
|
||||
z_stream zs;
|
||||
int status;
|
||||
size_t size;
|
||||
|
||||
assert(buf && !buf->data && hdr && obj);
|
||||
assert(level == Z_DEFAULT_COMPRESSION || (level >= 0 && level <= 9));
|
||||
|
||||
buf->data = NULL;
|
||||
buf->len = 0;
|
||||
init_stream(&zs, NULL, 0);
|
||||
|
||||
if (deflateInit(&zs, level) < Z_OK)
|
||||
return GIT_ERROR;
|
||||
|
||||
size = deflateBound(&zs, hdrlen + obj->len);
|
||||
|
||||
if ((buf->data = git__malloc(size)) == NULL) {
|
||||
deflateEnd(&zs);
|
||||
return GIT_ERROR;
|
||||
}
|
||||
|
||||
set_stream_output(&zs, buf->data, size);
|
||||
|
||||
/* compress the header */
|
||||
status = deflate_buf(&zs, hdr, hdrlen, Z_NO_FLUSH);
|
||||
|
||||
/* if header compressed OK, compress the object */
|
||||
if (status == Z_OK)
|
||||
status = deflate_buf(&zs, obj->data, obj->len, Z_FINISH);
|
||||
|
||||
if (status != Z_STREAM_END) {
|
||||
deflateEnd(&zs);
|
||||
free(buf->data);
|
||||
buf->data = NULL;
|
||||
return GIT_ERROR;
|
||||
}
|
||||
|
||||
buf->len = zs.total_out;
|
||||
deflateEnd(&zs);
|
||||
|
||||
return GIT_SUCCESS;
|
||||
}
|
||||
|
||||
static int write_obj(gitfo_buf *buf, git_oid *id, git_odb *db)
|
||||
{
|
||||
char file[GIT_PATH_MAX];
|
||||
char temp[GIT_PATH_MAX];
|
||||
git_file fd;
|
||||
|
||||
if (object_file_name(file, sizeof(file), db->objects_dir, id))
|
||||
return GIT_ERROR;
|
||||
|
||||
if (make_temp_file(&fd, temp, sizeof(temp), file) < 0)
|
||||
return GIT_ERROR;
|
||||
|
||||
if (gitfo_write(fd, buf->data, buf->len) < 0) {
|
||||
gitfo_close(fd);
|
||||
gitfo_unlink(temp);
|
||||
return GIT_ERROR;
|
||||
}
|
||||
|
||||
if (db->fsync_object_files)
|
||||
gitfo_fsync(fd);
|
||||
gitfo_close(fd);
|
||||
gitfo_chmod(temp, 0444);
|
||||
|
||||
if (gitfo_move_file(temp, file) < 0) {
|
||||
gitfo_unlink(temp);
|
||||
return GIT_ERROR;
|
||||
}
|
||||
|
||||
return GIT_SUCCESS;
|
||||
}
|
||||
|
||||
static int open_alternates(git_odb *db)
|
||||
{
|
||||
unsigned n = 0;
|
||||
@ -891,6 +1026,9 @@ int git_odb_open(git_odb **out, const char *objects_dir)
|
||||
|
||||
gitlck_init(&db->lock);
|
||||
|
||||
db->object_zlib_level = Z_BEST_SPEED;
|
||||
db->fsync_object_files = 0;
|
||||
|
||||
*out = db;
|
||||
return GIT_SUCCESS;
|
||||
}
|
||||
@ -1004,3 +1142,30 @@ int git_odb__read_packed(git_obj *out, git_odb *db, const git_oid *id)
|
||||
return GIT_ENOTFOUND;
|
||||
}
|
||||
|
||||
int git_odb_write(git_oid *id, git_odb *db, git_obj *obj)
|
||||
{
|
||||
char hdr[64];
|
||||
int hdrlen;
|
||||
gitfo_buf buf = GITFO_BUF_INIT;
|
||||
|
||||
assert(id && db && obj);
|
||||
|
||||
if (hash_obj(id, hdr, sizeof(hdr), &hdrlen, obj) < 0)
|
||||
return GIT_ERROR;
|
||||
|
||||
if (git_odb_exists(db, id))
|
||||
return GIT_SUCCESS;
|
||||
|
||||
if (deflate_obj(&buf, hdr, hdrlen, obj, db->object_zlib_level) < 0)
|
||||
return GIT_ERROR;
|
||||
|
||||
if (write_obj(&buf, id, db) < 0) {
|
||||
gitfo_free_buf(&buf);
|
||||
return GIT_ERROR;
|
||||
}
|
||||
|
||||
gitfo_free_buf(&buf);
|
||||
|
||||
return GIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -18,3 +18,5 @@ Categories
|
||||
addressable store.
|
||||
|
||||
02__: Basic object read access.
|
||||
|
||||
03__: Basic object writing.
|
||||
|
551
tests/t0301-write.c
Normal file
551
tests/t0301-write.c
Normal file
@ -0,0 +1,551 @@
|
||||
|
||||
#include "test_lib.h"
|
||||
#include <git/odb.h>
|
||||
#include "fileops.h"
|
||||
|
||||
static char *odb_dir = "test-objects";
|
||||
|
||||
typedef struct object_data {
|
||||
char *id; /* object id (sha1) */
|
||||
char *dir; /* object store (fan-out) directory name */
|
||||
char *file; /* object store filename */
|
||||
} object_data;
|
||||
|
||||
static object_data commit = {
|
||||
"3d7f8a6af076c8c3f20071a8935cdbe8228594d1",
|
||||
"test-objects/3d",
|
||||
"test-objects/3d/7f8a6af076c8c3f20071a8935cdbe8228594d1",
|
||||
};
|
||||
|
||||
static unsigned char commit_data[] = {
|
||||
0x74, 0x72, 0x65, 0x65, 0x20, 0x64, 0x66, 0x66,
|
||||
0x32, 0x64, 0x61, 0x39, 0x30, 0x62, 0x32, 0x35,
|
||||
0x34, 0x65, 0x31, 0x62, 0x65, 0x62, 0x38, 0x38,
|
||||
0x39, 0x64, 0x31, 0x66, 0x31, 0x66, 0x31, 0x32,
|
||||
0x38, 0x38, 0x62, 0x65, 0x31, 0x38, 0x30, 0x33,
|
||||
0x37, 0x38, 0x32, 0x64, 0x66, 0x0a, 0x61, 0x75,
|
||||
0x74, 0x68, 0x6f, 0x72, 0x20, 0x41, 0x20, 0x55,
|
||||
0x20, 0x54, 0x68, 0x6f, 0x72, 0x20, 0x3c, 0x61,
|
||||
0x75, 0x74, 0x68, 0x6f, 0x72, 0x40, 0x65, 0x78,
|
||||
0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
|
||||
0x6d, 0x3e, 0x20, 0x31, 0x32, 0x32, 0x37, 0x38,
|
||||
0x31, 0x34, 0x32, 0x39, 0x37, 0x20, 0x2b, 0x30,
|
||||
0x30, 0x30, 0x30, 0x0a, 0x63, 0x6f, 0x6d, 0x6d,
|
||||
0x69, 0x74, 0x74, 0x65, 0x72, 0x20, 0x43, 0x20,
|
||||
0x4f, 0x20, 0x4d, 0x69, 0x74, 0x74, 0x65, 0x72,
|
||||
0x20, 0x3c, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74,
|
||||
0x74, 0x65, 0x72, 0x40, 0x65, 0x78, 0x61, 0x6d,
|
||||
0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x3e,
|
||||
0x20, 0x31, 0x32, 0x32, 0x37, 0x38, 0x31, 0x34,
|
||||
0x32, 0x39, 0x37, 0x20, 0x2b, 0x30, 0x30, 0x30,
|
||||
0x30, 0x0a, 0x0a, 0x41, 0x20, 0x6f, 0x6e, 0x65,
|
||||
0x2d, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x63, 0x6f,
|
||||
0x6d, 0x6d, 0x69, 0x74, 0x20, 0x73, 0x75, 0x6d,
|
||||
0x6d, 0x61, 0x72, 0x79, 0x0a, 0x0a, 0x54, 0x68,
|
||||
0x65, 0x20, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x6f,
|
||||
0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f,
|
||||
0x6d, 0x6d, 0x69, 0x74, 0x20, 0x6d, 0x65, 0x73,
|
||||
0x73, 0x61, 0x67, 0x65, 0x2c, 0x20, 0x63, 0x6f,
|
||||
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67,
|
||||
0x20, 0x66, 0x75, 0x72, 0x74, 0x68, 0x65, 0x72,
|
||||
0x20, 0x65, 0x78, 0x70, 0x6c, 0x61, 0x6e, 0x61,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x6f, 0x66, 0x20,
|
||||
0x74, 0x68, 0x65, 0x20, 0x70, 0x75, 0x72, 0x70,
|
||||
0x6f, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74,
|
||||
0x68, 0x65, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67,
|
||||
0x65, 0x73, 0x20, 0x69, 0x6e, 0x74, 0x72, 0x6f,
|
||||
0x64, 0x75, 0x63, 0x65, 0x64, 0x20, 0x62, 0x79,
|
||||
0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d,
|
||||
0x6d, 0x69, 0x74, 0x2e, 0x0a, 0x0a, 0x53, 0x69,
|
||||
0x67, 0x6e, 0x65, 0x64, 0x2d, 0x6f, 0x66, 0x2d,
|
||||
0x62, 0x79, 0x3a, 0x20, 0x41, 0x20, 0x55, 0x20,
|
||||
0x54, 0x68, 0x6f, 0x72, 0x20, 0x3c, 0x61, 0x75,
|
||||
0x74, 0x68, 0x6f, 0x72, 0x40, 0x65, 0x78, 0x61,
|
||||
0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
|
||||
0x3e, 0x0a,
|
||||
};
|
||||
|
||||
static git_obj commit_obj = {
|
||||
commit_data,
|
||||
sizeof(commit_data),
|
||||
GIT_OBJ_COMMIT
|
||||
};
|
||||
|
||||
static object_data tree = {
|
||||
"dff2da90b254e1beb889d1f1f1288be1803782df",
|
||||
"test-objects/df",
|
||||
"test-objects/df/f2da90b254e1beb889d1f1f1288be1803782df",
|
||||
};
|
||||
|
||||
static unsigned char tree_data[] = {
|
||||
0x31, 0x30, 0x30, 0x36, 0x34, 0x34, 0x20, 0x6f,
|
||||
0x6e, 0x65, 0x00, 0x8b, 0x13, 0x78, 0x91, 0x79,
|
||||
0x1f, 0xe9, 0x69, 0x27, 0xad, 0x78, 0xe6, 0x4b,
|
||||
0x0a, 0xad, 0x7b, 0xde, 0xd0, 0x8b, 0xdc, 0x31,
|
||||
0x30, 0x30, 0x36, 0x34, 0x34, 0x20, 0x73, 0x6f,
|
||||
0x6d, 0x65, 0x00, 0xfd, 0x84, 0x30, 0xbc, 0x86,
|
||||
0x4c, 0xfc, 0xd5, 0xf1, 0x0e, 0x55, 0x90, 0xf8,
|
||||
0xa4, 0x47, 0xe0, 0x1b, 0x94, 0x2b, 0xfe, 0x31,
|
||||
0x30, 0x30, 0x36, 0x34, 0x34, 0x20, 0x74, 0x77,
|
||||
0x6f, 0x00, 0x78, 0x98, 0x19, 0x22, 0x61, 0x3b,
|
||||
0x2a, 0xfb, 0x60, 0x25, 0x04, 0x2f, 0xf6, 0xbd,
|
||||
0x87, 0x8a, 0xc1, 0x99, 0x4e, 0x85, 0x31, 0x30,
|
||||
0x30, 0x36, 0x34, 0x34, 0x20, 0x7a, 0x65, 0x72,
|
||||
0x6f, 0x00, 0xe6, 0x9d, 0xe2, 0x9b, 0xb2, 0xd1,
|
||||
0xd6, 0x43, 0x4b, 0x8b, 0x29, 0xae, 0x77, 0x5a,
|
||||
0xd8, 0xc2, 0xe4, 0x8c, 0x53, 0x91,
|
||||
};
|
||||
|
||||
static git_obj tree_obj = {
|
||||
tree_data,
|
||||
sizeof(tree_data),
|
||||
GIT_OBJ_TREE
|
||||
};
|
||||
|
||||
static object_data tag = {
|
||||
"09d373e1dfdc16b129ceec6dd649739911541e05",
|
||||
"test-objects/09",
|
||||
"test-objects/09/d373e1dfdc16b129ceec6dd649739911541e05",
|
||||
};
|
||||
|
||||
static unsigned char tag_data[] = {
|
||||
0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x33,
|
||||
0x64, 0x37, 0x66, 0x38, 0x61, 0x36, 0x61, 0x66,
|
||||
0x30, 0x37, 0x36, 0x63, 0x38, 0x63, 0x33, 0x66,
|
||||
0x32, 0x30, 0x30, 0x37, 0x31, 0x61, 0x38, 0x39,
|
||||
0x33, 0x35, 0x63, 0x64, 0x62, 0x65, 0x38, 0x32,
|
||||
0x32, 0x38, 0x35, 0x39, 0x34, 0x64, 0x31, 0x0a,
|
||||
0x74, 0x79, 0x70, 0x65, 0x20, 0x63, 0x6f, 0x6d,
|
||||
0x6d, 0x69, 0x74, 0x0a, 0x74, 0x61, 0x67, 0x20,
|
||||
0x76, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x0a, 0x74,
|
||||
0x61, 0x67, 0x67, 0x65, 0x72, 0x20, 0x43, 0x20,
|
||||
0x4f, 0x20, 0x4d, 0x69, 0x74, 0x74, 0x65, 0x72,
|
||||
0x20, 0x3c, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74,
|
||||
0x74, 0x65, 0x72, 0x40, 0x65, 0x78, 0x61, 0x6d,
|
||||
0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x3e,
|
||||
0x20, 0x31, 0x32, 0x32, 0x37, 0x38, 0x31, 0x34,
|
||||
0x32, 0x39, 0x37, 0x20, 0x2b, 0x30, 0x30, 0x30,
|
||||
0x30, 0x0a, 0x0a, 0x54, 0x68, 0x69, 0x73, 0x20,
|
||||
0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74,
|
||||
0x61, 0x67, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63,
|
||||
0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x72, 0x65,
|
||||
0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x76, 0x30,
|
||||
0x2e, 0x30, 0x2e, 0x31, 0x0a,
|
||||
};
|
||||
|
||||
static git_obj tag_obj = {
|
||||
tag_data,
|
||||
sizeof(tag_data),
|
||||
GIT_OBJ_TAG
|
||||
};
|
||||
|
||||
static object_data zero = {
|
||||
"e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
|
||||
"test-objects/e6",
|
||||
"test-objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391",
|
||||
};
|
||||
|
||||
static unsigned char zero_data[] = {
|
||||
0x00 /* dummy data */
|
||||
};
|
||||
|
||||
static git_obj zero_obj = {
|
||||
zero_data,
|
||||
0,
|
||||
GIT_OBJ_BLOB
|
||||
};
|
||||
|
||||
static object_data one = {
|
||||
"8b137891791fe96927ad78e64b0aad7bded08bdc",
|
||||
"test-objects/8b",
|
||||
"test-objects/8b/137891791fe96927ad78e64b0aad7bded08bdc",
|
||||
};
|
||||
|
||||
static unsigned char one_data[] = {
|
||||
0x0a,
|
||||
};
|
||||
|
||||
static git_obj one_obj = {
|
||||
one_data,
|
||||
sizeof(one_data),
|
||||
GIT_OBJ_BLOB
|
||||
};
|
||||
|
||||
static object_data two = {
|
||||
"78981922613b2afb6025042ff6bd878ac1994e85",
|
||||
"test-objects/78",
|
||||
"test-objects/78/981922613b2afb6025042ff6bd878ac1994e85",
|
||||
};
|
||||
|
||||
static unsigned char two_data[] = {
|
||||
0x61, 0x0a,
|
||||
};
|
||||
|
||||
static git_obj two_obj = {
|
||||
two_data,
|
||||
sizeof(two_data),
|
||||
GIT_OBJ_BLOB
|
||||
};
|
||||
|
||||
static object_data some = {
|
||||
"fd8430bc864cfcd5f10e5590f8a447e01b942bfe",
|
||||
"test-objects/fd",
|
||||
"test-objects/fd/8430bc864cfcd5f10e5590f8a447e01b942bfe",
|
||||
};
|
||||
|
||||
static unsigned char some_data[] = {
|
||||
0x2f, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x54, 0x68,
|
||||
0x69, 0x73, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20,
|
||||
0x69, 0x73, 0x20, 0x66, 0x72, 0x65, 0x65, 0x20,
|
||||
0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
|
||||
0x3b, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x63, 0x61,
|
||||
0x6e, 0x20, 0x72, 0x65, 0x64, 0x69, 0x73, 0x74,
|
||||
0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x69,
|
||||
0x74, 0x20, 0x61, 0x6e, 0x64, 0x2f, 0x6f, 0x72,
|
||||
0x20, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0a,
|
||||
0x20, 0x2a, 0x20, 0x69, 0x74, 0x20, 0x75, 0x6e,
|
||||
0x64, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20,
|
||||
0x74, 0x65, 0x72, 0x6d, 0x73, 0x20, 0x6f, 0x66,
|
||||
0x20, 0x74, 0x68, 0x65, 0x20, 0x47, 0x4e, 0x55,
|
||||
0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c,
|
||||
0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20,
|
||||
0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x2c,
|
||||
0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x20, 0x32, 0x2c, 0x0a, 0x20, 0x2a, 0x20, 0x61,
|
||||
0x73, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73,
|
||||
0x68, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74,
|
||||
0x68, 0x65, 0x20, 0x46, 0x72, 0x65, 0x65, 0x20,
|
||||
0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
|
||||
0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x20, 0x2a, 0x0a,
|
||||
0x20, 0x2a, 0x20, 0x49, 0x6e, 0x20, 0x61, 0x64,
|
||||
0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74,
|
||||
0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x65,
|
||||
0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x73, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65,
|
||||
0x20, 0x47, 0x4e, 0x55, 0x20, 0x47, 0x65, 0x6e,
|
||||
0x65, 0x72, 0x61, 0x6c, 0x20, 0x50, 0x75, 0x62,
|
||||
0x6c, 0x69, 0x63, 0x20, 0x4c, 0x69, 0x63, 0x65,
|
||||
0x6e, 0x73, 0x65, 0x2c, 0x0a, 0x20, 0x2a, 0x20,
|
||||
0x74, 0x68, 0x65, 0x20, 0x61, 0x75, 0x74, 0x68,
|
||||
0x6f, 0x72, 0x73, 0x20, 0x67, 0x69, 0x76, 0x65,
|
||||
0x20, 0x79, 0x6f, 0x75, 0x20, 0x75, 0x6e, 0x6c,
|
||||
0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x20, 0x70,
|
||||
0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x20, 0x74, 0x6f, 0x20, 0x6c, 0x69, 0x6e,
|
||||
0x6b, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f,
|
||||
0x6d, 0x70, 0x69, 0x6c, 0x65, 0x64, 0x0a, 0x20,
|
||||
0x2a, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69,
|
||||
0x73, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x69,
|
||||
0x6e, 0x74, 0x6f, 0x20, 0x63, 0x6f, 0x6d, 0x62,
|
||||
0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73,
|
||||
0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x6f, 0x74,
|
||||
0x68, 0x65, 0x72, 0x20, 0x70, 0x72, 0x6f, 0x67,
|
||||
0x72, 0x61, 0x6d, 0x73, 0x2c, 0x0a, 0x20, 0x2a,
|
||||
0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x6f, 0x20,
|
||||
0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75,
|
||||
0x74, 0x65, 0x20, 0x74, 0x68, 0x6f, 0x73, 0x65,
|
||||
0x20, 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x61,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x77, 0x69,
|
||||
0x74, 0x68, 0x6f, 0x75, 0x74, 0x20, 0x61, 0x6e,
|
||||
0x79, 0x20, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69,
|
||||
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x2a,
|
||||
0x20, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x20,
|
||||
0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65,
|
||||
0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20,
|
||||
0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x6c,
|
||||
0x65, 0x2e, 0x20, 0x20, 0x28, 0x54, 0x68, 0x65,
|
||||
0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c,
|
||||
0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20,
|
||||
0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x0a,
|
||||
0x20, 0x2a, 0x20, 0x72, 0x65, 0x73, 0x74, 0x72,
|
||||
0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20,
|
||||
0x64, 0x6f, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79,
|
||||
0x20, 0x69, 0x6e, 0x20, 0x6f, 0x74, 0x68, 0x65,
|
||||
0x72, 0x20, 0x72, 0x65, 0x73, 0x70, 0x65, 0x63,
|
||||
0x74, 0x73, 0x3b, 0x20, 0x66, 0x6f, 0x72, 0x20,
|
||||
0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2c,
|
||||
0x20, 0x74, 0x68, 0x65, 0x79, 0x20, 0x63, 0x6f,
|
||||
0x76, 0x65, 0x72, 0x0a, 0x20, 0x2a, 0x20, 0x6d,
|
||||
0x6f, 0x64, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74,
|
||||
0x68, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2c,
|
||||
0x20, 0x61, 0x6e, 0x64, 0x20, 0x64, 0x69, 0x73,
|
||||
0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x6e,
|
||||
0x6f, 0x74, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 0x65,
|
||||
0x64, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x0a, 0x20,
|
||||
0x2a, 0x20, 0x61, 0x20, 0x63, 0x6f, 0x6d, 0x62,
|
||||
0x69, 0x6e, 0x65, 0x64, 0x20, 0x65, 0x78, 0x65,
|
||||
0x63, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e,
|
||||
0x29, 0x0a, 0x20, 0x2a, 0x0a, 0x20, 0x2a, 0x20,
|
||||
0x54, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x6c,
|
||||
0x65, 0x20, 0x69, 0x73, 0x20, 0x64, 0x69, 0x73,
|
||||
0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64,
|
||||
0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20,
|
||||
0x68, 0x6f, 0x70, 0x65, 0x20, 0x74, 0x68, 0x61,
|
||||
0x74, 0x20, 0x69, 0x74, 0x20, 0x77, 0x69, 0x6c,
|
||||
0x6c, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65,
|
||||
0x66, 0x75, 0x6c, 0x2c, 0x20, 0x62, 0x75, 0x74,
|
||||
0x0a, 0x20, 0x2a, 0x20, 0x57, 0x49, 0x54, 0x48,
|
||||
0x4f, 0x55, 0x54, 0x20, 0x41, 0x4e, 0x59, 0x20,
|
||||
0x57, 0x41, 0x52, 0x52, 0x41, 0x4e, 0x54, 0x59,
|
||||
0x3b, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75,
|
||||
0x74, 0x20, 0x65, 0x76, 0x65, 0x6e, 0x20, 0x74,
|
||||
0x68, 0x65, 0x20, 0x69, 0x6d, 0x70, 0x6c, 0x69,
|
||||
0x65, 0x64, 0x20, 0x77, 0x61, 0x72, 0x72, 0x61,
|
||||
0x6e, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x0a, 0x20,
|
||||
0x2a, 0x20, 0x4d, 0x45, 0x52, 0x43, 0x48, 0x41,
|
||||
0x4e, 0x54, 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54,
|
||||
0x59, 0x20, 0x6f, 0x72, 0x20, 0x46, 0x49, 0x54,
|
||||
0x4e, 0x45, 0x53, 0x53, 0x20, 0x46, 0x4f, 0x52,
|
||||
0x20, 0x41, 0x20, 0x50, 0x41, 0x52, 0x54, 0x49,
|
||||
0x43, 0x55, 0x4c, 0x41, 0x52, 0x20, 0x50, 0x55,
|
||||
0x52, 0x50, 0x4f, 0x53, 0x45, 0x2e, 0x20, 0x20,
|
||||
0x53, 0x65, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20,
|
||||
0x47, 0x4e, 0x55, 0x0a, 0x20, 0x2a, 0x20, 0x47,
|
||||
0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x20, 0x50,
|
||||
0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x4c, 0x69,
|
||||
0x63, 0x65, 0x6e, 0x73, 0x65, 0x20, 0x66, 0x6f,
|
||||
0x72, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x64,
|
||||
0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x2e, 0x0a,
|
||||
0x20, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x59, 0x6f,
|
||||
0x75, 0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64,
|
||||
0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x72, 0x65,
|
||||
0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x20, 0x61,
|
||||
0x20, 0x63, 0x6f, 0x70, 0x79, 0x20, 0x6f, 0x66,
|
||||
0x20, 0x74, 0x68, 0x65, 0x20, 0x47, 0x4e, 0x55,
|
||||
0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c,
|
||||
0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20,
|
||||
0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x0a,
|
||||
0x20, 0x2a, 0x20, 0x61, 0x6c, 0x6f, 0x6e, 0x67,
|
||||
0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68,
|
||||
0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72,
|
||||
0x61, 0x6d, 0x3b, 0x20, 0x73, 0x65, 0x65, 0x20,
|
||||
0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65,
|
||||
0x20, 0x43, 0x4f, 0x50, 0x59, 0x49, 0x4e, 0x47,
|
||||
0x2e, 0x20, 0x20, 0x49, 0x66, 0x20, 0x6e, 0x6f,
|
||||
0x74, 0x2c, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65,
|
||||
0x20, 0x74, 0x6f, 0x0a, 0x20, 0x2a, 0x20, 0x74,
|
||||
0x68, 0x65, 0x20, 0x46, 0x72, 0x65, 0x65, 0x20,
|
||||
0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
|
||||
0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x35, 0x31, 0x20,
|
||||
0x46, 0x72, 0x61, 0x6e, 0x6b, 0x6c, 0x69, 0x6e,
|
||||
0x20, 0x53, 0x74, 0x72, 0x65, 0x65, 0x74, 0x2c,
|
||||
0x20, 0x46, 0x69, 0x66, 0x74, 0x68, 0x20, 0x46,
|
||||
0x6c, 0x6f, 0x6f, 0x72, 0x2c, 0x0a, 0x20, 0x2a,
|
||||
0x20, 0x42, 0x6f, 0x73, 0x74, 0x6f, 0x6e, 0x2c,
|
||||
0x20, 0x4d, 0x41, 0x20, 0x30, 0x32, 0x31, 0x31,
|
||||
0x30, 0x2d, 0x31, 0x33, 0x30, 0x31, 0x2c, 0x20,
|
||||
0x55, 0x53, 0x41, 0x2e, 0x0a, 0x20, 0x2a, 0x2f,
|
||||
0x0a,
|
||||
};
|
||||
|
||||
static git_obj some_obj = {
|
||||
some_data,
|
||||
sizeof(some_data),
|
||||
GIT_OBJ_BLOB
|
||||
};
|
||||
|
||||
static int make_odb_dir(void)
|
||||
{
|
||||
if (gitfo_mkdir(odb_dir, 0755) < 0) {
|
||||
if (errno == EEXIST) {
|
||||
fprintf(stderr, "odb directory \"%s\" already exists!\n", odb_dir);
|
||||
return -1;
|
||||
}
|
||||
fprintf(stderr, "can't make odb directory \"%s\"\n", odb_dir);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int remove_object_files(object_data *d)
|
||||
{
|
||||
if (gitfo_unlink(d->file) < 0) {
|
||||
fprintf(stderr, "can't delete object file \"%s\"\n", d->file);
|
||||
return -1;
|
||||
}
|
||||
if ((gitfo_rmdir(d->dir) < 0) && (errno != ENOTEMPTY)) {
|
||||
fprintf(stderr, "can't remove object directory \"%s\"\n", d->dir);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (gitfo_rmdir(odb_dir) < 0) {
|
||||
fprintf(stderr, "can't remove odb directory \"%s\"\n", odb_dir);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int check_object_files(object_data *d)
|
||||
{
|
||||
if (gitfo_exists(d->dir) < 0)
|
||||
return -1;
|
||||
if (gitfo_exists(d->file) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmp_objects(git_obj *o1, git_obj *o2)
|
||||
{
|
||||
if (o1->type != o2->type)
|
||||
return -1;
|
||||
if (o1->len != o2->len)
|
||||
return -1;
|
||||
if ((o1->len > 0) && (memcmp(o1->data, o2->data, o1->len) != 0))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
BEGIN_TEST(write_commit)
|
||||
git_odb *db;
|
||||
git_oid id1, id2;
|
||||
git_obj obj;
|
||||
|
||||
must_pass(make_odb_dir());
|
||||
must_pass(git_odb_open(&db, odb_dir));
|
||||
must_pass(git_oid_mkstr(&id1, commit.id));
|
||||
|
||||
must_pass(git_odb_write(&id2, db, &commit_obj));
|
||||
must_be_true(git_oid_cmp(&id1, &id2) == 0);
|
||||
must_pass(check_object_files(&commit));
|
||||
|
||||
must_pass(git_odb__read_loose(&obj, db, &id1));
|
||||
must_pass(cmp_objects(&obj, &commit_obj));
|
||||
|
||||
git_obj_close(&obj);
|
||||
git_odb_close(db);
|
||||
must_pass(remove_object_files(&commit));
|
||||
END_TEST
|
||||
|
||||
BEGIN_TEST(write_tree)
|
||||
git_odb *db;
|
||||
git_oid id1, id2;
|
||||
git_obj obj;
|
||||
|
||||
must_pass(make_odb_dir());
|
||||
must_pass(git_odb_open(&db, odb_dir));
|
||||
must_pass(git_oid_mkstr(&id1, tree.id));
|
||||
|
||||
must_pass(git_odb_write(&id2, db, &tree_obj));
|
||||
must_be_true(git_oid_cmp(&id1, &id2) == 0);
|
||||
must_pass(check_object_files(&tree));
|
||||
|
||||
must_pass(git_odb__read_loose(&obj, db, &id1));
|
||||
must_pass(cmp_objects(&obj, &tree_obj));
|
||||
|
||||
git_obj_close(&obj);
|
||||
git_odb_close(db);
|
||||
must_pass(remove_object_files(&tree));
|
||||
END_TEST
|
||||
|
||||
BEGIN_TEST(write_tag)
|
||||
git_odb *db;
|
||||
git_oid id1, id2;
|
||||
git_obj obj;
|
||||
|
||||
must_pass(make_odb_dir());
|
||||
must_pass(git_odb_open(&db, odb_dir));
|
||||
must_pass(git_oid_mkstr(&id1, tag.id));
|
||||
|
||||
must_pass(git_odb_write(&id2, db, &tag_obj));
|
||||
must_be_true(git_oid_cmp(&id1, &id2) == 0);
|
||||
must_pass(check_object_files(&tag));
|
||||
|
||||
must_pass(git_odb__read_loose(&obj, db, &id1));
|
||||
must_pass(cmp_objects(&obj, &tag_obj));
|
||||
|
||||
git_obj_close(&obj);
|
||||
git_odb_close(db);
|
||||
must_pass(remove_object_files(&tag));
|
||||
END_TEST
|
||||
|
||||
BEGIN_TEST(write_zero)
|
||||
git_odb *db;
|
||||
git_oid id1, id2;
|
||||
git_obj obj;
|
||||
|
||||
must_pass(make_odb_dir());
|
||||
must_pass(git_odb_open(&db, odb_dir));
|
||||
must_pass(git_oid_mkstr(&id1, zero.id));
|
||||
|
||||
must_pass(git_odb_write(&id2, db, &zero_obj));
|
||||
must_be_true(git_oid_cmp(&id1, &id2) == 0);
|
||||
must_pass(check_object_files(&zero));
|
||||
|
||||
must_pass(git_odb__read_loose(&obj, db, &id1));
|
||||
must_pass(cmp_objects(&obj, &zero_obj));
|
||||
|
||||
git_obj_close(&obj);
|
||||
git_odb_close(db);
|
||||
must_pass(remove_object_files(&zero));
|
||||
END_TEST
|
||||
|
||||
BEGIN_TEST(write_one)
|
||||
git_odb *db;
|
||||
git_oid id1, id2;
|
||||
git_obj obj;
|
||||
|
||||
must_pass(make_odb_dir());
|
||||
must_pass(git_odb_open(&db, odb_dir));
|
||||
must_pass(git_oid_mkstr(&id1, one.id));
|
||||
|
||||
must_pass(git_odb_write(&id2, db, &one_obj));
|
||||
must_be_true(git_oid_cmp(&id1, &id2) == 0);
|
||||
must_pass(check_object_files(&one));
|
||||
|
||||
must_pass(git_odb__read_loose(&obj, db, &id1));
|
||||
must_pass(cmp_objects(&obj, &one_obj));
|
||||
|
||||
git_obj_close(&obj);
|
||||
git_odb_close(db);
|
||||
must_pass(remove_object_files(&one));
|
||||
END_TEST
|
||||
|
||||
BEGIN_TEST(write_two)
|
||||
git_odb *db;
|
||||
git_oid id1, id2;
|
||||
git_obj obj;
|
||||
|
||||
must_pass(make_odb_dir());
|
||||
must_pass(git_odb_open(&db, odb_dir));
|
||||
must_pass(git_oid_mkstr(&id1, two.id));
|
||||
|
||||
must_pass(git_odb_write(&id2, db, &two_obj));
|
||||
must_be_true(git_oid_cmp(&id1, &id2) == 0);
|
||||
must_pass(check_object_files(&two));
|
||||
|
||||
must_pass(git_odb__read_loose(&obj, db, &id1));
|
||||
must_pass(cmp_objects(&obj, &two_obj));
|
||||
|
||||
git_obj_close(&obj);
|
||||
git_odb_close(db);
|
||||
must_pass(remove_object_files(&two));
|
||||
END_TEST
|
||||
|
||||
BEGIN_TEST(write_some)
|
||||
git_odb *db;
|
||||
git_oid id1, id2;
|
||||
git_obj obj;
|
||||
|
||||
must_pass(make_odb_dir());
|
||||
must_pass(git_odb_open(&db, odb_dir));
|
||||
must_pass(git_oid_mkstr(&id1, some.id));
|
||||
|
||||
must_pass(git_odb_write(&id2, db, &some_obj));
|
||||
must_be_true(git_oid_cmp(&id1, &id2) == 0);
|
||||
must_pass(check_object_files(&some));
|
||||
|
||||
must_pass(git_odb__read_loose(&obj, db, &id1));
|
||||
must_pass(cmp_objects(&obj, &some_obj));
|
||||
|
||||
git_obj_close(&obj);
|
||||
git_odb_close(db);
|
||||
must_pass(remove_object_files(&some));
|
||||
END_TEST
|
||||
|
Loading…
Reference in New Issue
Block a user