Esempio n. 1
0
File: path.c Progetto: Arhzi/libgit2
int git_path_dirload(
	git_vector *contents,
	const char *path,
	size_t prefix_len,
	uint32_t flags)
{
	git_path_diriter iter = GIT_PATH_DIRITER_INIT;
	const char *name;
	size_t name_len;
	char *dup;
	int error;

	assert(contents && path);

	if ((error = git_path_diriter_init(&iter, path, flags)) < 0)
		return error;

	while ((error = git_path_diriter_next(&iter)) == 0) {
		if ((error = git_path_diriter_fullpath(&name, &name_len, &iter)) < 0)
			break;

		assert(name_len > prefix_len);

		dup = git__strndup(name + prefix_len, name_len - prefix_len);
		GITERR_CHECK_ALLOC(dup);

		if ((error = git_vector_insert(contents, dup)) < 0)
			break;
	}

	if (error == GIT_ITEROVER)
		error = 0;

	git_path_diriter_free(&iter);
	return error;
}
Esempio n. 2
0
void test_repo_iterator__indexfilelist_2(void)
{
	git_iterator *i;
	git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT;
	git_index *index;
	git_vector filelist = GIT_VECTOR_INIT;
	int default_icase, expect;

	g_repo = cl_git_sandbox_init("icase");

	cl_git_pass(git_repository_index(&index, g_repo));

	cl_git_pass(git_vector_init(&filelist, 100, &git__strcmp_cb));
	cl_git_pass(git_vector_insert(&filelist, "0"));
	cl_git_pass(git_vector_insert(&filelist, "c"));
	cl_git_pass(git_vector_insert(&filelist, "D"));
	cl_git_pass(git_vector_insert(&filelist, "e"));
	cl_git_pass(git_vector_insert(&filelist, "k/1"));
	cl_git_pass(git_vector_insert(&filelist, "k/a"));

	/* In this test we DO NOT force a case setting on the index. */
	default_icase = ((git_index_caps(index) & GIT_INDEXCAP_IGNORE_CASE) != 0);

	i_opts.pathlist.strings = (char **)filelist.contents;
	i_opts.pathlist.count = filelist.length;

	i_opts.start = "b";
	i_opts.end = "k/D";

	/* (c D e k/1 k/a ==> 5) vs (c e k/1 ==> 3) */
	expect = default_icase ? 5 : 3;

	cl_git_pass(git_iterator_for_index(&i, index, &i_opts));
	expect_iterator_items(i, expect, NULL, expect, NULL);
	git_iterator_free(i);

	git_index_free(index);
	git_vector_free(&filelist);
}
Esempio n. 3
0
static int cb__reflist_add(const char *ref, void *data)
{
	return git_vector_insert((git_vector *)data, git__strdup(ref));
}
Esempio n. 4
0
void test_repo_iterator__indexfilelist_icase(void)
{
	git_iterator *i;
	git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT;
	git_index *index;
	int caps;
	git_vector filelist;

	cl_git_pass(git_vector_init(&filelist, 100, &git__strcmp_cb));
	cl_git_pass(git_vector_insert(&filelist, "a"));
	cl_git_pass(git_vector_insert(&filelist, "B"));
	cl_git_pass(git_vector_insert(&filelist, "c"));
	cl_git_pass(git_vector_insert(&filelist, "D"));
	cl_git_pass(git_vector_insert(&filelist, "e"));
	cl_git_pass(git_vector_insert(&filelist, "k/1"));
	cl_git_pass(git_vector_insert(&filelist, "k/a"));
	cl_git_pass(git_vector_insert(&filelist, "L/1"));

	g_repo = cl_git_sandbox_init("icase");

	cl_git_pass(git_repository_index(&index, g_repo));
	caps = git_index_caps(index);

	/* force case sensitivity */
	cl_git_pass(git_index_set_caps(index, caps & ~GIT_INDEXCAP_IGNORE_CASE));

	/* All indexfilelist iterator tests are "autoexpand with no tree entries" */

	i_opts.pathlist.strings = (char **)filelist.contents;
	i_opts.pathlist.count = filelist.length;

	i_opts.start = "c";
	i_opts.end = "k/D";
	cl_git_pass(git_iterator_for_index(&i, index, &i_opts));
	expect_iterator_items(i, 3, NULL, 3, NULL);
	git_iterator_free(i);

	i_opts.start = "k";
	i_opts.end = "k/Z";
	cl_git_pass(git_iterator_for_index(&i, index, &i_opts));
	expect_iterator_items(i, 1, NULL, 1, NULL);
	git_iterator_free(i);

	/* force case insensitivity */
	cl_git_pass(git_index_set_caps(index, caps | GIT_INDEXCAP_IGNORE_CASE));

	i_opts.start = "c";
	i_opts.end = "k/D";
	cl_git_pass(git_iterator_for_index(&i, index, &i_opts));
	expect_iterator_items(i, 5, NULL, 5, NULL);
	git_iterator_free(i);

	i_opts.start = "k";
	i_opts.end = "k/Z";
	cl_git_pass(git_iterator_for_index(&i, index, &i_opts));
	expect_iterator_items(i, 2, NULL, 2, NULL);
	git_iterator_free(i);

	cl_git_pass(git_index_set_caps(index, caps));
	git_index_free(index);
	git_vector_free(&filelist);
}
Esempio n. 5
0
int git_refspec__dwim_one(git_vector *out, git_refspec *spec, git_vector *refs)
{
	git_buf buf = GIT_BUF_INIT;
	size_t j, pos;
	git_remote_head key;

	const char* formatters[] = {
		GIT_REFS_DIR "%s",
		GIT_REFS_TAGS_DIR "%s",
		GIT_REFS_HEADS_DIR "%s",
		NULL
	};

	git_refspec *cur = git__calloc(1, sizeof(git_refspec));
	GITERR_CHECK_ALLOC(cur);

	cur->force = spec->force;
	cur->push = spec->push;
	cur->pattern = spec->pattern;
	cur->matching = spec->matching;
	cur->string = git__strdup(spec->string);

	/* shorthand on the lhs */
	if (git__prefixcmp(spec->src, GIT_REFS_DIR)) {
		for (j = 0; formatters[j]; j++) {
			git_buf_clear(&buf);
			if (git_buf_printf(&buf, formatters[j], spec->src) < 0)
				return -1;

			key.name = (char *) git_buf_cstr(&buf);
			if (!git_vector_search(&pos, refs, &key)) {
				/* we found something to match the shorthand, set src to that */
				cur->src = git_buf_detach(&buf);
			}
		}
	}

	/* No shorthands found, copy over the name */
	if (cur->src == NULL && spec->src != NULL) {
		cur->src = git__strdup(spec->src);
		GITERR_CHECK_ALLOC(cur->src);
	}

	if (spec->dst && git__prefixcmp(spec->dst, GIT_REFS_DIR)) {
		/* if it starts with "remotes" then we just prepend "refs/" */
		if (!git__prefixcmp(spec->dst, "remotes/")) {
			git_buf_puts(&buf, GIT_REFS_DIR);
		} else {
			git_buf_puts(&buf, GIT_REFS_HEADS_DIR);
		}

		if (git_buf_puts(&buf, spec->dst) < 0)
			return -1;

		cur->dst = git_buf_detach(&buf);
	}

	git_buf_free(&buf);

	if (cur->dst == NULL && spec->dst != NULL) {
		cur->dst = git__strdup(spec->dst);
		GITERR_CHECK_ALLOC(cur->dst);
	}

	return git_vector_insert(out, cur);
}
Esempio n. 6
0
int git_commit_add_parent(git_commit *commit, git_commit *new_parent)
{
	CHECK_FULL_PARSE();
	commit->object.modified = 1;
	return git_vector_insert(&commit->parents, new_parent);
}
Esempio n. 7
0
static int checkout_action_wd_only(
    checkout_data *data,
    git_iterator *workdir,
    const git_index_entry *wd,
    git_vector *pathspec)
{
    bool remove = false;
    git_checkout_notify_t notify = GIT_CHECKOUT_NOTIFY_NONE;

    if (!git_pathspec_match_path(
                pathspec, wd->path,
                (data->strategy & GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH) != 0,
                git_iterator_ignore_case(workdir), NULL))
        return 0;

    /* check if item is tracked in the index but not in the checkout diff */
    if (data->index != NULL) {
        if (wd->mode != GIT_FILEMODE_TREE) {
            int error;

            if ((error = git_index_find(NULL, data->index, wd->path)) == 0) {
                notify = GIT_CHECKOUT_NOTIFY_DIRTY;
                remove = ((data->strategy & GIT_CHECKOUT_FORCE) != 0);
            } else if (error != GIT_ENOTFOUND)
                return error;
        } else {
            /* for tree entries, we have to see if there are any index
             * entries that are contained inside that tree
             */
            size_t pos = git_index__prefix_position(data->index, wd->path);
            const git_index_entry *e = git_index_get_byindex(data->index, pos);

            if (e != NULL && data->diff->pfxcomp(e->path, wd->path) == 0) {
                notify = GIT_CHECKOUT_NOTIFY_DIRTY;
                remove = ((data->strategy & GIT_CHECKOUT_FORCE) != 0);
            }
        }
    }

    if (notify != GIT_CHECKOUT_NOTIFY_NONE)
        /* found in index */;
    else if (git_iterator_current_is_ignored(workdir)) {
        notify = GIT_CHECKOUT_NOTIFY_IGNORED;
        remove = ((data->strategy & GIT_CHECKOUT_REMOVE_IGNORED) != 0);
    }
    else {
        notify = GIT_CHECKOUT_NOTIFY_UNTRACKED;
        remove = ((data->strategy & GIT_CHECKOUT_REMOVE_UNTRACKED) != 0);
    }

    if (checkout_notify(data, notify, NULL, wd))
        return GIT_EUSER;

    if (remove) {
        char *path = git_pool_strdup(&data->pool, wd->path);
        GITERR_CHECK_ALLOC(path);

        if (git_vector_insert(&data->removes, path) < 0)
            return -1;
    }

    return 0;
}
Esempio n. 8
0
int git_path_dirload(
	const char *path,
	size_t prefix_len,
	size_t alloc_extra,
	git_vector *contents)
{
	int error, need_slash;
	DIR *dir;
	struct dirent *de, *de_buf;
	size_t path_len;

	assert(path != NULL && contents != NULL);
	path_len = strlen(path);
	assert(path_len > 0 && path_len >= prefix_len);

	if ((dir = opendir(path)) == NULL) {
		giterr_set(GITERR_OS, "Failed to open directory '%s'", path);
		return -1;
	}

#ifdef __sun
	de_buf = git__malloc(sizeof(struct dirent) + FILENAME_MAX + 1);
#else
	de_buf = git__malloc(sizeof(struct dirent));
#endif

	path += prefix_len;
	path_len -= prefix_len;
	need_slash = (path_len > 0 && path[path_len-1] != '/') ? 1 : 0;

	while ((error = p_readdir_r(dir, de_buf, &de)) == 0 && de != NULL) {
		char *entry_path;
		size_t entry_len;

		if (is_dot_or_dotdot(de->d_name))
			continue;

		entry_len = strlen(de->d_name);

		entry_path = git__malloc(
			path_len + need_slash + entry_len + 1 + alloc_extra);
		GITERR_CHECK_ALLOC(entry_path);

		if (path_len)
			memcpy(entry_path, path, path_len);
		if (need_slash)
			entry_path[path_len] = '/';
		memcpy(&entry_path[path_len + need_slash], de->d_name, entry_len);
		entry_path[path_len + need_slash + entry_len] = '\0';

		if (git_vector_insert(contents, entry_path) < 0) {
			closedir(dir);
			git__free(de_buf);
			return -1;
		}
	}

	closedir(dir);
	git__free(de_buf);

	if (error != 0)
		giterr_set(GITERR_OS, "Failed to process directory entry in '%s'", path);

	return error;
}
Esempio n. 9
0
void test_iterator_workdir__pathlist_with_dirs(void)
{
	git_iterator *i;
	git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT;
	git_vector filelist;

	cl_git_pass(git_vector_init(&filelist, 5, NULL));

	g_repo = cl_git_sandbox_init("icase");

	/* Test that a prefix `k` matches folders, even without trailing slash */
	{
		const char *expected[] = { "k/1", "k/B", "k/D", "k/a", "k/c" };
		size_t expected_len = 5;

		git_vector_clear(&filelist);
		cl_git_pass(git_vector_insert(&filelist, "k"));

		i_opts.pathlist.strings = (char **)filelist.contents;
		i_opts.pathlist.count = filelist.length;
		i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;

		cl_git_pass(git_iterator_for_workdir(&i, g_repo, NULL, NULL, &i_opts));
		expect_iterator_items(i, expected_len, expected, expected_len, expected);
		git_iterator_free(i);
	}

	/* Test that a `k/` matches a folder */
	{
		const char *expected[] = { "k/1", "k/B", "k/D", "k/a", "k/c" };
		size_t expected_len = 5;

		git_vector_clear(&filelist);
		cl_git_pass(git_vector_insert(&filelist, "k/"));

		i_opts.pathlist.strings = (char **)filelist.contents;
		i_opts.pathlist.count = filelist.length;
		i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;

		cl_git_pass(git_iterator_for_workdir(&i, g_repo, NULL, NULL, &i_opts));
		expect_iterator_items(i, expected_len, expected, expected_len, expected);
		git_iterator_free(i);
	}

	/* When the iterator is case sensitive, ensure we can't lookup the
	 * directory with the wrong case.
	 */
	{
		git_vector_clear(&filelist);
		cl_git_pass(git_vector_insert(&filelist, "K/"));

		i_opts.pathlist.strings = (char **)filelist.contents;
		i_opts.pathlist.count = filelist.length;
		i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;

		cl_git_pass(git_iterator_for_workdir(&i, g_repo, NULL, NULL, &i_opts));
		cl_git_fail_with(GIT_ITEROVER, git_iterator_advance(NULL, i));
		git_iterator_free(i);
	}

	/* Test that case insensitive matching works. */
	{
		const char *expected[] = { "k/1", "k/a", "k/B", "k/c", "k/D" };
		size_t expected_len = 5;

		git_vector_clear(&filelist);
		cl_git_pass(git_vector_insert(&filelist, "K/"));

		i_opts.pathlist.strings = (char **)filelist.contents;
		i_opts.pathlist.count = filelist.length;
		i_opts.flags = GIT_ITERATOR_IGNORE_CASE;

		cl_git_pass(git_iterator_for_workdir(&i, g_repo, NULL, NULL, &i_opts));
		expect_iterator_items(i, expected_len, expected, expected_len, expected);
		git_iterator_free(i);
	}

	/* Test that case insensitive matching works without trailing slash. */
	{
		const char *expected[] = { "k/1", "k/a", "k/B", "k/c", "k/D" };
		size_t expected_len = 5;

		git_vector_clear(&filelist);
		cl_git_pass(git_vector_insert(&filelist, "K"));

		i_opts.pathlist.strings = (char **)filelist.contents;
		i_opts.pathlist.count = filelist.length;
		i_opts.flags = GIT_ITERATOR_IGNORE_CASE;

		cl_git_pass(git_iterator_for_workdir(&i, g_repo, NULL, NULL, &i_opts));
		expect_iterator_items(i, expected_len, expected, expected_len, expected);
		git_iterator_free(i);
	}

	git_vector_free(&filelist);
}
Esempio n. 10
0
void test_iterator_workdir__pathlist(void)
{
	git_iterator *i;
	git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT;
	git_vector filelist;

	cl_git_pass(git_vector_init(&filelist, 100, NULL));
	cl_git_pass(git_vector_insert(&filelist, "a"));
	cl_git_pass(git_vector_insert(&filelist, "B"));
	cl_git_pass(git_vector_insert(&filelist, "c"));
	cl_git_pass(git_vector_insert(&filelist, "D"));
	cl_git_pass(git_vector_insert(&filelist, "e"));
	cl_git_pass(git_vector_insert(&filelist, "k.a"));
	cl_git_pass(git_vector_insert(&filelist, "k.b"));
	cl_git_pass(git_vector_insert(&filelist, "k/1"));
	cl_git_pass(git_vector_insert(&filelist, "k/a"));
	cl_git_pass(git_vector_insert(&filelist, "kZZZZZZZ"));
	cl_git_pass(git_vector_insert(&filelist, "L/1"));

	g_repo = cl_git_sandbox_init("icase");

	/* Test iterators without returning tree entries (but autoexpanding.) */

	i_opts.pathlist.strings = (char **)filelist.contents;
	i_opts.pathlist.count = filelist.length;

	/* Case sensitive */
	{
		const char *expected[] = {
			"B", "D", "L/1", "a", "c", "e", "k/1", "k/a" };
		size_t expected_len = 8;

		i_opts.start = NULL;
		i_opts.end = NULL;
		i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;

		cl_git_pass(git_iterator_for_workdir(&i, g_repo, NULL, NULL, &i_opts));
		expect_iterator_items(i, expected_len, expected, expected_len, expected);
		git_iterator_free(i);
	}

	/* Case INsensitive */
	{
		const char *expected[] = {
			"a", "B", "c", "D", "e", "k/1", "k/a", "L/1" };
		size_t expected_len = 8;

		i_opts.start = NULL;
		i_opts.end = NULL;
		i_opts.flags = GIT_ITERATOR_IGNORE_CASE;

		cl_git_pass(git_iterator_for_workdir(&i, g_repo, NULL, NULL, &i_opts));
		expect_iterator_items(i, expected_len, expected, expected_len, expected);
		git_iterator_free(i);
	}

	/* Set a start, but no end.  Case sensitive. */
	{
		const char *expected[] = { "c", "e", "k/1", "k/a" };
		size_t expected_len = 4;

		i_opts.start = "c";
		i_opts.end = NULL;
		i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;

		cl_git_pass(git_iterator_for_workdir(&i, g_repo, NULL, NULL, &i_opts));
		expect_iterator_items(i, expected_len, expected, expected_len, expected);
		git_iterator_free(i);
	}

	/* Set a start, but no end.  Case INsensitive. */
	{
		const char *expected[] = { "c", "D", "e", "k/1", "k/a", "L/1" };
		size_t expected_len = 6;

		i_opts.start = "c";
		i_opts.end = NULL;
		i_opts.flags = GIT_ITERATOR_IGNORE_CASE;

		cl_git_pass(git_iterator_for_workdir(&i, g_repo, NULL, NULL, &i_opts));
		expect_iterator_items(i, expected_len, expected, expected_len, expected);
		git_iterator_free(i);
	}

	/* Set no start, but an end.  Case sensitive. */
	{
		const char *expected[] = { "B", "D", "L/1", "a", "c", "e" };
		size_t expected_len = 6;

		i_opts.start = NULL;
		i_opts.end = "e";
		i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;

		cl_git_pass(git_iterator_for_workdir(&i, g_repo, NULL, NULL, &i_opts));
		expect_iterator_items(i, expected_len, expected, expected_len, expected);
		git_iterator_free(i);
	}

	/* Set no start, but an end.  Case INsensitive. */
	{
		const char *expected[] = { "a", "B", "c", "D", "e" };
		size_t expected_len = 5;

		i_opts.start = NULL;
		i_opts.end = "e";
		i_opts.flags = GIT_ITERATOR_IGNORE_CASE;

		cl_git_pass(git_iterator_for_workdir(&i, g_repo, NULL, NULL, &i_opts));
		expect_iterator_items(i, expected_len, expected, expected_len, expected);
		git_iterator_free(i);
	}

	/* Start and an end, case sensitive */
	{
		const char *expected[] = { "c", "e", "k/1" };
		size_t expected_len = 3;

		i_opts.start = "c";
		i_opts.end = "k/D";
		i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;

		cl_git_pass(git_iterator_for_workdir(&i, g_repo, NULL, NULL, &i_opts));
		expect_iterator_items(i, expected_len, expected, expected_len, expected);
		git_iterator_free(i);
	}

	/* Start and an end, case sensitive */
	{
		const char *expected[] = { "k/1" };
		size_t expected_len = 1;

		i_opts.start = "k";
		i_opts.end = "k/D";
		i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;

		cl_git_pass(git_iterator_for_workdir(&i, g_repo, NULL, NULL, &i_opts));
		expect_iterator_items(i, expected_len, expected, expected_len, expected);
		git_iterator_free(i);
	}

	/* Start and an end, case INsensitive */
	{
		const char *expected[] = { "c", "D", "e", "k/1", "k/a" };
		size_t expected_len = 5;

		i_opts.start = "c";
		i_opts.end = "k/D";
		i_opts.flags = GIT_ITERATOR_IGNORE_CASE;

		cl_git_pass(git_iterator_for_workdir(&i, g_repo, NULL, NULL, &i_opts));
		expect_iterator_items(i, expected_len, expected, expected_len, expected);
		git_iterator_free(i);
	}

	/* Start and an end, case INsensitive */
	{
		const char *expected[] = { "k/1", "k/a" };
		size_t expected_len = 2;

		i_opts.start = "k";
		i_opts.end = "k/D";
		i_opts.flags = GIT_ITERATOR_IGNORE_CASE;

		cl_git_pass(git_iterator_for_workdir(&i, g_repo, NULL, NULL, &i_opts));
		expect_iterator_items(i, expected_len, expected, expected_len, expected);
		git_iterator_free(i);
	}

	git_vector_free(&filelist);
}
Esempio n. 11
0
void test_iterator_workdir__bounded_submodules(void)
{
	git_iterator *i;
	git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT;
	git_vector filelist;
	git_index *index;
	git_tree *head;

	cl_git_pass(git_vector_init(&filelist, 5, NULL));

	g_repo = setup_fixture_submod2();
	cl_git_pass(git_repository_index(&index, g_repo));
	cl_git_pass(git_repository_head_tree(&head, g_repo));

	/* Test that a submodule matches */
	{
		const char *expected[] = { "sm_changed_head" };
		size_t expected_len = 1;

		git_vector_clear(&filelist);
		cl_git_pass(git_vector_insert(&filelist, "sm_changed_head"));

		i_opts.pathlist.strings = (char **)filelist.contents;
		i_opts.pathlist.count = filelist.length;
		i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;

		cl_git_pass(git_iterator_for_workdir(&i, g_repo, index, head, &i_opts));
		expect_iterator_items(i, expected_len, expected, expected_len, expected);
		git_iterator_free(i);
	}

	/* Test that a submodule still matches when suffixed with a '/' */
	{
		const char *expected[] = { "sm_changed_head" };
		size_t expected_len = 1;

		git_vector_clear(&filelist);
		cl_git_pass(git_vector_insert(&filelist, "sm_changed_head/"));

		i_opts.pathlist.strings = (char **)filelist.contents;
		i_opts.pathlist.count = filelist.length;
		i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;

		cl_git_pass(git_iterator_for_workdir(&i, g_repo, index, head, &i_opts));
		expect_iterator_items(i, expected_len, expected, expected_len, expected);
		git_iterator_free(i);
	}

	/* Test that start/end work with a submodule */
	{
		const char *expected[] = { "sm_changed_head", "sm_changed_index" };
		size_t expected_len = 2;

		i_opts.start = "sm_changed_head";
		i_opts.end = "sm_changed_index";
		i_opts.pathlist.strings = NULL;
		i_opts.pathlist.count = 0;
		i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;

		cl_git_pass(git_iterator_for_workdir(&i, g_repo, index, head, &i_opts));
		expect_iterator_items(i, expected_len, expected, expected_len, expected);
		git_iterator_free(i);
	}

	/* Test that start and end allow '/' suffixes of submodules */
	{
		const char *expected[] = { "sm_changed_head", "sm_changed_index" };
		size_t expected_len = 2;

		i_opts.start = "sm_changed_head";
		i_opts.end = "sm_changed_index";
		i_opts.pathlist.strings = NULL;
		i_opts.pathlist.count = 0;
		i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;

		cl_git_pass(git_iterator_for_workdir(&i, g_repo, index, head, &i_opts));
		expect_iterator_items(i, expected_len, expected, expected_len, expected);
		git_iterator_free(i);
	}

	git_vector_free(&filelist);
	git_index_free(index);
	git_tree_free(head);
}
Esempio n. 12
0
void test_iterator_workdir__pathlist_for_deeply_nested_item(void)
{
	git_iterator *i;
	git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT;
	git_vector filelist;

	cl_git_pass(git_vector_init(&filelist, 5, NULL));

	g_repo = cl_git_sandbox_init("icase");
	create_paths(git_repository_workdir(g_repo), 3);

	/* Ensure that we find the single path we're interested in, and we find
	 * it efficiently, and don't stat the entire world to get there.
	 */
	{
		const char *expected[] = { "item1/item3/item5/item7" };
		size_t expected_len = 1;

		git_vector_clear(&filelist);
		cl_git_pass(git_vector_insert(&filelist, "item1/item3/item5/item7"));

		i_opts.pathlist.strings = (char **)filelist.contents;
		i_opts.pathlist.count = filelist.length;
		i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;

		cl_git_pass(git_iterator_for_workdir(&i, g_repo, NULL, NULL, &i_opts));
		expect_iterator_items(i, expected_len, expected, expected_len, expected);
		cl_assert_equal_i(4, i->stat_calls);
		git_iterator_free(i);
	}

	/* Ensure that we find the single path we're interested in, and we find
	 * it efficiently, and don't stat the entire world to get there.
	 */
	{
		const char *expected[] = {
			"item1/item3/item5/item0", "item1/item3/item5/item1",
			"item1/item3/item5/item2", "item1/item3/item5/item3",
			"item1/item3/item5/item4", "item1/item3/item5/item5",
			"item1/item3/item5/item6", "item1/item3/item5/item7",
		};
		size_t expected_len = 8;

		git_vector_clear(&filelist);
		cl_git_pass(git_vector_insert(&filelist, "item1/item3/item5/"));

		i_opts.pathlist.strings = (char **)filelist.contents;
		i_opts.pathlist.count = filelist.length;
		i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;

		cl_git_pass(git_iterator_for_workdir(&i, g_repo, NULL, NULL, &i_opts));
		expect_iterator_items(i, expected_len, expected, expected_len, expected);
		cl_assert_equal_i(11, i->stat_calls);
		git_iterator_free(i);
	}

	/* Ensure that we find the single path we're interested in, and we find
	 * it efficiently, and don't stat the entire world to get there.
	 */
	{
		const char *expected[] = {
			"item1/item3/item0",
			"item1/item3/item1/item0", "item1/item3/item1/item1",
			"item1/item3/item1/item2", "item1/item3/item1/item3",
			"item1/item3/item1/item4", "item1/item3/item1/item5",
			"item1/item3/item1/item6", "item1/item3/item1/item7",
			"item1/item3/item2",
			"item1/item3/item3/item0", "item1/item3/item3/item1",
			"item1/item3/item3/item2", "item1/item3/item3/item3",
			"item1/item3/item3/item4", "item1/item3/item3/item5",
			"item1/item3/item3/item6", "item1/item3/item3/item7",
			"item1/item3/item4",
			"item1/item3/item5/item0", "item1/item3/item5/item1",
			"item1/item3/item5/item2", "item1/item3/item5/item3",
			"item1/item3/item5/item4", "item1/item3/item5/item5",
			"item1/item3/item5/item6", "item1/item3/item5/item7",
			"item1/item3/item6",
			"item1/item3/item7/item0", "item1/item3/item7/item1",
			"item1/item3/item7/item2", "item1/item3/item7/item3",
			"item1/item3/item7/item4", "item1/item3/item7/item5",
			"item1/item3/item7/item6", "item1/item3/item7/item7",
		};
		size_t expected_len = 36;

		git_vector_clear(&filelist);
		cl_git_pass(git_vector_insert(&filelist, "item1/item3/"));

		i_opts.pathlist.strings = (char **)filelist.contents;
		i_opts.pathlist.count = filelist.length;
		i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;

		cl_git_pass(git_iterator_for_workdir(&i, g_repo, NULL, NULL, &i_opts));
		expect_iterator_items(i, expected_len, expected, expected_len, expected);
		cl_assert_equal_i(42, i->stat_calls);
		git_iterator_free(i);
	}

	/* Ensure that we find the single path we're interested in, and we find
	 * it efficiently, and don't stat the entire world to get there.
	 */
	{
		const char *expected[] = {
			"item0", "item1/item2", "item5/item7/item4", "item6",
			"item7/item3/item1/item6" };
		size_t expected_len = 5;

		git_vector_clear(&filelist);
		cl_git_pass(git_vector_insert(&filelist, "item7/item3/item1/item6"));
		cl_git_pass(git_vector_insert(&filelist, "item6"));
		cl_git_pass(git_vector_insert(&filelist, "item5/item7/item4"));
		cl_git_pass(git_vector_insert(&filelist, "item1/item2"));
		cl_git_pass(git_vector_insert(&filelist, "item0"));

		/* also add some things that don't exist or don't match the right type */
		cl_git_pass(git_vector_insert(&filelist, "item2/"));
		cl_git_pass(git_vector_insert(&filelist, "itemN"));
		cl_git_pass(git_vector_insert(&filelist, "item1/itemA"));
		cl_git_pass(git_vector_insert(&filelist, "item5/item3/item4/"));

		i_opts.pathlist.strings = (char **)filelist.contents;
		i_opts.pathlist.count = filelist.length;
		i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;

		cl_git_pass(git_iterator_for_workdir(&i, g_repo, NULL, NULL, &i_opts));
		expect_iterator_items(i, expected_len, expected, expected_len, expected);
		cl_assert_equal_i(14, i->stat_calls);
		git_iterator_free(i);
	}

	git_vector_free(&filelist);
}
Esempio n. 13
0
void test_repo_iterator__treefilelist_icase(void)
{
	git_iterator *i;
	git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT;
	git_vector filelist;
	git_tree *tree;

	cl_git_pass(git_vector_init(&filelist, 100, &git__strcmp_cb));
	cl_git_pass(git_vector_insert(&filelist, "a"));
	cl_git_pass(git_vector_insert(&filelist, "B"));
	cl_git_pass(git_vector_insert(&filelist, "c"));
	cl_git_pass(git_vector_insert(&filelist, "D"));
	cl_git_pass(git_vector_insert(&filelist, "e"));
	cl_git_pass(git_vector_insert(&filelist, "k.a"));
	cl_git_pass(git_vector_insert(&filelist, "k.b"));
	cl_git_pass(git_vector_insert(&filelist, "k/1"));
	cl_git_pass(git_vector_insert(&filelist, "k/a"));
	cl_git_pass(git_vector_insert(&filelist, "kZZZZ"));
	cl_git_pass(git_vector_insert(&filelist, "L/1"));

	g_repo = cl_git_sandbox_init("icase");
	git_repository_head_tree(&tree, g_repo);

	i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;
	i_opts.pathlist.strings = (char **)filelist.contents;
	i_opts.pathlist.count = filelist.length;

	i_opts.start = "c";
	i_opts.end = "k/D";
	cl_git_pass(git_iterator_for_tree(&i, tree, &i_opts));
	expect_iterator_items(i, 3, NULL, 3, NULL);
	git_iterator_free(i);

	i_opts.start = "k";
	i_opts.end = "k/Z";
	cl_git_pass(git_iterator_for_tree(&i, tree, &i_opts));
	expect_iterator_items(i, 1, NULL, 1, NULL);
	git_iterator_free(i);

	i_opts.flags = GIT_ITERATOR_IGNORE_CASE;

	i_opts.start = "c";
	i_opts.end = "k/D";
	cl_git_pass(git_iterator_for_tree(&i, tree, &i_opts));
	expect_iterator_items(i, 5, NULL, 5, NULL);
	git_iterator_free(i);

	i_opts.start = "k";
	i_opts.end = "k/Z";
	cl_git_pass(git_iterator_for_tree(&i, tree, &i_opts));
	expect_iterator_items(i, 2, NULL, 2, NULL);
	git_iterator_free(i);

	git_vector_free(&filelist);
	git_tree_free(tree);
}
Esempio n. 14
0
void test_repo_iterator__treefilelist(void)
{
	git_iterator *i;
	git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT;
	git_vector filelist;
	git_tree *tree;
	bool default_icase;
	int expect;

	cl_git_pass(git_vector_init(&filelist, 100, &git__strcmp_cb));
	cl_git_pass(git_vector_insert(&filelist, "a"));
	cl_git_pass(git_vector_insert(&filelist, "B"));
	cl_git_pass(git_vector_insert(&filelist, "c"));
	cl_git_pass(git_vector_insert(&filelist, "D"));
	cl_git_pass(git_vector_insert(&filelist, "e"));
	cl_git_pass(git_vector_insert(&filelist, "k.a"));
	cl_git_pass(git_vector_insert(&filelist, "k.b"));
	cl_git_pass(git_vector_insert(&filelist, "k/1"));
	cl_git_pass(git_vector_insert(&filelist, "k/a"));
	cl_git_pass(git_vector_insert(&filelist, "kZZZZZZZ"));
	cl_git_pass(git_vector_insert(&filelist, "L/1"));

	g_repo = cl_git_sandbox_init("icase");
	git_repository_head_tree(&tree, g_repo);

	/* All indexfilelist iterator tests are "autoexpand with no tree entries" */
	/* In this test we DO NOT force a case on the iteratords and verify default behavior. */

	i_opts.pathlist.strings = (char **)filelist.contents;
	i_opts.pathlist.count = filelist.length;

	cl_git_pass(git_iterator_for_tree(&i, tree, &i_opts));
	expect_iterator_items(i, 8, NULL, 8, NULL);
	git_iterator_free(i);

	i_opts.start = "c";
	i_opts.end = NULL;
	cl_git_pass(git_iterator_for_tree(&i, tree, &i_opts));
	default_icase = git_iterator_ignore_case(i);
	/* (c D e k/1 k/a L ==> 6) vs (c e k/1 k/a ==> 4) */
	expect = ((default_icase) ? 6 : 4);
	expect_iterator_items(i, expect, NULL, expect, NULL);
	git_iterator_free(i);

	i_opts.start = NULL;
	i_opts.end = "e";
	cl_git_pass(git_iterator_for_tree(&i, tree, &i_opts));
	default_icase = git_iterator_ignore_case(i);
	/* (a B c D e ==> 5) vs (B D L/1 a c e ==> 6) */
	expect = ((default_icase) ? 5 : 6);
	expect_iterator_items(i, expect, NULL, expect, NULL);
	git_iterator_free(i);

	git_vector_free(&filelist);
	git_tree_free(tree);
}
Esempio n. 15
0
static int add_ref(const char *name, git_repository *repo, git_vector *vec)
{
	const char peeled[] = "^{}";
	git_remote_head *head;
	git_reference *ref;
	git_object *obj = NULL;
	int error = GIT_SUCCESS, peel_len, ret;

	head = git__malloc(sizeof(git_remote_head));
	if (head == NULL)
		return GIT_ENOMEM;

	head->name = git__strdup(name);
	if (head->name == NULL) {
		error = GIT_ENOMEM;
		goto out;
	}

	error = git_reference_lookup(&ref, repo, name);
	if (error < GIT_SUCCESS)
		goto out;

	error = git_reference_resolve(&ref, ref);
	if (error < GIT_SUCCESS)
		goto out;

	git_oid_cpy(&head->oid, git_reference_oid(ref));

	error = git_vector_insert(vec, head);
	if (error < GIT_SUCCESS)
		goto out;

	/* If it's not a tag, we don't need to try to peel it */
	if (git__prefixcmp(name, GIT_REFS_TAGS_DIR))
		goto out;

	error = git_object_lookup(&obj, repo, &head->oid, GIT_OBJ_ANY);
	if (error < GIT_SUCCESS) {
		git__rethrow(error, "Failed to lookup object");
	}

	/* If it's not an annotated tag, just get out */
	if (git_object_type(obj) != GIT_OBJ_TAG)
		goto out;

	/* And if it's a tag, peel it, and add it to the list */
	head = git__malloc(sizeof(git_remote_head));
	peel_len = strlen(name) + STRLEN(peeled);
	head->name = git__malloc(peel_len + 1);
	ret = snprintf(head->name, peel_len + 1, "%s%s", name, peeled);
	if (ret >= peel_len + 1) {
		error = git__throw(GIT_ERROR, "The string is magically to long");
	}

	git_oid_cpy(&head->oid, git_tag_target_oid((git_tag *) obj));

	error = git_vector_insert(vec, head);
	if (error < GIT_SUCCESS)
		goto out;

 out:
	git_object_close(obj);
	if (error < GIT_SUCCESS) {
		free(head->name);
		free(head);
	}
	return error;
}
Esempio n. 16
0
int git_path_dirload(
	const char *path,
	size_t prefix_len,
	size_t alloc_extra,
	unsigned int flags,
	git_vector *contents)
{
	int error, need_slash;
	DIR *dir;
	size_t path_len;
	path_dirent_data de_data;
	struct dirent *de, *de_buf = (struct dirent *)&de_data;

	(void)flags;

#ifdef GIT_USE_ICONV
	git_path_iconv_t ic = GIT_PATH_ICONV_INIT;
#endif

	assert(path && contents);

	path_len = strlen(path);

	if (!path_len || path_len < prefix_len) {
		giterr_set(GITERR_INVALID, "Invalid directory path '%s'", path);
		return -1;
	}
	if ((dir = opendir(path)) == NULL) {
		giterr_set(GITERR_OS, "Failed to open directory '%s'", path);
		return -1;
	}

#ifdef GIT_USE_ICONV
	if ((flags & GIT_PATH_DIR_PRECOMPOSE_UNICODE) != 0)
		(void)git_path_iconv_init_precompose(&ic);
#endif

	path += prefix_len;
	path_len -= prefix_len;
	need_slash = (path_len > 0 && path[path_len-1] != '/') ? 1 : 0;

	while ((error = p_readdir_r(dir, de_buf, &de)) == 0 && de != NULL) {
		char *entry_path, *de_path = de->d_name;
		size_t alloc_size, de_len = strlen(de_path);

		if (git_path_is_dot_or_dotdot(de_path))
			continue;

#ifdef GIT_USE_ICONV
		if ((error = git_path_iconv(&ic, &de_path, &de_len)) < 0)
			break;
#endif

		alloc_size = path_len + need_slash + de_len + 1 + alloc_extra;
		if ((entry_path = git__calloc(alloc_size, 1)) == NULL) {
			error = -1;
			break;
		}

		if (path_len)
			memcpy(entry_path, path, path_len);
		if (need_slash)
			entry_path[path_len] = '/';
		memcpy(&entry_path[path_len + need_slash], de_path, de_len);

		if ((error = git_vector_insert(contents, entry_path)) < 0)
			break;
	}

	closedir(dir);

#ifdef GIT_USE_ICONV
	git_path_iconv_clear(&ic);
#endif

	if (error != 0)
		giterr_set(GITERR_OS, "Failed to process directory entry in '%s'", path);

	return error;
}
Esempio n. 17
0
static int index_insert(git_index *index, const git_index_entry *source_entry, int replace)
{
	git_index_entry *entry;
	size_t path_length;
	int position;
	git_index_entry **entry_array;

	assert(index && source_entry);

	if (source_entry->path == NULL)
		return git__throw(GIT_EMISSINGOBJDATA, "Failed to insert into index. Entry has no path");

	entry = git__malloc(sizeof(git_index_entry));
	if (entry == NULL)
		return GIT_ENOMEM;

	memcpy(entry, source_entry, sizeof(git_index_entry));

	/* duplicate the path string so we own it */
	entry->path = git__strdup(entry->path);
	if (entry->path == NULL)
		return GIT_ENOMEM;

	/* make sure that the path length flag is correct */
	path_length = strlen(entry->path);

	entry->flags &= ~GIT_IDXENTRY_NAMEMASK;

	if (path_length < GIT_IDXENTRY_NAMEMASK)
		entry->flags |= path_length & GIT_IDXENTRY_NAMEMASK;
	else
		entry->flags |= GIT_IDXENTRY_NAMEMASK;;

	/*
	 * replacing is not requested: just insert entry at the end;
	 * the index is no longer sorted
	 */
	if (!replace) {
		if (git_vector_insert(&index->entries, entry) < GIT_SUCCESS)
			goto cleanup_oom;

		return GIT_SUCCESS;
	}

	/* look if an entry with this path already exists */
	position = git_index_find(index, source_entry->path);

	/*
	 * if no entry exists add the entry at the end;
	 * the index is no longer sorted
	 */
	if (position == GIT_ENOTFOUND) {
		if (git_vector_insert(&index->entries, entry) < GIT_SUCCESS)
			goto cleanup_oom;

		return GIT_SUCCESS;
	}

	/* exists, replace it */
	entry_array = (git_index_entry **) index->entries.contents;
	free((char *)entry_array[position]->path);
	free(entry_array[position]);
	entry_array[position] = entry;

	return GIT_SUCCESS;

cleanup_oom:
	free((char *)entry->path);
	free(entry);
	return GIT_ENOMEM;;
}
Esempio n. 18
0
int git_commit__parse_buffer(git_commit *commit, const void *data, size_t len)
{
	const char *buffer = data;
	const char *buffer_end = (const char *)data + len;

	git_oid parent_oid;
	int error;

	git_vector_init(&commit->parent_oids, 4, NULL);

	if ((error = git_oid__parse(&commit->tree_oid, &buffer, buffer_end, "tree ")) < GIT_SUCCESS)
		return git__rethrow(error, "Failed to parse buffer");

	/*
	 * TODO: commit grafts!
	 */

	while (git_oid__parse(&parent_oid, &buffer, buffer_end, "parent ") == GIT_SUCCESS) {
		git_oid *new_oid;

		new_oid = git__malloc(sizeof(git_oid));
		git_oid_cpy(new_oid, &parent_oid);

		if (git_vector_insert(&commit->parent_oids, new_oid) < GIT_SUCCESS)
			return GIT_ENOMEM;
	}

	commit->author = git__malloc(sizeof(git_signature));
	if ((error = git_signature__parse(commit->author, &buffer, buffer_end, "author ", '\n')) < GIT_SUCCESS)
		return git__rethrow(error, "Failed to parse commit");

	/* Always parse the committer; we need the commit time */
	commit->committer = git__malloc(sizeof(git_signature));
	if ((error = git_signature__parse(commit->committer, &buffer, buffer_end, "committer ", '\n')) < GIT_SUCCESS)
		return git__rethrow(error, "Failed to parse commit");

	if (git__prefixcmp(buffer, "encoding ") == 0) {
		const char *encoding_end;
		buffer += strlen("encoding ");

		encoding_end = buffer;
		while (encoding_end < buffer_end && *encoding_end != '\n')
			encoding_end++;

		commit->message_encoding = git__strndup(buffer, encoding_end - buffer);
		if (!commit->message_encoding)
			return GIT_ENOMEM;

		buffer = encoding_end;
	}

	/* parse commit message */
	while (buffer < buffer_end && *buffer == '\n')
		buffer++;

	if (buffer < buffer_end) {
		commit->message = git__strndup(buffer, buffer_end - buffer);
		if (!commit->message)
			return GIT_ENOMEM;
	}

	return GIT_SUCCESS;
}
Esempio n. 19
0
static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
{
	unsigned int i;
	struct index_header header;
	git_oid checksum_calculated, checksum_expected;

#define seek_forward(_increase) { \
	if (_increase >= buffer_size) \
		return git__throw(GIT_EOBJCORRUPTED, "Failed to seek forward. Buffer size exceeded"); \
	buffer += _increase; \
	buffer_size -= _increase;\
}

	if (buffer_size < INDEX_HEADER_SIZE + INDEX_FOOTER_SIZE)
		return git__throw(GIT_EOBJCORRUPTED, "Failed to parse index. Buffer too small");

	/* Precalculate the SHA1 of the files's contents -- we'll match it to
	 * the provided SHA1 in the footer */
	git_hash_buf(&checksum_calculated, buffer, buffer_size - INDEX_FOOTER_SIZE);

	/* Parse header */
	if (read_header(&header, buffer) < GIT_SUCCESS)
		return git__throw(GIT_EOBJCORRUPTED, "Failed to parse index. Header is corrupted");

	seek_forward(INDEX_HEADER_SIZE);

	git_vector_clear(&index->entries);

	/* Parse all the entries */
	for (i = 0; i < header.entry_count && buffer_size > INDEX_FOOTER_SIZE; ++i) {
		size_t entry_size;
		git_index_entry *entry;

		entry = git__malloc(sizeof(git_index_entry));
		if (entry == NULL)
			return GIT_ENOMEM;

		entry_size = read_entry(entry, buffer, buffer_size);

		/* 0 bytes read means an object corruption */
		if (entry_size == 0)
			return git__throw(GIT_EOBJCORRUPTED, "Failed to parse index. Entry size is zero");

		if (git_vector_insert(&index->entries, entry) < GIT_SUCCESS)
			return GIT_ENOMEM;

		seek_forward(entry_size);
	}

	if (i != header.entry_count)
		return git__throw(GIT_EOBJCORRUPTED, "Failed to parse index. Header entries changed while parsing");

	/* There's still space for some extensions! */
	while (buffer_size > INDEX_FOOTER_SIZE) {
		size_t extension_size;

		extension_size = read_extension(index, buffer, buffer_size);

		/* see if we have read any bytes from the extension */
		if (extension_size == 0)
			return git__throw(GIT_EOBJCORRUPTED, "Failed to parse index. Extension size is zero");

		seek_forward(extension_size);
	}

	if (buffer_size != INDEX_FOOTER_SIZE)
		return git__throw(GIT_EOBJCORRUPTED, "Failed to parse index. Buffer size does not match index footer size");

	/* 160-bit SHA-1 over the content of the index file before this checksum. */
	git_oid_fromraw(&checksum_expected, (const unsigned char *)buffer);

	if (git_oid_cmp(&checksum_calculated, &checksum_expected) != 0)
		return git__throw(GIT_EOBJCORRUPTED, "Failed to parse index. Calculated checksum does not match expected checksum");

#undef seek_forward

	/* force sorting in the vector: the entries are
	 * assured to be sorted on the index */
	index->entries.sorted = 1;
	return GIT_SUCCESS;
}
Esempio n. 20
0
int commit_parse_buffer(git_commit *commit, void *data, size_t len, unsigned int parse_flags)
{
	char *buffer = (char *)data;
	const char *buffer_end = (char *)data + len;

	git_oid oid;
	int error;

	/* first parse; the vector hasn't been initialized yet */
	if (commit->parents.contents == NULL) {
		git_vector_init(&commit->parents, 4, NULL, NULL);
	}

	clear_parents(commit);


	if ((error = git__parse_oid(&oid, &buffer, buffer_end, "tree ")) < GIT_SUCCESS)
		return error;

	if ((error = git_repository_lookup((git_object **)&commit->tree, commit->object.repo, &oid, GIT_OBJ_TREE)) < GIT_SUCCESS)
		return error;

	/*
	 * TODO: commit grafts!
	 */

	while (git__parse_oid(&oid, &buffer, buffer_end, "parent ") == GIT_SUCCESS) {
		git_commit *parent;

		if ((error = git_repository_lookup((git_object **)&parent, commit->object.repo, &oid, GIT_OBJ_COMMIT)) < GIT_SUCCESS)
			return error;

		if (git_vector_insert(&commit->parents, parent) < GIT_SUCCESS)
			return GIT_ENOMEM;
	}


	if (parse_flags & COMMIT_FULL_PARSE) {
		if (commit->author)
			git_signature_free(commit->author);

		commit->author = git__malloc(sizeof(git_signature));
		if ((error = git_signature__parse(commit->author, &buffer, buffer_end, "author ")) < GIT_SUCCESS)
			return error;

	} else {
		if ((buffer = memchr(buffer, '\n', buffer_end - buffer)) == NULL)
			return GIT_EOBJCORRUPTED;

		buffer++;
	}

	/* Always parse the committer; we need the commit time */
	if (commit->committer)
		git_signature_free(commit->committer);

	commit->committer = git__malloc(sizeof(git_signature));
	if ((error = git_signature__parse(commit->committer, &buffer, buffer_end, "committer ")) < GIT_SUCCESS)
		return error;

	/* parse commit message */
	while (buffer <= buffer_end && *buffer == '\n')
		buffer++;

	if (parse_flags & COMMIT_FULL_PARSE && buffer < buffer_end) {
		const char *line_end;
		size_t message_len = buffer_end - buffer;

		/* Long message */
		message_len = buffer_end - buffer;
		commit->message = git__malloc(message_len + 1);
		memcpy(commit->message, buffer, message_len);
		commit->message[message_len] = 0;

		/* Short message */
		if((line_end = memchr(buffer, '\n', buffer_end - buffer)) == NULL)
			line_end = buffer_end;
		message_len = line_end - buffer;

		commit->message_short = git__malloc(message_len + 1);
		memcpy(commit->message_short, buffer, message_len);
		commit->message_short[message_len] = 0;
	}

	return GIT_SUCCESS;
}
Esempio n. 21
0
static int add_ref(transport_local *t, const char *name)
{
	const char peeled[] = "^{}";
	git_remote_head *head;
	git_object *obj = NULL, *target = NULL;
	git_transport *transport = (git_transport *) t;
	git_buf buf = GIT_BUF_INIT;
	git_pkt_ref *pkt;

	head = git__malloc(sizeof(git_remote_head));
	GITERR_CHECK_ALLOC(head);
	pkt = git__malloc(sizeof(git_pkt_ref));
	GITERR_CHECK_ALLOC(pkt);

	head->name = git__strdup(name);
	GITERR_CHECK_ALLOC(head->name);

	if (git_reference_name_to_oid(&head->oid, t->repo, name) < 0) {
		git__free(head);
		git__free(pkt->head.name);
		git__free(pkt);
	}

	pkt->type = GIT_PKT_REF;
	memcpy(&pkt->head, head, sizeof(git_remote_head));
	git__free(head);

	if (git_vector_insert(&transport->refs, pkt) < 0)
	{
		git__free(pkt->head.name);
		git__free(pkt);
		return -1;
	}

	/* If it's not a tag, we don't need to try to peel it */
	if (git__prefixcmp(name, GIT_REFS_TAGS_DIR))
		return 0;

	if (git_object_lookup(&obj, t->repo, &pkt->head.oid, GIT_OBJ_ANY) < 0)
		return -1;

	head = NULL;

	/* If it's not an annotated tag, just get out */
	if (git_object_type(obj) != GIT_OBJ_TAG) {
		git_object_free(obj);
		return 0;
	}

	/* And if it's a tag, peel it, and add it to the list */
	head = git__malloc(sizeof(git_remote_head));
	GITERR_CHECK_ALLOC(head);
	if (git_buf_join(&buf, 0, name, peeled) < 0)
		return -1;

	head->name = git_buf_detach(&buf);

	pkt = git__malloc(sizeof(git_pkt_ref));
	GITERR_CHECK_ALLOC(pkt);
	pkt->type = GIT_PKT_REF;

	if (git_tag_peel(&target, (git_tag *) obj) < 0)
		goto on_error;

	git_oid_cpy(&head->oid, git_object_id(target));
	git_object_free(obj);
	git_object_free(target);
	memcpy(&pkt->head, head, sizeof(git_remote_head));
	git__free(head);

	if (git_vector_insert(&transport->refs, pkt) < 0)
		return -1;

	return 0;

on_error:
	git_object_free(obj);
	git_object_free(target);
	return -1;
}
Esempio n. 22
0
static int cb__reflist_add(const char *ref, void *data)
{
	char *name = git__strdup(ref);
	GITERR_CHECK_ALLOC(name);
	return git_vector_insert((git_vector *)data, name);
}
Esempio n. 23
0
int git_commit__parse_buffer(git_commit *commit, const void *data, size_t len)
{
	const char *buffer = data;
	const char *buffer_end = (const char *)data + len;
	git_oid parent_id;

	if (git_vector_init(&commit->parent_ids, 4, NULL) < 0)
		return -1;

	if (git_oid__parse(&commit->tree_id, &buffer, buffer_end, "tree ") < 0)
		goto bad_buffer;

	/*
	 * TODO: commit grafts!
	 */

	while (git_oid__parse(&parent_id, &buffer, buffer_end, "parent ") == 0) {
		git_oid *new_id = git__malloc(sizeof(git_oid));
		GITERR_CHECK_ALLOC(new_id);

		git_oid_cpy(new_id, &parent_id);

		if (git_vector_insert(&commit->parent_ids, new_id) < 0)
			return -1;
	}

	commit->author = git__malloc(sizeof(git_signature));
	GITERR_CHECK_ALLOC(commit->author);

	if (git_signature__parse(commit->author, &buffer, buffer_end, "author ", '\n') < 0)
		return -1;

	/* Always parse the committer; we need the commit time */
	commit->committer = git__malloc(sizeof(git_signature));
	GITERR_CHECK_ALLOC(commit->committer);

	if (git_signature__parse(commit->committer, &buffer, buffer_end, "committer ", '\n') < 0)
		return -1;

	/* Parse add'l header entries until blank line found */
	while (buffer < buffer_end && *buffer != '\n') {
		const char *eoln = buffer;
		while (eoln < buffer_end && *eoln != '\n')
			++eoln;

		if (git__prefixcmp(buffer, "encoding ") == 0) {
			buffer += strlen("encoding ");

			commit->message_encoding = git__strndup(buffer, eoln - buffer);
			GITERR_CHECK_ALLOC(commit->message_encoding);
		}

		if (eoln < buffer_end && *eoln == '\n')
			++eoln;

		buffer = eoln;
	}

	/* skip blank lines */
	while (buffer < buffer_end - 1 && *buffer == '\n')
		buffer++;

	/* parse commit message */
	if (buffer <= buffer_end) {
		commit->message = git__strndup(buffer, buffer_end - buffer);
		GITERR_CHECK_ALLOC(commit->message);
	}

	return 0;

bad_buffer:
	giterr_set(GITERR_OBJECT, "Failed to parse bad commit object");
	return -1;
}
Esempio n. 24
0
int git_path_dirload(
	const char *path,
	size_t prefix_len,
	size_t alloc_extra,
	unsigned int flags,
	git_vector *contents)
{
	int error;
	DIR *dir;
	size_t path_len;
	path_dirent_data de_data;
	struct dirent *de, *de_buf = (struct dirent *)&de_data;

#ifdef GIT_USE_ICONV
	git_path_iconv_t ic = GIT_PATH_ICONV_INIT;
#endif

	GIT_UNUSED(flags);

	assert(path && contents);

	path_len = strlen(path);

	if (!path_len || path_len < prefix_len) {
		giterr_set(GITERR_INVALID, "Invalid directory path '%s'", path);
		return -1;
	}
	if ((dir = opendir(path)) == NULL) {
		giterr_set(GITERR_OS, "Failed to open directory '%s'", path);
		return -1;
	}

#ifdef GIT_USE_ICONV
	if ((flags & GIT_PATH_DIR_PRECOMPOSE_UNICODE) != 0)
		(void)git_path_iconv_init_precompose(&ic);
#endif

	path += prefix_len;
	path_len -= prefix_len;

	while ((error = p_readdir_r(dir, de_buf, &de)) == 0 && de != NULL) {
		char *entry_path, *de_path = de->d_name;
		size_t de_len = strlen(de_path);

		if (git_path_is_dot_or_dotdot(de_path))
			continue;

#ifdef GIT_USE_ICONV
		if ((error = git_path_iconv(&ic, &de_path, &de_len)) < 0)
			break;
#endif

		if ((error = entry_path_alloc(&entry_path,
				path, path_len, de_path, de_len, alloc_extra)) < 0)
			break;

		if ((error = git_vector_insert(contents, entry_path)) < 0) {
			git__free(entry_path);
			break;
		}
	}

	closedir(dir);

#ifdef GIT_USE_ICONV
	git_path_iconv_clear(&ic);
#endif

	if (error != 0)
		giterr_set(GITERR_OS, "Failed to process directory entry in '%s'", path);

	return error;
}
Esempio n. 25
0
int record_ref_cb(git_remote_head *head, void *payload)
{
	git_vector *refs = (git_vector *) payload;
	return git_vector_insert(refs, head);
}