示例#1
0
文件: blob.c 项目: AChep/libgit2
void test_filter_blob__ident(void)
{
	git_oid id;
	git_blob *blob;
	git_buf buf = { 0 };

	cl_git_mkfile("crlf/test.ident", "Some text\n$Id$\nGoes there\n");
	cl_git_pass(git_blob_create_fromworkdir(&id, g_repo, "test.ident"));
	cl_git_pass(git_blob_lookup(&blob, g_repo, &id));
	cl_assert_equal_s(
		"Some text\n$Id$\nGoes there\n", git_blob_rawcontent(blob));
	git_blob_free(blob);

	cl_git_mkfile("crlf/test.ident", "Some text\n$Id: Any old just you want$\nGoes there\n");
	cl_git_pass(git_blob_create_fromworkdir(&id, g_repo, "test.ident"));
	cl_git_pass(git_blob_lookup(&blob, g_repo, &id));
	cl_assert_equal_s(
		"Some text\n$Id$\nGoes there\n", git_blob_rawcontent(blob));

	cl_git_pass(git_blob_filtered_content(&buf, blob, "filter.bin", 1));
	cl_assert_equal_s(
		"Some text\n$Id$\nGoes there\n", buf.ptr);

	cl_git_pass(git_blob_filtered_content(&buf, blob, "filter.identcrlf", 1));
	cl_assert_equal_s(
		"Some text\r\n$Id: 3164f585d548ac68027d22b104f2d8100b2b6845$\r\nGoes there\r\n", buf.ptr);

	cl_git_pass(git_blob_filtered_content(&buf, blob, "filter.identlf", 1));
	cl_assert_equal_s(
		"Some text\n$Id: 3164f585d548ac68027d22b104f2d8100b2b6845$\nGoes there\n", buf.ptr);

	git_buf_free(&buf);
	git_blob_free(blob);

}
示例#2
0
void test_filter_custom__order_dependency(void)
{
	git_index *index;
	git_blob *blob;
	git_buf buf = { 0 };

	/* so if ident and reverse are used together, an interesting thing
	 * happens - a reversed "$Id$" string is no longer going to trigger
	 * ident correctly.  When checking out, the filters should be applied
	 * in order CLRF, then ident, then reverse, so ident expansion should
	 * work correctly.  On check in, the content should be reversed, then
	 * ident, then CRLF filtered.  Let's make sure that works...
	 */

	cl_git_mkfile(
		"empty_standard_repo/.gitattributes",
		"hero.*.rev-ident text ident prereverse eol=lf\n");

	cl_git_mkfile(
		"empty_standard_repo/hero.1.rev-ident",
		"This is a test\n$Id$\nHave fun!\n");

	cl_git_mkfile(
		"empty_standard_repo/hero.2.rev-ident",
		"Another test\n$dI$\nCrazy!\n");

	cl_git_pass(git_repository_index(&index, g_repo));
	cl_git_pass(git_index_add_bypath(index, "hero.1.rev-ident"));
	cl_git_pass(git_index_add_bypath(index, "hero.2.rev-ident"));
	cl_repo_commit_from_index(NULL, g_repo, NULL, 0, "Filter chains\n");
	git_index_free(index);

	cl_git_pass(git_blob_lookup(&blob, g_repo,
		& git_index_get_bypath(index, "hero.1.rev-ident", 0)->oid));
	cl_assert_equal_s(
		"\n!nuf evaH\n$dI$\ntset a si sihT", git_blob_rawcontent(blob));
	cl_git_pass(git_blob_filtered_content(&buf, blob, "hero.1.rev-ident", 0));
	/* no expansion because id was reversed at checkin and now at ident
	 * time, reverse is not applied yet */
	cl_assert_equal_s(
		"This is a test\n$Id$\nHave fun!\n", buf.ptr);
	git_blob_free(blob);

	cl_git_pass(git_blob_lookup(&blob, g_repo,
		& git_index_get_bypath(index, "hero.2.rev-ident", 0)->oid));
	cl_assert_equal_s(
		"\n!yzarC\n$Id$\ntset rehtonA", git_blob_rawcontent(blob));
	cl_git_pass(git_blob_filtered_content(&buf, blob, "hero.2.rev-ident", 0));
	/* expansion because reverse was applied at checkin and at ident time,
	 * reverse is not applied yet */
	cl_assert_equal_s(
		"Another test\n$59001fe193103b1016b27027c0c827d036fd0ac8 :dI$\nCrazy!\n", buf.ptr);
	cl_assert_equal_i(0, git_oid_strcmp(
		git_blob_id(blob), "8ca0df630d728c0c72072b6101b301391ef10095"));
	git_blob_free(blob);

	git_buf_free(&buf);
}
示例#3
0
void test_diff_binary__blob_to_blob(void)
{
	git_index *index;
	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
	git_blob *old_blob, *new_blob;
	git_oid old_id, new_id;
	struct diff_data diff_data = {0};

	opts.flags = GIT_DIFF_SHOW_BINARY | GIT_DIFF_FORCE_BINARY;
	opts.id_abbrev = GIT_OID_HEXSZ;

	repo = cl_git_sandbox_init("renames");
	cl_git_pass(git_repository_index__weakptr(&index, repo));

	cl_git_append2file("renames/untimely.txt", "Oh that crazy Kipling!\r\n");
	cl_git_pass(git_index_add_bypath(index, "untimely.txt"));
	cl_git_pass(git_index_write(index));

	git_oid_fromstr(&old_id, "9a69d960ae94b060f56c2a8702545e2bb1abb935");
	git_oid_fromstr(&new_id, "1111d4f11f4b35bf6759e0fb714fe09731ef0840");

	cl_git_pass(git_blob_lookup(&old_blob, repo, &old_id));
	cl_git_pass(git_blob_lookup(&new_blob, repo, &new_id));

	cl_git_pass(git_diff_blobs(old_blob,
		"untimely.txt", new_blob, "untimely.txt", &opts,
		file_cb, binary_cb, hunk_cb, line_cb, &diff_data));

	cl_assert_equal_s("untimely.txt", diff_data.old_path);
	cl_assert_equal_oid(&old_id, &diff_data.old_id);
	cl_assert_equal_i(GIT_DIFF_BINARY_DELTA, diff_data.old_binary_type);
	cl_assert_equal_i(7, diff_data.old_binary_inflatedlen);
	cl_assert_equal_s("c%18D`@*{63ljhg(E~C7",
		diff_data.old_binary_base85.ptr);

	cl_assert_equal_s("untimely.txt", diff_data.new_path);
	cl_assert_equal_oid(&new_id, &diff_data.new_id);
	cl_assert_equal_i(GIT_DIFF_BINARY_DELTA, diff_data.new_binary_type);
	cl_assert_equal_i(32, diff_data.new_binary_inflatedlen);
	cl_assert_equal_s("c%1vf+QYWt3zLL@hC)e3Vu?a>QDRl4f_G*?PG(-ZA}<#J$+QbW",
		diff_data.new_binary_base85.ptr);

	git_blob_free(old_blob);
	git_blob_free(new_blob);

	git__free(diff_data.old_path);
	git__free(diff_data.new_path);

	git_buf_dispose(&diff_data.old_binary_base85);
	git_buf_dispose(&diff_data.new_binary_base85);
}
示例#4
0
int CRepositoryBrowser::ReadTreeRecursive(git_repository &repo, git_tree * tree, CShadowFilesTree * treeroot)
{
	size_t count = git_tree_entrycount(tree);

	for (size_t i = 0; i < count; ++i)
	{
		const git_tree_entry *entry = git_tree_entry_byindex(tree, i);
		if (entry == NULL)
			continue;

		const int mode = git_tree_entry_filemode(entry);

		CString base = CUnicodeUtils::GetUnicode(git_tree_entry_name(entry), CP_UTF8);

		const git_oid *oid = git_tree_entry_id(entry);
		CShadowFilesTree * pNextTree = &treeroot->m_ShadowTree[base];
		pNextTree->m_sName = base;
		pNextTree->m_pParent = treeroot;
		pNextTree->m_hash = CGitHash((char *)oid->id);

		if (mode == GIT_FILEMODE_COMMIT)
			pNextTree->m_bSubmodule = true;
		else if (mode & S_IFDIR)
		{
			pNextTree->m_bFolder = true;

			TVINSERTSTRUCT tvinsert = {0};
			tvinsert.hParent = treeroot->m_hTree;
			tvinsert.hInsertAfter = TVI_SORT;
			tvinsert.itemex.mask = TVIF_DI_SETITEM | TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_STATE;
			tvinsert.itemex.pszText = base.GetBuffer(base.GetLength());
			tvinsert.itemex.lParam = (LPARAM)pNextTree;
			tvinsert.itemex.iImage = m_nIconFolder;
			tvinsert.itemex.iSelectedImage = m_nOpenIconFolder;
			pNextTree->m_hTree = m_RepoTree.InsertItem(&tvinsert);
			base.ReleaseBuffer();

			git_object *object = nullptr;
			git_tree_entry_to_object(&object, &repo, entry);
			if (object == nullptr)
				continue;

			ReadTreeRecursive(repo, (git_tree*)object, pNextTree);

			git_object_free(object);
		}
		else
		{
			git_blob * blob = nullptr;
			git_blob_lookup(&blob, &repo, oid);
			if (blob == NULL)
				continue;

			pNextTree->m_iSize = git_blob_rawsize(blob);
			git_blob_free(blob);
		}
	}

	return 0;
}
示例#5
0
文件: reader.c 项目: ocodo/.emacs.d
static int index_reader_read(
	git_buf *out,
	git_oid *out_id,
	git_filemode_t *out_filemode,
	git_reader *_reader,
	const char *filename)
{
	index_reader *reader = (index_reader *)_reader;
	const git_index_entry *entry;
	git_blob *blob;
	int error;

	if ((entry = git_index_get_bypath(reader->index, filename, 0)) == NULL)
		return GIT_ENOTFOUND;

	if ((error = git_blob_lookup(&blob, reader->repo, &entry->id)) < 0)
		goto done;

	if (out_id)
		git_oid_cpy(out_id, &entry->id);

	if (out_filemode)
		*out_filemode = entry->mode;

	error = git_blob__getbuf(out, blob);

done:
	git_blob_free(blob);
	return error;
}
示例#6
0
文件: notes.c 项目: Asquera/libgit2
void test_notes_notes__1(void)
{
	git_oid oid, note_oid;
	static git_note *note;
	static git_blob *blob;

	cl_git_pass(git_oid_fromstr(&oid, "8496071c1b46c854b31185ea97743be6a8774479"));

	cl_git_pass(git_note_create(&note_oid, _repo, _sig, _sig, "refs/notes/some/namespace", &oid, "hello world\n"));
	cl_git_pass(git_note_create(&note_oid, _repo, _sig, _sig, NULL, &oid, "hello world\n"));

	cl_git_pass(git_note_read(&note, _repo, NULL, &oid));

	cl_assert_equal_s(git_note_message(note), "hello world\n");
	cl_assert(!git_oid_cmp(git_note_oid(note), &note_oid));

	cl_git_pass(git_blob_lookup(&blob, _repo, &note_oid));
	cl_assert_equal_s(git_note_message(note), git_blob_rawcontent(blob));

	cl_git_fail(git_note_create(&note_oid, _repo, _sig, _sig, NULL, &oid, "hello world\n"));
	cl_git_fail(git_note_create(&note_oid, _repo, _sig, _sig, "refs/notes/some/namespace", &oid, "hello world\n"));

	cl_git_pass(git_note_remove(_repo, NULL, _sig, _sig, &oid));
	cl_git_pass(git_note_remove(_repo, "refs/notes/some/namespace", _sig, _sig, &oid));

	cl_git_fail(git_note_remove(_repo, NULL, _sig, _sig, &note_oid));
	cl_git_fail(git_note_remove(_repo, "refs/notes/some/namespace", _sig, _sig, &oid));

	git_note_free(note);
	git_blob_free(blob);
}
示例#7
0
static int note_lookup(git_note **out, git_repository *repo,
		       git_tree *tree, const char *target)
{
	int error, fanout = 0;
	git_oid oid;
	git_blob *blob = NULL;
	git_note *note = NULL;
	git_tree *subtree = NULL;

	if ((error = find_subtree_r(&subtree, tree, repo, target, &fanout)) < 0)
		goto cleanup;

	if ((error = find_blob(&oid, subtree, target + fanout)) < 0)
		goto cleanup;

	if ((error = git_blob_lookup(&blob, repo, &oid)) < 0)
		goto cleanup;

	if ((error = note_new(&note, &oid, blob)) < 0)
		goto cleanup;

	*out = note;

cleanup:
	git_tree_free(subtree);
	git_blob_free(blob);
	return error;
}
示例#8
0
文件: reader.c 项目: ocodo/.emacs.d
static int tree_reader_read(
	git_buf *out,
	git_oid *out_id,
	git_filemode_t *out_filemode,
	git_reader *_reader,
	const char *filename)
{
	tree_reader *reader = (tree_reader *)_reader;
	git_tree_entry *tree_entry = NULL;
	git_blob *blob = NULL;
	int error;

	if ((error = git_tree_entry_bypath(&tree_entry, reader->tree, filename)) < 0 ||
	    (error = git_blob_lookup(&blob, git_tree_owner(reader->tree), git_tree_entry_id(tree_entry))) < 0 ||
	    (error = git_buf_set(out, git_blob_rawcontent(blob), git_blob_rawsize(blob))) < 0)
		goto done;

	if (out_id)
		git_oid_cpy(out_id, git_tree_entry_id(tree_entry));

	if (out_filemode)
		*out_filemode = git_tree_entry_filemode(tree_entry);

done:
	git_blob_free(blob);
	git_tree_entry_free(tree_entry);
	return error;
}
static int checkout_blob(
	struct checkout_diff_data *data,
	const git_diff_file *file)
{
	git_blob *blob;
	int error;

	git_buf_truncate(data->path, data->workdir_len);
	if (git_buf_joinpath(data->path, git_buf_cstr(data->path), file->path) < 0)
		return -1;

	if ((error = git_blob_lookup(&blob, data->owner, &file->oid)) < 0)
		return error;

	if (S_ISLNK(file->mode))
		error = blob_content_to_link(
			blob, git_buf_cstr(data->path), data->can_symlink);
	else
		error = blob_content_to_file(
			blob, git_buf_cstr(data->path), file->mode, data->checkout_opts);

	git_blob_free(blob);

	return error;
}
示例#10
0
git_blob *git_tree_entry_blob(git_repository *repo, const git_tree_entry *entry)
{
	const git_oid *id = git_tree_entry_id(entry);
	git_blob *blob;

	if (git_blob_lookup(&blob, repo, id))
		return NULL;
	return blob;
}
示例#11
0
文件: tests.c 项目: 1336/libgit2
void test_index_tests__add_frombuffer(void)
{
	git_index *index;
	git_repository *repo;
        git_index_entry entry;
	const git_index_entry *returned_entry;

	git_oid id1;
	git_blob *blob;

	const char *content = "hey there\n";

	cl_set_cleanup(&cleanup_myrepo, NULL);

	/* Intialize a new repository */
	cl_git_pass(git_repository_init(&repo, "./myrepo", 0));

	/* Ensure we're the only guy in the room */
	cl_git_pass(git_repository_index(&index, repo));
	cl_assert(git_index_entrycount(index) == 0);

	/* Store the expected hash of the file/blob
	 * This has been generated by executing the following
	 * $ echo "hey there" | git hash-object --stdin
	 */
	cl_git_pass(git_oid_fromstr(&id1, "a8233120f6ad708f843d861ce2b7228ec4e3dec6"));

	/* Add the new file to the index */
	memset(&entry, 0x0, sizeof(git_index_entry));
	entry.mode = GIT_FILEMODE_BLOB;
	entry.path = "test.txt";
	cl_git_pass(git_index_add_frombuffer(index, &entry,
		content, strlen(content)));

	/* Wow... it worked! */
	cl_assert(git_index_entrycount(index) == 1);
	returned_entry = git_index_get_byindex(index, 0);

	/* And the built-in hashing mechanism worked as expected */
	cl_assert_equal_oid(&id1, &returned_entry->id);
	/* And mode is the one asked */
	cl_assert_equal_i(GIT_FILEMODE_BLOB, returned_entry->mode);

	/* Test access by path instead of index */
	cl_assert((returned_entry = git_index_get_bypath(index, "test.txt", 0)) != NULL);
	cl_assert_equal_oid(&id1, &returned_entry->id);

	/* Test the blob is in the repository */
	cl_git_pass(git_blob_lookup(&blob, repo, &id1));
	cl_assert_equal_s(
		content, git_blob_rawcontent(blob));
	git_blob_free(blob);

	git_index_free(index);
	git_repository_free(repo);
}
示例#12
0
static void assert_note_equal(git_note *note, char *message, git_oid *note_oid) {
	git_blob *blob;

	cl_assert_equal_s(git_note_message(note), message);
	cl_assert_equal_oid(git_note_id(note), note_oid);

	cl_git_pass(git_blob_lookup(&blob, _repo, note_oid));
	cl_assert_equal_s(git_note_message(note), (const char *)git_blob_rawcontent(blob));

	git_blob_free(blob);
}
示例#13
0
文件: diff_file.c 项目: 0CV0/libgit2
static int diff_file_content_load_blob(git_diff_file_content *fc)
{
	int error = 0;
	git_odb_object *odb_obj = NULL;

	if (git_oid_iszero(&fc->file->oid))
		return 0;

	if (fc->file->mode == GIT_FILEMODE_COMMIT)
		return diff_file_content_commit_to_str(fc, false);

	/* if we don't know size, try to peek at object header first */
	if (!fc->file->size) {
		git_odb *odb;
		size_t len;
		git_otype type;

		if (!(error = git_repository_odb__weakptr(&odb, fc->repo))) {
			error = git_odb__read_header_or_object(
				&odb_obj, &len, &type, odb, &fc->file->oid);
			git_odb_free(odb);
		}
		if (error)
			return error;

		fc->file->size = len;
	}

	if (diff_file_content_binary_by_size(fc))
		return 0;

	if (odb_obj != NULL) {
		error = git_object__from_odb_object(
			(git_object **)&fc->blob, fc->repo, odb_obj, GIT_OBJ_BLOB);
		git_odb_object_free(odb_obj);
	} else {
		error = git_blob_lookup(
			(git_blob **)&fc->blob, fc->repo, &fc->file->oid);
	}

	if (!error) {
		fc->flags |= GIT_DIFF_FLAG__FREE_BLOB;
		fc->map.data = (void *)git_blob_rawcontent(fc->blob);
		fc->map.len  = (size_t)git_blob_rawsize(fc->blob);
	}

	return error;
}
示例#14
0
文件: filter.c 项目: 1336/libgit2
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);
	}
}
示例#15
0
文件: filter.c 项目: 1336/libgit2
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_free(&buf);
}
示例#16
0
文件: filter.c 项目: 1336/libgit2
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_free(&zeroed);

		git_blob_free(blob);
	}

	git_filter_list_free(fl);
	git_buf_free(&out);
	git_config_free(cfg);
}
示例#17
0
文件: ident.c 项目: AChep/libgit2
static void add_blob_and_filter(
	const char *data,
	git_filter_list *fl,
	const char *expected)
{
	git_oid id;
	git_blob *blob;
	git_buf out = { 0 };

	cl_git_mkfile("crlf/identtest", data);
	cl_git_pass(git_blob_create_fromworkdir(&id, g_repo, "identtest"));
	cl_git_pass(git_blob_lookup(&blob, g_repo, &id));

	cl_git_pass(git_filter_list_apply_to_blob(&out, fl, blob));

	cl_assert_equal_s(expected, out.ptr);

	git_blob_free(blob);
	git_buf_free(&out);
}
示例#18
0
文件: crlf.c 项目: Study-C/libgit2
static int has_cr_in_index(const git_filter_source *src)
{
	git_repository *repo = git_filter_source_repo(src);
	const char *path = git_filter_source_path(src);
	git_index *index;
	const git_index_entry *entry;
	git_blob *blob;
	const void *blobcontent;
	git_off_t blobsize;
	bool found_cr;

	if (!path)
		return false;

	if (git_repository_index__weakptr(&index, repo) < 0) {
		giterr_clear();
		return false;
	}

	if (!(entry = git_index_get_bypath(index, path, 0)) &&
		!(entry = git_index_get_bypath(index, path, 1)))
		return false;

	if (!S_ISREG(entry->mode)) /* don't crlf filter non-blobs */
		return true;

	if (git_blob_lookup(&blob, repo, &entry->id) < 0)
		return false;

	blobcontent = git_blob_rawcontent(blob);
	blobsize    = git_blob_rawsize(blob);
	if (!git__is_sizet(blobsize))
		blobsize = (size_t)-1;

	found_cr = (blobcontent != NULL &&
		blobsize > 0 &&
		memchr(blobcontent, '\r', (size_t)blobsize) != NULL);

	git_blob_free(blob);
	return found_cr;
}
示例#19
0
static int diff_file_content_load_blob(
	git_diff_file_content *fc,
	git_diff_options *opts)
{
	int error = 0;
	git_odb_object *odb_obj = NULL;

	if (git_oid_iszero(&fc->file->id))
		return 0;

	if (fc->file->mode == GIT_FILEMODE_COMMIT)
		return diff_file_content_commit_to_str(fc, false);

	/* if we don't know size, try to peek at object header first */
	if (!fc->file->size) {
		if ((error = git_diff_file__resolve_zero_size(
				fc->file, &odb_obj, fc->repo)) < 0)
			return error;
	}

	if ((opts->flags & GIT_DIFF_SHOW_BINARY) == 0 &&
		diff_file_content_binary_by_size(fc))
		return 0;

	if (odb_obj != NULL) {
		error = git_object__from_odb_object(
			(git_object **)&fc->blob, fc->repo, odb_obj, GIT_OBJECT_BLOB);
		git_odb_object_free(odb_obj);
	} else {
		error = git_blob_lookup(
			(git_blob **)&fc->blob, fc->repo, &fc->file->id);
	}

	if (!error) {
		fc->flags |= GIT_DIFF_FLAG__FREE_BLOB;
		fc->map.data = (void *)git_blob_rawcontent(fc->blob);
		fc->map.len  = (size_t)git_blob_rawsize(fc->blob);
	}

	return error;
}
示例#20
0
int configctl_git_commit(char *path)
{
	int rc;
	int git_status = -1;
	git_oid oid_blob;
	git_oid oid_tree;
	git_oid oid_commit;
	git_blob *blob;
	git_tree *tree_cmt;
	git_treebuilder *tree_bld;
	char *file;

	file = get_file(path);

#if 0
	// TODO: check if file is changed
	__debug("%s", file);
	git_diff_stats *stats;
	git_diff *diff;
	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
	opts.pathspec.strings = &file;
	opts.pathspec.count = 1;
	rc = git_diff_index_to_workdir(&diff, repo, NULL, &opts);
	if(rc)
		goto error;
	int diff_num = git_diff_num_deltas(diff);
	__debug("%d", diff_num);

	git_diff_get_stats(&stats, diff);
	int x = git_diff_stats_files_changed(stats);
	__debug("%d", x);

	git_diff_free(diff);
#endif

	rc = git_add(file);
	if (rc)
		goto error;

	rc = git_blob_create_fromworkdir(&oid_blob, repo, file);
	if (rc)
		goto error;

	rc = git_blob_lookup(&blob, repo, &oid_blob);
	if (rc)
		goto error;

	rc = git_treebuilder_new(&tree_bld, repo, NULL );
	if (0 == rc) {
		rc = git_treebuilder_insert(NULL, tree_bld, file, &oid_blob, GIT_FILEMODE_BLOB);
		if (!rc) {
			rc = git_treebuilder_write(&oid_tree, tree_bld);
			if (!rc) {
				rc = git_tree_lookup(&tree_cmt, repo, &oid_tree);
				if (0 == rc) {
					git_commit *commit;
					commit = get_last_commit();
					git_signature_now(&sign, sign_name, sign_email);
					rc = git_commit_create(&oid_commit, repo, "HEAD", sign, sign, NULL,
						commit_message, tree_cmt, 1, (const struct git_commit **) &commit);
					if (!rc) {
						git_status = 0;
						__debug("successful git commit");
					}
					git_tree_free( tree_cmt );
					git_commit_free(commit);
					git_signature_free(sign);
				}
			}
		}
		git_treebuilder_free(tree_bld);
	}
	git_blob_free( blob );

error:
	return git_status;
}
示例#21
0
int CRepositoryBrowser::ReadTreeRecursive(git_repository &repo, const git_tree * tree, CShadowFilesTree * treeroot)
{
	size_t count = git_tree_entrycount(tree);
	bool hasSubfolders = false;

	for (size_t i = 0; i < count; ++i)
	{
		const git_tree_entry *entry = git_tree_entry_byindex(tree, i);
		if (entry == NULL)
			continue;

		const int mode = git_tree_entry_filemode(entry);

		CString base = CUnicodeUtils::GetUnicode(git_tree_entry_name(entry), CP_UTF8);

		const git_oid *oid = git_tree_entry_id(entry);
		CShadowFilesTree * pNextTree = &treeroot->m_ShadowTree[base];
		pNextTree->m_sName = base;
		pNextTree->m_pParent = treeroot;
		pNextTree->m_hash = CGitHash((char *)oid->id);

		if (mode == GIT_FILEMODE_COMMIT)
			pNextTree->m_bSubmodule = true;
		else if (mode & S_IFDIR)
		{
			hasSubfolders = true;
			pNextTree->m_bFolder = true;
			pNextTree->m_bLoaded = false;

			TVINSERTSTRUCT tvinsert = {0};
			tvinsert.hParent = treeroot->m_hTree;
			tvinsert.hInsertAfter = TVI_SORT;
			tvinsert.itemex.mask = TVIF_DI_SETITEM | TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_STATE | TVIF_CHILDREN;
			tvinsert.itemex.pszText = base.GetBuffer(base.GetLength());
			tvinsert.itemex.cChildren = 1;
			tvinsert.itemex.lParam = (LPARAM)pNextTree;
			tvinsert.itemex.iImage = m_nIconFolder;
			tvinsert.itemex.iSelectedImage = m_nOpenIconFolder;
			pNextTree->m_hTree = m_RepoTree.InsertItem(&tvinsert);
			base.ReleaseBuffer();
		}
		else
		{
			if (mode == GIT_FILEMODE_BLOB_EXECUTABLE)
				pNextTree->m_bExecutable = true;
			if (mode == GIT_FILEMODE_LINK)
				pNextTree->m_bSymlink = true;
			CAutoBlob blob;
			git_blob_lookup(blob.GetPointer(), &repo, oid);
			if (!blob)
				continue;

			pNextTree->m_iSize = git_blob_rawsize(blob);
		}
	}

	if (!hasSubfolders)
	{
		TVITEM tvitem = { 0 };
		tvitem.hItem = treeroot->m_hTree;
		tvitem.mask = TVIF_CHILDREN;
		tvitem.cChildren = 0;
		m_RepoTree.SetItem(&tvitem);
	}

	return 0;
}
示例#22
0
QByteArray PmrWorkspace::headFileContents(const QString &pFileName)
{
    // Retrieve the contents of the given file name at the HEAD revision
    // Note: the below code is based on Repository::GetHeadBlob() from git-utils
    //       (see https://github.com/atom/git-utils)...

    git_reference *head;

    if (git_repository_head(&head, mGitRepository) != GIT_OK) {
        return {};
    }

    const git_oid *sha = git_reference_target(head);
    git_commit *commit;
    int commitStatus = git_commit_lookup(&commit, mGitRepository, sha);

    git_reference_free(head);

    if (commitStatus != GIT_OK) {
        return {};
    }

    git_tree *tree;
    int treeStatus = git_commit_tree(&tree, commit);

    git_commit_free(commit);

    if (treeStatus != GIT_OK) {
        return {};
    }

    git_tree_entry *treeEntry;

    if (git_tree_entry_bypath(&treeEntry, tree, pFileName.toUtf8().constData()) != GIT_OK) {
        git_tree_free(tree);

        return {};
    }

    git_blob *blob = nullptr;
    const git_oid *blobSha = git_tree_entry_id(treeEntry);

    if (   (blobSha != nullptr)
        && (git_blob_lookup(&blob, mGitRepository, blobSha) != GIT_OK)) {
        blob = nullptr;
    }

    git_tree_entry_free(treeEntry);
    git_tree_free(tree);

    if (blob == nullptr) {
        return {};
    }

    QByteArray res(static_cast<const char *>(git_blob_rawcontent(blob)),
                   int(git_blob_rawsize(blob)));

    git_blob_free(blob);

    return res;
}
示例#23
0
int git_attr_file__load(
	git_attr_file **out,
	git_repository *repo,
	git_attr_session *attr_session,
	git_attr_file_entry *entry,
	git_attr_file_source source,
	git_attr_file_parser parser)
{
	int error = 0;
	git_blob *blob = NULL;
	git_buf content = GIT_BUF_INIT;
	git_attr_file *file;
	struct stat st;
	bool nonexistent = false;

	*out = NULL;

	switch (source) {
	case GIT_ATTR_FILE__IN_MEMORY:
		/* in-memory attribute file doesn't need data */
		break;
	case GIT_ATTR_FILE__FROM_INDEX: {
		git_oid id;

		if ((error = attr_file_oid_from_index(&id, repo, entry->path)) < 0 ||
			(error = git_blob_lookup(&blob, repo, &id)) < 0)
			return error;

		/* Do not assume that data straight from the ODB is NULL-terminated;
		 * copy the contents of a file to a buffer to work on */
		git_buf_put(&content, git_blob_rawcontent(blob), git_blob_rawsize(blob));
		break;
	}
	case GIT_ATTR_FILE__FROM_FILE: {
		int fd = -1;

		/* For open or read errors, pretend that we got ENOTFOUND. */
		/* TODO: issue warning when warning API is available */

		if (p_stat(entry->fullpath, &st) < 0 ||
			S_ISDIR(st.st_mode) ||
			(fd = git_futils_open_ro(entry->fullpath)) < 0 ||
			(error = git_futils_readbuffer_fd(&content, fd, (size_t)st.st_size)) < 0)
			nonexistent = true;

		if (fd >= 0)
			p_close(fd);

		break;
	}
	default:
		giterr_set(GITERR_INVALID, "Unknown file source %d", source);
		return -1;
	}

	if ((error = git_attr_file__new(&file, entry, source)) < 0)
		goto cleanup;

	/* store the key of the attr_reader; don't bother with cache
	 * invalidation during the same attr reader session.
	 */
	if (attr_session)
		file->session_key = attr_session->key;

	if (parser && (error = parser(repo, file, git_buf_cstr(&content))) < 0) {
		git_attr_file__free(file);
		goto cleanup;
	}

	/* write cache breakers */
	if (nonexistent)
		file->nonexistent = 1;
	else if (source == GIT_ATTR_FILE__FROM_INDEX)
		git_oid_cpy(&file->cache_data.oid, git_blob_id(blob));
	else if (source == GIT_ATTR_FILE__FROM_FILE)
		git_futils_filestamp_set_from_stat(&file->cache_data.stamp, &st);
	/* else always cacheable */

	*out = file;

cleanup:
	git_blob_free(blob);
	git_buf_free(&content);

	return error;
}
示例#24
0
文件: general.c 项目: ileitch/meanie
int main (int argc, char** argv)
{
  // ### Opening the Repository

  // There are a couple of methods for opening a repository, this being the simplest.
  // There are also [methods][me] for specifying the index file and work tree locations, here
  // we are assuming they are in the normal places.
  //
  // [me]: http://libgit2.github.com/libgit2/#HEAD/group/repository
  git_repository *repo;
  if (argc > 1) {
    git_repository_open(&repo, argv[1]);
  } else {
    git_repository_open(&repo, "/opt/libgit2-test/.git");
  }

  // ### SHA-1 Value Conversions

  // For our first example, we will convert a 40 character hex value to the 20 byte raw SHA1 value.
  printf("*Hex to Raw*\n");
  char hex[] = "fd6e612585290339ea8bf39c692a7ff6a29cb7c3";

  // The `git_oid` is the structure that keeps the SHA value. We will use this throughout the example
  // for storing the value of the current SHA key we're working with.
  git_oid oid;
  git_oid_fromstr(&oid, hex);

  // Once we've converted the string into the oid value, we can get the raw value of the SHA.
  printf("Raw 20 bytes: [%.20s]\n", (&oid)->id);

  // Next we will convert the 20 byte raw SHA1 value to a human readable 40 char hex value.
  printf("\n*Raw to Hex*\n");
  char out[41];
  out[40] = '\0';

  // If you have a oid, you can easily get the hex value of the SHA as well.
  git_oid_fmt(out, &oid);
  printf("SHA hex string: %s\n", out);

  // ### Working with the Object Database
  // **libgit2** provides [direct access][odb] to the object database.
  // The object database is where the actual objects are stored in Git. For
  // working with raw objects, we'll need to get this structure from the
  // repository.
  // [odb]: http://libgit2.github.com/libgit2/#HEAD/group/odb
  git_odb *odb;
  git_repository_odb(&odb, repo);

  // #### Raw Object Reading

  printf("\n*Raw Object Read*\n");
  git_odb_object *obj;
  git_otype otype;
  const unsigned char *data;
  const char *str_type;
  int error;

  // We can read raw objects directly from the object database if we have the oid (SHA)
  // of the object.  This allows us to access objects without knowing thier type and inspect
  // the raw bytes unparsed.
  error = git_odb_read(&obj, odb, &oid);

  // A raw object only has three properties - the type (commit, blob, tree or tag), the size
  // of the raw data and the raw, unparsed data itself.  For a commit or tag, that raw data
  // is human readable plain ASCII text. For a blob it is just file contents, so it could be
  // text or binary data. For a tree it is a special binary format, so it's unlikely to be
  // hugely helpful as a raw object.
  data = (const unsigned char *)git_odb_object_data(obj);
  otype = git_odb_object_type(obj);

  // We provide methods to convert from the object type which is an enum, to a string
  // representation of that value (and vice-versa).
  str_type = git_object_type2string(otype);
  printf("object length and type: %d, %s\n",
      (int)git_odb_object_size(obj),
      str_type);

  // For proper memory management, close the object when you are done with it or it will leak
  // memory.
  git_odb_object_free(obj);

  // #### Raw Object Writing

  printf("\n*Raw Object Write*\n");

  // You can also write raw object data to Git. This is pretty cool because it gives you
  // direct access to the key/value properties of Git.  Here we'll write a new blob object
  // that just contains a simple string.  Notice that we have to specify the object type as
  // the `git_otype` enum.
  git_odb_write(&oid, odb, "test data", sizeof("test data") - 1, GIT_OBJ_BLOB);

  // Now that we've written the object, we can check out what SHA1 was generated when the
  // object was written to our database.
  git_oid_fmt(out, &oid);
  printf("Written Object: %s\n", out);

  // ### Object Parsing
  // libgit2 has methods to parse every object type in Git so you don't have to work directly
  // with the raw data. This is much faster and simpler than trying to deal with the raw data
  // yourself.

  // #### Commit Parsing
  // [Parsing commit objects][pco] is simple and gives you access to all the data in the commit
  // - the // author (name, email, datetime), committer (same), tree, message, encoding and parent(s).
  // [pco]: http://libgit2.github.com/libgit2/#HEAD/group/commit

  printf("\n*Commit Parsing*\n");

  git_commit *commit;
  git_oid_fromstr(&oid, "f0877d0b841d75172ec404fc9370173dfffc20d1");

  error = git_commit_lookup(&commit, repo, &oid);

  const git_signature *author, *cmtter;
  const char *message;
  time_t ctime;
  unsigned int parents, p;

  // Each of the properties of the commit object are accessible via methods, including commonly
  // needed variations, such as `git_commit_time` which returns the author time and `_message`
  // which gives you the commit message.
  message  = git_commit_message(commit);
  author   = git_commit_author(commit);
  cmtter   = git_commit_committer(commit);
  ctime    = git_commit_time(commit);

  // The author and committer methods return [git_signature] structures, which give you name, email
  // and `when`, which is a `git_time` structure, giving you a timestamp and timezone offset.
  printf("Author: %s (%s)\n", author->name, author->email);

  // Commits can have zero or more parents. The first (root) commit will have no parents, most commits
  // will have one, which is the commit it was based on, and merge commits will have two or more.
  // Commits can technically have any number, though it's pretty rare to have more than two.
  parents  = git_commit_parentcount(commit);
  for (p = 0;p < parents;p++) {
    git_commit *parent;
    git_commit_parent(&parent, commit, p);
    git_oid_fmt(out, git_commit_id(parent));
    printf("Parent: %s\n", out);
    git_commit_free(parent);
  }

  // Don't forget to close the object to prevent memory leaks. You will have to do this for
  // all the objects you open and parse.
  git_commit_free(commit);

  // #### Writing Commits
  //
  // libgit2 provides a couple of methods to create commit objects easily as well. There are four
  // different create signatures, we'll just show one of them here.  You can read about the other
  // ones in the [commit API docs][cd].
  // [cd]: http://libgit2.github.com/libgit2/#HEAD/group/commit

  printf("\n*Commit Writing*\n");
  git_oid tree_id, parent_id, commit_id;
  git_tree *tree;
  git_commit *parent;

  // Creating signatures for an authoring identity and time is pretty simple - you will need to have
  // this to create a commit in order to specify who created it and when.  Default values for the name
  // and email should be found in the `user.name` and `user.email` configuration options.  See the `config`
  // section of this example file to see how to access config values.
  git_signature_new((git_signature **)&author, "Scott Chacon", "*****@*****.**",
      123456789, 60);
  git_signature_new((git_signature **)&cmtter, "Scott A Chacon", "*****@*****.**",
      987654321, 90);

  // Commit objects need a tree to point to and optionally one or more parents.  Here we're creating oid
  // objects to create the commit with, but you can also use
  git_oid_fromstr(&tree_id, "28873d96b4e8f4e33ea30f4c682fd325f7ba56ac");
  git_tree_lookup(&tree, repo, &tree_id);
  git_oid_fromstr(&parent_id, "f0877d0b841d75172ec404fc9370173dfffc20d1");
  git_commit_lookup(&parent, repo, &parent_id);

  // Here we actually create the commit object with a single call with all the values we need to create
  // the commit.  The SHA key is written to the `commit_id` variable here.
  git_commit_create_v(
    &commit_id, /* out id */
    repo,
    NULL, /* do not update the HEAD */
    author,
    cmtter,
    NULL, /* use default message encoding */
    "example commit",
    tree,
    1, parent);

  // Now we can take a look at the commit SHA we've generated.
  git_oid_fmt(out, &commit_id);
  printf("New Commit: %s\n", out);

  // #### Tag Parsing
  // You can parse and create tags with the [tag management API][tm], which functions very similarly
  // to the commit lookup, parsing and creation methods, since the objects themselves are very similar.
  // [tm]: http://libgit2.github.com/libgit2/#HEAD/group/tag
  printf("\n*Tag Parsing*\n");
  git_tag *tag;
  const char *tmessage, *tname;
  git_otype ttype;

  // We create an oid for the tag object if we know the SHA and look it up in the repository the same
  // way that we would a commit (or any other) object.
  git_oid_fromstr(&oid, "bc422d45275aca289c51d79830b45cecebff7c3a");

  error = git_tag_lookup(&tag, repo, &oid);

  // Now that we have the tag object, we can extract the information it generally contains: the target
  // (usually a commit object), the type of the target object (usually 'commit'), the name ('v1.0'),
  // the tagger (a git_signature - name, email, timestamp), and the tag message.
  git_tag_target((git_object **)&commit, tag);
  tname = git_tag_name(tag);    // "test"
  ttype = git_tag_type(tag);    // GIT_OBJ_COMMIT (otype enum)
  tmessage = git_tag_message(tag); // "tag message\n"
  printf("Tag Message: %s\n", tmessage);

  git_commit_free(commit);

  // #### Tree Parsing
  // [Tree parsing][tp] is a bit different than the other objects, in that we have a subtype which is the
  // tree entry.  This is not an actual object type in Git, but a useful structure for parsing and
  // traversing tree entries.
  //
  // [tp]: http://libgit2.github.com/libgit2/#HEAD/group/tree
  printf("\n*Tree Parsing*\n");

  const git_tree_entry *entry;
  git_object *objt;

  // Create the oid and lookup the tree object just like the other objects.
  git_oid_fromstr(&oid, "2a741c18ac5ff082a7caaec6e74db3075a1906b5");
  git_tree_lookup(&tree, repo, &oid);

  // Getting the count of entries in the tree so you can iterate over them if you want to.
  int cnt = git_tree_entrycount(tree); // 3
  printf("tree entries: %d\n", cnt);

  entry = git_tree_entry_byindex(tree, 0);
  printf("Entry name: %s\n", git_tree_entry_name(entry)); // "hello.c"

  // You can also access tree entries by name if you know the name of the entry you're looking for.
  entry = git_tree_entry_byname(tree, "hello.c");
  git_tree_entry_name(entry); // "hello.c"

  // Once you have the entry object, you can access the content or subtree (or commit, in the case
  // of submodules) that it points to.  You can also get the mode if you want.
  git_tree_entry_to_object(&objt, repo, entry); // blob

  // Remember to close the looked-up object once you are done using it
  git_object_free(objt);

  // #### Blob Parsing
  //
  // The last object type is the simplest and requires the least parsing help. Blobs are just file
  // contents and can contain anything, there is no structure to it. The main advantage to using the
  // [simple blob api][ba] is that when you're creating blobs you don't have to calculate the size
  // of the content.  There is also a helper for reading a file from disk and writing it to the db and
  // getting the oid back so you don't have to do all those steps yourself.
  //
  // [ba]: http://libgit2.github.com/libgit2/#HEAD/group/blob

  printf("\n*Blob Parsing*\n");
  git_blob *blob;

  git_oid_fromstr(&oid, "af7574ea73f7b166f869ef1a39be126d9a186ae0");
  git_blob_lookup(&blob, repo, &oid);

  // You can access a buffer with the raw contents of the blob directly.
  // Note that this buffer may not be contain ASCII data for certain blobs (e.g. binary files):
  // do not consider the buffer a NULL-terminated string, and use the `git_blob_rawsize` attribute to
  // find out its exact size in bytes
  printf("Blob Size: %ld\n", git_blob_rawsize(blob)); // 8
  git_blob_rawcontent(blob); // "content"

  // ### Revwalking
  //
  // The libgit2 [revision walking api][rw] provides methods to traverse the directed graph created
  // by the parent pointers of the commit objects.  Since all commits point back to the commit that
  // came directly before them, you can walk this parentage as a graph and find all the commits that
  // were ancestors of (reachable from) a given starting point.  This can allow you to create `git log`
  // type functionality.
  //
  // [rw]: http://libgit2.github.com/libgit2/#HEAD/group/revwalk

  printf("\n*Revwalking*\n");
  git_revwalk *walk;
  git_commit *wcommit;

  git_oid_fromstr(&oid, "f0877d0b841d75172ec404fc9370173dfffc20d1");

  // To use the revwalker, create a new walker, tell it how you want to sort the output and then push
  // one or more starting points onto the walker.  If you want to emulate the output of `git log` you
  // would push the SHA of the commit that HEAD points to into the walker and then start traversing them.
  // You can also 'hide' commits that you want to stop at or not see any of their ancestors.  So if you
  // want to emulate `git log branch1..branch2`, you would push the oid of `branch2` and hide the oid
  // of `branch1`.
  git_revwalk_new(&walk, repo);
  git_revwalk_sorting(walk, GIT_SORT_TOPOLOGICAL | GIT_SORT_REVERSE);
  git_revwalk_push(walk, &oid);

  const git_signature *cauth;
  const char *cmsg;

  // Now that we have the starting point pushed onto the walker, we can start asking for ancestors. It
  // will return them in the sorting order we asked for as commit oids.
  // We can then lookup and parse the commited pointed at by the returned OID;
  // note that this operation is specially fast since the raw contents of the commit object will
  // be cached in memory
  while ((git_revwalk_next(&oid, walk)) == 0) {
    error = git_commit_lookup(&wcommit, repo, &oid);
    cmsg  = git_commit_message(wcommit);
    cauth = git_commit_author(wcommit);
    printf("%s (%s)\n", cmsg, cauth->email);
    git_commit_free(wcommit);
  }

  // Like the other objects, be sure to free the revwalker when you're done to prevent memory leaks.
  // Also, make sure that the repository being walked it not deallocated while the walk is in
  // progress, or it will result in undefined behavior
  git_revwalk_free(walk);

  // ### Index File Manipulation
  //
  // The [index file API][gi] allows you to read, traverse, update and write the Git index file
  // (sometimes thought of as the staging area).
  //
  // [gi]: http://libgit2.github.com/libgit2/#HEAD/group/index

  printf("\n*Index Walking*\n");

  git_index *index;
  unsigned int i, ecount;

  // You can either open the index from the standard location in an open repository, as we're doing
  // here, or you can open and manipulate any index file with `git_index_open_bare()`. The index
  // for the repository will be located and loaded from disk.
  git_repository_index(&index, repo);

  // For each entry in the index, you can get a bunch of information including the SHA (oid), path
  // and mode which map to the tree objects that are written out.  It also has filesystem properties
  // to help determine what to inspect for changes (ctime, mtime, dev, ino, uid, gid, file_size and flags)
  // All these properties are exported publicly in the `git_index_entry` struct
  ecount = git_index_entrycount(index);
  for (i = 0; i < ecount; ++i) {
    git_index_entry *e = git_index_get(index, i);

    printf("path: %s\n", e->path);
    printf("mtime: %d\n", (int)e->mtime.seconds);
    printf("fs: %d\n", (int)e->file_size);
  }

  git_index_free(index);

  // ### References
  //
  // The [reference API][ref] allows you to list, resolve, create and update references such as
  // branches, tags and remote references (everything in the .git/refs directory).
  //
  // [ref]: http://libgit2.github.com/libgit2/#HEAD/group/reference

  printf("\n*Reference Listing*\n");

  // Here we will implement something like `git for-each-ref` simply listing out all available
  // references and the object SHA they resolve to.
  git_strarray ref_list;
  git_reference_list(&ref_list, repo, GIT_REF_LISTALL);

  const char *refname;
  git_reference *ref;

  // Now that we have the list of reference names, we can lookup each ref one at a time and
  // resolve them to the SHA, then print both values out.
  for (i = 0; i < ref_list.count; ++i) {
    refname = ref_list.strings[i];
    git_reference_lookup(&ref, repo, refname);

    switch (git_reference_type(ref)) {
    case GIT_REF_OID:
      git_oid_fmt(out, git_reference_oid(ref));
      printf("%s [%s]\n", refname, out);
      break;

    case GIT_REF_SYMBOLIC:
      printf("%s => %s\n", refname, git_reference_target(ref));
      break;
    default:
      fprintf(stderr, "Unexpected reference type\n");
      exit(1);
    }
  }

  git_strarray_free(&ref_list);

  // ### Config Files
  //
  // The [config API][config] allows you to list and updatee config values in
  // any of the accessible config file locations (system, global, local).
  //
  // [config]: http://libgit2.github.com/libgit2/#HEAD/group/config

  printf("\n*Config Listing*\n");

  const char *email;
  int32_t j;

  git_config *cfg;

  // Open a config object so we can read global values from it.
  git_config_open_ondisk(&cfg, "~/.gitconfig");

  git_config_get_int32(cfg, "help.autocorrect", &j);
  printf("Autocorrect: %d\n", j);

  git_config_get_string(cfg, "user.email", &email);
  printf("Email: %s\n", email);

  // Finally, when you're done with the repository, you can free it as well.
  git_repository_free(repo);

  return 0;
}
示例#25
0
int git_attr_file__load(
	git_attr_file **out,
	git_repository *repo,
	git_attr_file_entry *entry,
	git_attr_file_source source,
	git_attr_file_parser parser)
{
	int error = 0;
	git_blob *blob = NULL;
	git_buf content = GIT_BUF_INIT;
	const char *data = NULL;
	git_attr_file *file;
	struct stat st;

	*out = NULL;

	switch (source) {
	case GIT_ATTR_FILE__IN_MEMORY:
		/* in-memory attribute file doesn't need data */
		break;
	case GIT_ATTR_FILE__FROM_INDEX: {
		git_oid id;

		if ((error = attr_file_oid_from_index(&id, repo, entry->path)) < 0 ||
			(error = git_blob_lookup(&blob, repo, &id)) < 0)
			return error;

		data = git_blob_rawcontent(blob);
		break;
	}
	case GIT_ATTR_FILE__FROM_FILE: {
		int fd;

		if (p_stat(entry->fullpath, &st) < 0)
			return git_path_set_error(errno, entry->fullpath, "stat");
		if (S_ISDIR(st.st_mode))
			return GIT_ENOTFOUND;

		/* For open or read errors, return ENOTFOUND to skip item */
		/* TODO: issue warning when warning API is available */

		if ((fd = git_futils_open_ro(entry->fullpath)) < 0)
			return GIT_ENOTFOUND;

		error = git_futils_readbuffer_fd(&content, fd, (size_t)st.st_size);
		p_close(fd);

		if (error < 0)
			return GIT_ENOTFOUND;

		data = content.ptr;
		break;
	}
	default:
		giterr_set(GITERR_INVALID, "Unknown file source %d", source);
		return -1;
	}

	if ((error = git_attr_file__new(&file, entry, source)) < 0)
		goto cleanup;

	if (parser && (error = parser(repo, file, data)) < 0) {
		git_attr_file__free(file);
		goto cleanup;
	}

	/* write cache breaker */
	if (source == GIT_ATTR_FILE__FROM_INDEX)
		git_oid_cpy(&file->cache_data.oid, git_blob_id(blob));
	else if (source == GIT_ATTR_FILE__FROM_FILE)
		git_futils_filestamp_set_from_stat(&file->cache_data.stamp, &st);
	/* else always cacheable */

	*out = file;

cleanup:
	git_blob_free(blob);
	git_buf_free(&content);

	return error;
}
示例#26
0
文件: crlf.c 项目: 1336/libgit2
void test_checkout_crlf__with_ident(void)
{
	git_index *index;
	git_blob *blob;
	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
	opts.checkout_strategy = GIT_CHECKOUT_FORCE;

	cl_git_mkfile("crlf/.gitattributes",
		"*.txt text\n*.bin binary\n"
		"*.crlf text eol=crlf\n"
		"*.lf text eol=lf\n"
		"*.ident text ident\n"
		"*.identcrlf ident text eol=crlf\n"
		"*.identlf ident text eol=lf\n");

	cl_repo_set_bool(g_repo, "core.autocrlf", true);

	/* add files with $Id$ */

	cl_git_mkfile("crlf/lf.ident", ALL_LF_TEXT_RAW "\n$Id: initial content$\n");
	cl_git_mkfile("crlf/crlf.ident", ALL_CRLF_TEXT_RAW "\r\n$Id$\r\n\r\n");
	cl_git_mkfile("crlf/more1.identlf", "$Id$\n" MORE_LF_TEXT_RAW);
	cl_git_mkfile("crlf/more2.identcrlf", "\r\n$Id: $\r\n" MORE_CRLF_TEXT_RAW);

	cl_git_pass(git_repository_index(&index, g_repo));
	cl_git_pass(git_index_add_bypath(index, "lf.ident"));
	cl_git_pass(git_index_add_bypath(index, "crlf.ident"));
	cl_git_pass(git_index_add_bypath(index, "more1.identlf"));
	cl_git_pass(git_index_add_bypath(index, "more2.identcrlf"));
	cl_repo_commit_from_index(NULL, g_repo, NULL, 0, "Some ident files\n");

	git_checkout_head(g_repo, &opts);

	/* check that blobs have $Id$ */

	cl_git_pass(git_blob_lookup(&blob, g_repo,
		& git_index_get_bypath(index, "lf.ident", 0)->id));
	cl_assert_equal_s(
		ALL_LF_TEXT_RAW "\n$Id$\n", git_blob_rawcontent(blob));
	git_blob_free(blob);

	cl_git_pass(git_blob_lookup(&blob, g_repo,
		& git_index_get_bypath(index, "more2.identcrlf", 0)->id));
	cl_assert_equal_s(
		"\n$Id$\n" MORE_CRLF_TEXT_AS_LF, git_blob_rawcontent(blob));
	git_blob_free(blob);

	/* check that filesystem is initially untouched - matching core Git */

	cl_assert_equal_file(
		ALL_LF_TEXT_RAW "\n$Id: initial content$\n", 0, "crlf/lf.ident");

	/* check that forced checkout rewrites correctly */

	p_unlink("crlf/lf.ident");
	p_unlink("crlf/crlf.ident");
	p_unlink("crlf/more1.identlf");
	p_unlink("crlf/more2.identcrlf");

	git_checkout_head(g_repo, &opts);

	if (GIT_EOL_NATIVE == GIT_EOL_LF) {
		cl_assert_equal_file(
			ALL_LF_TEXT_RAW
			"\n$Id: fcf6d4d9c212dc66563b1171b1cd99953c756467 $\n",
			0, "crlf/lf.ident");
		cl_assert_equal_file(
			ALL_CRLF_TEXT_AS_LF
			"\n$Id: f2c66ad9b2b5a734d9bf00d5000cc10a62b8a857 $\n\n",
			0, "crlf/crlf.ident");
	} else {
		cl_assert_equal_file(
			ALL_LF_TEXT_AS_CRLF
			"\r\n$Id: fcf6d4d9c212dc66563b1171b1cd99953c756467 $\r\n",
			0, "crlf/lf.ident");
		cl_assert_equal_file(
			ALL_CRLF_TEXT_RAW
			"\r\n$Id: f2c66ad9b2b5a734d9bf00d5000cc10a62b8a857 $\r\n\r\n",
			0, "crlf/crlf.ident");
	}

	cl_assert_equal_file(
		"$Id: f7830382dac1f1583422be5530fdfbd26289431b $\n"
		MORE_LF_TEXT_AS_LF, 0, "crlf/more1.identlf");

	cl_assert_equal_file(
		"\r\n$Id: 74677a68413012ce8d7e7cfc3f12603df3a3eac4 $\r\n"
		MORE_CRLF_TEXT_AS_CRLF, 0, "crlf/more2.identcrlf");

	git_index_free(index);
}