Initial commit - full huishou project

This commit is contained in:
jiapengyu
2026-07-27 14:07:26 +08:00
commit 60790ad1b3
39127 changed files with 5989265 additions and 0 deletions
+150
View File
@@ -0,0 +1,150 @@
#include "clar_libgit2.h"
#include "posix.h"
#include "blob.h"
#include "buf_text.h"
static git_repository *g_repo = NULL;
#define CRLF_NUM_TEST_OBJECTS 9
static const char *g_crlf_raw[CRLF_NUM_TEST_OBJECTS] = {
"",
"foo\nbar\n",
"foo\rbar\r",
"foo\r\nbar\r\n",
"foo\nbar\rboth\r\nreversed\n\ragain\nproblems\r",
"123\n\000\001\002\003\004abc\255\254\253\r\n",
"\xEF\xBB\xBFThis is UTF-8\n",
"\xEF\xBB\xBF\xE3\x81\xBB\xE3\x81\x92\xE3\x81\xBB\xE3\x81\x92\r\n\xE3\x81\xBB\xE3\x81\x92\xE3\x81\xBB\xE3\x81\x92\r\n",
"\xFE\xFF\x00T\x00h\x00i\x00s\x00!"
};
static off64_t g_crlf_raw_len[CRLF_NUM_TEST_OBJECTS] = {
-1, -1, -1, -1, -1, 17, -1, -1, 12
};
static git_oid g_crlf_oids[CRLF_NUM_TEST_OBJECTS];
static git_buf g_crlf_filtered[CRLF_NUM_TEST_OBJECTS] = {
{ "", 0, 0 },
{ "foo\nbar\n", 0, 8 },
{ "foo\rbar\r", 0, 8 },
{ "foo\nbar\n", 0, 8 },
{ "foo\nbar\rboth\nreversed\n\ragain\nproblems\r", 0, 38 },
{ "123\n\000\001\002\003\004abc\255\254\253\n", 0, 16 },
{ "\xEF\xBB\xBFThis is UTF-8\n", 0, 17 },
{ "\xEF\xBB\xBF\xE3\x81\xBB\xE3\x81\x92\xE3\x81\xBB\xE3\x81\x92\n\xE3\x81\xBB\xE3\x81\x92\xE3\x81\xBB\xE3\x81\x92\n", 0, 29 },
{ "\xFE\xFF\x00T\x00h\x00i\x00s\x00!", 0, 12 }
};
static git_buf_text_stats g_crlf_filtered_stats[CRLF_NUM_TEST_OBJECTS] = {
{ 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 2, 0, 6, 0 },
{ 0, 0, 2, 0, 0, 6, 0 },
{ 0, 0, 2, 2, 2, 6, 0 },
{ 0, 0, 4, 4, 1, 31, 0 },
{ 0, 1, 1, 2, 1, 9, 5 },
{ GIT_BOM_UTF8, 0, 0, 1, 0, 16, 0 },
{ GIT_BOM_UTF8, 0, 2, 2, 2, 27, 0 },
{ GIT_BOM_UTF16_BE, 5, 0, 0, 0, 7, 5 },
};
void test_object_blob_filter__initialize(void)
{
int i;
g_repo = cl_git_sandbox_init("empty_standard_repo");
for (i = 0; i < CRLF_NUM_TEST_OBJECTS; i++) {
if (g_crlf_raw_len[i] < 0)
g_crlf_raw_len[i] = strlen(g_crlf_raw[i]);
cl_git_pass(git_blob_create_from_buffer(
&g_crlf_oids[i], g_repo, g_crlf_raw[i], (size_t)g_crlf_raw_len[i]));
}
}
void test_object_blob_filter__cleanup(void)
{
cl_git_sandbox_cleanup();
}
void test_object_blob_filter__unfiltered(void)
{
int i;
git_blob *blob;
for (i = 0; i < CRLF_NUM_TEST_OBJECTS; i++) {
size_t raw_len = (size_t)g_crlf_raw_len[i];
cl_git_pass(git_blob_lookup(&blob, g_repo, &g_crlf_oids[i]));
cl_assert_equal_sz(raw_len, (size_t)git_blob_rawsize(blob));
cl_assert_equal_i(
0, memcmp(g_crlf_raw[i], git_blob_rawcontent(blob), raw_len));
git_blob_free(blob);
}
}
void test_object_blob_filter__stats(void)
{
int i;
git_blob *blob;
git_buf buf = GIT_BUF_INIT;
git_buf_text_stats stats;
for (i = 0; i < CRLF_NUM_TEST_OBJECTS; i++) {
cl_git_pass(git_blob_lookup(&blob, g_repo, &g_crlf_oids[i]));
cl_git_pass(git_blob__getbuf(&buf, blob));
git_buf_text_gather_stats(&stats, &buf, false);
cl_assert_equal_i(
0, memcmp(&g_crlf_filtered_stats[i], &stats, sizeof(stats)));
git_blob_free(blob);
}
git_buf_dispose(&buf);
}
void test_object_blob_filter__to_odb(void)
{
git_filter_list *fl = NULL;
git_config *cfg;
int i;
git_blob *blob;
git_buf out = GIT_BUF_INIT, zeroed;
cl_git_pass(git_repository_config(&cfg, g_repo));
cl_assert(cfg);
git_attr_cache_flush(g_repo);
cl_git_append2file("empty_standard_repo/.gitattributes", "*.txt text\n");
cl_git_pass(git_filter_list_load(
&fl, g_repo, NULL, "filename.txt", GIT_FILTER_TO_ODB, 0));
cl_assert(fl != NULL);
for (i = 0; i < CRLF_NUM_TEST_OBJECTS; i++) {
cl_git_pass(git_blob_lookup(&blob, g_repo, &g_crlf_oids[i]));
/* try once with allocated blob */
cl_git_pass(git_filter_list_apply_to_blob(&out, fl, blob));
cl_assert_equal_sz(g_crlf_filtered[i].size, out.size);
cl_assert_equal_i(
0, memcmp(out.ptr, g_crlf_filtered[i].ptr, out.size));
/* try again with zeroed blob */
memset(&zeroed, 0, sizeof(zeroed));
cl_git_pass(git_filter_list_apply_to_blob(&zeroed, fl, blob));
cl_assert_equal_sz(g_crlf_filtered[i].size, zeroed.size);
cl_assert_equal_i(
0, memcmp(zeroed.ptr, g_crlf_filtered[i].ptr, zeroed.size));
git_buf_dispose(&zeroed);
git_blob_free(blob);
}
git_filter_list_free(fl);
git_buf_dispose(&out);
git_config_free(cfg);
}
+87
View File
@@ -0,0 +1,87 @@
#include "clar_libgit2.h"
#include "buffer.h"
#include "posix.h"
#include "path.h"
#include "futils.h"
static git_repository *repo;
static char textual_content[] = "libgit2\n\r\n\0";
void test_object_blob_fromstream__initialize(void)
{
repo = cl_git_sandbox_init("testrepo.git");
}
void test_object_blob_fromstream__cleanup(void)
{
cl_git_sandbox_cleanup();
}
void test_object_blob_fromstream__multiple_write(void)
{
git_oid expected_id, id;
git_object *blob;
git_writestream *stream;
int i, howmany = 6;
cl_git_pass(git_oid_fromstr(&expected_id, "321cbdf08803c744082332332838df6bd160f8f9"));
cl_git_fail_with(GIT_ENOTFOUND,
git_object_lookup(&blob, repo, &expected_id, GIT_OBJECT_ANY));
cl_git_pass(git_blob_create_from_stream(&stream, repo, NULL));
for (i = 0; i < howmany; i++)
cl_git_pass(stream->write(stream, textual_content, strlen(textual_content)));
cl_git_pass(git_blob_create_from_stream_commit(&id, stream));
cl_assert_equal_oid(&expected_id, &id);
cl_git_pass(git_object_lookup(&blob, repo, &expected_id, GIT_OBJECT_BLOB));
git_object_free(blob);
}
#define GITATTR "* text=auto\n" \
"*.txt text\n" \
"*.data binary\n"
static void write_attributes(git_repository *repo)
{
git_buf buf = GIT_BUF_INIT;
cl_git_pass(git_buf_joinpath(&buf, git_repository_path(repo), "info"));
cl_git_pass(git_buf_joinpath(&buf, git_buf_cstr(&buf), "attributes"));
cl_git_pass(git_futils_mkpath2file(git_buf_cstr(&buf), 0777));
cl_git_rewritefile(git_buf_cstr(&buf), GITATTR);
git_buf_dispose(&buf);
}
static void assert_named_chunked_blob(const char *expected_sha, const char *fake_name)
{
git_oid expected_id, id;
git_writestream *stream;
int i, howmany = 6;
cl_git_pass(git_oid_fromstr(&expected_id, expected_sha));
cl_git_pass(git_blob_create_from_stream(&stream, repo, fake_name));
for (i = 0; i < howmany; i++)
cl_git_pass(stream->write(stream, textual_content, strlen(textual_content)));
cl_git_pass(git_blob_create_from_stream_commit(&id, stream));
cl_assert_equal_oid(&expected_id, &id);
}
void test_object_blob_fromstream__creating_a_blob_from_chunks_honors_the_attributes_directives(void)
{
write_attributes(repo);
assert_named_chunked_blob("321cbdf08803c744082332332838df6bd160f8f9", "dummy.data");
assert_named_chunked_blob("e9671e138a780833cb689753570fd10a55be84fb", "dummy.txt");
assert_named_chunked_blob("e9671e138a780833cb689753570fd10a55be84fb", "dummy.dunno");
}
+69
View File
@@ -0,0 +1,69 @@
#include "clar_libgit2.h"
#include "buffer.h"
#include "posix.h"
#include "path.h"
#include "futils.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_from_workdir);
}
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_from_disk);
git_buf_dispose(&full_path);
cl_must_pass(git_futils_rmdir_r(ELSEWHERE, NULL, GIT_RMDIR_REMOVE_FILES));
}
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_from_disk);
git_buf_dispose(&full_path);
cl_must_pass(git_futils_rmdir_r(ELSEWHERE, NULL, GIT_RMDIR_REMOVE_FILES));
}
+276
View File
@@ -0,0 +1,276 @@
#include "clar_libgit2.h"
#include "repository.h"
static git_repository *g_repo;
static size_t cache_limit;
static int object_type;
void test_object_cache__initialize_cache_no_blobs(void)
{
g_repo = NULL;
object_type = GIT_OBJECT_BLOB;
cache_limit = 0;
}
void test_object_cache__initialize_cache_tiny_blobs(void)
{
g_repo = NULL;
object_type = GIT_OBJECT_BLOB;
cache_limit = 10;
}
void test_object_cache__initialize_cache_all_blobs(void)
{
g_repo = NULL;
object_type = GIT_OBJECT_BLOB;
cache_limit = 32767;
}
void test_object_cache__initialize_cache_no_trees(void)
{
g_repo = NULL;
object_type = GIT_OBJECT_TREE;
cache_limit = 0;
}
void test_object_cache__cleanup(void)
{
git_repository_free(g_repo);
g_repo = NULL;
git_libgit2_opts(GIT_OPT_SET_CACHE_OBJECT_LIMIT, (int)GIT_OBJECT_BLOB, (size_t)0);
git_libgit2_opts(GIT_OPT_SET_CACHE_OBJECT_LIMIT, (int)GIT_OBJECT_TREE, (size_t)4096);
git_libgit2_opts(GIT_OPT_SET_CACHE_OBJECT_LIMIT, (int)GIT_OBJECT_COMMIT, (size_t)4096);
}
static struct {
git_object_t type;
const char *sha;
size_t size;
} g_data[] = {
/* HEAD */
{ GIT_OBJECT_BLOB, "a8233120f6ad708f843d861ce2b7228ec4e3dec6", 10 }, /* README */
{ GIT_OBJECT_BLOB, "3697d64be941a53d4ae8f6a271e4e3fa56b022cc", 8 }, /* branch_file.txt */
{ GIT_OBJECT_BLOB, "a71586c1dfe8a71c6cbf6c129f404c5642ff31bd", 12 }, /* new.txt */
/* refs/heads/subtrees */
{ GIT_OBJECT_BLOB, "1385f264afb75a56a5bec74243be9b367ba4ca08", 4 }, /* README */
{ GIT_OBJECT_TREE, "f1425cef211cc08caa31e7b545ffb232acb098c3", 90 }, /* ab */
{ GIT_OBJECT_BLOB, "d6c93164c249c8000205dd4ec5cbca1b516d487f", 6 }, /* ab/4.txt */
{ GIT_OBJECT_TREE, "9a03079b8a8ee85a0bee58bf9be3da8b62414ed4", 33 }, /* ab/c */
{ GIT_OBJECT_BLOB, "270b8ea76056d5cad83af921837702d3e3c2924d", 6 }, /* ab/c/3.txt */
{ GIT_OBJECT_TREE, "b6361fc6a97178d8fc8639fdeed71c775ab52593", 63 }, /* ab/de */
{ GIT_OBJECT_BLOB, "e7b4ad382349ff96dd8199000580b9b1e2042eb0", 6 }, /* ab/de/2.txt */
{ GIT_OBJECT_TREE, "3259a6bd5b57fb9c1281bb7ed3167b50f224cb54", 33 }, /* ab/de/fgh */
{ GIT_OBJECT_BLOB, "1f67fc4386b2d171e0d21be1c447e12660561f9b", 6 }, /* ab/de/fgh/1.txt */
{ GIT_OBJECT_BLOB, "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", 3 }, /* branch_file.txt */
{ GIT_OBJECT_BLOB, "fa49b077972391ad58037050f2a75f74e3671e92", 9 }, /* new.txt */
/* refs/heads/chomped */
{ GIT_OBJECT_BLOB, "0266163a49e280c4f5ed1e08facd36a2bd716bcf", 51 }, /* readme.txt */
{ 0, NULL, 0 },
{ 0, NULL, 0 }
};
void test_object_cache__cache_counts(void)
{
int i, start, nonmatching = 0;
git_oid oid;
git_odb_object *odb_obj;
git_object *obj;
git_odb *odb;
git_libgit2_opts(GIT_OPT_SET_CACHE_OBJECT_LIMIT, object_type, cache_limit);
cl_git_pass(git_repository_open(&g_repo, cl_fixture("testrepo.git")));
cl_git_pass(git_repository_odb(&odb, g_repo));
start = (int)git_cache_size(&g_repo->objects);
for (i = 0; g_data[i].sha != NULL; ++i) {
int count = (int)git_cache_size(&g_repo->objects);
cl_git_pass(git_oid_fromstr(&oid, g_data[i].sha));
/* alternate between loading raw and parsed objects */
if ((i & 1) == 0) {
cl_git_pass(git_odb_read(&odb_obj, odb, &oid));
cl_assert(g_data[i].type == git_odb_object_type(odb_obj));
git_odb_object_free(odb_obj);
} else {
cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJECT_ANY));
cl_assert(g_data[i].type == git_object_type(obj));
git_object_free(obj);
}
if ((g_data[i].type == object_type && g_data[i].size >= cache_limit) ||
(g_data[i].type != object_type && g_data[i].type == GIT_OBJECT_BLOB))
cl_assert_equal_i(count, (int)git_cache_size(&g_repo->objects));
else {
cl_assert_equal_i(count + 1, (int)git_cache_size(&g_repo->objects));
nonmatching++;
}
}
cl_assert_equal_i(nonmatching, (int)git_cache_size(&g_repo->objects) - start);
for (i = 0; g_data[i].sha != NULL; ++i) {
int count = (int)git_cache_size(&g_repo->objects);
cl_git_pass(git_oid_fromstr(&oid, g_data[i].sha));
cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJECT_ANY));
cl_assert(g_data[i].type == git_object_type(obj));
git_object_free(obj);
cl_assert_equal_i(count, (int)git_cache_size(&g_repo->objects));
}
git_odb_free(odb);
}
static void *cache_parsed(void *arg)
{
int i;
git_oid oid;
git_object *obj;
for (i = ((int *)arg)[1]; g_data[i].sha != NULL; i += 2) {
cl_git_pass(git_oid_fromstr(&oid, g_data[i].sha));
cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJECT_ANY));
cl_assert(g_data[i].type == git_object_type(obj));
git_object_free(obj);
}
for (i = 0; i < ((int *)arg)[1]; i += 2) {
cl_git_pass(git_oid_fromstr(&oid, g_data[i].sha));
cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJECT_ANY));
cl_assert(g_data[i].type == git_object_type(obj));
git_object_free(obj);
}
return arg;
}
static void *cache_raw(void *arg)
{
int i;
git_oid oid;
git_odb *odb;
git_odb_object *odb_obj;
cl_git_pass(git_repository_odb(&odb, g_repo));
for (i = ((int *)arg)[1]; g_data[i].sha != NULL; i += 2) {
cl_git_pass(git_oid_fromstr(&oid, g_data[i].sha));
cl_git_pass(git_odb_read(&odb_obj, odb, &oid));
cl_assert(g_data[i].type == git_odb_object_type(odb_obj));
git_odb_object_free(odb_obj);
}
for (i = 0; i < ((int *)arg)[1]; i += 2) {
cl_git_pass(git_oid_fromstr(&oid, g_data[i].sha));
cl_git_pass(git_odb_read(&odb_obj, odb, &oid));
cl_assert(g_data[i].type == git_odb_object_type(odb_obj));
git_odb_object_free(odb_obj);
}
git_odb_free(odb);
return arg;
}
#define REPEAT 20
#define THREADCOUNT 50
void test_object_cache__threadmania(void)
{
int try, th, max_i;
void *data;
void *(*fn)(void *);
#ifdef GIT_THREADS
git_thread t[THREADCOUNT];
#endif
for (max_i = 0; g_data[max_i].sha != NULL; ++max_i)
/* count up */;
for (try = 0; try < REPEAT; ++try) {
cl_git_pass(git_repository_open(&g_repo, cl_fixture("testrepo.git")));
for (th = 0; th < THREADCOUNT; ++th) {
data = git__malloc(2 * sizeof(int));
((int *)data)[0] = th;
((int *)data)[1] = th % max_i;
fn = (th & 1) ? cache_parsed : cache_raw;
#ifdef GIT_THREADS
cl_git_pass(git_thread_create(&t[th], fn, data));
#else
cl_assert(fn(data) == data);
git__free(data);
#endif
}
#ifdef GIT_THREADS
for (th = 0; th < THREADCOUNT; ++th) {
cl_git_pass(git_thread_join(&t[th], &data));
cl_assert_equal_i(th, ((int *)data)[0]);
git__free(data);
}
#endif
git_repository_free(g_repo);
g_repo = NULL;
}
}
static void *cache_quick(void *arg)
{
git_oid oid;
git_object *obj;
cl_git_pass(git_oid_fromstr(&oid, g_data[4].sha));
cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJECT_ANY));
cl_assert(g_data[4].type == git_object_type(obj));
git_object_free(obj);
return arg;
}
void test_object_cache__fast_thread_rush(void)
{
int try, th, data[THREADCOUNT*2];
#ifdef GIT_THREADS
git_thread t[THREADCOUNT*2];
#endif
for (try = 0; try < REPEAT; ++try) {
cl_git_pass(git_repository_open(&g_repo, cl_fixture("testrepo.git")));
for (th = 0; th < THREADCOUNT*2; ++th) {
data[th] = th;
#ifdef GIT_THREADS
cl_git_pass(
git_thread_create(&t[th], cache_quick, &data[th]));
#else
cl_assert(cache_quick(&data[th]) == &data[th]);
#endif
}
#ifdef GIT_THREADS
for (th = 0; th < THREADCOUNT*2; ++th) {
void *rval;
cl_git_pass(git_thread_join(&t[th], &rval));
cl_assert_equal_i(th, *((int *)rval));
}
#endif
git_repository_free(g_repo);
g_repo = NULL;
}
}
@@ -0,0 +1,219 @@
#include "clar_libgit2.h"
#include "posix.h"
static git_repository *repo;
void test_object_commit_commitstagedfile__initialize(void)
{
cl_fixture("treebuilder");
cl_git_pass(git_repository_init(&repo, "treebuilder/", 0));
cl_assert(repo != NULL);
}
void test_object_commit_commitstagedfile__cleanup(void)
{
git_repository_free(repo);
repo = NULL;
cl_fixture_cleanup("treebuilder");
}
void test_object_commit_commitstagedfile__generate_predictable_object_ids(void)
{
git_index *index;
const git_index_entry *entry;
git_oid expected_blob_oid, tree_oid, expected_tree_oid, commit_oid, expected_commit_oid;
git_signature *signature;
git_tree *tree;
git_buf buffer;
/*
* The test below replicates the following git scenario
*
* $ echo "test" > test.txt
* $ git hash-object test.txt
* 9daeafb9864cf43055ae93beb0afd6c7d144bfa4
*
* $ git add .
* $ git commit -m "Initial commit"
*
* $ git log
* commit 1fe3126578fc4eca68c193e4a3a0a14a0704624d
* Author: nulltoken <emeric.fermas@gmail.com>
* Date: Wed Dec 14 08:29:03 2011 +0100
*
* Initial commit
*
* $ git show 1fe3 --format=raw
* commit 1fe3126578fc4eca68c193e4a3a0a14a0704624d
* tree 2b297e643c551e76cfa1f93810c50811382f9117
* author nulltoken <emeric.fermas@gmail.com> 1323847743 +0100
* committer nulltoken <emeric.fermas@gmail.com> 1323847743 +0100
*
* Initial commit
*
* diff --git a/test.txt b/test.txt
* new file mode 100644
* index 0000000..9daeafb
* --- /dev/null
* +++ b/test.txt
* @@ -0,0 +1 @@
* +test
*
* $ git ls-tree 2b297
* 100644 blob 9daeafb9864cf43055ae93beb0afd6c7d144bfa4 test.txt
*/
cl_git_pass(git_oid_fromstr(&expected_commit_oid, "1fe3126578fc4eca68c193e4a3a0a14a0704624d"));
cl_git_pass(git_oid_fromstr(&expected_tree_oid, "2b297e643c551e76cfa1f93810c50811382f9117"));
cl_git_pass(git_oid_fromstr(&expected_blob_oid, "9daeafb9864cf43055ae93beb0afd6c7d144bfa4"));
/*
* Add a new file to the index
*/
cl_git_mkfile("treebuilder/test.txt", "test\n");
cl_git_pass(git_repository_index(&index, repo));
cl_git_pass(git_index_add_bypath(index, "test.txt"));
entry = git_index_get_byindex(index, 0);
cl_assert(git_oid_cmp(&expected_blob_oid, &entry->id) == 0);
/*
* Information about index entry should match test file
*/
{
struct stat st;
cl_must_pass(p_lstat("treebuilder/test.txt", &st));
cl_assert(entry->file_size == st.st_size);
#ifndef _WIN32
/*
* Windows doesn't populate these fields, and the signage is
* wrong in the Windows version of the struct, so lets avoid
* the "comparing signed and unsigned" compilation warning in
* that case.
*/
cl_assert(entry->uid == st.st_uid);
cl_assert(entry->gid == st.st_gid);
#endif
}
/*
* Build the tree from the index
*/
cl_git_pass(git_index_write_tree(&tree_oid, index));
cl_assert(git_oid_cmp(&expected_tree_oid, &tree_oid) == 0);
/*
* Commit the staged file
*/
cl_git_pass(git_signature_new(&signature, "nulltoken", "emeric.fermas@gmail.com", 1323847743, 60));
cl_git_pass(git_tree_lookup(&tree, repo, &tree_oid));
memset(&buffer, 0, sizeof(git_buf));
cl_git_pass(git_message_prettify(&buffer, "Initial commit", 0, '#'));
cl_git_pass(git_commit_create_v(
&commit_oid,
repo,
"HEAD",
signature,
signature,
NULL,
buffer.ptr,
tree,
0));
cl_assert(git_oid_cmp(&expected_commit_oid, &commit_oid) == 0);
git_buf_dispose(&buffer);
git_signature_free(signature);
git_tree_free(tree);
git_index_free(index);
}
static void assert_commit_tree_has_n_entries(git_commit *c, int count)
{
git_tree *tree;
cl_git_pass(git_commit_tree(&tree, c));
cl_assert_equal_i(count, git_tree_entrycount(tree));
git_tree_free(tree);
}
static void assert_commit_is_head_(git_commit *c, const char *file, int line)
{
git_commit *head;
cl_git_pass(git_revparse_single((git_object **)&head, repo, "HEAD"));
clar__assert(git_oid_equal(git_commit_id(c), git_commit_id(head)), file, line, "Commit is not the HEAD", NULL, 1);
git_commit_free(head);
}
#define assert_commit_is_head(C) assert_commit_is_head_((C),__FILE__,__LINE__)
void test_object_commit_commitstagedfile__amend_commit(void)
{
git_index *index;
git_oid old_oid, new_oid, tree_oid;
git_commit *old_commit, *new_commit;
git_tree *tree;
/* make a commit */
cl_git_mkfile("treebuilder/myfile", "This is a file\n");
cl_git_pass(git_repository_index(&index, repo));
cl_git_pass(git_index_add_bypath(index, "myfile"));
cl_repo_commit_from_index(&old_oid, repo, NULL, 0, "first commit");
cl_git_pass(git_commit_lookup(&old_commit, repo, &old_oid));
cl_assert_equal_i(0, git_commit_parentcount(old_commit));
assert_commit_tree_has_n_entries(old_commit, 1);
assert_commit_is_head(old_commit);
/* let's amend the message of the HEAD commit */
cl_git_pass(git_commit_amend(
&new_oid, old_commit, "HEAD", NULL, NULL, NULL, "Initial commit", NULL));
/* fail because the commit isn't the tip of the branch anymore */
cl_git_fail(git_commit_amend(
&new_oid, old_commit, "HEAD", NULL, NULL, NULL, "Initial commit", NULL));
cl_git_pass(git_commit_lookup(&new_commit, repo, &new_oid));
cl_assert_equal_i(0, git_commit_parentcount(new_commit));
assert_commit_tree_has_n_entries(new_commit, 1);
assert_commit_is_head(new_commit);
git_commit_free(old_commit);
old_commit = new_commit;
/* let's amend the tree of that last commit */
cl_git_mkfile("treebuilder/anotherfile", "This is another file\n");
cl_git_pass(git_index_add_bypath(index, "anotherfile"));
cl_git_pass(git_index_write_tree(&tree_oid, index));
cl_git_pass(git_tree_lookup(&tree, repo, &tree_oid));
cl_assert_equal_i(2, git_tree_entrycount(tree));
/* fail to amend on a ref which does not exist */
cl_git_fail_with(GIT_ENOTFOUND, git_commit_amend(
&new_oid, old_commit, "refs/heads/nope", NULL, NULL, NULL, "Initial commit", tree));
cl_git_pass(git_commit_amend(
&new_oid, old_commit, "HEAD", NULL, NULL, NULL, "Initial commit", tree));
git_tree_free(tree);
cl_git_pass(git_commit_lookup(&new_commit, repo, &new_oid));
cl_assert_equal_i(0, git_commit_parentcount(new_commit));
assert_commit_tree_has_n_entries(new_commit, 2);
assert_commit_is_head(new_commit);
/* cleanup */
git_commit_free(old_commit);
git_commit_free(new_commit);
git_index_free(index);
}
+232
View File
@@ -0,0 +1,232 @@
#include "clar_libgit2.h"
#include "commit.h"
#include "object.h"
#include "signature.h"
static void assert_commit_parses(const char *data, size_t datalen,
const char *expected_treeid,
const char *expected_author,
const char *expected_committer,
const char *expected_encoding,
const char *expected_message,
size_t expected_parents)
{
git_commit *commit;
if (!datalen)
datalen = strlen(data);
cl_git_pass(git_object__from_raw((git_object **) &commit, data, datalen, GIT_OBJECT_COMMIT));
if (expected_author) {
git_signature *author;
cl_git_pass(git_signature_from_buffer(&author, expected_author));
cl_assert(git_signature__equal(author, commit->author));
cl_assert_equal_s(author->name, commit->author->name);
cl_assert_equal_s(author->email, commit->author->email);
cl_assert_equal_i(author->when.time, commit->author->when.time);
cl_assert_equal_i(author->when.offset, commit->author->when.offset);
cl_assert_equal_i(author->when.sign, commit->author->when.sign);
git_signature_free(author);
}
if (expected_committer) {
git_signature *committer;
cl_git_pass(git_signature_from_buffer(&committer, expected_committer));
cl_assert_equal_s(committer->name, commit->committer->name);
cl_assert_equal_s(committer->email, commit->committer->email);
cl_assert_equal_i(committer->when.time, commit->committer->when.time);
cl_assert_equal_i(committer->when.offset, commit->committer->when.offset);
cl_assert_equal_i(committer->when.sign, commit->committer->when.sign);
git_signature_free(committer);
}
if (expected_encoding)
cl_assert_equal_s(commit->message_encoding, expected_encoding);
else
cl_assert_equal_p(commit->message_encoding, NULL);
if (expected_message)
cl_assert_equal_s(commit->raw_message, expected_message);
else
cl_assert_equal_p(commit->message_encoding, NULL);
if (expected_treeid) {
git_oid tree_oid;
cl_git_pass(git_oid_fromstr(&tree_oid, expected_treeid));
cl_assert_equal_oid(&tree_oid, &commit->tree_id);
}
cl_assert_equal_i(commit->parent_ids.size, expected_parents);
git_object__free(&commit->object);
}
static void assert_commit_fails(const char *data, size_t datalen)
{
git_object *object;
if (!datalen)
datalen = strlen(data);
cl_git_fail(git_object__from_raw(&object, data, datalen, GIT_OBJECT_COMMIT));
}
void test_object_commit_parse__parsing_commit_succeeds(void)
{
const char *commit =
"tree 3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8\n"
"author Author <author@example.com>\n"
"committer Committer <committer@example.com>\n"
"encoding Encoding\n"
"\n"
"Message";
assert_commit_parses(commit, 0,
"3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8",
"Author <author@example.com>",
"Committer <committer@example.com>",
"Encoding",
"Message", 0);
}
void test_object_commit_parse__parsing_commit_without_encoding_succeeds(void)
{
const char *commit =
"tree 3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8\n"
"author Author <author@example.com>\n"
"committer Committer <committer@example.com>\n"
"\n"
"Message";
assert_commit_parses(commit, 0,
"3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8",
"Author <author@example.com>",
"Committer <committer@example.com>",
NULL,
"Message", 0);
}
void test_object_commit_parse__parsing_commit_with_multiple_authors_succeeds(void)
{
const char *commit =
"tree 3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8\n"
"author Author1 <author@example.com>\n"
"author Author2 <author@example.com>\n"
"author Author3 <author@example.com>\n"
"author Author4 <author@example.com>\n"
"committer Committer <committer@example.com>\n"
"\n"
"Message";
assert_commit_parses(commit, 0,
"3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8",
"Author1 <author@example.com>",
"Committer <committer@example.com>",
NULL,
"Message", 0);
}
void test_object_commit_parse__parsing_commit_with_multiple_committers_succeeds(void)
{
const char *commit =
"tree 3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8\n"
"author Author <author@example.com>\n"
"committer Committer1 <committer@example.com>\n"
"committer Committer2 <committer@example.com>\n"
"committer Committer3 <committer@example.com>\n"
"committer Committer4 <committer@example.com>\n"
"\n"
"Message";
assert_commit_parses(commit, 0,
"3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8",
"Author <author@example.com>",
"Committer1 <committer@example.com>",
NULL,
"Message", 0);
}
void test_object_commit_parse__parsing_commit_without_message_succeeds(void)
{
const char *commit =
"tree 3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8\n"
"author Author <author@example.com>\n"
"committer Committer <committer@example.com>\n";
assert_commit_parses(commit, 0,
"3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8",
"Author <author@example.com>",
"Committer <committer@example.com>",
NULL,
"", 0);
}
void test_object_commit_parse__parsing_commit_with_unknown_fields_succeeds(void)
{
const char *commit =
"tree 3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8\n"
"author Author <author@example.com>\n"
"committer Committer <committer@example.com>\n"
"foo bar\n"
"more garbage\n"
"\n"
"Message";
assert_commit_parses(commit, 0,
"3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8",
"Author <author@example.com>",
"Committer <committer@example.com>",
NULL,
"Message", 0);
}
void test_object_commit_parse__parsing_commit_with_invalid_tree_fails(void)
{
const char *commit =
"tree 3e7ac388cadacccdf1xxx5f3445895b71d9cb0f8\n"
"author Author <author@example.com>\n"
"committer Committer <committer@example.com>\n"
"\n"
"Message";
assert_commit_fails(commit, 0);
}
void test_object_commit_parse__parsing_commit_without_tree_fails(void)
{
const char *commit =
"author Author <author@example.com>\n"
"committer Committer <committer@example.com>\n"
"\n"
"Message";
assert_commit_fails(commit, 0);
}
void test_object_commit_parse__parsing_commit_without_author_fails(void)
{
const char *commit =
"tree 3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8\n"
"committer Committer <committer@example.com>\n"
"\n"
"Message";
assert_commit_fails(commit, 0);
}
void test_object_commit_parse__parsing_commit_without_committer_fails(void)
{
const char *commit =
"tree 3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8\n"
"author Author <author@example.com>\n"
"\n"
"Message";
assert_commit_fails(commit, 0);
}
void test_object_commit_parse__parsing_encoding_will_not_cause_oob_read(void)
{
const char *commit =
"tree 3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8\n"
"author <>\n"
"committer <>\n"
"encoding foo\n";
/*
* As we ignore unknown fields, the cut-off encoding field will be
* parsed just fine.
*/
assert_commit_parses(commit, strlen(commit) - strlen("ncoding foo\n"),
"3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8",
"<>",
"<>",
NULL,
"", 0);
}
+122
View File
@@ -0,0 +1,122 @@
#include "clar_libgit2.h"
#include "repository.h"
static git_repository *g_repo;
void test_object_lookup__initialize(void)
{
g_repo = cl_git_sandbox_init("testrepo.git");
}
void test_object_lookup__cleanup(void)
{
cl_git_sandbox_cleanup();
}
void test_object_lookup__lookup_wrong_type_returns_enotfound(void)
{
const char *commit = "e90810b8df3e80c413d903f631643c716887138d";
git_oid oid;
git_object *object;
cl_git_pass(git_oid_fromstr(&oid, commit));
cl_assert_equal_i(
GIT_ENOTFOUND, git_object_lookup(&object, g_repo, &oid, GIT_OBJECT_TAG));
}
void test_object_lookup__lookup_nonexisting_returns_enotfound(void)
{
const char *unknown = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef";
git_oid oid;
git_object *object;
cl_git_pass(git_oid_fromstr(&oid, unknown));
cl_assert_equal_i(
GIT_ENOTFOUND, git_object_lookup(&object, g_repo, &oid, GIT_OBJECT_ANY));
}
void test_object_lookup__lookup_wrong_type_by_abbreviated_id_returns_enotfound(void)
{
const char *commit = "e90810b";
git_oid oid;
git_object *object;
cl_git_pass(git_oid_fromstrn(&oid, commit, strlen(commit)));
cl_assert_equal_i(
GIT_ENOTFOUND, git_object_lookup_prefix(&object, g_repo, &oid, strlen(commit), GIT_OBJECT_TAG));
}
void test_object_lookup__lookup_wrong_type_eventually_returns_enotfound(void)
{
const char *commit = "e90810b8df3e80c413d903f631643c716887138d";
git_oid oid;
git_object *object;
cl_git_pass(git_oid_fromstr(&oid, commit));
cl_git_pass(git_object_lookup(&object, g_repo, &oid, GIT_OBJECT_COMMIT));
git_object_free(object);
cl_assert_equal_i(
GIT_ENOTFOUND, git_object_lookup(&object, g_repo, &oid, GIT_OBJECT_TAG));
}
void test_object_lookup__lookup_corrupt_object_returns_error(void)
{
const char *commit = "8e73b769e97678d684b809b163bebdae2911720f",
*file = "objects/8e/73b769e97678d684b809b163bebdae2911720f";
git_buf path = GIT_BUF_INIT, contents = GIT_BUF_INIT;
git_oid oid;
git_object *object;
size_t i;
cl_git_pass(git_oid_fromstr(&oid, commit));
cl_git_pass(git_buf_joinpath(&path, git_repository_path(g_repo), file));
cl_git_pass(git_futils_readbuffer(&contents, path.ptr));
/* Corrupt and try to read the object */
for (i = 0; i < contents.size; i++) {
contents.ptr[i] ^= 0x1;
cl_git_pass(git_futils_writebuffer(&contents, path.ptr, O_RDWR, 0644));
cl_git_fail(git_object_lookup(&object, g_repo, &oid, GIT_OBJECT_COMMIT));
contents.ptr[i] ^= 0x1;
}
/* Restore original content and assert we can read the object */
cl_git_pass(git_futils_writebuffer(&contents, path.ptr, O_RDWR, 0644));
cl_git_pass(git_object_lookup(&object, g_repo, &oid, GIT_OBJECT_COMMIT));
git_object_free(object);
git_buf_dispose(&path);
git_buf_dispose(&contents);
}
void test_object_lookup__lookup_object_with_wrong_hash_returns_error(void)
{
const char *oldloose = "objects/8e/73b769e97678d684b809b163bebdae2911720f",
*newloose = "objects/8e/73b769e97678d684b809b163bebdae2911720e",
*commit = "8e73b769e97678d684b809b163bebdae2911720e";
git_buf oldpath = GIT_BUF_INIT, newpath = GIT_BUF_INIT;
git_object *object;
git_oid oid;
cl_git_pass(git_oid_fromstr(&oid, commit));
/* Copy object to another location with wrong hash */
cl_git_pass(git_buf_joinpath(&oldpath, git_repository_path(g_repo), oldloose));
cl_git_pass(git_buf_joinpath(&newpath, git_repository_path(g_repo), newloose));
cl_git_pass(git_futils_cp(oldpath.ptr, newpath.ptr, 0644));
/* Verify that lookup fails due to a hashsum mismatch */
cl_git_fail_with(GIT_EMISMATCH, git_object_lookup(&object, g_repo, &oid, GIT_OBJECT_COMMIT));
/* Disable verification and try again */
cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION, 0));
cl_git_pass(git_object_lookup(&object, g_repo, &oid, GIT_OBJECT_COMMIT));
cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION, 1));
git_object_free(object);
git_buf_dispose(&oldpath);
git_buf_dispose(&newpath);
}
+83
View File
@@ -0,0 +1,83 @@
#include "clar_libgit2.h"
#include "repository.h"
static git_repository *g_repo;
static git_tree *g_root_tree;
static git_commit *g_head_commit;
static git_object *g_expectedobject,
*g_actualobject;
void test_object_lookupbypath__initialize(void)
{
git_reference *head;
git_tree_entry *tree_entry;
cl_git_pass(git_repository_open(&g_repo, cl_fixture("attr/.gitted")));
cl_git_pass(git_repository_head(&head, g_repo));
cl_git_pass(git_reference_peel((git_object**)&g_head_commit, head, GIT_OBJECT_COMMIT));
cl_git_pass(git_commit_tree(&g_root_tree, g_head_commit));
cl_git_pass(git_tree_entry_bypath(&tree_entry, g_root_tree, "subdir/subdir_test2.txt"));
cl_git_pass(git_object_lookup(&g_expectedobject, g_repo, git_tree_entry_id(tree_entry),
GIT_OBJECT_ANY));
git_tree_entry_free(tree_entry);
git_reference_free(head);
g_actualobject = NULL;
}
void test_object_lookupbypath__cleanup(void)
{
git_object_free(g_actualobject);
git_object_free(g_expectedobject);
git_tree_free(g_root_tree);
git_commit_free(g_head_commit);
g_expectedobject = NULL;
git_repository_free(g_repo);
g_repo = NULL;
}
void test_object_lookupbypath__errors(void)
{
cl_assert_equal_i(GIT_EINVALIDSPEC,
git_object_lookup_bypath(&g_actualobject, (git_object*)g_root_tree,
"subdir/subdir_test2.txt", GIT_OBJECT_TREE)); /* It's not a tree */
cl_assert_equal_i(GIT_ENOTFOUND,
git_object_lookup_bypath(&g_actualobject, (git_object*)g_root_tree,
"file/doesnt/exist", GIT_OBJECT_ANY));
}
void test_object_lookupbypath__from_root_tree(void)
{
cl_git_pass(git_object_lookup_bypath(&g_actualobject, (git_object*)g_root_tree,
"subdir/subdir_test2.txt", GIT_OBJECT_BLOB));
cl_assert_equal_oid(git_object_id(g_expectedobject),
git_object_id(g_actualobject));
}
void test_object_lookupbypath__from_head_commit(void)
{
cl_git_pass(git_object_lookup_bypath(&g_actualobject, (git_object*)g_head_commit,
"subdir/subdir_test2.txt", GIT_OBJECT_BLOB));
cl_assert_equal_oid(git_object_id(g_expectedobject),
git_object_id(g_actualobject));
}
void test_object_lookupbypath__from_subdir_tree(void)
{
git_tree_entry *entry = NULL;
git_tree *tree = NULL;
cl_git_pass(git_tree_entry_bypath(&entry, g_root_tree, "subdir"));
cl_git_pass(git_tree_lookup(&tree, g_repo, git_tree_entry_id(entry)));
cl_git_pass(git_object_lookup_bypath(&g_actualobject, (git_object*)tree,
"subdir_test2.txt", GIT_OBJECT_BLOB));
cl_assert_equal_oid(git_object_id(g_expectedobject),
git_object_id(g_actualobject));
git_tree_entry_free(entry);
git_tree_free(tree);
}
+199
View File
@@ -0,0 +1,199 @@
#include "clar_libgit2.h"
#include "buffer.h"
#include "message.h"
static void assert_message_prettifying(char *expected_output, char *input, int strip_comments)
{
git_buf prettified_message = GIT_BUF_INIT;
git_message_prettify(&prettified_message, input, strip_comments, '#');
cl_assert_equal_s(expected_output, git_buf_cstr(&prettified_message));
git_buf_dispose(&prettified_message);
}
#define t40 "A quick brown fox jumps over the lazy do"
#define s40 " "
#define sss s40 s40 s40 s40 s40 s40 s40 s40 s40 s40 /* # 400 */
#define ttt t40 t40 t40 t40 t40 t40 t40 t40 t40 t40 /* # 400 */
/* Ported from git.git */
/* see https://github.com/git/git/blob/master/t/t0030-stripspace.sh */
void test_object_message__long_lines_without_spaces_should_be_unchanged(void)
{
assert_message_prettifying(ttt "\n", ttt, 0);
assert_message_prettifying(ttt ttt "\n", ttt ttt, 0);
assert_message_prettifying(ttt ttt ttt "\n", ttt ttt ttt, 0);
assert_message_prettifying(ttt ttt ttt ttt "\n", ttt ttt ttt ttt, 0);
}
void test_object_message__lines_with_spaces_at_the_beginning_should_be_unchanged(void)
{
assert_message_prettifying(sss ttt "\n", sss ttt, 0);
assert_message_prettifying(sss sss ttt "\n", sss sss ttt, 0);
assert_message_prettifying(sss sss sss ttt "\n", sss sss sss ttt, 0);
}
void test_object_message__lines_with_intermediate_spaces_should_be_unchanged(void)
{
assert_message_prettifying(ttt sss ttt "\n", ttt sss ttt, 0);
assert_message_prettifying(ttt sss sss ttt "\n", ttt sss sss ttt, 0);
}
void test_object_message__consecutive_blank_lines_should_be_unified(void)
{
assert_message_prettifying(ttt "\n\n" ttt "\n", ttt "\n\n\n\n\n" ttt "\n", 0);
assert_message_prettifying(ttt ttt "\n\n" ttt "\n", ttt ttt "\n\n\n\n\n" ttt "\n", 0);
assert_message_prettifying(ttt ttt ttt "\n\n" ttt "\n", ttt ttt ttt "\n\n\n\n\n" ttt "\n", 0);
assert_message_prettifying(ttt "\n\n" ttt ttt "\n", ttt "\n\n\n\n\n" ttt ttt "\n", 0);
assert_message_prettifying(ttt "\n\n" ttt ttt ttt "\n", ttt "\n\n\n\n\n" ttt ttt ttt "\n", 0);
assert_message_prettifying(ttt "\n\n" ttt "\n", ttt "\n\t\n \n\n \t\t\n" ttt "\n", 0);
assert_message_prettifying(ttt ttt "\n\n" ttt "\n", ttt ttt "\n\t\n \n\n \t\t\n" ttt "\n", 0);
assert_message_prettifying(ttt ttt ttt "\n\n" ttt "\n", ttt ttt ttt "\n\t\n \n\n \t\t\n" ttt "\n", 0);
assert_message_prettifying(ttt "\n\n" ttt ttt "\n", ttt "\n\t\n \n\n \t\t\n" ttt ttt "\n", 0);
assert_message_prettifying(ttt "\n\n" ttt ttt ttt "\n", ttt "\n\t\n \n\n \t\t\n" ttt ttt ttt "\n", 0);
}
void test_object_message__only_consecutive_blank_lines_should_be_completely_removed(void)
{
assert_message_prettifying("", "\n", 0);
assert_message_prettifying("", "\n\n\n", 0);
assert_message_prettifying("", sss "\n" sss "\n" sss "\n", 0);
assert_message_prettifying("", sss sss "\n" sss "\n\n", 0);
}
void test_object_message__consecutive_blank_lines_at_the_beginning_should_be_removed(void)
{
assert_message_prettifying(ttt "\n", "\n" ttt "\n", 0);
assert_message_prettifying(ttt "\n", "\n\n\n" ttt "\n", 0);
assert_message_prettifying(ttt ttt "\n", "\n\n\n" ttt ttt "\n", 0);
assert_message_prettifying(ttt ttt ttt "\n", "\n\n\n" ttt ttt ttt "\n", 0);
assert_message_prettifying(ttt ttt ttt ttt "\n", "\n\n\n" ttt ttt ttt ttt "\n", 0);
assert_message_prettifying(ttt "\n", sss "\n" sss "\n" sss "\n" ttt "\n", 0);
assert_message_prettifying(ttt "\n", "\n" sss "\n" sss sss "\n" ttt "\n", 0);
assert_message_prettifying(ttt "\n", sss sss "\n" sss "\n\n" ttt "\n", 0);
assert_message_prettifying(ttt "\n", sss sss sss "\n\n\n" ttt "\n", 0);
assert_message_prettifying(ttt "\n", "\n" sss sss sss "\n\n" ttt "\n", 0);
assert_message_prettifying(ttt "\n", "\n\n" sss sss sss "\n" ttt "\n", 0);
}
void test_object_message__consecutive_blank_lines_at_the_end_should_be_removed(void)
{
assert_message_prettifying(ttt "\n", ttt "\n\n", 0);
assert_message_prettifying(ttt "\n", ttt "\n\n\n\n", 0);
assert_message_prettifying(ttt ttt "\n", ttt ttt "\n\n\n\n", 0);
assert_message_prettifying(ttt ttt ttt "\n", ttt ttt ttt "\n\n\n\n", 0);
assert_message_prettifying(ttt ttt ttt ttt "\n", ttt ttt ttt ttt "\n\n\n\n", 0);
assert_message_prettifying(ttt "\n", ttt "\n" sss "\n" sss "\n" sss "\n", 0);
assert_message_prettifying(ttt "\n", ttt "\n\n" sss "\n" sss sss "\n", 0);
assert_message_prettifying(ttt "\n", ttt "\n" sss sss "\n" sss "\n\n", 0);
assert_message_prettifying(ttt "\n", ttt "\n" sss sss sss "\n\n\n", 0);
assert_message_prettifying(ttt "\n", ttt "\n\n" sss sss sss "\n\n", 0);
assert_message_prettifying(ttt "\n", ttt "\n\n\n" sss sss sss "\n\n", 0);
}
void test_object_message__text_without_newline_at_end_should_end_with_newline(void)
{
assert_message_prettifying(ttt "\n", ttt, 0);
assert_message_prettifying(ttt ttt "\n", ttt ttt, 0);
assert_message_prettifying(ttt ttt ttt "\n", ttt ttt ttt, 0);
assert_message_prettifying(ttt ttt ttt ttt "\n", ttt ttt ttt ttt, 0);
}
void test_object_message__text_plus_spaces_without_newline_should_not_show_spaces_and_end_with_newline(void)
{
assert_message_prettifying(ttt "\n", ttt sss, 0);
assert_message_prettifying(ttt ttt "\n", ttt ttt sss, 0);
assert_message_prettifying(ttt ttt ttt "\n", ttt ttt ttt sss, 0);
assert_message_prettifying(ttt "\n", ttt sss sss, 0);
assert_message_prettifying(ttt ttt "\n", ttt ttt sss sss, 0);
assert_message_prettifying(ttt "\n", ttt sss sss sss, 0);
}
void test_object_message__text_plus_spaces_ending_with_newline_should_be_cleaned_and_newline_must_remain(void){
assert_message_prettifying(ttt "\n", ttt sss "\n", 0);
assert_message_prettifying(ttt "\n", ttt sss sss "\n", 0);
assert_message_prettifying(ttt "\n", ttt sss sss sss "\n", 0);
assert_message_prettifying(ttt ttt "\n", ttt ttt sss "\n", 0);
assert_message_prettifying(ttt ttt "\n", ttt ttt sss sss "\n", 0);
assert_message_prettifying(ttt ttt ttt "\n", ttt ttt ttt sss "\n", 0);
}
void test_object_message__spaces_with_newline_at_end_should_be_replaced_with_empty_string(void)
{
assert_message_prettifying("", sss "\n", 0);
assert_message_prettifying("", sss sss "\n", 0);
assert_message_prettifying("", sss sss sss "\n", 0);
assert_message_prettifying("", sss sss sss sss "\n", 0);
}
void test_object_message__spaces_without_newline_at_end_should_be_replaced_with_empty_string(void)
{
assert_message_prettifying("", "", 0);
assert_message_prettifying("", sss sss, 0);
assert_message_prettifying("", sss sss sss, 0);
assert_message_prettifying("", sss sss sss sss, 0);
}
void test_object_message__consecutive_text_lines_should_be_unchanged(void)
{
assert_message_prettifying(ttt ttt "\n" ttt "\n", ttt ttt "\n" ttt "\n", 0);
assert_message_prettifying(ttt "\n" ttt ttt "\n" ttt "\n", ttt "\n" ttt ttt "\n" ttt "\n", 0);
assert_message_prettifying(ttt "\n" ttt "\n" ttt "\n" ttt ttt "\n", ttt "\n" ttt "\n" ttt "\n" ttt ttt "\n", 0);
assert_message_prettifying(ttt "\n" ttt "\n\n" ttt ttt "\n" ttt "\n", ttt "\n" ttt "\n\n" ttt ttt "\n" ttt "\n", 0);
assert_message_prettifying(ttt ttt "\n\n" ttt "\n" ttt ttt "\n", ttt ttt "\n\n" ttt "\n" ttt ttt "\n", 0);
assert_message_prettifying(ttt "\n" ttt ttt "\n\n" ttt "\n", ttt "\n" ttt ttt "\n\n" ttt "\n", 0);
}
void test_object_message__strip_comments(void)
{
assert_message_prettifying("", "# comment", 1);
assert_message_prettifying("", "# comment\n", 1);
assert_message_prettifying("", "# comment \n", 1);
assert_message_prettifying(ttt "\n", ttt "\n" "# comment\n", 1);
assert_message_prettifying(ttt "\n", "# comment\n" ttt "\n", 1);
assert_message_prettifying(ttt "\n" ttt "\n", ttt "\n" "# comment\n" ttt "\n", 1);
}
void test_object_message__keep_comments(void)
{
assert_message_prettifying("# comment\n", "# comment", 0);
assert_message_prettifying("# comment\n", "# comment\n", 0);
assert_message_prettifying("# comment\n", "# comment \n", 0);
assert_message_prettifying(ttt "\n" "# comment\n", ttt "\n" "# comment\n", 0);
assert_message_prettifying("# comment\n" ttt "\n", "# comment\n" ttt "\n", 0);
assert_message_prettifying(ttt "\n" "# comment\n" ttt "\n", ttt "\n" "# comment\n" ttt "\n", 0);
}
void test_object_message__message_prettify(void)
{
git_buf buffer;
memset(&buffer, 0, sizeof(buffer));
cl_git_pass(git_message_prettify(&buffer, "", 0, '#'));
cl_assert_equal_s(buffer.ptr, "");
git_buf_dispose(&buffer);
cl_git_pass(git_message_prettify(&buffer, "", 1, '#'));
cl_assert_equal_s(buffer.ptr, "");
git_buf_dispose(&buffer);
cl_git_pass(git_message_prettify(&buffer, "Short", 0, '#'));
cl_assert_equal_s("Short\n", buffer.ptr);
git_buf_dispose(&buffer);
cl_git_pass(git_message_prettify(&buffer, "Short", 1, '#'));
cl_assert_equal_s("Short\n", buffer.ptr);
git_buf_dispose(&buffer);
cl_git_pass(git_message_prettify(&buffer, "This is longer\nAnd multiline\n# with some comments still in\n", 0, '#'));
cl_assert_equal_s(buffer.ptr, "This is longer\nAnd multiline\n# with some comments still in\n");
git_buf_dispose(&buffer);
cl_git_pass(git_message_prettify(&buffer, "This is longer\nAnd multiline\n# with some comments still in\n", 1, '#'));
cl_assert_equal_s(buffer.ptr, "This is longer\nAnd multiline\n");
git_buf_dispose(&buffer);
}
+118
View File
@@ -0,0 +1,118 @@
#include "clar_libgit2.h"
static git_repository *g_repo;
void test_object_peel__initialize(void)
{
cl_git_pass(git_repository_open(&g_repo, cl_fixture("testrepo.git")));
}
void test_object_peel__cleanup(void)
{
git_repository_free(g_repo);
g_repo = NULL;
}
static void assert_peel(
const char *sha,
git_object_t requested_type,
const char* expected_sha,
git_object_t expected_type)
{
git_oid oid, expected_oid;
git_object *obj;
git_object *peeled;
cl_git_pass(git_oid_fromstr(&oid, sha));
cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJECT_ANY));
cl_git_pass(git_object_peel(&peeled, obj, requested_type));
cl_git_pass(git_oid_fromstr(&expected_oid, expected_sha));
cl_assert_equal_oid(&expected_oid, git_object_id(peeled));
cl_assert_equal_i(expected_type, git_object_type(peeled));
git_object_free(peeled);
git_object_free(obj);
}
static void assert_peel_error(int error, const char *sha, git_object_t requested_type)
{
git_oid oid;
git_object *obj;
git_object *peeled;
cl_git_pass(git_oid_fromstr(&oid, sha));
cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJECT_ANY));
cl_assert_equal_i(error, git_object_peel(&peeled, obj, requested_type));
git_object_free(obj);
}
void test_object_peel__peeling_an_object_into_its_own_type_returns_another_instance_of_it(void)
{
assert_peel("e90810b8df3e80c413d903f631643c716887138d", GIT_OBJECT_COMMIT,
"e90810b8df3e80c413d903f631643c716887138d", GIT_OBJECT_COMMIT);
assert_peel("7b4384978d2493e851f9cca7858815fac9b10980", GIT_OBJECT_TAG,
"7b4384978d2493e851f9cca7858815fac9b10980", GIT_OBJECT_TAG);
assert_peel("53fc32d17276939fc79ed05badaef2db09990016", GIT_OBJECT_TREE,
"53fc32d17276939fc79ed05badaef2db09990016", GIT_OBJECT_TREE);
assert_peel("0266163a49e280c4f5ed1e08facd36a2bd716bcf", GIT_OBJECT_BLOB,
"0266163a49e280c4f5ed1e08facd36a2bd716bcf", GIT_OBJECT_BLOB);
}
void test_object_peel__tag(void)
{
assert_peel("7b4384978d2493e851f9cca7858815fac9b10980", GIT_OBJECT_COMMIT,
"e90810b8df3e80c413d903f631643c716887138d", GIT_OBJECT_COMMIT);
assert_peel("7b4384978d2493e851f9cca7858815fac9b10980", GIT_OBJECT_TREE,
"53fc32d17276939fc79ed05badaef2db09990016", GIT_OBJECT_TREE);
assert_peel_error(GIT_EPEEL, "7b4384978d2493e851f9cca7858815fac9b10980", GIT_OBJECT_BLOB);
assert_peel("7b4384978d2493e851f9cca7858815fac9b10980", GIT_OBJECT_ANY,
"e90810b8df3e80c413d903f631643c716887138d", GIT_OBJECT_COMMIT);
}
void test_object_peel__commit(void)
{
assert_peel_error(GIT_EINVALIDSPEC, "e90810b8df3e80c413d903f631643c716887138d", GIT_OBJECT_BLOB);
assert_peel("e90810b8df3e80c413d903f631643c716887138d", GIT_OBJECT_TREE,
"53fc32d17276939fc79ed05badaef2db09990016", GIT_OBJECT_TREE);
assert_peel("e90810b8df3e80c413d903f631643c716887138d", GIT_OBJECT_COMMIT,
"e90810b8df3e80c413d903f631643c716887138d", GIT_OBJECT_COMMIT);
assert_peel_error(GIT_EINVALIDSPEC, "e90810b8df3e80c413d903f631643c716887138d", GIT_OBJECT_TAG);
assert_peel("e90810b8df3e80c413d903f631643c716887138d", GIT_OBJECT_ANY,
"53fc32d17276939fc79ed05badaef2db09990016", GIT_OBJECT_TREE);
}
void test_object_peel__tree(void)
{
assert_peel_error(GIT_EINVALIDSPEC, "53fc32d17276939fc79ed05badaef2db09990016", GIT_OBJECT_BLOB);
assert_peel("53fc32d17276939fc79ed05badaef2db09990016", GIT_OBJECT_TREE,
"53fc32d17276939fc79ed05badaef2db09990016", GIT_OBJECT_TREE);
assert_peel_error(GIT_EINVALIDSPEC, "53fc32d17276939fc79ed05badaef2db09990016", GIT_OBJECT_COMMIT);
assert_peel_error(GIT_EINVALIDSPEC, "53fc32d17276939fc79ed05badaef2db09990016", GIT_OBJECT_TAG);
assert_peel_error(GIT_EINVALIDSPEC, "53fc32d17276939fc79ed05badaef2db09990016", GIT_OBJECT_ANY);
}
void test_object_peel__blob(void)
{
assert_peel("0266163a49e280c4f5ed1e08facd36a2bd716bcf", GIT_OBJECT_BLOB,
"0266163a49e280c4f5ed1e08facd36a2bd716bcf", GIT_OBJECT_BLOB);
assert_peel_error(GIT_EINVALIDSPEC, "0266163a49e280c4f5ed1e08facd36a2bd716bcf", GIT_OBJECT_TREE);
assert_peel_error(GIT_EINVALIDSPEC, "0266163a49e280c4f5ed1e08facd36a2bd716bcf", GIT_OBJECT_COMMIT);
assert_peel_error(GIT_EINVALIDSPEC, "0266163a49e280c4f5ed1e08facd36a2bd716bcf", GIT_OBJECT_TAG);
assert_peel_error(GIT_EINVALIDSPEC, "0266163a49e280c4f5ed1e08facd36a2bd716bcf", GIT_OBJECT_ANY);
}
void test_object_peel__target_any_object_for_type_change(void)
{
/* tag to commit */
assert_peel("7b4384978d2493e851f9cca7858815fac9b10980", GIT_OBJECT_ANY,
"e90810b8df3e80c413d903f631643c716887138d", GIT_OBJECT_COMMIT);
/* commit to tree */
assert_peel("e90810b8df3e80c413d903f631643c716887138d", GIT_OBJECT_ANY,
"53fc32d17276939fc79ed05badaef2db09990016", GIT_OBJECT_TREE);
}
+41
View File
@@ -0,0 +1,41 @@
#include "clar_libgit2.h"
#include "odb.h"
void test_object_raw_chars__find_invalid_chars_in_oid(void)
{
git_oid out;
unsigned char exp[] = {
0x16, 0xa6, 0x77, 0x70, 0xb7,
0xd8, 0xd7, 0x23, 0x17, 0xc4,
0xb7, 0x75, 0x21, 0x3c, 0x23,
0xa8, 0xbd, 0x74, 0xf5, 0xe0,
};
char in[] = "16a67770b7d8d72317c4b775213c23a8bd74f5e0";
unsigned int i;
for (i = 0; i < 256; i++) {
in[38] = (char)i;
if (git__fromhex(i) >= 0) {
exp[19] = (unsigned char)(git__fromhex(i) << 4);
cl_git_pass(git_oid_fromstr(&out, in));
cl_assert(memcmp(out.id, exp, sizeof(out.id)) == 0);
} else {
cl_git_fail(git_oid_fromstr(&out, in));
}
}
}
void test_object_raw_chars__build_valid_oid_from_raw_bytes(void)
{
git_oid out;
unsigned char exp[] = {
0x16, 0xa6, 0x77, 0x70, 0xb7,
0xd8, 0xd7, 0x23, 0x17, 0xc4,
0xb7, 0x75, 0x21, 0x3c, 0x23,
0xa8, 0xbd, 0x74, 0xf5, 0xe0,
};
git_oid_fromraw(&out, exp);
cl_git_pass(memcmp(out.id, exp, sizeof(out.id)));
}
+123
View File
@@ -0,0 +1,123 @@
#include "clar_libgit2.h"
#include "odb.h"
void test_object_raw_compare__succeed_on_copy_oid(void)
{
git_oid a, b;
unsigned char exp[] = {
0x16, 0xa6, 0x77, 0x70, 0xb7,
0xd8, 0xd7, 0x23, 0x17, 0xc4,
0xb7, 0x75, 0x21, 0x3c, 0x23,
0xa8, 0xbd, 0x74, 0xf5, 0xe0,
};
memset(&b, 0, sizeof(b));
git_oid_fromraw(&a, exp);
git_oid_cpy(&b, &a);
cl_git_pass(memcmp(a.id, exp, sizeof(a.id)));
}
void test_object_raw_compare__succeed_on_oid_comparison_lesser(void)
{
git_oid a, b;
unsigned char a_in[] = {
0x16, 0xa6, 0x77, 0x70, 0xb7,
0xd8, 0xd7, 0x23, 0x17, 0xc4,
0xb7, 0x75, 0x21, 0x3c, 0x23,
0xa8, 0xbd, 0x74, 0xf5, 0xe0,
};
unsigned char b_in[] = {
0x16, 0xa6, 0x77, 0x70, 0xb7,
0xd8, 0xd7, 0x23, 0x17, 0xc4,
0xb7, 0x75, 0x21, 0x3c, 0x23,
0xa8, 0xbd, 0x74, 0xf5, 0xf0,
};
git_oid_fromraw(&a, a_in);
git_oid_fromraw(&b, b_in);
cl_assert(git_oid_cmp(&a, &b) < 0);
}
void test_object_raw_compare__succeed_on_oid_comparison_equal(void)
{
git_oid a, b;
unsigned char a_in[] = {
0x16, 0xa6, 0x77, 0x70, 0xb7,
0xd8, 0xd7, 0x23, 0x17, 0xc4,
0xb7, 0x75, 0x21, 0x3c, 0x23,
0xa8, 0xbd, 0x74, 0xf5, 0xe0,
};
git_oid_fromraw(&a, a_in);
git_oid_fromraw(&b, a_in);
cl_assert(git_oid_cmp(&a, &b) == 0);
}
void test_object_raw_compare__succeed_on_oid_comparison_greater(void)
{
git_oid a, b;
unsigned char a_in[] = {
0x16, 0xa6, 0x77, 0x70, 0xb7,
0xd8, 0xd7, 0x23, 0x17, 0xc4,
0xb7, 0x75, 0x21, 0x3c, 0x23,
0xa8, 0xbd, 0x74, 0xf5, 0xe0,
};
unsigned char b_in[] = {
0x16, 0xa6, 0x77, 0x70, 0xb7,
0xd8, 0xd7, 0x23, 0x17, 0xc4,
0xb7, 0x75, 0x21, 0x3c, 0x23,
0xa8, 0xbd, 0x74, 0xf5, 0xd0,
};
git_oid_fromraw(&a, a_in);
git_oid_fromraw(&b, b_in);
cl_assert(git_oid_cmp(&a, &b) > 0);
}
void test_object_raw_compare__compare_fmt_oids(void)
{
const char *exp = "16a0123456789abcdef4b775213c23a8bd74f5e0";
git_oid in;
char out[GIT_OID_HEXSZ + 1];
cl_git_pass(git_oid_fromstr(&in, exp));
/* Format doesn't touch the last byte */
out[GIT_OID_HEXSZ] = 'Z';
git_oid_fmt(out, &in);
cl_assert(out[GIT_OID_HEXSZ] == 'Z');
/* Format produced the right result */
out[GIT_OID_HEXSZ] = '\0';
cl_assert_equal_s(exp, out);
}
void test_object_raw_compare__compare_static_oids(void)
{
const char *exp = "16a0123456789abcdef4b775213c23a8bd74f5e0";
git_oid in;
char *out;
cl_git_pass(git_oid_fromstr(&in, exp));
out = git_oid_tostr_s(&in);
cl_assert(out);
cl_assert_equal_s(exp, out);
}
void test_object_raw_compare__compare_pathfmt_oids(void)
{
const char *exp1 = "16a0123456789abcdef4b775213c23a8bd74f5e0";
const char *exp2 = "16/a0123456789abcdef4b775213c23a8bd74f5e0";
git_oid in;
char out[GIT_OID_HEXSZ + 2];
cl_git_pass(git_oid_fromstr(&in, exp1));
/* Format doesn't touch the last byte */
out[GIT_OID_HEXSZ + 1] = 'Z';
git_oid_pathfmt(out, &in);
cl_assert(out[GIT_OID_HEXSZ + 1] == 'Z');
/* Format produced the right result */
out[GIT_OID_HEXSZ + 1] = '\0';
cl_assert_equal_s(exp2, out);
}
+112
View File
@@ -0,0 +1,112 @@
#include "clar_libgit2.h"
#include "odb.h"
void test_object_raw_convert__succeed_on_oid_to_string_conversion(void)
{
const char *exp = "16a0123456789abcdef4b775213c23a8bd74f5e0";
git_oid in;
char out[GIT_OID_HEXSZ + 1];
char *str;
int i;
cl_git_pass(git_oid_fromstr(&in, exp));
/* NULL buffer pointer, returns static empty string */
str = git_oid_tostr(NULL, sizeof(out), &in);
cl_assert(str && *str == '\0' && str != out);
/* zero buffer size, returns static empty string */
str = git_oid_tostr(out, 0, &in);
cl_assert(str && *str == '\0' && str != out);
/* NULL oid pointer, sets existing buffer to empty string */
str = git_oid_tostr(out, sizeof(out), NULL);
cl_assert(str && *str == '\0' && str == out);
/* n == 1, returns out as an empty string */
str = git_oid_tostr(out, 1, &in);
cl_assert(str && *str == '\0' && str == out);
for (i = 1; i < GIT_OID_HEXSZ; i++) {
out[i+1] = 'Z';
str = git_oid_tostr(out, i+1, &in);
/* returns out containing c-string */
cl_assert(str && str == out);
/* must be '\0' terminated */
cl_assert(*(str+i) == '\0');
/* must not touch bytes past end of string */
cl_assert(*(str+(i+1)) == 'Z');
/* i == n-1 charaters of string */
cl_git_pass(strncmp(exp, out, i));
}
/* returns out as hex formatted c-string */
str = git_oid_tostr(out, sizeof(out), &in);
cl_assert(str && str == out && *(str+GIT_OID_HEXSZ) == '\0');
cl_assert_equal_s(exp, out);
}
void test_object_raw_convert__succeed_on_oid_to_string_conversion_big(void)
{
const char *exp = "16a0123456789abcdef4b775213c23a8bd74f5e0";
git_oid in;
char big[GIT_OID_HEXSZ + 1 + 3]; /* note + 4 => big buffer */
char *str;
cl_git_pass(git_oid_fromstr(&in, exp));
/* place some tail material */
big[GIT_OID_HEXSZ+0] = 'W'; /* should be '\0' afterwards */
big[GIT_OID_HEXSZ+1] = 'X'; /* should remain untouched */
big[GIT_OID_HEXSZ+2] = 'Y'; /* ditto */
big[GIT_OID_HEXSZ+3] = 'Z'; /* ditto */
/* returns big as hex formatted c-string */
str = git_oid_tostr(big, sizeof(big), &in);
cl_assert(str && str == big && *(str+GIT_OID_HEXSZ) == '\0');
cl_assert_equal_s(exp, big);
/* check tail material is untouched */
cl_assert(str && str == big && *(str+GIT_OID_HEXSZ+1) == 'X');
cl_assert(str && str == big && *(str+GIT_OID_HEXSZ+2) == 'Y');
cl_assert(str && str == big && *(str+GIT_OID_HEXSZ+3) == 'Z');
}
static void check_partial_oid(
char *buffer, size_t count, const git_oid *oid, const char *expected)
{
git_oid_nfmt(buffer, count, oid);
buffer[count] = '\0';
cl_assert_equal_s(expected, buffer);
}
void test_object_raw_convert__convert_oid_partially(void)
{
const char *exp = "16a0123456789abcdef4b775213c23a8bd74f5e0";
git_oid in;
char big[GIT_OID_HEXSZ + 1 + 3]; /* note + 4 => big buffer */
cl_git_pass(git_oid_fromstr(&in, exp));
git_oid_nfmt(big, sizeof(big), &in);
cl_assert_equal_s(exp, big);
git_oid_nfmt(big, GIT_OID_HEXSZ + 1, &in);
cl_assert_equal_s(exp, big);
check_partial_oid(big, 1, &in, "1");
check_partial_oid(big, 2, &in, "16");
check_partial_oid(big, 3, &in, "16a");
check_partial_oid(big, 4, &in, "16a0");
check_partial_oid(big, 5, &in, "16a01");
check_partial_oid(big, GIT_OID_HEXSZ, &in, exp);
check_partial_oid(
big, GIT_OID_HEXSZ - 1, &in, "16a0123456789abcdef4b775213c23a8bd74f5e");
check_partial_oid(
big, GIT_OID_HEXSZ - 2, &in, "16a0123456789abcdef4b775213c23a8bd74f5");
check_partial_oid(
big, GIT_OID_HEXSZ - 3, &in, "16a0123456789abcdef4b775213c23a8bd74f");
}
+323
View File
@@ -0,0 +1,323 @@
/*
* Raw data
*/
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 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 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,
};
/*
* Dummy data
*/
static unsigned char zero_data[] = {
0x00,
};
static unsigned char one_data[] = {
0x0a,
};
static unsigned char two_data[] = {
0x61, 0x0a,
};
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,
};
/*
* SHA1 Hashes
*/
static char *commit_id = "3d7f8a6af076c8c3f20071a8935cdbe8228594d1";
static char *tree_id = "dff2da90b254e1beb889d1f1f1288be1803782df";
static char *tag_id = "09d373e1dfdc16b129ceec6dd649739911541e05";
static char *zero_id = "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391";
static char *one_id = "8b137891791fe96927ad78e64b0aad7bded08bdc";
static char *two_id = "78981922613b2afb6025042ff6bd878ac1994e85";
static char *some_id = "fd8430bc864cfcd5f10e5590f8a447e01b942bfe";
/*
* In-memory objects
*/
static git_rawobj tree_obj = {
tree_data,
sizeof(tree_data),
GIT_OBJECT_TREE
};
static git_rawobj tag_obj = {
tag_data,
sizeof(tag_data),
GIT_OBJECT_TAG
};
static git_rawobj zero_obj = {
zero_data,
0,
GIT_OBJECT_BLOB
};
static git_rawobj one_obj = {
one_data,
sizeof(one_data),
GIT_OBJECT_BLOB
};
static git_rawobj two_obj = {
two_data,
sizeof(two_data),
GIT_OBJECT_BLOB
};
static git_rawobj commit_obj = {
commit_data,
sizeof(commit_data),
GIT_OBJECT_COMMIT
};
static git_rawobj some_obj = {
some_data,
sizeof(some_data),
GIT_OBJECT_BLOB
};
static git_rawobj junk_obj = {
NULL,
0,
GIT_OBJECT_INVALID
};
+30
View File
@@ -0,0 +1,30 @@
#include "clar_libgit2.h"
#include "odb.h"
void test_object_raw_fromstr__fail_on_invalid_oid_string(void)
{
git_oid out;
cl_git_fail(git_oid_fromstr(&out, ""));
cl_git_fail(git_oid_fromstr(&out, "moo"));
cl_git_fail(git_oid_fromstr(&out, "16a67770b7d8d72317c4b775213c23a8bd74f5ez"));
}
void test_object_raw_fromstr__succeed_on_valid_oid_string(void)
{
git_oid out;
unsigned char exp[] = {
0x16, 0xa6, 0x77, 0x70, 0xb7,
0xd8, 0xd7, 0x23, 0x17, 0xc4,
0xb7, 0x75, 0x21, 0x3c, 0x23,
0xa8, 0xbd, 0x74, 0xf5, 0xe0,
};
cl_git_pass(git_oid_fromstr(&out, "16a67770b7d8d72317c4b775213c23a8bd74f5e0"));
cl_git_pass(memcmp(out.id, exp, sizeof(out.id)));
cl_git_pass(git_oid_fromstr(&out, "16A67770B7D8D72317C4b775213C23A8BD74F5E0"));
cl_git_pass(memcmp(out.id, exp, sizeof(out.id)));
}
+169
View File
@@ -0,0 +1,169 @@
#include "clar_libgit2.h"
#include "odb.h"
#include "hash.h"
#include "data.h"
static void hash_object_pass(git_oid *oid, git_rawobj *obj)
{
cl_git_pass(git_odb_hash(oid, obj->data, obj->len, obj->type));
}
static void hash_object_fail(git_oid *oid, git_rawobj *obj)
{
cl_git_fail(git_odb_hash(oid, obj->data, obj->len, obj->type));
}
static char *hello_id = "22596363b3de40b06f981fb85d82312e8c0ed511";
static char *hello_text = "hello world\n";
static char *bye_id = "ce08fe4884650f067bd5703b6a59a8b3b3c99a09";
static char *bye_text = "bye world\n";
void test_object_raw_hash__hash_by_blocks(void)
{
git_hash_ctx ctx;
git_oid id1, id2;
cl_git_pass(git_hash_ctx_init(&ctx));
/* should already be init'd */
cl_git_pass(git_hash_update(&ctx, hello_text, strlen(hello_text)));
cl_git_pass(git_hash_final(&id2, &ctx));
cl_git_pass(git_oid_fromstr(&id1, hello_id));
cl_assert(git_oid_cmp(&id1, &id2) == 0);
/* reinit should permit reuse */
cl_git_pass(git_hash_init(&ctx));
cl_git_pass(git_hash_update(&ctx, bye_text, strlen(bye_text)));
cl_git_pass(git_hash_final(&id2, &ctx));
cl_git_pass(git_oid_fromstr(&id1, bye_id));
cl_assert(git_oid_cmp(&id1, &id2) == 0);
git_hash_ctx_cleanup(&ctx);
}
void test_object_raw_hash__hash_buffer_in_single_call(void)
{
git_oid id1, id2;
cl_git_pass(git_oid_fromstr(&id1, hello_id));
git_hash_buf(&id2, hello_text, strlen(hello_text));
cl_assert(git_oid_cmp(&id1, &id2) == 0);
}
void test_object_raw_hash__hash_vector(void)
{
git_oid id1, id2;
git_buf_vec vec[2];
cl_git_pass(git_oid_fromstr(&id1, hello_id));
vec[0].data = hello_text;
vec[0].len = 4;
vec[1].data = hello_text+4;
vec[1].len = strlen(hello_text)-4;
git_hash_vec(&id2, vec, 2);
cl_assert(git_oid_cmp(&id1, &id2) == 0);
}
void test_object_raw_hash__hash_junk_data(void)
{
git_oid id, id_zero;
cl_git_pass(git_oid_fromstr(&id_zero, zero_id));
/* invalid types: */
junk_obj.data = some_data;
hash_object_fail(&id, &junk_obj);
junk_obj.type = 0; /* EXT1 */
hash_object_fail(&id, &junk_obj);
junk_obj.type = 5; /* EXT2 */
hash_object_fail(&id, &junk_obj);
junk_obj.type = GIT_OBJECT_OFS_DELTA;
hash_object_fail(&id, &junk_obj);
junk_obj.type = GIT_OBJECT_REF_DELTA;
hash_object_fail(&id, &junk_obj);
junk_obj.type = 42;
hash_object_fail(&id, &junk_obj);
/* data can be NULL only if len is zero: */
junk_obj.type = GIT_OBJECT_BLOB;
junk_obj.data = NULL;
hash_object_pass(&id, &junk_obj);
cl_assert(git_oid_cmp(&id, &id_zero) == 0);
junk_obj.len = 1;
hash_object_fail(&id, &junk_obj);
}
void test_object_raw_hash__hash_commit_object(void)
{
git_oid id1, id2;
cl_git_pass(git_oid_fromstr(&id1, commit_id));
hash_object_pass(&id2, &commit_obj);
cl_assert(git_oid_cmp(&id1, &id2) == 0);
}
void test_object_raw_hash__hash_tree_object(void)
{
git_oid id1, id2;
cl_git_pass(git_oid_fromstr(&id1, tree_id));
hash_object_pass(&id2, &tree_obj);
cl_assert(git_oid_cmp(&id1, &id2) == 0);
}
void test_object_raw_hash__hash_tag_object(void)
{
git_oid id1, id2;
cl_git_pass(git_oid_fromstr(&id1, tag_id));
hash_object_pass(&id2, &tag_obj);
cl_assert(git_oid_cmp(&id1, &id2) == 0);
}
void test_object_raw_hash__hash_zero_length_object(void)
{
git_oid id1, id2;
cl_git_pass(git_oid_fromstr(&id1, zero_id));
hash_object_pass(&id2, &zero_obj);
cl_assert(git_oid_cmp(&id1, &id2) == 0);
}
void test_object_raw_hash__hash_one_byte_object(void)
{
git_oid id1, id2;
cl_git_pass(git_oid_fromstr(&id1, one_id));
hash_object_pass(&id2, &one_obj);
cl_assert(git_oid_cmp(&id1, &id2) == 0);
}
void test_object_raw_hash__hash_two_byte_object(void)
{
git_oid id1, id2;
cl_git_pass(git_oid_fromstr(&id1, two_id));
hash_object_pass(&id2, &two_obj);
cl_assert(git_oid_cmp(&id1, &id2) == 0);
}
void test_object_raw_hash__hash_multi_byte_object(void)
{
git_oid id1, id2;
cl_git_pass(git_oid_fromstr(&id1, some_id));
hash_object_pass(&id2, &some_obj);
cl_assert(git_oid_cmp(&id1, &id2) == 0);
}
+137
View File
@@ -0,0 +1,137 @@
#include "clar_libgit2.h"
#include "odb.h"
#include "hash.h"
void test_object_raw_short__oid_shortener_no_duplicates(void)
{
git_oid_shorten *os;
int min_len;
os = git_oid_shorten_new(0);
cl_assert(os != NULL);
git_oid_shorten_add(os, "22596363b3de40b06f981fb85d82312e8c0ed511");
git_oid_shorten_add(os, "ce08fe4884650f067bd5703b6a59a8b3b3c99a09");
git_oid_shorten_add(os, "16a0123456789abcdef4b775213c23a8bd74f5e0");
min_len = git_oid_shorten_add(os, "ce08fe4884650f067bd5703b6a59a8b3b3c99a09");
cl_assert(min_len == GIT_OID_HEXSZ + 1);
git_oid_shorten_free(os);
}
static int insert_sequential_oids(
char ***out, git_oid_shorten *os, int n, int fail)
{
int i, min_len = 0;
char numbuf[16];
git_oid oid;
char **oids = git__calloc(n, sizeof(char *));
cl_assert(oids != NULL);
for (i = 0; i < n; ++i) {
p_snprintf(numbuf, sizeof(numbuf), "%u", (unsigned int)i);
git_hash_buf(&oid, numbuf, strlen(numbuf));
oids[i] = git__malloc(GIT_OID_HEXSZ + 1);
cl_assert(oids[i]);
git_oid_nfmt(oids[i], GIT_OID_HEXSZ + 1, &oid);
min_len = git_oid_shorten_add(os, oids[i]);
/* After "fail", we expect git_oid_shorten_add to fail */
if (fail >= 0 && i >= fail)
cl_assert(min_len < 0);
else
cl_assert(min_len >= 0);
}
*out = oids;
return min_len;
}
static void free_oids(int n, char **oids)
{
int i;
for (i = 0; i < n; ++i) {
git__free(oids[i]);
}
git__free(oids);
}
void test_object_raw_short__oid_shortener_stresstest_git_oid_shorten(void)
{
#define MAX_OIDS 1000
git_oid_shorten *os;
size_t i, j;
int min_len = 0, found_collision;
char **oids;
os = git_oid_shorten_new(0);
cl_assert(os != NULL);
/*
* Insert in the shortener 1000 unique SHA1 ids
*/
min_len = insert_sequential_oids(&oids, os, MAX_OIDS, MAX_OIDS);
cl_assert(min_len > 0);
/*
* Compare the first `min_char - 1` characters of each
* SHA1 OID. If the minimizer worked, we should find at
* least one collision
*/
found_collision = 0;
for (i = 0; i < MAX_OIDS; ++i) {
for (j = i + 1; j < MAX_OIDS; ++j) {
if (memcmp(oids[i], oids[j], min_len - 1) == 0)
found_collision = 1;
}
}
cl_assert_equal_b(true, found_collision);
/*
* Compare the first `min_char` characters of each
* SHA1 OID. If the minimizer worked, every single preffix
* should be unique.
*/
found_collision = 0;
for (i = 0; i < MAX_OIDS; ++i) {
for (j = i + 1; j < MAX_OIDS; ++j) {
if (memcmp(oids[i], oids[j], min_len) == 0)
found_collision = 1;
}
}
cl_assert_equal_b(false, found_collision);
/* cleanup */
free_oids(MAX_OIDS, oids);
git_oid_shorten_free(os);
#undef MAX_OIDS
}
void test_object_raw_short__oid_shortener_too_much_oids(void)
{
/* The magic number of oids at which an oid_shortener will fail.
* This was experimentally established. */
#define MAX_OIDS 24556
git_oid_shorten *os;
char **oids;
os = git_oid_shorten_new(0);
cl_assert(os != NULL);
cl_assert(insert_sequential_oids(&oids, os, MAX_OIDS, MAX_OIDS - 1) < 0);
free_oids(MAX_OIDS, oids);
git_oid_shorten_free(os);
#undef MAX_OIDS
}
+13
View File
@@ -0,0 +1,13 @@
#include "clar_libgit2.h"
#include "odb.h"
void test_object_raw_size__validate_oid_size(void)
{
git_oid out;
cl_assert(20 == GIT_OID_RAWSZ);
cl_assert(40 == GIT_OID_HEXSZ);
cl_assert(sizeof(out) == GIT_OID_RAWSZ);
cl_assert(sizeof(out.id) == GIT_OID_RAWSZ);
}
+54
View File
@@ -0,0 +1,54 @@
#include "clar_libgit2.h"
#include "odb.h"
#include "hash.h"
void test_object_raw_type2string__convert_type_to_string(void)
{
cl_assert_equal_s(git_object_type2string(GIT_OBJECT_INVALID), "");
cl_assert_equal_s(git_object_type2string(0), ""); /* EXT1 */
cl_assert_equal_s(git_object_type2string(GIT_OBJECT_COMMIT), "commit");
cl_assert_equal_s(git_object_type2string(GIT_OBJECT_TREE), "tree");
cl_assert_equal_s(git_object_type2string(GIT_OBJECT_BLOB), "blob");
cl_assert_equal_s(git_object_type2string(GIT_OBJECT_TAG), "tag");
cl_assert_equal_s(git_object_type2string(5), ""); /* EXT2 */
cl_assert_equal_s(git_object_type2string(GIT_OBJECT_OFS_DELTA), "OFS_DELTA");
cl_assert_equal_s(git_object_type2string(GIT_OBJECT_REF_DELTA), "REF_DELTA");
cl_assert_equal_s(git_object_type2string(-2), "");
cl_assert_equal_s(git_object_type2string(8), "");
cl_assert_equal_s(git_object_type2string(1234), "");
}
void test_object_raw_type2string__convert_string_to_type(void)
{
cl_assert(git_object_string2type(NULL) == GIT_OBJECT_INVALID);
cl_assert(git_object_string2type("") == GIT_OBJECT_INVALID);
cl_assert(git_object_string2type("commit") == GIT_OBJECT_COMMIT);
cl_assert(git_object_string2type("tree") == GIT_OBJECT_TREE);
cl_assert(git_object_string2type("blob") == GIT_OBJECT_BLOB);
cl_assert(git_object_string2type("tag") == GIT_OBJECT_TAG);
cl_assert(git_object_string2type("OFS_DELTA") == GIT_OBJECT_OFS_DELTA);
cl_assert(git_object_string2type("REF_DELTA") == GIT_OBJECT_REF_DELTA);
cl_assert(git_object_string2type("CoMmIt") == GIT_OBJECT_INVALID);
cl_assert(git_object_string2type("hohoho") == GIT_OBJECT_INVALID);
}
void test_object_raw_type2string__check_type_is_loose(void)
{
cl_assert(git_object_typeisloose(GIT_OBJECT_INVALID) == 0);
cl_assert(git_object_typeisloose(0) == 0); /* EXT1 */
cl_assert(git_object_typeisloose(GIT_OBJECT_COMMIT) == 1);
cl_assert(git_object_typeisloose(GIT_OBJECT_TREE) == 1);
cl_assert(git_object_typeisloose(GIT_OBJECT_BLOB) == 1);
cl_assert(git_object_typeisloose(GIT_OBJECT_TAG) == 1);
cl_assert(git_object_typeisloose(5) == 0); /* EXT2 */
cl_assert(git_object_typeisloose(GIT_OBJECT_OFS_DELTA) == 0);
cl_assert(git_object_typeisloose(GIT_OBJECT_REF_DELTA) == 0);
cl_assert(git_object_typeisloose(-2) == 0);
cl_assert(git_object_typeisloose(8) == 0);
cl_assert(git_object_typeisloose(1234) == 0);
}
+462
View File
@@ -0,0 +1,462 @@
#include "clar_libgit2.h"
#include "git2/odb_backend.h"
#include "futils.h"
#include "odb.h"
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 const char *odb_dir = "test-objects";
void test_body(object_data *d, git_rawobj *o);
/* Helpers */
static void remove_object_files(object_data *d)
{
cl_git_pass(p_unlink(d->file));
cl_git_pass(p_rmdir(d->dir));
cl_assert(errno != ENOTEMPTY);
cl_git_pass(p_rmdir(odb_dir) < 0);
}
static void streaming_write(git_oid *oid, git_odb *odb, git_rawobj *raw)
{
git_odb_stream *stream;
int error;
cl_git_pass(git_odb_open_wstream(&stream, odb, raw->len, raw->type));
git_odb_stream_write(stream, raw->data, raw->len);
error = git_odb_stream_finalize_write(oid, stream);
git_odb_stream_free(stream);
cl_git_pass(error);
}
static void check_object_files(object_data *d)
{
cl_assert(git_path_exists(d->dir));
cl_assert(git_path_exists(d->file));
}
static void cmp_objects(git_rawobj *o1, git_rawobj *o2)
{
cl_assert(o1->type == o2->type);
cl_assert(o1->len == o2->len);
if (o1->len > 0)
cl_assert(memcmp(o1->data, o2->data, o1->len) == 0);
}
static void make_odb_dir(void)
{
cl_git_pass(p_mkdir(odb_dir, GIT_OBJECT_DIR_MODE));
}
/* Standard test form */
void test_body(object_data *d, git_rawobj *o)
{
git_odb *db;
git_oid id1, id2;
git_odb_object *obj;
git_rawobj tmp;
make_odb_dir();
cl_git_pass(git_odb_open(&db, odb_dir));
cl_git_pass(git_oid_fromstr(&id1, d->id));
streaming_write(&id2, db, o);
cl_assert(git_oid_cmp(&id1, &id2) == 0);
check_object_files(d);
cl_git_pass(git_odb_read(&obj, db, &id1));
tmp.data = obj->buffer;
tmp.len = obj->cached.size;
tmp.type = obj->cached.type;
cmp_objects(&tmp, o);
git_odb_object_free(obj);
git_odb_free(db);
remove_object_files(d);
}
void test_object_raw_write__loose_object(void)
{
object_data commit = {
"3d7f8a6af076c8c3f20071a8935cdbe8228594d1",
"test-objects/3d",
"test-objects/3d/7f8a6af076c8c3f20071a8935cdbe8228594d1",
};
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,
};
git_rawobj commit_obj = {
commit_data,
sizeof(commit_data),
GIT_OBJECT_COMMIT
};
test_body(&commit, &commit_obj);
}
void test_object_raw_write__loose_tree(void)
{
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_rawobj tree_obj = {
tree_data,
sizeof(tree_data),
GIT_OBJECT_TREE
};
test_body(&tree, &tree_obj);
}
void test_object_raw_write__loose_tag(void)
{
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_rawobj tag_obj = {
tag_data,
sizeof(tag_data),
GIT_OBJECT_TAG
};
test_body(&tag, &tag_obj);
}
void test_object_raw_write__zero_length(void)
{
static object_data zero = {
"e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
"test-objects/e6",
"test-objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391",
};
static unsigned char zero_data[] = {
0x00 /* dummy data */
};
static git_rawobj zero_obj = {
zero_data,
0,
GIT_OBJECT_BLOB
};
test_body(&zero, &zero_obj);
}
void test_object_raw_write__one_byte(void)
{
static object_data one = {
"8b137891791fe96927ad78e64b0aad7bded08bdc",
"test-objects/8b",
"test-objects/8b/137891791fe96927ad78e64b0aad7bded08bdc",
};
static unsigned char one_data[] = {
0x0a,
};
static git_rawobj one_obj = {
one_data,
sizeof(one_data),
GIT_OBJECT_BLOB
};
test_body(&one, &one_obj);
}
void test_object_raw_write__two_byte(void)
{
static object_data two = {
"78981922613b2afb6025042ff6bd878ac1994e85",
"test-objects/78",
"test-objects/78/981922613b2afb6025042ff6bd878ac1994e85",
};
static unsigned char two_data[] = {
0x61, 0x0a,
};
static git_rawobj two_obj = {
two_data,
sizeof(two_data),
GIT_OBJECT_BLOB
};
test_body(&two, &two_obj);
}
void test_object_raw_write__several_bytes(void)
{
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_rawobj some_obj = {
some_data,
sizeof(some_data),
GIT_OBJECT_BLOB
};
test_body(&some, &some_obj);
}
+51
View File
@@ -0,0 +1,51 @@
#include "clar_libgit2.h"
git_repository *_repo;
void test_object_shortid__initialize(void)
{
cl_git_pass(git_repository_open(&_repo, cl_fixture("duplicate.git")));
}
void test_object_shortid__cleanup(void)
{
git_repository_free(_repo);
_repo = NULL;
}
void test_object_shortid__select(void)
{
git_oid full;
git_object *obj;
git_buf shorty = {0};
git_oid_fromstr(&full, "ce013625030ba8dba906f756967f9e9ca394464a");
cl_git_pass(git_object_lookup(&obj, _repo, &full, GIT_OBJECT_ANY));
cl_git_pass(git_object_short_id(&shorty, obj));
cl_assert_equal_i(7, shorty.size);
cl_assert_equal_s("ce01362", shorty.ptr);
git_object_free(obj);
git_oid_fromstr(&full, "038d718da6a1ebbc6a7780a96ed75a70cc2ad6e2");
cl_git_pass(git_object_lookup(&obj, _repo, &full, GIT_OBJECT_ANY));
cl_git_pass(git_object_short_id(&shorty, obj));
cl_assert_equal_i(7, shorty.size);
cl_assert_equal_s("038d718", shorty.ptr);
git_object_free(obj);
git_oid_fromstr(&full, "dea509d097ce692e167dfc6a48a7a280cc5e877e");
cl_git_pass(git_object_lookup(&obj, _repo, &full, GIT_OBJECT_ANY));
cl_git_pass(git_object_short_id(&shorty, obj));
cl_assert_equal_i(9, shorty.size);
cl_assert_equal_s("dea509d09", shorty.ptr);
git_object_free(obj);
git_oid_fromstr(&full, "dea509d0b3cb8ee0650f6ca210bc83f4678851ba");
cl_git_pass(git_object_lookup(&obj, _repo, &full, GIT_OBJECT_ANY));
cl_git_pass(git_object_short_id(&shorty, obj));
cl_assert_equal_i(9, shorty.size);
cl_assert_equal_s("dea509d0b", shorty.ptr);
git_object_free(obj);
git_buf_dispose(&shorty);
}
+117
View File
@@ -0,0 +1,117 @@
#include "clar_libgit2.h"
#include "tag.h"
static git_repository *g_repo;
#define MAX_USED_TAGS 6
struct pattern_match_t
{
const char* pattern;
const size_t expected_matches;
const char* expected_results[MAX_USED_TAGS];
};
/* Helpers */
static void ensure_tag_pattern_match(git_repository *repo,
const struct pattern_match_t* data)
{
int already_found[MAX_USED_TAGS] = { 0 };
git_strarray tag_list;
int error = 0;
size_t sucessfully_found = 0;
size_t i, j;
cl_assert(data->expected_matches <= MAX_USED_TAGS);
if ((error = git_tag_list_match(&tag_list, data->pattern, repo)) < 0)
goto exit;
if (tag_list.count != data->expected_matches)
{
error = GIT_ERROR;
goto exit;
}
/* we have to be prepared that tags come in any order. */
for (i = 0; i < tag_list.count; i++)
{
for (j = 0; j < data->expected_matches; j++)
{
if (!already_found[j] && !strcmp(data->expected_results[j], tag_list.strings[i]))
{
already_found[j] = 1;
sucessfully_found++;
break;
}
}
}
cl_assert_equal_i((int)sucessfully_found, (int)data->expected_matches);
exit:
git_strarray_free(&tag_list);
cl_git_pass(error);
}
/* Fixture setup and teardown */
void test_object_tag_list__initialize(void)
{
g_repo = cl_git_sandbox_init("testrepo");
}
void test_object_tag_list__cleanup(void)
{
cl_git_sandbox_cleanup();
}
void test_object_tag_list__list_all(void)
{
/* list all tag names from the repository */
git_strarray tag_list;
cl_git_pass(git_tag_list(&tag_list, g_repo));
cl_assert_equal_i((int)tag_list.count, 6);
git_strarray_free(&tag_list);
}
static const struct pattern_match_t matches[] = {
/* All tags, including a packed one and two namespaced ones. */
{ "", 6, { "e90810b", "point_to_blob", "test", "packed-tag", "foo/bar", "foo/foo/bar" } },
/* beginning with */
{ "t*", 1, { "test" } },
/* ending with */
{ "*b", 2, { "e90810b", "point_to_blob" } },
/* exact match */
{ "e", 0 },
{ "e90810b", 1, { "e90810b" } },
/* either or */
{ "e90810[ab]", 1, { "e90810b" } },
/* glob in the middle */
{ "foo/*/bar", 1, { "foo/foo/bar" } },
/*
* The matching of '*' is based on plain string matching analog to the regular expression ".*"
* => a '/' in the tag name has no special meaning.
* Compare to `git tag -l "*bar"`
*/
{ "*bar", 2, { "foo/bar", "foo/foo/bar" } },
/* End of list */
{ NULL }
};
void test_object_tag_list__list_by_pattern(void)
{
/* list all tag names from the repository matching a specified pattern */
size_t i = 0;
while (matches[i].pattern)
ensure_tag_pattern_match(g_repo, &matches[i++]);
}
+218
View File
@@ -0,0 +1,218 @@
#include "clar_libgit2.h"
#include "object.h"
#include "signature.h"
#include "tag.h"
static void assert_tag_parses(const char *data, size_t datalen,
const char *expected_oid,
const char *expected_name,
const char *expected_tagger,
const char *expected_message)
{
git_tag *tag;
if (!datalen)
datalen = strlen(data);
cl_git_pass(git_object__from_raw((git_object **) &tag, data, datalen, GIT_OBJECT_TAG));
cl_assert_equal_i(tag->type, GIT_OBJECT_TAG);
if (expected_oid) {
git_oid oid;
cl_git_pass(git_oid_fromstr(&oid, expected_oid));
cl_assert_equal_oid(&oid, &tag->target);
}
if (expected_name)
cl_assert_equal_s(expected_name, tag->tag_name);
else
cl_assert_equal_s(tag->message, NULL);
if (expected_tagger) {
git_signature *tagger;
cl_git_pass(git_signature_from_buffer(&tagger, expected_tagger));
cl_assert_equal_s(tagger->name, tag->tagger->name);
cl_assert_equal_s(tagger->email, tag->tagger->email);
cl_assert_equal_i(tagger->when.time, tag->tagger->when.time);
cl_assert_equal_i(tagger->when.offset, tag->tagger->when.offset);
cl_assert_equal_i(tagger->when.sign, tag->tagger->when.sign);
git_signature_free(tagger);
} else {
cl_assert_equal_s(tag->tagger, NULL);
}
if (expected_message)
cl_assert_equal_s(expected_message, tag->message);
else
cl_assert_equal_s(tag->message, NULL);
git_object__free(&tag->object);
}
static void assert_tag_fails(const char *data, size_t datalen)
{
git_object *object;
if (!datalen)
datalen = strlen(data);
cl_git_fail(git_object__from_raw(&object, data, datalen, GIT_OBJECT_TAG));
}
void test_object_tag_parse__valid_tag_parses(void)
{
const char *tag =
"object a8d447f68076d1520f69649bb52629941be7031f\n"
"type tag\n"
"tag tagname\n"
"tagger Taggy Mr. Taggart <taggy@taggart.com>\n"
"\n"
"Message";
assert_tag_parses(tag, 0,
"a8d447f68076d1520f69649bb52629941be7031f",
"tagname",
"Taggy Mr. Taggart <taggy@taggart.com>",
"Message");
}
void test_object_tag_parse__missing_tagger_parses(void)
{
const char *tag =
"object a8d447f68076d1520f69649bb52629941be7031f\n"
"type tag\n"
"tag tagname\n"
"\n"
"Message";
assert_tag_parses(tag, 0,
"a8d447f68076d1520f69649bb52629941be7031f",
"tagname",
NULL,
"Message");
}
void test_object_tag_parse__missing_message_parses(void)
{
const char *tag =
"object a8d447f68076d1520f69649bb52629941be7031f\n"
"type tag\n"
"tag tagname\n"
"tagger Taggy Mr. Taggart <taggy@taggart.com>\n";
assert_tag_parses(tag, 0,
"a8d447f68076d1520f69649bb52629941be7031f",
"tagname",
"Taggy Mr. Taggart <taggy@taggart.com>",
NULL);
}
void test_object_tag_parse__unknown_field_parses(void)
{
const char *tag =
"object a8d447f68076d1520f69649bb52629941be7031f\n"
"type tag\n"
"tag tagname\n"
"tagger Taggy Mr. Taggart <taggy@taggart.com>\n"
"foo bar\n"
"frubble frabble\n"
"\n"
"Message";
assert_tag_parses(tag, 0,
"a8d447f68076d1520f69649bb52629941be7031f",
"tagname",
"Taggy Mr. Taggart <taggy@taggart.com>",
"Message");
}
void test_object_tag_parse__missing_object_fails(void)
{
const char *tag =
"type tag\n"
"tag tagname\n"
"tagger Taggy Mr. Taggart <taggy@taggart.com>\n"
"\n"
"Message";
assert_tag_fails(tag, 0);
}
void test_object_tag_parse__malformatted_object_fails(void)
{
const char *tag =
"object a8d447f68076d15xxxxxxxxxxxxxxxx41be7031f\n"
"type tag\n"
"tag tagname\n"
"tagger Taggy Mr. Taggart <taggy@taggart.com>\n"
"\n"
"Message";
assert_tag_fails(tag, 0);
}
void test_object_tag_parse__missing_type_fails(void)
{
const char *tag =
"object a8d447f68076d1520f69649bb52629941be7031f\n"
"tag tagname\n"
"tagger Taggy Mr. Taggart <taggy@taggart.com>\n"
"\n"
"Message";
assert_tag_fails(tag, 0);
}
void test_object_tag_parse__invalid_type_fails(void)
{
const char *tag =
"object a8d447f68076d1520f69649bb52629941be7031f\n"
"type garbage\n"
"tag tagname\n"
"tagger Taggy Mr. Taggart <taggy@taggart.com>\n"
"\n"
"Message";
assert_tag_fails(tag, 0);
}
void test_object_tag_parse__missing_tagname_fails(void)
{
const char *tag =
"object a8d447f68076d1520f69649bb52629941be7031f\n"
"type tag\n"
"tagger Taggy Mr. Taggart <taggy@taggart.com>\n"
"\n"
"Message";
assert_tag_fails(tag, 0);
}
void test_object_tag_parse__misformatted_tagger_fails(void)
{
const char *tag =
"object a8d447f68076d1520f69649bb52629941be7031f\n"
"type tag\n"
"tag Tag\n"
"tagger taggy@taggart.com>\n"
"\n"
"Message";
assert_tag_fails(tag, 0);
}
void test_object_tag_parse__missing_message_fails(void)
{
const char *tag =
"object a8d447f68076d1520f69649bb52629941be7031f\n"
"type tag\n"
"tag Tag\n"
"tagger taggy@taggart.com>\n";
assert_tag_fails(tag, 0);
}
void test_object_tag_parse__no_oob_read_when_searching_message(void)
{
const char *tag =
"object a8d447f68076d1520f69649bb52629941be7031f\n"
"type tag\n"
"tag \n"
"tagger <>\n"
" \n\n"
"Message";
/*
* The OOB read previously resulted in an OOM error. We
* thus want to make sure that the resulting error is the
* expected one.
*/
assert_tag_fails(tag, strlen(tag) - strlen("\n\nMessage"));
cl_assert(strstr(git_error_last()->message, "tag contains no message"));
}
+61
View File
@@ -0,0 +1,61 @@
#include "clar_libgit2.h"
#include "tag.h"
static git_repository *repo;
static git_tag *tag;
static git_object *target;
void test_object_tag_peel__initialize(void)
{
cl_fixture_sandbox("testrepo.git");
cl_git_pass(git_repository_open(&repo, "testrepo.git"));
}
void test_object_tag_peel__cleanup(void)
{
git_tag_free(tag);
tag = NULL;
git_object_free(target);
target = NULL;
git_repository_free(repo);
repo = NULL;
cl_fixture_cleanup("testrepo.git");
}
static void retrieve_tag_from_oid(git_tag **tag_out, git_repository *repo, const char *sha)
{
git_oid oid;
cl_git_pass(git_oid_fromstr(&oid, sha));
cl_git_pass(git_tag_lookup(tag_out, repo, &oid));
}
void test_object_tag_peel__can_peel_to_a_commit(void)
{
retrieve_tag_from_oid(&tag, repo, "7b4384978d2493e851f9cca7858815fac9b10980");
cl_git_pass(git_tag_peel(&target, tag));
cl_assert(git_object_type(target) == GIT_OBJECT_COMMIT);
cl_git_pass(git_oid_streq(git_object_id(target), "e90810b8df3e80c413d903f631643c716887138d"));
}
void test_object_tag_peel__can_peel_several_nested_tags_to_a_commit(void)
{
retrieve_tag_from_oid(&tag, repo, "b25fa35b38051e4ae45d4222e795f9df2e43f1d1");
cl_git_pass(git_tag_peel(&target, tag));
cl_assert(git_object_type(target) == GIT_OBJECT_COMMIT);
cl_git_pass(git_oid_streq(git_object_id(target), "e90810b8df3e80c413d903f631643c716887138d"));
}
void test_object_tag_peel__can_peel_to_a_non_commit(void)
{
retrieve_tag_from_oid(&tag, repo, "521d87c1ec3aef9824daf6d96cc0ae3710766d91");
cl_git_pass(git_tag_peel(&target, tag));
cl_assert(git_object_type(target) == GIT_OBJECT_BLOB);
cl_git_pass(git_oid_streq(git_object_id(target), "1385f264afb75a56a5bec74243be9b367ba4ca08"));
}
+179
View File
@@ -0,0 +1,179 @@
#include "clar_libgit2.h"
#include "tag.h"
static const char *tag1_id = "b25fa35b38051e4ae45d4222e795f9df2e43f1d1";
static const char *tag2_id = "7b4384978d2493e851f9cca7858815fac9b10980";
static const char *tagged_commit = "e90810b8df3e80c413d903f631643c716887138d";
static const char *bad_tag_id = "eda9f45a2a98d4c17a09d681d88569fa4ea91755";
static const char *badly_tagged_commit = "e90810b8df3e80c413d903f631643c716887138d";
static const char *short_tag_id = "5da7760512a953e3c7c4e47e4392c7a4338fb729";
static const char *short_tagged_commit = "4a5ed60bafcf4638b7c8356bd4ce1916bfede93c";
static const char *taggerless = "4a23e2e65ad4e31c4c9db7dc746650bfad082679";
static git_repository *g_repo;
/* Fixture setup and teardown */
void test_object_tag_read__initialize(void)
{
g_repo = cl_git_sandbox_init("testrepo");
}
void test_object_tag_read__cleanup(void)
{
cl_git_sandbox_cleanup();
}
void test_object_tag_read__parse(void)
{
/* read and parse a tag from the repository */
git_tag *tag1, *tag2;
git_commit *commit;
git_oid id1, id2, id_commit;
git_oid_fromstr(&id1, tag1_id);
git_oid_fromstr(&id2, tag2_id);
git_oid_fromstr(&id_commit, tagged_commit);
cl_git_pass(git_tag_lookup(&tag1, g_repo, &id1));
cl_assert_equal_s(git_tag_name(tag1), "test");
cl_assert(git_tag_target_type(tag1) == GIT_OBJECT_TAG);
cl_git_pass(git_tag_target((git_object **)&tag2, tag1));
cl_assert(tag2 != NULL);
cl_assert(git_oid_cmp(&id2, git_tag_id(tag2)) == 0);
cl_git_pass(git_tag_target((git_object **)&commit, tag2));
cl_assert(commit != NULL);
cl_assert(git_oid_cmp(&id_commit, git_commit_id(commit)) == 0);
git_tag_free(tag1);
git_tag_free(tag2);
git_commit_free(commit);
}
void test_object_tag_read__parse_without_tagger(void)
{
/* read and parse a tag without a tagger field */
git_repository *bad_tag_repo;
git_tag *bad_tag;
git_commit *commit;
git_oid id, id_commit;
/* TODO: This is a little messy */
cl_git_pass(git_repository_open(&bad_tag_repo, cl_fixture("bad_tag.git")));
git_oid_fromstr(&id, bad_tag_id);
git_oid_fromstr(&id_commit, badly_tagged_commit);
cl_git_pass(git_tag_lookup(&bad_tag, bad_tag_repo, &id));
cl_assert(bad_tag != NULL);
cl_assert_equal_s(git_tag_name(bad_tag), "e90810b");
cl_assert(git_oid_cmp(&id, git_tag_id(bad_tag)) == 0);
cl_assert(bad_tag->tagger == NULL);
cl_git_pass(git_tag_target((git_object **)&commit, bad_tag));
cl_assert(commit != NULL);
cl_assert(git_oid_cmp(&id_commit, git_commit_id(commit)) == 0);
git_tag_free(bad_tag);
git_commit_free(commit);
git_repository_free(bad_tag_repo);
}
void test_object_tag_read__parse_without_message(void)
{
/* read and parse a tag without a message field */
git_repository *short_tag_repo;
git_tag *short_tag;
git_commit *commit;
git_oid id, id_commit;
/* TODO: This is a little messy */
cl_git_pass(git_repository_open(&short_tag_repo, cl_fixture("short_tag.git")));
git_oid_fromstr(&id, short_tag_id);
git_oid_fromstr(&id_commit, short_tagged_commit);
cl_git_pass(git_tag_lookup(&short_tag, short_tag_repo, &id));
cl_assert(short_tag != NULL);
cl_assert_equal_s(git_tag_name(short_tag), "no_description");
cl_assert(git_oid_cmp(&id, git_tag_id(short_tag)) == 0);
cl_assert(short_tag->message == NULL);
cl_git_pass(git_tag_target((git_object **)&commit, short_tag));
cl_assert(commit != NULL);
cl_assert(git_oid_cmp(&id_commit, git_commit_id(commit)) == 0);
git_tag_free(short_tag);
git_commit_free(commit);
git_repository_free(short_tag_repo);
}
void test_object_tag_read__without_tagger_nor_message(void)
{
git_tag *tag;
git_oid id;
git_repository *repo;
cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
cl_git_pass(git_oid_fromstr(&id, taggerless));
cl_git_pass(git_tag_lookup(&tag, repo, &id));
cl_assert_equal_s(git_tag_name(tag), "taggerless");
cl_assert(git_tag_target_type(tag) == GIT_OBJECT_COMMIT);
cl_assert(tag->message == NULL);
cl_assert(tag->tagger == NULL);
git_tag_free(tag);
git_repository_free(repo);
}
static const char *silly_tag = "object c054ccaefbf2da31c3b19178f9e3ef20a3867924\n\
type commit\n\
tag v1_0_1\n\
tagger Jamis Buck <jamis@37signals.com> 1107717917\n\
diff --git a/lib/sqlite3/version.rb b/lib/sqlite3/version.rb\n\
index 0b3bf69..4ee8fc2 100644\n\
--- a/lib/sqlite3/version.rb\n\
+++ b/lib/sqlite3/version.rb\n\
@@ -36,7 +36,7 @@ module SQLite3\n\
\n\
MAJOR = 1\n\
MINOR = 0\n\
- TINY = 0\n\
+ TINY = 1\n\
\n\
STRING = [ MAJOR, MINOR, TINY ].join( \".\" )\n\
\n\
-0600\n\
\n\
v1_0_1 release\n";
void test_object_tag_read__extra_header_fields(void)
{
git_tag *tag;
git_odb *odb;
git_oid id;
cl_git_pass(git_repository_odb__weakptr(&odb, g_repo));
cl_git_pass(git_odb_write(&id, odb, silly_tag, strlen(silly_tag), GIT_OBJECT_TAG));
cl_git_pass(git_tag_lookup(&tag, g_repo, &id));
cl_assert_equal_s("v1_0_1 release\n", git_tag_message(tag));
git_tag_free(tag);
}
+260
View File
@@ -0,0 +1,260 @@
#include "clar_libgit2.h"
static const char* tagger_name = "Vicent Marti";
static const char* tagger_email = "vicent@github.com";
static const char* tagger_message = "This is my tag.\n\nThere are many tags, but this one is mine\n";
static const char *tag2_id = "7b4384978d2493e851f9cca7858815fac9b10980";
static const char *tagged_commit = "e90810b8df3e80c413d903f631643c716887138d";
static git_repository *g_repo;
/* Fixture setup and teardown */
void test_object_tag_write__initialize(void)
{
g_repo = cl_git_sandbox_init("testrepo");
}
void test_object_tag_write__cleanup(void)
{
cl_git_sandbox_cleanup();
}
void test_object_tag_write__basic(void)
{
/* write a tag to the repository and read it again */
git_tag *tag;
git_oid target_id, tag_id;
git_signature *tagger;
const git_signature *tagger1;
git_reference *ref_tag;
git_object *target;
git_oid_fromstr(&target_id, tagged_commit);
cl_git_pass(git_object_lookup(&target, g_repo, &target_id, GIT_OBJECT_COMMIT));
/* create signature */
cl_git_pass(git_signature_new(&tagger, tagger_name, tagger_email, 123456789, 60));
cl_git_pass(
git_tag_create(&tag_id, g_repo,
"the-tag", target, tagger, tagger_message, 0)
);
git_object_free(target);
git_signature_free(tagger);
cl_git_pass(git_tag_lookup(&tag, g_repo, &tag_id));
cl_assert(git_oid_cmp(git_tag_target_id(tag), &target_id) == 0);
/* Check attributes were set correctly */
tagger1 = git_tag_tagger(tag);
cl_assert(tagger1 != NULL);
cl_assert_equal_s(tagger1->name, tagger_name);
cl_assert_equal_s(tagger1->email, tagger_email);
cl_assert(tagger1->when.time == 123456789);
cl_assert(tagger1->when.offset == 60);
cl_assert_equal_s(git_tag_message(tag), tagger_message);
cl_git_pass(git_reference_lookup(&ref_tag, g_repo, "refs/tags/the-tag"));
cl_assert(git_oid_cmp(git_reference_target(ref_tag), &tag_id) == 0);
cl_git_pass(git_reference_delete(ref_tag));
git_reference_free(ref_tag);
git_tag_free(tag);
}
void test_object_tag_write__overwrite(void)
{
/* Attempt to write a tag bearing the same name than an already existing tag */
git_oid target_id, tag_id;
git_signature *tagger;
git_object *target;
git_oid_fromstr(&target_id, tagged_commit);
cl_git_pass(git_object_lookup(&target, g_repo, &target_id, GIT_OBJECT_COMMIT));
/* create signature */
cl_git_pass(git_signature_new(&tagger, tagger_name, tagger_email, 123456789, 60));
cl_assert_equal_i(GIT_EEXISTS, git_tag_create(
&tag_id, /* out id */
g_repo,
"e90810b",
target,
tagger,
tagger_message,
0));
git_object_free(target);
git_signature_free(tagger);
}
void test_object_tag_write__replace(void)
{
/* Replace an already existing tag */
git_oid target_id, tag_id, old_tag_id;
git_signature *tagger;
git_reference *ref_tag;
git_object *target;
git_oid_fromstr(&target_id, tagged_commit);
cl_git_pass(git_object_lookup(&target, g_repo, &target_id, GIT_OBJECT_COMMIT));
cl_git_pass(git_reference_lookup(&ref_tag, g_repo, "refs/tags/e90810b"));
git_oid_cpy(&old_tag_id, git_reference_target(ref_tag));
git_reference_free(ref_tag);
/* create signature */
cl_git_pass(git_signature_new(&tagger, tagger_name, tagger_email, 123456789, 60));
cl_git_pass(git_tag_create(
&tag_id, /* out id */
g_repo,
"e90810b",
target,
tagger,
tagger_message,
1));
git_object_free(target);
git_signature_free(tagger);
cl_git_pass(git_reference_lookup(&ref_tag, g_repo, "refs/tags/e90810b"));
cl_assert(git_oid_cmp(git_reference_target(ref_tag), &tag_id) == 0);
cl_assert(git_oid_cmp(git_reference_target(ref_tag), &old_tag_id) != 0);
git_reference_free(ref_tag);
}
void test_object_tag_write__lightweight(void)
{
/* write a lightweight tag to the repository and read it again */
git_oid target_id, object_id;
git_reference *ref_tag;
git_object *target;
git_oid_fromstr(&target_id, tagged_commit);
cl_git_pass(git_object_lookup(&target, g_repo, &target_id, GIT_OBJECT_COMMIT));
cl_git_pass(git_tag_create_lightweight(
&object_id,
g_repo,
"light-tag",
target,
0));
git_object_free(target);
cl_assert(git_oid_cmp(&object_id, &target_id) == 0);
cl_git_pass(git_reference_lookup(&ref_tag, g_repo, "refs/tags/light-tag"));
cl_assert(git_oid_cmp(git_reference_target(ref_tag), &target_id) == 0);
cl_git_pass(git_tag_delete(g_repo, "light-tag"));
git_reference_free(ref_tag);
}
void test_object_tag_write__lightweight_over_existing(void)
{
/* Attempt to write a lightweight tag bearing the same name than an already existing tag */
git_oid target_id, object_id, existing_object_id;
git_object *target;
git_oid_fromstr(&target_id, tagged_commit);
cl_git_pass(git_object_lookup(&target, g_repo, &target_id, GIT_OBJECT_COMMIT));
cl_assert_equal_i(GIT_EEXISTS, git_tag_create_lightweight(
&object_id,
g_repo,
"e90810b",
target,
0));
git_oid_fromstr(&existing_object_id, tag2_id);
cl_assert(git_oid_cmp(&object_id, &existing_object_id) == 0);
git_object_free(target);
}
void test_object_tag_write__delete(void)
{
/* Delete an already existing tag */
git_reference *ref_tag;
cl_git_pass(git_tag_delete(g_repo, "e90810b"));
cl_git_fail(git_reference_lookup(&ref_tag, g_repo, "refs/tags/e90810b"));
git_reference_free(ref_tag);
}
void test_object_tag_write__creating_with_an_invalid_name_returns_EINVALIDSPEC(void)
{
git_oid target_id, tag_id;
git_signature *tagger;
git_object *target;
git_oid_fromstr(&target_id, tagged_commit);
cl_git_pass(git_object_lookup(&target, g_repo, &target_id, GIT_OBJECT_COMMIT));
cl_git_pass(git_signature_new(&tagger, tagger_name, tagger_email, 123456789, 60));
cl_assert_equal_i(GIT_EINVALIDSPEC,
git_tag_create(&tag_id, g_repo,
"Inv@{id", target, tagger, tagger_message, 0)
);
cl_assert_equal_i(GIT_EINVALIDSPEC,
git_tag_create_lightweight(&tag_id, g_repo,
"Inv@{id", target, 0)
);
git_object_free(target);
git_signature_free(tagger);
}
void test_object_tag_write__deleting_with_an_invalid_name_returns_EINVALIDSPEC(void)
{
cl_assert_equal_i(GIT_EINVALIDSPEC, git_tag_delete(g_repo, "Inv@{id"));
}
void create_annotation(git_oid *tag_id, const char *name)
{
git_object *target;
git_oid target_id;
git_signature *tagger;
cl_git_pass(git_signature_new(&tagger, tagger_name, tagger_email, 123456789, 60));
git_oid_fromstr(&target_id, tagged_commit);
cl_git_pass(git_object_lookup(&target, g_repo, &target_id, GIT_OBJECT_COMMIT));
cl_git_pass(git_tag_annotation_create(tag_id, g_repo, name, target, tagger, "boom!"));
git_object_free(target);
git_signature_free(tagger);
}
void test_object_tag_write__creating_an_annotation_stores_the_new_object_in_the_odb(void)
{
git_oid tag_id;
git_tag *tag;
create_annotation(&tag_id, "new_tag");
cl_git_pass(git_tag_lookup(&tag, g_repo, &tag_id));
cl_assert_equal_s("new_tag", git_tag_name(tag));
git_tag_free(tag);
}
void test_object_tag_write__creating_an_annotation_does_not_create_a_reference(void)
{
git_oid tag_id;
git_reference *tag_ref;
create_annotation(&tag_id, "new_tag");
cl_git_fail_with(git_reference_lookup(&tag_ref, g_repo, "refs/tags/new_tag"), GIT_ENOTFOUND);
}
+118
View File
@@ -0,0 +1,118 @@
#include "clar_libgit2.h"
#include "tree.h"
static git_repository *repo;
static const char *blob_oid = "3d0970ec547fc41ef8a5882dde99c6adce65b021";
static const char *tree_oid = "1b05fdaa881ee45b48cbaa5e9b037d667a47745e";
void test_object_tree_attributes__initialize(void)
{
repo = cl_git_sandbox_init("deprecated-mode.git");
}
void test_object_tree_attributes__cleanup(void)
{
cl_git_sandbox_cleanup();
}
void test_object_tree_attributes__ensure_correctness_of_attributes_on_insertion(void)
{
git_treebuilder *builder;
git_oid oid;
cl_git_pass(git_oid_fromstr(&oid, blob_oid));
cl_git_pass(git_treebuilder_new(&builder, repo, NULL));
cl_git_fail(git_treebuilder_insert(NULL, builder, "one.txt", &oid, (git_filemode_t)0777777));
cl_git_fail(git_treebuilder_insert(NULL, builder, "one.txt", &oid, (git_filemode_t)0100666));
cl_git_fail(git_treebuilder_insert(NULL, builder, "one.txt", &oid, (git_filemode_t)0000001));
git_treebuilder_free(builder);
}
void test_object_tree_attributes__group_writable_tree_entries_created_with_an_antique_git_version_can_still_be_accessed(void)
{
git_oid tid;
git_tree *tree;
const git_tree_entry *entry;
cl_git_pass(git_oid_fromstr(&tid, tree_oid));
cl_git_pass(git_tree_lookup(&tree, repo, &tid));
entry = git_tree_entry_byname(tree, "old_mode.txt");
cl_assert_equal_i(
GIT_FILEMODE_BLOB,
git_tree_entry_filemode(entry));
git_tree_free(tree);
}
void test_object_tree_attributes__treebuilder_reject_invalid_filemode(void)
{
git_treebuilder *builder;
git_oid bid;
const git_tree_entry *entry;
cl_git_pass(git_oid_fromstr(&bid, blob_oid));
cl_git_pass(git_treebuilder_new(&builder, repo, NULL));
cl_git_fail(git_treebuilder_insert(
&entry,
builder,
"normalized.txt",
&bid,
GIT_FILEMODE_BLOB_GROUP_WRITABLE));
git_treebuilder_free(builder);
}
void test_object_tree_attributes__normalize_attributes_when_creating_a_tree_from_an_existing_one(void)
{
git_treebuilder *builder;
git_oid tid, tid2;
git_tree *tree;
const git_tree_entry *entry;
cl_git_pass(git_oid_fromstr(&tid, tree_oid));
cl_git_pass(git_tree_lookup(&tree, repo, &tid));
cl_git_pass(git_treebuilder_new(&builder, repo, tree));
entry = git_treebuilder_get(builder, "old_mode.txt");
cl_assert(entry != NULL);
cl_assert_equal_i(
GIT_FILEMODE_BLOB,
git_tree_entry_filemode(entry));
cl_git_pass(git_treebuilder_write(&tid2, builder));
git_treebuilder_free(builder);
git_tree_free(tree);
cl_git_pass(git_tree_lookup(&tree, repo, &tid2));
entry = git_tree_entry_byname(tree, "old_mode.txt");
cl_assert(entry != NULL);
cl_assert_equal_i(
GIT_FILEMODE_BLOB,
git_tree_entry_filemode(entry));
git_tree_free(tree);
}
void test_object_tree_attributes__normalize_600(void)
{
git_oid id;
git_tree *tree;
const git_tree_entry *entry;
git_oid_fromstr(&id, "0810fb7818088ff5ac41ee49199b51473b1bd6c7");
cl_git_pass(git_tree_lookup(&tree, repo, &id));
entry = git_tree_entry_byname(tree, "ListaTeste.xml");
cl_assert_equal_i(git_tree_entry_filemode(entry), GIT_FILEMODE_BLOB);
cl_assert_equal_i(git_tree_entry_filemode_raw(entry), 0100600);
git_tree_free(tree);
}
@@ -0,0 +1,157 @@
#include "clar_libgit2.h"
#include "tree.h"
static git_repository *_repo;
void test_object_tree_duplicateentries__initialize(void) {
_repo = cl_git_sandbox_init("testrepo");
}
void test_object_tree_duplicateentries__cleanup(void) {
cl_git_sandbox_cleanup();
}
/*
* $ git show --format=raw refs/heads/dir
* commit 144344043ba4d4a405da03de3844aa829ae8be0e
* tree d52a8fe84ceedf260afe4f0287bbfca04a117e83
* parent cf80f8de9f1185bf3a05f993f6121880dd0cfbc9
* author Ben Straub <bstraub@github.com> 1343755506 -0700
* committer Ben Straub <bstraub@github.com> 1343755506 -0700
*
* Change a file mode
*
* diff --git a/a/b.txt b/a/b.txt
* old mode 100644
* new mode 100755
*
* $ git ls-tree d52a8fe84ceedf260afe4f0287bbfca04a117e83
* 100644 blob a8233120f6ad708f843d861ce2b7228ec4e3dec6 README
* 040000 tree 4e0883eeeeebc1fb1735161cea82f7cb5fab7e63 a
* 100644 blob 45b983be36b73c0788dc9cbcb76cbb80fc7bb057 branch_file.txt
* 100644 blob a71586c1dfe8a71c6cbf6c129f404c5642ff31bd new.txt
*/
static void tree_checker(
git_oid *tid,
const char *expected_sha,
git_filemode_t expected_filemode)
{
git_tree *tree;
const git_tree_entry *entry;
git_oid oid;
cl_git_pass(git_tree_lookup(&tree, _repo, tid));
cl_assert_equal_i(1, (int)git_tree_entrycount(tree));
entry = git_tree_entry_byindex(tree, 0);
cl_git_pass(git_oid_fromstr(&oid, expected_sha));
cl_assert_equal_i(0, git_oid_cmp(&oid, git_tree_entry_id(entry)));
cl_assert_equal_i(expected_filemode, git_tree_entry_filemode(entry));
git_tree_free(tree);
}
static void tree_creator(git_oid *out, void (*fn)(git_treebuilder *))
{
git_treebuilder *builder;
cl_git_pass(git_treebuilder_new(&builder, _repo, NULL));
fn(builder);
cl_git_pass(git_treebuilder_write(out, builder));
git_treebuilder_free(builder);
}
static void two_blobs(git_treebuilder *bld)
{
git_oid oid;
const git_tree_entry *entry;
cl_git_pass(git_oid_fromstr(&oid,
"a8233120f6ad708f843d861ce2b7228ec4e3dec6")); /* blob oid (README) */
cl_git_pass(git_treebuilder_insert(
&entry, bld, "duplicate", &oid,
GIT_FILEMODE_BLOB));
cl_git_pass(git_oid_fromstr(&oid,
"a71586c1dfe8a71c6cbf6c129f404c5642ff31bd")); /* blob oid (new.txt) */
cl_git_pass(git_treebuilder_insert(
&entry, bld, "duplicate", &oid,
GIT_FILEMODE_BLOB));
}
static void one_blob_and_one_tree(git_treebuilder *bld)
{
git_oid oid;
const git_tree_entry *entry;
cl_git_pass(git_oid_fromstr(&oid,
"a8233120f6ad708f843d861ce2b7228ec4e3dec6")); /* blob oid (README) */
cl_git_pass(git_treebuilder_insert(
&entry, bld, "duplicate", &oid,
GIT_FILEMODE_BLOB));
cl_git_pass(git_oid_fromstr(&oid,
"4e0883eeeeebc1fb1735161cea82f7cb5fab7e63")); /* tree oid (a) */
cl_git_pass(git_treebuilder_insert(
&entry, bld, "duplicate", &oid,
GIT_FILEMODE_TREE));
}
void test_object_tree_duplicateentries__cannot_create_a_duplicate_entry_through_the_treebuilder(void)
{
git_oid tid;
tree_creator(&tid, two_blobs);
tree_checker(&tid, "a71586c1dfe8a71c6cbf6c129f404c5642ff31bd", GIT_FILEMODE_BLOB);
tree_creator(&tid, one_blob_and_one_tree);
tree_checker(&tid, "4e0883eeeeebc1fb1735161cea82f7cb5fab7e63", GIT_FILEMODE_TREE);
}
static void add_fake_conflicts(git_index *index)
{
git_index_entry ancestor_entry, our_entry, their_entry;
memset(&ancestor_entry, 0x0, sizeof(git_index_entry));
memset(&our_entry, 0x0, sizeof(git_index_entry));
memset(&their_entry, 0x0, sizeof(git_index_entry));
ancestor_entry.path = "duplicate";
ancestor_entry.mode = GIT_FILEMODE_BLOB;
GIT_INDEX_ENTRY_STAGE_SET(&ancestor_entry, 1);
git_oid_fromstr(&ancestor_entry.id, "a8233120f6ad708f843d861ce2b7228ec4e3dec6");
our_entry.path = "duplicate";
our_entry.mode = GIT_FILEMODE_BLOB;
GIT_INDEX_ENTRY_STAGE_SET(&our_entry, 2);
git_oid_fromstr(&our_entry.id, "45b983be36b73c0788dc9cbcb76cbb80fc7bb057");
their_entry.path = "duplicate";
their_entry.mode = GIT_FILEMODE_BLOB;
GIT_INDEX_ENTRY_STAGE_SET(&their_entry, 3);
git_oid_fromstr(&their_entry.id, "a71586c1dfe8a71c6cbf6c129f404c5642ff31bd");
cl_git_pass(git_index_conflict_add(index, &ancestor_entry, &our_entry, &their_entry));
}
void test_object_tree_duplicateentries__cannot_create_a_duplicate_entry_building_a_tree_from_a_index_with_conflicts(void)
{
git_index *index;
git_oid tid;
cl_git_pass(git_repository_index(&index, _repo));
add_fake_conflicts(index);
cl_assert_equal_i(GIT_EUNMERGED, git_index_write_tree(&tid, index));
git_index_free(index);
}
+68
View File
@@ -0,0 +1,68 @@
#include "clar_libgit2.h"
static git_repository *repo;
static git_tree *tree;
void test_object_tree_frompath__initialize(void)
{
git_oid id;
const char *tree_with_subtrees_oid = "ae90f12eea699729ed24555e40b9fd669da12a12";
cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
cl_assert(repo != NULL);
cl_git_pass(git_oid_fromstr(&id, tree_with_subtrees_oid));
cl_git_pass(git_tree_lookup(&tree, repo, &id));
cl_assert(tree != NULL);
}
void test_object_tree_frompath__cleanup(void)
{
git_tree_free(tree);
tree = NULL;
git_repository_free(repo);
repo = NULL;
}
static void assert_tree_from_path(
git_tree *root,
const char *path,
const char *expected_entry_name)
{
git_tree_entry *entry;
cl_git_pass(git_tree_entry_bypath(&entry, root, path));
cl_assert_equal_s(git_tree_entry_name(entry), expected_entry_name);
git_tree_entry_free(entry);
}
void test_object_tree_frompath__retrieve_tree_from_path_to_treeentry(void)
{
git_tree_entry *e;
assert_tree_from_path(tree, "README", "README");
assert_tree_from_path(tree, "ab/de/fgh/1.txt", "1.txt");
assert_tree_from_path(tree, "ab/de/fgh", "fgh");
assert_tree_from_path(tree, "ab/de/fgh/", "fgh");
assert_tree_from_path(tree, "ab/de", "de");
assert_tree_from_path(tree, "ab/", "ab");
assert_tree_from_path(tree, "ab/de/", "de");
cl_assert_equal_i(GIT_ENOTFOUND, git_tree_entry_bypath(&e, tree, "i-do-not-exist.txt"));
cl_assert_equal_i(GIT_ENOTFOUND, git_tree_entry_bypath(&e, tree, "README/"));
cl_assert_equal_i(GIT_ENOTFOUND, git_tree_entry_bypath(&e, tree, "ab/de/fgh/i-do-not-exist.txt"));
cl_assert_equal_i(GIT_ENOTFOUND, git_tree_entry_bypath(&e, tree, "nope/de/fgh/1.txt"));
cl_assert_equal_i(GIT_ENOTFOUND, git_tree_entry_bypath(&e, tree, "ab/me-neither/fgh/2.txt"));
cl_assert_equal_i(GIT_ENOTFOUND, git_tree_entry_bypath(&e, tree, "ab/me-neither/fgh/2.txt/"));
}
void test_object_tree_frompath__fail_when_processing_an_invalid_path(void)
{
git_tree_entry *e;
cl_must_fail(git_tree_entry_bypath(&e, tree, "/"));
cl_must_fail(git_tree_entry_bypath(&e, tree, "/ab"));
cl_must_fail(git_tree_entry_bypath(&e, tree, "/ab/de"));
cl_must_fail(git_tree_entry_bypath(&e, tree, "ab//de"));
}
+164
View File
@@ -0,0 +1,164 @@
#include "clar_libgit2.h"
#include "tree.h"
#include "object.h"
#define OID1_HEX \
"\xae\x90\xf1\x2e\xea\x69\x97\x29\xed\x24" \
"\x55\x5e\x40\xb9\xfd\x66\x9d\xa1\x2a\x12"
#define OID1_STR "ae90f12eea699729ed24555e40b9fd669da12a12"
#define OID2_HEX \
"\xe8\xbf\xe5\xaf\x39\x57\x9a\x7e\x48\x98" \
"\xbb\x23\xf3\xa7\x6a\x72\xc3\x68\xce\xe6"
#define OID2_STR "e8bfe5af39579a7e4898bb23f3a76a72c368cee6"
typedef struct {
const char *filename;
uint16_t attr;
const char *oid;
} expected_entry;
static void assert_tree_parses(const char *data, size_t datalen,
expected_entry *expected_entries, size_t expected_nentries)
{
git_tree *tree;
size_t n;
if (!datalen)
datalen = strlen(data);
cl_git_pass(git_object__from_raw((git_object **) &tree, data, datalen, GIT_OBJECT_TREE));
cl_assert_equal_i(git_tree_entrycount(tree), expected_nentries);
for (n = 0; n < expected_nentries; n++) {
expected_entry *expected = expected_entries + n;
const git_tree_entry *entry;
git_oid oid;
cl_git_pass(git_oid_fromstr(&oid, expected->oid));
cl_assert(entry = git_tree_entry_byname(tree, expected->filename));
cl_assert_equal_s(expected->filename, entry->filename);
cl_assert_equal_i(expected->attr, entry->attr);
cl_assert_equal_oid(&oid, entry->oid);
}
git_object_free(&tree->object);
}
static void assert_tree_fails(const char *data, size_t datalen)
{
git_object *object;
if (!datalen)
datalen = strlen(data);
cl_git_fail(git_object__from_raw(&object, data, datalen, GIT_OBJECT_TREE));
}
void test_object_tree_parse__single_blob_parses(void)
{
expected_entry entries[] = {
{ "foo", 0100644, OID1_STR },
};
const char data[] = "100644 foo\x00" OID1_HEX;
assert_tree_parses(data, ARRAY_SIZE(data) - 1, entries, ARRAY_SIZE(entries));
}
void test_object_tree_parse__single_tree_parses(void)
{
expected_entry entries[] = {
{ "foo", 040000, OID1_STR },
};
const char data[] = "040000 foo\x00" OID1_HEX;
assert_tree_parses(data, ARRAY_SIZE(data) - 1, entries, ARRAY_SIZE(entries));
}
void test_object_tree_parse__leading_filename_spaces_parse(void)
{
expected_entry entries[] = {
{ " bar", 0100644, OID1_STR },
};
const char data[] = "100644 bar\x00" OID1_HEX;
assert_tree_parses(data, ARRAY_SIZE(data) - 1, entries, ARRAY_SIZE(entries));
}
void test_object_tree_parse__multiple_entries_parse(void)
{
expected_entry entries[] = {
{ "bar", 0100644, OID1_STR },
{ "foo", 040000, OID2_STR },
};
const char data[] =
"100644 bar\x00" OID1_HEX
"040000 foo\x00" OID2_HEX;
assert_tree_parses(data, ARRAY_SIZE(data) - 1, entries, ARRAY_SIZE(entries));
}
void test_object_tree_parse__invalid_mode_fails(void)
{
const char data[] = "10x644 bar\x00" OID1_HEX;
assert_tree_fails(data, ARRAY_SIZE(data) - 1);
}
void test_object_tree_parse__missing_mode_fails(void)
{
const char data[] = " bar\x00" OID1_HEX;
assert_tree_fails(data, ARRAY_SIZE(data) - 1);
}
void test_object_tree_parse__mode_doesnt_cause_oob_read(void)
{
const char data[] = "100644 bar\x00" OID1_HEX;
assert_tree_fails(data, 2);
/*
* An oob-read would correctly parse the filename and
* later fail to parse the OID with a different error
* message
*/
cl_assert_equal_s(git_error_last()->message, "failed to parse tree: missing space after filemode");
}
void test_object_tree_parse__unreasonably_large_mode_fails(void)
{
const char data[] = "10000000000000000000000000 bar\x00" OID1_HEX;
assert_tree_fails(data, ARRAY_SIZE(data) - 1);
}
void test_object_tree_parse__missing_filename_separator_fails(void)
{
const char data[] = "100644bar\x00" OID1_HEX;
assert_tree_fails(data, ARRAY_SIZE(data) - 1);
}
void test_object_tree_parse__missing_filename_terminator_fails(void)
{
const char data[] = "100644 bar" OID1_HEX;
assert_tree_fails(data, ARRAY_SIZE(data) - 1);
}
void test_object_tree_parse__empty_filename_fails(void)
{
const char data[] = "100644 \x00" OID1_HEX;
assert_tree_fails(data, ARRAY_SIZE(data) - 1);
}
void test_object_tree_parse__trailing_garbage_fails(void)
{
const char data[] = "100644 bar\x00" OID1_HEX "x";
assert_tree_fails(data, ARRAY_SIZE(data) - 1);
}
void test_object_tree_parse__leading_space_fails(void)
{
const char data[] = " 100644 bar\x00" OID1_HEX;
assert_tree_fails(data, ARRAY_SIZE(data) - 1);
}
void test_object_tree_parse__truncated_oid_fails(void)
{
const char data[] = " 100644 bar\x00" OID1_HEX;
assert_tree_fails(data, ARRAY_SIZE(data) - 2);
}
+119
View File
@@ -0,0 +1,119 @@
#include "clar_libgit2.h"
#include "tree.h"
static const char *tree_oid = "1810dff58d8a660512d4832e740f692884338ccd";
static git_repository *g_repo;
/* Fixture setup and teardown */
void test_object_tree_read__initialize(void)
{
g_repo = cl_git_sandbox_init("testrepo");
}
void test_object_tree_read__cleanup(void)
{
cl_git_sandbox_cleanup();
}
void test_object_tree_read__loaded(void)
{
/* acces randomly the entries on a loaded tree */
git_oid id;
git_tree *tree;
git_oid_fromstr(&id, tree_oid);
cl_git_pass(git_tree_lookup(&tree, g_repo, &id));
cl_assert(git_tree_entry_byname(tree, "README") != NULL);
cl_assert(git_tree_entry_byname(tree, "NOTEXISTS") == NULL);
cl_assert(git_tree_entry_byname(tree, "") == NULL);
cl_assert(git_tree_entry_byindex(tree, 0) != NULL);
cl_assert(git_tree_entry_byindex(tree, 2) != NULL);
cl_assert(git_tree_entry_byindex(tree, 3) == NULL);
cl_assert(git_tree_entry_byindex(tree, (unsigned int)-1) == NULL);
git_tree_free(tree);
}
void test_object_tree_read__two(void)
{
/* read a tree from the repository */
git_oid id;
git_tree *tree;
const git_tree_entry *entry;
git_object *obj;
git_oid_fromstr(&id, tree_oid);
cl_git_pass(git_tree_lookup(&tree, g_repo, &id));
cl_assert(git_tree_entrycount(tree) == 3);
/* GH-86: git_object_lookup() should also check the type if the object comes from the cache */
cl_assert(git_object_lookup(&obj, g_repo, &id, GIT_OBJECT_TREE) == 0);
cl_assert(obj != NULL);
git_object_free(obj);
obj = NULL;
cl_git_fail(git_object_lookup(&obj, g_repo, &id, GIT_OBJECT_BLOB));
cl_assert(obj == NULL);
entry = git_tree_entry_byname(tree, "README");
cl_assert(entry != NULL);
cl_assert_equal_s(git_tree_entry_name(entry), "README");
cl_git_pass(git_tree_entry_to_object(&obj, g_repo, entry));
cl_assert(obj != NULL);
git_object_free(obj);
git_tree_free(tree);
}
#define BIGFILE "bigfile"
#ifdef GIT_ARCH_64
#define BIGFILE_SIZE (off_t)4294967296
#else
# define BIGFILE_SIZE SIZE_MAX
#endif
void test_object_tree_read__largefile(void)
{
const git_tree_entry *entry;
git_index_entry ie;
git_commit *commit;
git_object *object;
git_index *index;
git_tree *tree;
git_oid oid;
char *buf;
if (!cl_is_env_set("GITTEST_INVASIVE_FS_SIZE"))
cl_skip();
cl_assert(buf = git__calloc(1, BIGFILE_SIZE));
memset(&ie, 0, sizeof(ie));
ie.mode = GIT_FILEMODE_BLOB;
ie.path = BIGFILE;
cl_git_pass(git_repository_index(&index, g_repo));
cl_git_pass(git_index_add_from_buffer(index, &ie, buf, BIGFILE_SIZE));
cl_repo_commit_from_index(&oid, g_repo, NULL, 0, BIGFILE);
cl_git_pass(git_commit_lookup(&commit, g_repo, &oid));
cl_git_pass(git_commit_tree(&tree, commit));
cl_assert(entry = git_tree_entry_byname(tree, BIGFILE));
cl_git_pass(git_tree_entry_to_object(&object, g_repo, entry));
git_object_free(object);
git_tree_free(tree);
git_index_free(index);
git_commit_free(commit);
git__free(buf);
}
+302
View File
@@ -0,0 +1,302 @@
#include "clar_libgit2.h"
#include "tree.h"
static git_repository *g_repo;
void test_object_tree_update__initialize(void)
{
g_repo = cl_git_sandbox_init("testrepo2");
}
void test_object_tree_update__cleanup(void)
{
cl_git_sandbox_cleanup();
}
void test_object_tree_update__remove_blob(void)
{
git_oid tree_index_id, tree_updater_id, base_id;
git_tree *base_tree;
git_index *idx;
const char *path = "README";
git_tree_update updates[] = {
{ GIT_TREE_UPDATE_REMOVE, {{0}}, GIT_FILEMODE_BLOB /* ignored */, path},
};
cl_git_pass(git_oid_fromstr(&base_id, "c4dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b"));
cl_git_pass(git_tree_lookup(&base_tree, g_repo, &base_id));
/* Create it with an index */
cl_git_pass(git_index_new(&idx));
cl_git_pass(git_index_read_tree(idx, base_tree));
cl_git_pass(git_index_remove(idx, path, 0));
cl_git_pass(git_index_write_tree_to(&tree_index_id, idx, g_repo));
git_index_free(idx);
/* Perform the same operation via the tree updater */
cl_git_pass(git_tree_create_updated(&tree_updater_id, g_repo, base_tree, 1, updates));
cl_assert_equal_oid(&tree_index_id, &tree_updater_id);
git_tree_free(base_tree);
}
void test_object_tree_update__remove_blob_deeper(void)
{
git_oid tree_index_id, tree_updater_id, base_id;
git_tree *base_tree;
git_index *idx;
const char *path = "subdir/README";
git_tree_update updates[] = {
{ GIT_TREE_UPDATE_REMOVE, {{0}}, GIT_FILEMODE_BLOB /* ignored */, path},
};
cl_git_pass(git_oid_fromstr(&base_id, "c4dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b"));
cl_git_pass(git_tree_lookup(&base_tree, g_repo, &base_id));
/* Create it with an index */
cl_git_pass(git_index_new(&idx));
cl_git_pass(git_index_read_tree(idx, base_tree));
cl_git_pass(git_index_remove(idx, path, 0));
cl_git_pass(git_index_write_tree_to(&tree_index_id, idx, g_repo));
git_index_free(idx);
/* Perform the same operation via the tree updater */
cl_git_pass(git_tree_create_updated(&tree_updater_id, g_repo, base_tree, 1, updates));
cl_assert_equal_oid(&tree_index_id, &tree_updater_id);
git_tree_free(base_tree);
}
void test_object_tree_update__remove_all_entries(void)
{
git_oid tree_index_id, tree_updater_id, base_id;
git_tree *base_tree;
git_index *idx;
const char *path1 = "subdir/subdir2/README";
const char *path2 = "subdir/subdir2/new.txt";
git_tree_update updates[] = {
{ GIT_TREE_UPDATE_REMOVE, {{0}}, GIT_FILEMODE_BLOB /* ignored */, path1},
{ GIT_TREE_UPDATE_REMOVE, {{0}}, GIT_FILEMODE_BLOB /* ignored */, path2},
};
cl_git_pass(git_oid_fromstr(&base_id, "c4dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b"));
cl_git_pass(git_tree_lookup(&base_tree, g_repo, &base_id));
/* Create it with an index */
cl_git_pass(git_index_new(&idx));
cl_git_pass(git_index_read_tree(idx, base_tree));
cl_git_pass(git_index_remove(idx, path1, 0));
cl_git_pass(git_index_remove(idx, path2, 0));
cl_git_pass(git_index_write_tree_to(&tree_index_id, idx, g_repo));
git_index_free(idx);
/* Perform the same operation via the tree updater */
cl_git_pass(git_tree_create_updated(&tree_updater_id, g_repo, base_tree, 2, updates));
cl_assert_equal_oid(&tree_index_id, &tree_updater_id);
git_tree_free(base_tree);
}
void test_object_tree_update__replace_blob(void)
{
git_oid tree_index_id, tree_updater_id, base_id;
git_tree *base_tree;
git_index *idx;
const char *path = "README";
git_index_entry entry = { {0} };
git_tree_update updates[] = {
{ GIT_TREE_UPDATE_UPSERT, {{0}}, GIT_FILEMODE_BLOB, path},
};
cl_git_pass(git_oid_fromstr(&base_id, "c4dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b"));
cl_git_pass(git_tree_lookup(&base_tree, g_repo, &base_id));
/* Create it with an index */
cl_git_pass(git_index_new(&idx));
cl_git_pass(git_index_read_tree(idx, base_tree));
entry.path = path;
cl_git_pass(git_oid_fromstr(&entry.id, "fa49b077972391ad58037050f2a75f74e3671e92"));
entry.mode = GIT_FILEMODE_BLOB;
cl_git_pass(git_index_add(idx, &entry));
cl_git_pass(git_index_write_tree_to(&tree_index_id, idx, g_repo));
git_index_free(idx);
/* Perform the same operation via the tree updater */
cl_git_pass(git_oid_fromstr(&updates[0].id, "fa49b077972391ad58037050f2a75f74e3671e92"));
cl_git_pass(git_tree_create_updated(&tree_updater_id, g_repo, base_tree, 1, updates));
cl_assert_equal_oid(&tree_index_id, &tree_updater_id);
git_tree_free(base_tree);
}
void test_object_tree_update__add_blobs(void)
{
git_oid tree_index_id, tree_updater_id, base_id;
git_tree *base_tree;
git_index *idx;
git_index_entry entry = { {0} };
int i;
const char *paths[] = {
"some/deep/path",
"some/other/path",
"a/path/elsewhere",
};
git_tree_update updates[] = {
{ GIT_TREE_UPDATE_UPSERT, {{0}}, GIT_FILEMODE_BLOB, paths[0]},
{ GIT_TREE_UPDATE_UPSERT, {{0}}, GIT_FILEMODE_BLOB, paths[1]},
{ GIT_TREE_UPDATE_UPSERT, {{0}}, GIT_FILEMODE_BLOB, paths[2]},
};
cl_git_pass(git_oid_fromstr(&base_id, "c4dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b"));
entry.mode = GIT_FILEMODE_BLOB;
cl_git_pass(git_oid_fromstr(&entry.id, "fa49b077972391ad58037050f2a75f74e3671e92"));
for (i = 0; i < 3; i++) {
cl_git_pass(git_oid_fromstr(&updates[i].id, "fa49b077972391ad58037050f2a75f74e3671e92"));
}
for (i = 0; i < 2; i++) {
int j;
/* Create it with an index */
cl_git_pass(git_index_new(&idx));
base_tree = NULL;
if (i == 1) {
cl_git_pass(git_tree_lookup(&base_tree, g_repo, &base_id));
cl_git_pass(git_index_read_tree(idx, base_tree));
}
for (j = 0; j < 3; j++) {
entry.path = paths[j];
cl_git_pass(git_index_add(idx, &entry));
}
cl_git_pass(git_index_write_tree_to(&tree_index_id, idx, g_repo));
git_index_free(idx);
/* Perform the same operations via the tree updater */
cl_git_pass(git_tree_create_updated(&tree_updater_id, g_repo, base_tree, 3, updates));
cl_assert_equal_oid(&tree_index_id, &tree_updater_id);
}
git_tree_free(base_tree);
}
void test_object_tree_update__add_blobs_unsorted(void)
{
git_oid tree_index_id, tree_updater_id, base_id;
git_tree *base_tree;
git_index *idx;
git_index_entry entry = { {0} };
int i;
const char *paths[] = {
"some/deep/path",
"a/path/elsewhere",
"some/other/path",
};
git_tree_update updates[] = {
{ GIT_TREE_UPDATE_UPSERT, {{0}}, GIT_FILEMODE_BLOB, paths[0]},
{ GIT_TREE_UPDATE_UPSERT, {{0}}, GIT_FILEMODE_BLOB, paths[1]},
{ GIT_TREE_UPDATE_UPSERT, {{0}}, GIT_FILEMODE_BLOB, paths[2]},
};
cl_git_pass(git_oid_fromstr(&base_id, "c4dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b"));
entry.mode = GIT_FILEMODE_BLOB;
cl_git_pass(git_oid_fromstr(&entry.id, "fa49b077972391ad58037050f2a75f74e3671e92"));
for (i = 0; i < 3; i++) {
cl_git_pass(git_oid_fromstr(&updates[i].id, "fa49b077972391ad58037050f2a75f74e3671e92"));
}
for (i = 0; i < 2; i++) {
int j;
/* Create it with an index */
cl_git_pass(git_index_new(&idx));
base_tree = NULL;
if (i == 1) {
cl_git_pass(git_tree_lookup(&base_tree, g_repo, &base_id));
cl_git_pass(git_index_read_tree(idx, base_tree));
}
for (j = 0; j < 3; j++) {
entry.path = paths[j];
cl_git_pass(git_index_add(idx, &entry));
}
cl_git_pass(git_index_write_tree_to(&tree_index_id, idx, g_repo));
git_index_free(idx);
/* Perform the same operations via the tree updater */
cl_git_pass(git_tree_create_updated(&tree_updater_id, g_repo, base_tree, 3, updates));
cl_assert_equal_oid(&tree_index_id, &tree_updater_id);
}
git_tree_free(base_tree);
}
void test_object_tree_update__add_conflict(void)
{
int i;
git_oid tree_updater_id;
git_tree_update updates[] = {
{ GIT_TREE_UPDATE_UPSERT, {{0}}, GIT_FILEMODE_BLOB, "a/dir/blob"},
{ GIT_TREE_UPDATE_UPSERT, {{0}}, GIT_FILEMODE_BLOB, "a/dir"},
};
for (i = 0; i < 2; i++) {
cl_git_pass(git_oid_fromstr(&updates[i].id, "a71586c1dfe8a71c6cbf6c129f404c5642ff31bd"));
}
cl_git_fail(git_tree_create_updated(&tree_updater_id, g_repo, NULL, 2, updates));
}
void test_object_tree_update__add_conflict2(void)
{
int i;
git_oid tree_updater_id;
git_tree_update updates[] = {
{ GIT_TREE_UPDATE_UPSERT, {{0}}, GIT_FILEMODE_BLOB, "a/dir/blob"},
{ GIT_TREE_UPDATE_UPSERT, {{0}}, GIT_FILEMODE_TREE, "a/dir/blob"},
};
for (i = 0; i < 2; i++) {
cl_git_pass(git_oid_fromstr(&updates[i].id, "a71586c1dfe8a71c6cbf6c129f404c5642ff31bd"));
}
cl_git_fail(git_tree_create_updated(&tree_updater_id, g_repo, NULL, 2, updates));
}
void test_object_tree_update__remove_invalid_submodule(void)
{
git_tree *baseline;
git_oid updated_tree_id, baseline_id;
git_tree_update updates[] = {
{GIT_TREE_UPDATE_REMOVE, {{0}}, GIT_FILEMODE_BLOB, "submodule"},
};
/* This tree contains a submodule with an all-zero commit for a submodule named 'submodule' */
cl_git_pass(git_oid_fromstr(&baseline_id, "396c7f1adb7925f51ba13a75f48252f44c5a14a2"));
cl_git_pass(git_tree_lookup(&baseline, g_repo, &baseline_id));
cl_git_pass(git_tree_create_updated(&updated_tree_id, g_repo, baseline, 1, updates));
git_tree_free(baseline);
}
+177
View File
@@ -0,0 +1,177 @@
#include "clar_libgit2.h"
#include "tree.h"
static const char *tree_oid = "1810dff58d8a660512d4832e740f692884338ccd";
static git_repository *g_repo;
void test_object_tree_walk__initialize(void)
{
g_repo = cl_git_sandbox_init("testrepo");
}
void test_object_tree_walk__cleanup(void)
{
cl_git_sandbox_cleanup();
}
static int treewalk_count_cb(
const char *root, const git_tree_entry *entry, void *payload)
{
int *count = payload;
GIT_UNUSED(root);
GIT_UNUSED(entry);
(*count) += 1;
return 0;
}
void test_object_tree_walk__0(void)
{
git_oid id;
git_tree *tree;
int ct;
git_oid_fromstr(&id, tree_oid);
cl_git_pass(git_tree_lookup(&tree, g_repo, &id));
ct = 0;
cl_git_pass(git_tree_walk(tree, GIT_TREEWALK_PRE, treewalk_count_cb, &ct));
cl_assert_equal_i(3, ct);
ct = 0;
cl_git_pass(git_tree_walk(tree, GIT_TREEWALK_POST, treewalk_count_cb, &ct));
cl_assert_equal_i(3, ct);
git_tree_free(tree);
}
static int treewalk_stop_cb(
const char *root, const git_tree_entry *entry, void *payload)
{
int *count = payload;
GIT_UNUSED(root);
GIT_UNUSED(entry);
(*count) += 1;
return (*count == 2) ? -123 : 0;
}
static int treewalk_stop_immediately_cb(
const char *root, const git_tree_entry *entry, void *payload)
{
GIT_UNUSED(root);
GIT_UNUSED(entry);
GIT_UNUSED(payload);
return -100;
}
void test_object_tree_walk__1(void)
{
git_oid id;
git_tree *tree;
int ct;
git_oid_fromstr(&id, tree_oid);
cl_git_pass(git_tree_lookup(&tree, g_repo, &id));
ct = 0;
cl_assert_equal_i(
-123, git_tree_walk(tree, GIT_TREEWALK_PRE, treewalk_stop_cb, &ct));
cl_assert_equal_i(2, ct);
ct = 0;
cl_assert_equal_i(
-123, git_tree_walk(tree, GIT_TREEWALK_POST, treewalk_stop_cb, &ct));
cl_assert_equal_i(2, ct);
cl_assert_equal_i(
-100, git_tree_walk(
tree, GIT_TREEWALK_PRE, treewalk_stop_immediately_cb, NULL));
cl_assert_equal_i(
-100, git_tree_walk(
tree, GIT_TREEWALK_POST, treewalk_stop_immediately_cb, NULL));
git_tree_free(tree);
}
struct treewalk_skip_data {
int files;
int dirs;
const char *skip;
const char *stop;
};
static int treewalk_skip_de_cb(
const char *root, const git_tree_entry *entry, void *payload)
{
struct treewalk_skip_data *data = payload;
const char *name = git_tree_entry_name(entry);
GIT_UNUSED(root);
if (git_tree_entry_type(entry) == GIT_OBJECT_TREE)
data->dirs++;
else
data->files++;
if (data->skip && !strcmp(name, data->skip))
return 1;
else if (data->stop && !strcmp(name, data->stop))
return -1;
else
return 0;
}
void test_object_tree_walk__2(void)
{
git_oid id;
git_tree *tree;
struct treewalk_skip_data data;
/* look up a deep tree */
git_oid_fromstr(&id, "ae90f12eea699729ed24555e40b9fd669da12a12");
cl_git_pass(git_tree_lookup(&tree, g_repo, &id));
memset(&data, 0, sizeof(data));
data.skip = "de";
cl_assert_equal_i(0, git_tree_walk(
tree, GIT_TREEWALK_PRE, treewalk_skip_de_cb, &data));
cl_assert_equal_i(5, data.files);
cl_assert_equal_i(3, data.dirs);
memset(&data, 0, sizeof(data));
data.stop = "3.txt";
cl_assert_equal_i(-1, git_tree_walk(
tree, GIT_TREEWALK_PRE, treewalk_skip_de_cb, &data));
cl_assert_equal_i(3, data.files);
cl_assert_equal_i(2, data.dirs);
memset(&data, 0, sizeof(data));
data.skip = "new.txt";
cl_assert_equal_i(0, git_tree_walk(
tree, GIT_TREEWALK_PRE, treewalk_skip_de_cb, &data));
cl_assert_equal_i(7, data.files);
cl_assert_equal_i(4, data.dirs);
memset(&data, 0, sizeof(data));
data.stop = "new.txt";
cl_assert_equal_i(-1, git_tree_walk(
tree, GIT_TREEWALK_PRE, treewalk_skip_de_cb, &data));
cl_assert_equal_i(7, data.files);
cl_assert_equal_i(4, data.dirs);
git_tree_free(tree);
}
+525
View File
@@ -0,0 +1,525 @@
#include "clar_libgit2.h"
#include "tree.h"
static const char *blob_oid = "fa49b077972391ad58037050f2a75f74e3671e92";
static const char *first_tree = "181037049a54a1eb5fab404658a3a250b44335d7";
static const char *second_tree = "f60079018b664e4e79329a7ef9559c8d9e0378d1";
static const char *third_tree = "eb86d8b81d6adbd5290a935d6c9976882de98488";
static git_repository *g_repo;
/* Fixture setup and teardown */
void test_object_tree_write__initialize(void)
{
g_repo = cl_git_sandbox_init("testrepo");
}
void test_object_tree_write__cleanup(void)
{
cl_git_sandbox_cleanup();
cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_STRICT_OBJECT_CREATION, 1));
}
void test_object_tree_write__from_memory(void)
{
/* write a tree from a memory */
git_treebuilder *builder;
git_tree *tree;
git_oid id, bid, rid, id2;
git_oid_fromstr(&id, first_tree);
git_oid_fromstr(&id2, second_tree);
git_oid_fromstr(&bid, blob_oid);
/* create a second tree from first tree using `git_treebuilder_insert`
* on REPOSITORY_FOLDER.
*/
cl_git_pass(git_tree_lookup(&tree, g_repo, &id));
cl_git_pass(git_treebuilder_new(&builder, g_repo, tree));
cl_git_fail(git_treebuilder_insert(NULL, builder, "",
&bid, GIT_FILEMODE_BLOB));
cl_git_fail(git_treebuilder_insert(NULL, builder, "/",
&bid, GIT_FILEMODE_BLOB));
cl_git_fail(git_treebuilder_insert(NULL, builder, ".git",
&bid, GIT_FILEMODE_BLOB));
cl_git_fail(git_treebuilder_insert(NULL, builder, "..",
&bid, GIT_FILEMODE_BLOB));
cl_git_fail(git_treebuilder_insert(NULL, builder, ".",
&bid, GIT_FILEMODE_BLOB));
cl_git_fail(git_treebuilder_insert(NULL, builder, "folder/new.txt",
&bid, GIT_FILEMODE_BLOB));
cl_git_pass(git_treebuilder_insert(
NULL, builder, "new.txt", &bid, GIT_FILEMODE_BLOB));
cl_git_pass(git_treebuilder_write(&rid, builder));
cl_assert(git_oid_cmp(&rid, &id2) == 0);
git_treebuilder_free(builder);
git_tree_free(tree);
}
void test_object_tree_write__subtree(void)
{
/* write a hierarchical tree from a memory */
git_treebuilder *builder;
git_tree *tree;
git_oid id, bid, subtree_id, id2, id3;
git_oid id_hiearar;
git_oid_fromstr(&id, first_tree);
git_oid_fromstr(&id2, second_tree);
git_oid_fromstr(&id3, third_tree);
git_oid_fromstr(&bid, blob_oid);
/* create subtree */
cl_git_pass(git_treebuilder_new(&builder, g_repo, NULL));
cl_git_pass(git_treebuilder_insert(
NULL, builder, "new.txt", &bid, GIT_FILEMODE_BLOB)); /* -V536 */
cl_git_pass(git_treebuilder_write(&subtree_id, builder));
git_treebuilder_free(builder);
/* create parent tree */
cl_git_pass(git_tree_lookup(&tree, g_repo, &id));
cl_git_pass(git_treebuilder_new(&builder, g_repo, tree));
cl_git_pass(git_treebuilder_insert(
NULL, builder, "new", &subtree_id, GIT_FILEMODE_TREE)); /* -V536 */
cl_git_pass(git_treebuilder_write(&id_hiearar, builder));
git_treebuilder_free(builder);
git_tree_free(tree);
cl_assert(git_oid_cmp(&id_hiearar, &id3) == 0);
/* check data is correct */
cl_git_pass(git_tree_lookup(&tree, g_repo, &id_hiearar));
cl_assert(2 == git_tree_entrycount(tree));
git_tree_free(tree);
}
/*
* And the Lord said: Is this tree properly sorted?
*/
void test_object_tree_write__sorted_subtrees(void)
{
git_treebuilder *builder;
git_tree *tree;
unsigned int i;
int position_c = -1, position_cake = -1, position_config = -1;
struct {
unsigned int attr;
const char *filename;
} entries[] = {
{ GIT_FILEMODE_BLOB, ".gitattributes" },
{ GIT_FILEMODE_BLOB, ".gitignore" },
{ GIT_FILEMODE_BLOB, ".htaccess" },
{ GIT_FILEMODE_BLOB, "Capfile" },
{ GIT_FILEMODE_BLOB, "Makefile"},
{ GIT_FILEMODE_BLOB, "README"},
{ GIT_FILEMODE_TREE, "app"},
{ GIT_FILEMODE_TREE, "cake"},
{ GIT_FILEMODE_TREE, "config"},
{ GIT_FILEMODE_BLOB, "c"},
{ GIT_FILEMODE_BLOB, "git_test.txt"},
{ GIT_FILEMODE_BLOB, "htaccess.htaccess"},
{ GIT_FILEMODE_BLOB, "index.php"},
{ GIT_FILEMODE_TREE, "plugins"},
{ GIT_FILEMODE_TREE, "schemas"},
{ GIT_FILEMODE_TREE, "ssl-certs"},
{ GIT_FILEMODE_TREE, "vendors"}
};
git_oid bid, tid, tree_oid;
cl_git_pass(git_oid_fromstr(&bid, blob_oid));
cl_git_pass(git_oid_fromstr(&tid, first_tree));
cl_git_pass(git_treebuilder_new(&builder, g_repo, NULL));
for (i = 0; i < ARRAY_SIZE(entries); ++i) {
git_oid *id = entries[i].attr == GIT_FILEMODE_TREE ? &tid : &bid;
cl_git_pass(git_treebuilder_insert(NULL,
builder, entries[i].filename, id, entries[i].attr));
}
cl_git_pass(git_treebuilder_write(&tree_oid, builder));
cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_oid));
for (i = 0; i < git_tree_entrycount(tree); i++) {
const git_tree_entry *entry = git_tree_entry_byindex(tree, i);
if (strcmp(entry->filename, "c") == 0)
position_c = i;
if (strcmp(entry->filename, "cake") == 0)
position_cake = i;
if (strcmp(entry->filename, "config") == 0)
position_config = i;
}
git_tree_free(tree);
cl_assert(position_c != -1);
cl_assert(position_cake != -1);
cl_assert(position_config != -1);
cl_assert(position_c < position_cake);
cl_assert(position_cake < position_config);
git_treebuilder_free(builder);
}
static struct {
unsigned int attr;
const char *filename;
} _entries[] = {
{ GIT_FILEMODE_BLOB, "aardvark" },
{ GIT_FILEMODE_BLOB, ".first" },
{ GIT_FILEMODE_BLOB, "apple" },
{ GIT_FILEMODE_BLOB, "last"},
{ GIT_FILEMODE_BLOB, "apple_after"},
{ GIT_FILEMODE_BLOB, "after_aardvark"},
{ 0, NULL },
};
void test_object_tree_write__removing_and_re_adding_in_treebuilder(void)
{
git_treebuilder *builder;
int i, aardvark_i, apple_i, apple_after_i, apple_extra_i, last_i;
git_oid entry_oid, tree_oid;
git_tree *tree;
cl_git_pass(git_oid_fromstr(&entry_oid, blob_oid));
cl_git_pass(git_treebuilder_new(&builder, g_repo, NULL));
cl_assert_equal_i(0, (int)git_treebuilder_entrycount(builder));
for (i = 0; _entries[i].filename; ++i)
cl_git_pass(git_treebuilder_insert(NULL,
builder, _entries[i].filename, &entry_oid, _entries[i].attr));
cl_assert_equal_i(6, (int)git_treebuilder_entrycount(builder));
cl_git_pass(git_treebuilder_remove(builder, "apple"));
cl_assert_equal_i(5, (int)git_treebuilder_entrycount(builder));
cl_git_pass(git_treebuilder_remove(builder, "apple_after"));
cl_assert_equal_i(4, (int)git_treebuilder_entrycount(builder));
cl_git_pass(git_treebuilder_insert(
NULL, builder, "before_last", &entry_oid, GIT_FILEMODE_BLOB));
cl_assert_equal_i(5, (int)git_treebuilder_entrycount(builder));
/* reinsert apple_after */
cl_git_pass(git_treebuilder_insert(
NULL, builder, "apple_after", &entry_oid, GIT_FILEMODE_BLOB));
cl_assert_equal_i(6, (int)git_treebuilder_entrycount(builder));
cl_git_pass(git_treebuilder_remove(builder, "last"));
cl_assert_equal_i(5, (int)git_treebuilder_entrycount(builder));
/* reinsert last */
cl_git_pass(git_treebuilder_insert(
NULL, builder, "last", &entry_oid, GIT_FILEMODE_BLOB));
cl_assert_equal_i(6, (int)git_treebuilder_entrycount(builder));
cl_git_pass(git_treebuilder_insert(
NULL, builder, "apple_extra", &entry_oid, GIT_FILEMODE_BLOB));
cl_assert_equal_i(7, (int)git_treebuilder_entrycount(builder));
cl_git_pass(git_treebuilder_write(&tree_oid, builder));
git_treebuilder_free(builder);
cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_oid));
cl_assert_equal_i(7, (int)git_tree_entrycount(tree));
cl_assert(git_tree_entry_byname(tree, ".first") != NULL);
cl_assert(git_tree_entry_byname(tree, "apple") == NULL);
cl_assert(git_tree_entry_byname(tree, "apple_after") != NULL);
cl_assert(git_tree_entry_byname(tree, "apple_extra") != NULL);
cl_assert(git_tree_entry_byname(tree, "last") != NULL);
aardvark_i = apple_i = apple_after_i = apple_extra_i = last_i = -1;
for (i = 0; i < 7; ++i) {
const git_tree_entry *entry = git_tree_entry_byindex(tree, i);
if (!strcmp(entry->filename, "aardvark"))
aardvark_i = i;
else if (!strcmp(entry->filename, "apple"))
apple_i = i;
else if (!strcmp(entry->filename, "apple_after"))
apple_after_i = i;
else if (!strcmp(entry->filename, "apple_extra"))
apple_extra_i = i;
else if (!strcmp(entry->filename, "last"))
last_i = i;
}
cl_assert_equal_i(-1, apple_i);
cl_assert_equal_i(6, last_i);
cl_assert(aardvark_i < apple_after_i);
cl_assert(apple_after_i < apple_extra_i);
git_tree_free(tree);
}
static int treebuilder_filter_prefixed(
const git_tree_entry *entry, void *payload)
{
return !git__prefixcmp(git_tree_entry_name(entry), payload);
}
void test_object_tree_write__filtering(void)
{
git_treebuilder *builder;
int i;
git_oid entry_oid, tree_oid;
git_tree *tree;
git_oid_fromstr(&entry_oid, blob_oid);
cl_git_pass(git_treebuilder_new(&builder, g_repo, NULL));
for (i = 0; _entries[i].filename; ++i)
cl_git_pass(git_treebuilder_insert(NULL,
builder, _entries[i].filename, &entry_oid, _entries[i].attr));
cl_assert_equal_i(6, (int)git_treebuilder_entrycount(builder));
cl_assert(git_treebuilder_get(builder, "apple") != NULL);
cl_assert(git_treebuilder_get(builder, "aardvark") != NULL);
cl_assert(git_treebuilder_get(builder, "last") != NULL);
git_treebuilder_filter(builder, treebuilder_filter_prefixed, "apple");
cl_assert_equal_i(4, (int)git_treebuilder_entrycount(builder));
cl_assert(git_treebuilder_get(builder, "apple") == NULL);
cl_assert(git_treebuilder_get(builder, "aardvark") != NULL);
cl_assert(git_treebuilder_get(builder, "last") != NULL);
git_treebuilder_filter(builder, treebuilder_filter_prefixed, "a");
cl_assert_equal_i(2, (int)git_treebuilder_entrycount(builder));
cl_assert(git_treebuilder_get(builder, "aardvark") == NULL);
cl_assert(git_treebuilder_get(builder, "last") != NULL);
cl_git_pass(git_treebuilder_write(&tree_oid, builder));
git_treebuilder_free(builder);
cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_oid));
cl_assert_equal_i(2, (int)git_tree_entrycount(tree));
git_tree_free(tree);
}
void test_object_tree_write__cruel_paths(void)
{
static const char *the_paths[] = {
"C:\\",
" : * ? \" \n < > |",
"a\\b",
"\\\\b\a",
":\\",
"COM1",
"foo.aux",
REP1024("1234"), /* 4096 char string */
REP1024("12345678"), /* 8192 char string */
"\xC5\xAA\x6E\xC4\xAD\x63\xC5\x8D\x64\x65\xCC\xBD", /* Ūnĭcōde̽ */
NULL
};
git_treebuilder *builder;
git_tree *tree;
git_oid id, bid, subid;
const char **scan;
int count = 0, i, j;
git_tree_entry *te;
git_oid_fromstr(&bid, blob_oid);
/* create tree */
cl_git_pass(git_treebuilder_new(&builder, g_repo, NULL));
for (scan = the_paths; *scan; ++scan) {
cl_git_pass(git_treebuilder_insert(
NULL, builder, *scan, &bid, GIT_FILEMODE_BLOB));
count++;
}
cl_git_pass(git_treebuilder_write(&id, builder));
git_treebuilder_free(builder);
/* check data is correct */
cl_git_pass(git_tree_lookup(&tree, g_repo, &id));
cl_assert_equal_i(count, git_tree_entrycount(tree));
for (scan = the_paths; *scan; ++scan) {
const git_tree_entry *cte = git_tree_entry_byname(tree, *scan);
cl_assert(cte != NULL);
cl_assert_equal_s(*scan, git_tree_entry_name(cte));
}
for (scan = the_paths; *scan; ++scan) {
cl_git_pass(git_tree_entry_bypath(&te, tree, *scan));
cl_assert_equal_s(*scan, git_tree_entry_name(te));
git_tree_entry_free(te);
}
git_tree_free(tree);
/* let's try longer paths */
cl_git_pass(git_treebuilder_new(&builder, g_repo, NULL));
for (scan = the_paths; *scan; ++scan) {
cl_git_pass(git_treebuilder_insert(
NULL, builder, *scan, &id, GIT_FILEMODE_TREE));
}
cl_git_pass(git_treebuilder_write(&subid, builder));
git_treebuilder_free(builder);
/* check data is correct */
cl_git_pass(git_tree_lookup(&tree, g_repo, &subid));
cl_assert_equal_i(count, git_tree_entrycount(tree));
for (i = 0; i < count; ++i) {
for (j = 0; j < count; ++j) {
git_buf b = GIT_BUF_INIT;
cl_git_pass(git_buf_joinpath(&b, the_paths[i], the_paths[j]));
cl_git_pass(git_tree_entry_bypath(&te, tree, b.ptr));
cl_assert_equal_s(the_paths[j], git_tree_entry_name(te));
git_tree_entry_free(te);
git_buf_dispose(&b);
}
}
git_tree_free(tree);
}
void test_object_tree_write__protect_filesystems(void)
{
git_treebuilder *builder;
git_oid bid;
cl_git_pass(git_oid_fromstr(&bid, "fa49b077972391ad58037050f2a75f74e3671e92"));
/* Ensure that (by default) we can write objects with funny names on
* platforms that are not affected.
*/
cl_git_pass(git_treebuilder_new(&builder, g_repo, NULL));
cl_git_fail(git_treebuilder_insert(NULL, builder, ".git.", &bid, GIT_FILEMODE_BLOB));
cl_git_fail(git_treebuilder_insert(NULL, builder, "git~1", &bid, GIT_FILEMODE_BLOB));
#ifndef __APPLE__
cl_git_pass(git_treebuilder_insert(NULL, builder, ".git\xef\xbb\xbf", &bid, GIT_FILEMODE_BLOB));
cl_git_pass(git_treebuilder_insert(NULL, builder, ".git\xe2\x80\xad", &bid, GIT_FILEMODE_BLOB));
#endif
git_treebuilder_free(builder);
/* Now turn on core.protectHFS and core.protectNTFS and validate that these
* paths are rejected.
*/
cl_repo_set_bool(g_repo, "core.protectHFS", true);
cl_repo_set_bool(g_repo, "core.protectNTFS", true);
cl_git_pass(git_treebuilder_new(&builder, g_repo, NULL));
cl_git_fail(git_treebuilder_insert(NULL, builder, ".git.", &bid, GIT_FILEMODE_BLOB));
cl_git_fail(git_treebuilder_insert(NULL, builder, "git~1", &bid, GIT_FILEMODE_BLOB));
cl_git_fail(git_treebuilder_insert(NULL, builder, ".git\xef\xbb\xbf", &bid, GIT_FILEMODE_BLOB));
cl_git_fail(git_treebuilder_insert(NULL, builder, ".git\xe2\x80\xad", &bid, GIT_FILEMODE_BLOB));
cl_git_fail(git_treebuilder_insert(NULL, builder, ".git::$INDEX_ALLOCATION/dummy-file", &bid, GIT_FILEMODE_BLOB));
git_treebuilder_free(builder);
}
static void test_invalid_objects(bool should_allow_invalid)
{
git_treebuilder *builder;
git_oid valid_blob_id, invalid_blob_id, valid_tree_id, invalid_tree_id;
#define assert_allowed(expr) \
clar__assert(!(expr) == should_allow_invalid, __FILE__, __LINE__, \
(should_allow_invalid ? \
"Expected function call to succeed: " #expr : \
"Expected function call to fail: " #expr), \
NULL, 1)
cl_git_pass(git_oid_fromstr(&valid_blob_id, blob_oid));
cl_git_pass(git_oid_fromstr(&invalid_blob_id,
"1234567890123456789012345678901234567890"));
cl_git_pass(git_oid_fromstr(&valid_tree_id, first_tree));
cl_git_pass(git_oid_fromstr(&invalid_tree_id,
"0000000000111111111122222222223333333333"));
cl_git_pass(git_treebuilder_new(&builder, g_repo, NULL));
/* test valid blobs and trees (these should always pass) */
cl_git_pass(git_treebuilder_insert(NULL, builder, "file.txt", &valid_blob_id, GIT_FILEMODE_BLOB));
cl_git_pass(git_treebuilder_insert(NULL, builder, "folder", &valid_tree_id, GIT_FILEMODE_TREE));
/* replace valid files and folders with invalid ones */
assert_allowed(git_treebuilder_insert(NULL, builder, "file.txt", &invalid_blob_id, GIT_FILEMODE_BLOB));
assert_allowed(git_treebuilder_insert(NULL, builder, "folder", &invalid_blob_id, GIT_FILEMODE_BLOB));
/* insert new invalid files and folders */
assert_allowed(git_treebuilder_insert(NULL, builder, "invalid_file.txt", &invalid_blob_id, GIT_FILEMODE_BLOB));
assert_allowed(git_treebuilder_insert(NULL, builder, "invalid_folder", &invalid_blob_id, GIT_FILEMODE_BLOB));
/* insert valid blobs as trees and trees as blobs */
assert_allowed(git_treebuilder_insert(NULL, builder, "file_as_folder", &valid_blob_id, GIT_FILEMODE_TREE));
assert_allowed(git_treebuilder_insert(NULL, builder, "folder_as_file.txt", &valid_tree_id, GIT_FILEMODE_BLOB));
#undef assert_allowed
git_treebuilder_free(builder);
}
static void test_inserting_submodule(void)
{
git_treebuilder *bld;
git_oid sm_id;
cl_git_pass(git_oid_fromstr(&sm_id, "da39a3ee5e6b4b0d3255bfef95601890afd80709"));
cl_git_pass(git_treebuilder_new(&bld, g_repo, NULL));
cl_git_pass(git_treebuilder_insert(NULL, bld, "sm", &sm_id, GIT_FILEMODE_COMMIT));
git_treebuilder_free(bld);
}
void test_object_tree_write__object_validity(void)
{
/* Ensure that we cannot add invalid objects by default */
test_invalid_objects(false);
test_inserting_submodule();
/* Ensure that we can turn off validation */
cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_STRICT_OBJECT_CREATION, 0));
test_invalid_objects(true);
test_inserting_submodule();
}
void test_object_tree_write__invalid_null_oid(void)
{
git_treebuilder *bld;
git_oid null_oid = {{0}};
cl_git_pass(git_treebuilder_new(&bld, g_repo, NULL));
cl_git_fail(git_treebuilder_insert(NULL, bld, "null_oid_file", &null_oid, GIT_FILEMODE_BLOB));
cl_assert(git_error_last() && strstr(git_error_last()->message, "null OID") != NULL);
git_treebuilder_free(bld);
}