Exemple #1
0
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_create(&builder, NULL));
	cl_git_pass(git_treebuilder_insert(NULL,builder,"new.txt",&bid,0100644));
	cl_git_pass(git_treebuilder_write(&subtree_id, g_repo, builder));
	git_treebuilder_free(builder);

	// create parent tree
	cl_git_pass(git_tree_lookup(&tree, g_repo, &id));
	cl_git_pass(git_treebuilder_create(&builder, tree));
	cl_git_pass(git_treebuilder_insert(NULL,builder,"new",&subtree_id,040000));
	cl_git_pass(git_treebuilder_write(&id_hiearar, g_repo, 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);
}
void test_object_tree_attributes__normalize_attributes_when_creating_a_tree_from_an_existing_one(void)
{
	git_repository *repo;
	git_treebuilder *builder;
	git_oid tid, tid2;
	git_tree *tree;
	const git_tree_entry *entry;

	repo = cl_git_sandbox_init("deprecated-mode.git");

	cl_git_pass(git_oid_fromstr(&tid, tree_oid));
	cl_git_pass(git_tree_lookup(&tree, repo, &tid));

	cl_git_pass(git_treebuilder_create(&builder, tree));
	
	entry = git_treebuilder_get(builder, "old_mode.txt");
	cl_assert_equal_i(
		GIT_FILEMODE_BLOB,
		git_tree_entry_filemode(entry));

	cl_git_pass(git_treebuilder_write(&tid2, repo, 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_equal_i(
		GIT_FILEMODE_BLOB,
		git_tree_entry_filemode(entry));

	git_tree_free(tree);
	cl_git_sandbox_cleanup();
}
Exemple #3
0
static int tree_write(
	git_tree **out,
	git_repository *repo,
	git_tree *source_tree,
	const git_oid *object_oid,
	const char *treeentry_name,
	unsigned int attributes)
{
	int error;
	git_treebuilder *tb = NULL;
	const git_tree_entry *entry;
	git_oid tree_oid;

	if ((error = git_treebuilder_create(&tb, source_tree)) < 0)
		goto cleanup;

	if (object_oid) {
		if ((error = git_treebuilder_insert(
				&entry, tb, treeentry_name, object_oid, attributes)) < 0)
			goto cleanup;
	} else {
		if ((error = git_treebuilder_remove(tb, treeentry_name)) < 0)
			goto cleanup;
	}

	if ((error = git_treebuilder_write(&tree_oid, repo, tb)) < 0)
		goto cleanup;

	error = git_tree_lookup(out, repo, &tree_oid);

cleanup:
	git_treebuilder_free(tb);
	return error;
}
Exemple #4
0
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_create(&builder, tree));

	cl_git_fail(git_treebuilder_insert(NULL, builder, "", &bid, 0100644));
	cl_git_fail(git_treebuilder_insert(NULL, builder, "/", &bid, 0100644));
	cl_git_fail(git_treebuilder_insert(NULL, builder, "folder/new.txt", &bid, 0100644));

	cl_git_pass(git_treebuilder_insert(NULL,builder,"new.txt",&bid,0100644));
	cl_git_pass(git_treebuilder_write(&rid, g_repo, builder));

	cl_assert(git_oid_cmp(&rid, &id2) == 0);

	git_treebuilder_free(builder);
	git_tree_free(tree);
}
Exemple #5
0
PyObject *
Repository_TreeBuilder(Repository *self, PyObject *args)
{
    TreeBuilder *builder;
    git_treebuilder *bld;
    PyObject *py_src = NULL;
    git_oid oid;
    git_tree *tree = NULL;
    git_tree *must_free = NULL;
    int err;

    if (!PyArg_ParseTuple(args, "|O", &py_src))
        return NULL;

    if (py_src) {
        if (PyObject_TypeCheck(py_src, &TreeType)) {
            Tree *py_tree = (Tree *)py_src;
            if (py_tree->repo->repo != self->repo) {
                //return Error_set(GIT_EINVALIDARGS);
                return Error_set(GIT_ERROR);
            }
            tree = py_tree->tree;
        } else {
            err = py_str_to_git_oid_expand(self->repo, py_src, &oid);
            if (err < 0)
                return NULL;

            err = git_tree_lookup(&tree, self->repo, &oid);
            if (err < 0)
                return Error_set(err);
            must_free = tree;
        }
    }

    err = git_treebuilder_create(&bld, tree);
    if (must_free != NULL) {
        git_tree_free(must_free);
    }

    if (err < 0)
        return Error_set(err);

    builder = PyObject_New(TreeBuilder, &TreeBuilderType);
    if (builder) {
        builder->repo = self;
        builder->bld = bld;
        Py_INCREF(self);
    }

    return (PyObject*)builder;
}
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_create(&builder, 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);
}
Exemple #7
0
static VALUE
backend_write_tree(VALUE rb_obj, VALUE rb_hash)
{
  git_oid oid;
  int error;
  git_treebuilder *bld;

  git_treebuilder_create(&bld, NULL);
  rb_hash_foreach(rb_hash, backend_add_tree_entry, (VALUE)bld);

  error = git_treebuilder_odb_write(&oid, DATA_PTR(rb_obj), bld);
  git_treebuilder_free(bld);

  backend_exception_check(error);

  return backend_create_oid(&oid);
}
Exemple #8
0
void test_object_tree_write__filtering(void)
{
	git_treebuilder *builder;
	int i;
	git_oid blank_oid, tree_oid;
	git_tree *tree;

	memset(&blank_oid, 0x0, sizeof(blank_oid));

	cl_git_pass(git_treebuilder_create(&builder, NULL));

	for (i = 0; _entries[i].filename; ++i)
		cl_git_pass(git_treebuilder_insert(NULL,
			builder, _entries[i].filename, &blank_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, g_repo, 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_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_create(&builder, NULL));

	cl_git_fail(git_treebuilder_insert(
		&entry,
		builder,
		"normalized.txt",
		&bid,
		GIT_FILEMODE_BLOB_GROUP_WRITABLE));

	git_treebuilder_free(builder);
}
Exemple #10
0
static VALUE rb_git_treebuilder_init(int argc, VALUE *argv, VALUE self)
{
	git_treebuilder *builder;
	git_tree *tree = NULL;
	VALUE rb_object;
	int error;

	if (rb_scan_args(argc, argv, "01", &rb_object) == 1) {
		if (!rb_obj_is_kind_of(rb_object, rb_cRuggedTree))
			rb_raise(rb_eTypeError, "A Rugged::Tree instance is required");

		Data_Get_Struct(rb_object, git_tree, tree);
	}

	error = git_treebuilder_create(&builder, tree);
	rugged_exception_check(error);

	DATA_PTR(self) = builder;
	return Qnil;
}
Exemple #11
0
/*
 * This does *not* make sure the new subdirectory doesn't
 * alias some existing name. That is actually useful: you
 * can create multiple directories with the same name, and
 * set the "unique" flag, which will then append the SHA1
 * of the directory to the name when it is written.
 */
static struct dir *new_directory(struct dir *parent, struct membuffer *namebuf)
{
	struct dir *subdir;
	const char *name = mb_cstring(namebuf);
	int len = namebuf->len;

	subdir = malloc(sizeof(*subdir)+len);

	/*
	 * It starts out empty: no subdirectories of its own,
	 * and an empty treebuilder list of files.
	 */
	subdir->subdirs = NULL;
	git_treebuilder_create(&subdir->files, NULL);
	memcpy(subdir->name, name, len);
	subdir->unique = 0;
	subdir->name[len] = 0;

	/* Add it to the list of subdirs of the parent */
	subdir->sibling = parent->subdirs;
	parent->subdirs = subdir;

	return subdir;
}
Exemple #12
0
/*
 * 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 blank_oid, tree_oid;

	memset(&blank_oid, 0x0, sizeof(blank_oid));

	cl_git_pass(git_treebuilder_create(&builder, NULL));

	for (i = 0; i < ARRAY_SIZE(entries); ++i) {
		cl_git_pass(git_treebuilder_insert(NULL,
			builder, entries[i].filename, &blank_oid, entries[i].attr));
	}

	cl_git_pass(git_treebuilder_write(&tree_oid, g_repo, 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);
}
Exemple #13
0
int
edit_repo(const char *repo_name)
{
	int r;

	git_repository *repo;
	git_oid blob_id;
	git_oid oid;
	git_oid tree_id;
	git_signature *author;
	git_time_t time;
	git_config *config;
	git_index *index;
	git_tree *tree;
	git_treebuilder *tree_builder;
	git_treebuilder *empty_tree_builder;
	git_reference *head;
	git_commit *commit_parents[1];
	char global_config_path[GIT_PATH_MAX];
	char out[41];
	out[40] = '\0';
	
	// create the repository
	r = git_repository_open(&repo, repo_name);
	if (r)
		printf("error in opening repository\n");
	printf("Repo opened\n");
	
	// create a treebuilder
	r = git_treebuilder_create(&tree_builder, NULL);
	if (r)
		printf("error in creting treebuilder\n");
	printf("Tree builder created\n");

	// ADDING FIRST FILE
	// create a blob
	r = git_blob_create_fromdisk(&blob_id, repo, "test2");
	if (r)
		printf("error in creating blob from disk\n");
	printf("Blob created\n");

	// insert into tree
	r = git_treebuilder_insert(NULL, tree_builder, "test1", &blob_id, 0100644);
	if (r)
		printf("error in inserting into treebuilder\n");
	printf("Insert into treebuilder successful\n");
	
	// write the tree to the repo
	r = git_treebuilder_write(&oid, repo, tree_builder);
	if (r)
		printf("error in writing the tree to the repo\n");
	printf("Writing the tree to repo successful\n");

	// tree lookup
	r = git_tree_lookup(&tree, repo, &oid);
	if (r)
		printf("error in tree lookup\n");
	printf("Tree lookup done\n");
	
	// create a author
	time = get_time();
	r = git_signature_new(&author, "Varun Agrawal", "*****@*****.**", time, -300);
	if (r)
		printf("error in creating signature\n");
	printf("Author signature created\n");

	// obtaining the head
	r = git_repository_head(&head, repo);
	if (r)
		printf("error in obtaining the head\n");
	r = git_reference_name_to_oid(&oid, repo, git_reference_name(head));
	if (r)
		printf("error in obtaining the ref id of head\n");
	printf("Obtained the head id %s\n", git_oid_tostr(out, 41, &oid));
	git_commit_lookup(&commit_parents[0], repo, &oid);

	// create a commit
	r = git_commit_create(  &oid, // object id
				repo, // repository
				"HEAD", // update reference, this will update the HEAD to this commit
				author, // author
				author, // committer
				NULL, // message encoding, by default UTF-8 is used
				"second commit", // message for the commit
				tree, // the git_tree object which will be used as the tree for this commit. don't know if NULL is valid
				1, // number of parents. Don't know what value should be used here
				commit_parents); // array of pointers to the parents(git_commit *parents[])
	if (r)
		printf("error in creating a commit\n");
	printf("Commit created\n");
	
	git_repository_free(repo);
	return 0;
}
Exemple #14
0
int
create_repo(const char *repo_name)
{
	int r;

	git_repository *repo;
	git_oid blob_id;
	git_oid oid;
	git_oid tree_id;
	git_signature *author;
	git_time_t time;
	git_config *config;
	git_index *index;
	git_tree *tree;
	git_treebuilder *tree_builder;
	git_treebuilder *empty_tree_builder;
	char global_config_path[GIT_PATH_MAX];
	
	// create the repository
	r = git_repository_init(&repo, repo_name, 1);
	if (r)
		printf("error in creating repository\n");
	printf("Repo created\n");
	
	// set the repository config
	git_config_new(&config);
	git_config_find_global(global_config_path, GIT_PATH_MAX);
	git_config_add_file_ondisk(config, global_config_path, 1);
	//git_config_set_string(config, "name", "Varun Agrawal");
	//git_config_set_string(config, "email", "*****@*****.**");
	git_repository_set_config(repo, config);
	printf("Repo config set\n");

	// create a treebuilder
	r = git_treebuilder_create(&tree_builder, NULL);
	if (r)
		printf("error in creting treebuilder\n");
	printf("Tree builder created\n");

	// ADDING FIRST FILE
	// create a blob
	r = git_blob_create_fromdisk(&blob_id, repo, "test1");
	if (r)
		printf("error in creating blob from disk\n");
	printf("Blob created\n");

	// insert into tree
	r = git_treebuilder_insert(NULL, tree_builder, "test1", &blob_id, 0100644);
	if (r)
		printf("error in inserting into treebuilder\n");
	printf("Insert into treebuilder successful\n");

	// ADDING SECOND FILE
	// create a blob
	r = git_blob_create_fromdisk(&blob_id, repo, "test2");
	if (r)
		printf("error in creating blob from disk\n");
	printf("Blob created\n");

	// insert into tree
	r = git_treebuilder_insert(NULL, tree_builder, "test2", &blob_id, 0100644);
	if (r)
		printf("error in inserting into treebuilder\n");
	printf("Insert into treebuilder successful\n");

	// ADDING A EMPTY FOLDER
	// create a empty tree
	r = git_treebuilder_create(&empty_tree_builder, NULL);
	if (r)
		printf("error in creting empty treebuilder\n");
	printf("Empty Tree builder created\n");
	
	// write the empty tree to the repo
	r = git_treebuilder_write(&tree_id, repo, empty_tree_builder);
	if (r)
		printf("error in writing the empty tree to the repo\n");
	printf("Writing the empty tree to repo successful\n");


	// insert empty tree into the tree
	r = git_treebuilder_insert(NULL, tree_builder, "test_dir", &tree_id, 0040000);
	if (r)
		printf("error in inserting into treebuilder\n");
	printf("Insert into treebuilder successful\n");

	// write the tree to the repo
	r = git_treebuilder_write(&oid, repo, tree_builder);
	if (r)
		printf("error in writing the tree to the repo\n");
	printf("Writing the tree to repo successful\n");

	// tree lookup
	r = git_tree_lookup(&tree, repo, &oid);
	if (r)
		printf("error in tree lookup\n");
	printf("Tree lookup done\n");
	
	// create a author
	time = get_time();
	r = git_signature_new(&author, "Varun Agrawal", "*****@*****.**", time, -300);
	if (r)
		printf("error in creating signature\n");
	printf("Author signature created\n");

	// create a commit
	r = git_commit_create(  &oid, // object id
				repo, // repository
				"HEAD", // update reference, this will update the HEAD to this commit
				author, // author
				author, // committer
				NULL, // message encoding, by default UTF-8 is used
				"first commit", // message for the commit
				tree, // the git_tree object which will be used as the tree for this commit. don't know if NULL is valid
				0, // number of parents. Don't know what value should be used here
				NULL); // array of pointers to the parents(git_commit *parents[])
	if (r)
		printf("error in creating a commit\n");
	printf("Commit created\n");
	
	git_repository_free(repo);
	return 0;
}
Exemple #15
0
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_create(&builder, 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, g_repo, 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_create(&builder, 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, g_repo, 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_free(&b);
		}
	}

	git_tree_free(tree);
}
Exemple #16
0
#endif

BEGIN_TEST(write2, "write a tree from a memory")
	git_repository *repo;
	git_treebuilder *builder;
	git_tree *tree;
	git_oid id, bid, rid, id2;

	must_pass(open_temp_repo(&repo, REPOSITORY_FOLDER));
	git_oid_mkstr(&id, first_tree);
	git_oid_mkstr(&id2, second_tree);
	git_oid_mkstr(&bid, blob_oid);

	//create a second tree from first tree using `git_treebuilder_insert` on REPOSITORY_FOLDER.
	must_pass(git_tree_lookup(&tree, repo, &id));
	must_pass(git_treebuilder_create(&builder, tree));
	must_pass(git_treebuilder_insert(NULL,builder,"new.txt",&bid,0100644));
	must_pass(git_treebuilder_write(&rid,repo,builder));

	must_be_true(git_oid_cmp(&rid, &id2) == 0);

	git_treebuilder_free(builder);
	git_tree_close(tree);
	close_temp_repo(repo);
END_TEST

BEGIN_TEST(write3, "write a hierarchical tree from a memory")
	git_repository *repo;
	git_treebuilder *builder;
	git_tree *tree;
	git_oid id, bid, subtree_id, id2, id3;
Exemple #17
0
void test_core_merge__demo_create_merge_commit(void) {

	AGBError * error;
	agb_error_new(&error);


	// Here we're going to try to use the merge iterator to create a merge commit that contains the right information.
	// Note - this version does not recurse into directories. (subtrees)
	git_treebuilder * builder;
	git_treebuilder_create(&builder, base_tree);
	AGBMergeIterator * it = agb_merge__create_iterator(head_tree, branch_tree, base_tree, agb_merge_iterator_options_NONE);

	for( ; agb_merge_iterator_is_valid(it) ; agb_merge_iterator_next(it) ) {
        AGBMergeEntry * entry = agb_merge_entry_from_iterator(it);
		int hasLocalChanged = !agb_git_oid_equal( agb_merge_entry_id(entry,AGB_MERGE_BASE), agb_merge_entry_id(entry,AGB_MERGE_LOCAL) );
		int hasRemoteChanged = !agb_git_oid_equal( agb_merge_entry_id(entry,AGB_MERGE_BASE), agb_merge_entry_id(entry,AGB_MERGE_REMOTE) );
		printf("-- %s %d %d\n", agb_merge_entry_name(entry), hasLocalChanged, hasRemoteChanged);

		if( !hasLocalChanged && !hasRemoteChanged) {
			continue;
		}

		if( hasLocalChanged && !hasRemoteChanged) {
			//We want the head version.
			if(agb_merge_entry_id(entry,AGB_MERGE_LOCAL) == NULL) {
				//TODO: Check error message.
				printf("REMOVING %s from tree\n", agb_merge_entry_name(entry) );
				git_treebuilder_remove(builder, agb_merge_entry_name(entry) );
				continue;
			}

			//TODO: Check for error
			printf("ADDING OR UPDATING %s to tree\n", agb_merge_entry_name(entry) );
			int ok = git_treebuilder_insert(NULL, builder, agb_merge_entry_name(entry), agb_merge_entry_id(entry,AGB_MERGE_LOCAL), agb_merge_entry_filemode(entry,AGB_MERGE_LOCAL) );
            if(ok!=0) {
                printf("Error duting add/update of tree builder: %s\n", giterr_last()->message);
                abort();
            }
            continue;
		}

		if( !hasLocalChanged && hasRemoteChanged) {
			//We want the head version.
			if(agb_merge_entry_id(entry,AGB_MERGE_REMOTE) == NULL) {
				//TODO: Check error message.
				printf("REMOVING %s from tree\n", agb_merge_entry_name(entry) );
				git_treebuilder_remove(builder, agb_merge_entry_name(entry) );
				continue;
			}

			//TODO: Check for error
			printf("ADDING OR UPDATING %s to tree\n", agb_merge_entry_name(entry) );
			int ok = git_treebuilder_insert(NULL, builder, agb_merge_entry_name(entry), agb_merge_entry_id(entry,AGB_MERGE_REMOTE), agb_merge_entry_filemode(entry,AGB_MERGE_REMOTE) );
			if(ok!=0) {
                printf("Error duting add/update of tree builder: %s\n", giterr_last()->message);
                abort();
            }
            continue;
		}

			printf("CONFLICT %s in tree\n", agb_merge_entry_name(entry) );
		//TODO: CONFLICT - Handle it!

	}

	// Our tree builder should now be full...
	// Lets write it out to a tree
	//
	//TODO: Check for errors
	git_oid new_tree_oid = {};
	git_treebuilder_write(&new_tree_oid, repo, builder);

	char hexid[GIT_OID_HEXSZ+1];
	printf("Tree SHA is %s\n", git_oid_tostr(hexid,GIT_OID_HEXSZ+1, &new_tree_oid));

	git_tree * new_tree = NULL;
	git_tree_lookup(&new_tree, repo, &new_tree_oid);

	// Now we need to create the commit.
    const git_commit** parents = (const git_commit**)malloc(sizeof(git_commit*)*2);

	parents[0] = head_commit;
	parents[1] = branch_commit;


	git_signature * author_signature = NULL;

	// Time since epoch
	// TODO: Get these correctly -
	// Could use git_signature_now instead...
	{

		git_time_t author_time = time(NULL);
		int timezone_offset = 0;
		int ok;

		if((ok=git_signature_new(&author_signature,"Someone","*****@*****.**", author_time, timezone_offset))!=0) {
			agb__error_translate(error,"git_signature_new failed",ok);
			goto cleanup_error;
		}
	}



	git_oid commit_id;
	int ok = git_commit_create(
				&commit_id,
				repo,
				NULL,
				author_signature,
				author_signature,
				"UTF-8",
				"An exciting commit",
				new_tree,
			       	2, //Two parents
				parents
				);
	if(ok!=0) {
		agb__error_translate(error,"git_commit_create failed",ok);
		goto cleanup_error;
	}

	// Then update the refs.
	//TODO: Do we need to release this ref?
	git_reference * ref;
	ok = git_reference_create_matching(
			&ref,
			repo,
		   	"refs/heads/branch_c",
			&commit_id,
			1,
			NULL,
			author_signature,
			"merged by libagb");

	if(ok!=0) {
		agb__error_translate(error,"git_reference_create failed",ok);
		goto cleanup_error;
	}

	git_signature_free(author_signature);

	// Now check we got the expected files
	cl_assert_equal_c('A', test_core_merge__compare_with_parents_merge_base("branch_c", "created_in_a.txt"));
	cl_assert_equal_c('A', test_core_merge__compare_with_parents_merge_base("branch_c", "created_in_b.txt"));

	return;

cleanup_error:

	printf("ERROR: %s\n",error->message);

	if(author_signature) {
		git_signature_free(author_signature);
	}
	cl_fail(error->message);


}
Exemple #18
0
static int write_tree(git_oid *oid, git_index *index, const char *dirname, unsigned int start)
{
	git_treebuilder *bld = NULL;
	unsigned int i, entries = git_index_entrycount(index);
	int error;
	size_t dirname_len = strlen(dirname);
	const git_tree_cache *cache;

	cache = git_tree_cache_get(index->tree, dirname);
	if (cache != NULL && cache->entries >= 0){
		git_oid_cpy(oid, &cache->oid);
		return find_next_dir(dirname, index, start);
	}

	error = git_treebuilder_create(&bld, NULL);
	if (bld == NULL) {
		return GIT_ENOMEM;
	}

	/*
	 * This loop is unfortunate, but necessary. The index doesn't have
	 * any directores, so we need to handle that manually, and we
	 * need to keep track of the current position.
	 */
	for (i = start; i < entries; ++i) {
		git_index_entry *entry = git_index_get(index, i);
		char *filename, *next_slash;

	/*
	 * If we've left our (sub)tree, exit the loop and return. The
	 * first check is an early out (and security for the
	 * third). The second check is a simple prefix comparison. The
	 * third check catches situations where there is a directory
	 * win32/sys and a file win32mmap.c. Without it, the following
	 * code believes there is a file win32/mmap.c
	 */
		if (strlen(entry->path) < dirname_len ||
		    memcmp(entry->path, dirname, dirname_len) ||
		    (dirname_len > 0 && entry->path[dirname_len] != '/')) {
			break;
		}

		filename = entry->path + dirname_len;
		if (*filename == '/')
			filename++;
		next_slash = strchr(filename, '/');
		if (next_slash) {
			git_oid sub_oid;
			int written;
			char *subdir, *last_comp;

			subdir = git__strndup(entry->path, next_slash - entry->path);
			if (subdir == NULL) {
				error = GIT_ENOMEM;
				goto cleanup;
			}

			/* Write out the subtree */
			written = write_tree(&sub_oid, index, subdir, i);
			if (written < 0) {
				error = git__rethrow(written, "Failed to write subtree %s", subdir);
			} else {
				i = written - 1; /* -1 because of the loop increment */
			}

			/*
			 * We need to figure out what we want toinsert
			 * into this tree. If we're traversing
			 * deps/zlib/, then we only want to write
			 * 'zlib' into the tree.
			 */
			last_comp = strrchr(subdir, '/');
			if (last_comp) {
				last_comp++; /* Get rid of the '/' */
			} else {
				last_comp = subdir;
			}
			error = append_entry(bld, last_comp, &sub_oid, S_IFDIR);
			free(subdir);
			if (error < GIT_SUCCESS) {
				error = git__rethrow(error, "Failed to insert dir");
				goto cleanup;
			}
		} else {
			error = append_entry(bld, filename, &entry->oid, entry->mode);
			if (error < GIT_SUCCESS) {
				error = git__rethrow(error, "Failed to insert file");
			}
		}
	}

	error = git_treebuilder_write(oid, index->repository, bld);
	if (error < GIT_SUCCESS)
		error = git__rethrow(error, "Failed to write tree to db");

 cleanup:
	git_treebuilder_free(bld);

	if (error < GIT_SUCCESS)
		return error;
	else
		return i;
}
Exemple #19
0
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 blank_oid, tree_oid;
	git_tree *tree;

	memset(&blank_oid, 0x0, sizeof(blank_oid));

	cl_git_pass(git_treebuilder_create(&builder, 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, &blank_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", &blank_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", &blank_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", &blank_oid, GIT_FILEMODE_BLOB));
	cl_assert_equal_i(6, (int)git_treebuilder_entrycount(builder));

	cl_git_pass(git_treebuilder_insert(
		NULL, builder, "apple_extra", &blank_oid, GIT_FILEMODE_BLOB));
	cl_assert_equal_i(7, (int)git_treebuilder_entrycount(builder));

	cl_git_pass(git_treebuilder_write(&tree_oid, g_repo, 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);
}