Git-Raw

 view release on metacpan or  search on metacpan

xs/Repository.xs  view on Meta::CPAN


			if (entry -> status & GIT_STATUS_WT_MODIFIED)
				av_push(flags, newSVpv("worktree_modified", 0));

			if (entry -> status & GIT_STATUS_WT_DELETED)
				av_push(flags, newSVpv("worktree_deleted", 0));

			if (entry -> status & GIT_STATUS_WT_RENAMED)
				av_push(flags, newSVpv("worktree_renamed", 0));

			if (entry -> status & GIT_STATUS_WT_UNREADABLE)
				av_push(flags, newSVpv("worktree_unreadable", 0));

			if (entry -> status & GIT_STATUS_IGNORED)
				av_push(flags, newSVpv("ignored", 0));

			if (entry -> status & GIT_STATUS_CONFLICTED)
				av_push(flags, newSVpv("conflicted", 0));

			file_status_hv = newHV();

			if (entry -> index_to_workdir) {
				if (entry -> status & GIT_STATUS_WT_RENAMED) {
					HV *worktree_status_hv = newHV();

					hv_stores(worktree_status_hv, "old_file",
						newSVpv(entry -> index_to_workdir -> old_file.path, 0));
					hv_stores(file_status_hv, "worktree", newRV_noinc((SV *) worktree_status_hv));
				}

				path = entry -> index_to_workdir -> new_file.path;
			}

			if (entry -> head_to_index) {
				if (entry -> status & GIT_STATUS_INDEX_RENAMED) {
					HV *index_status_hv = newHV();

					hv_stores(index_status_hv, "old_file",
						newSVpv(entry -> head_to_index -> old_file.path, 0));
					hv_stores(file_status_hv, "index", newRV_noinc((SV *) index_status_hv));
				}

				if (!path)
					path = entry -> head_to_index -> new_file.path;
			}

			hv_stores(file_status_hv, "flags", newRV_noinc((SV *) flags));
			hv_store(status_hv, path, strlen(path), newRV_noinc((SV *) file_status_hv), 0);
		}

		git_status_list_free(list);

		RETVAL = status_hv;

	OUTPUT: RETVAL

void
is_worktree(self)
	Repository self

	PPCODE:
		if (git_repository_is_worktree (self -> repository))
			XSRETURN_YES;

		XSRETURN_NO;

SV *
path_is_ignored(self, path)
	Repository self
	const char *path

	PREINIT:
		int rc, ignore;

	CODE:
		rc = git_ignore_path_is_ignored(&ignore, self -> repository, path);
		git_check_error(rc);

		RETVAL = newSViv(ignore);

	OUTPUT: RETVAL

void
ignore(self, rules)
	Repository self
	SV *rules

	PREINIT:
		int rc;

	CODE:
		rc = git_ignore_add_rule(self -> repository, git_ensure_pv(rules, "rules"));
		git_check_error(rc);

SV *
diff(self, ...)
	SV *self

	PROTOTYPE: $;$

	PREINIT:
		int rc;

		Repository repo_ptr;
		Diff diff;
		Index index;

		Tree tree = NULL;

		git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;

	CODE:
		repo_ptr = GIT_SV_TO_PTR(Repository, self);

		rc = git_repository_index(&index, repo_ptr -> repository);
		git_check_error(rc);

		if (items == 2) {
			HV *opts = git_ensure_hv(ST(1), "diff_opts");
			git_hv_to_diff_opts(opts, &diff_opts, &tree);
		}

xs/Repository.xs  view on Meta::CPAN

			av_push(result, newSVpv("fast_forward", 0));
		if (analysis & GIT_MERGE_ANALYSIS_UNBORN)
			av_push(result, newSVpv("unborn", 0));

		RETVAL = newRV_noinc((SV *) result);

	OUTPUT: RETVAL

void
merge(self, ref, ...)
	Repository self
	Reference ref

	PROTOTYPE: $$;$;$
	PREINIT:
		int rc;

		git_annotated_commit *merge_head;

		git_merge_options merge_opts = GIT_MERGE_OPTIONS_INIT;
		git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;

	CODE:
		rc = git_annotated_commit_from_ref(&merge_head, self -> repository, ref);
		git_check_error(rc);

		if (items >= 3) {
			HV *opts = git_ensure_hv(ST(2), "merge_opts");
			git_hv_to_merge_opts(opts, &merge_opts);
		}

		if (items >= 4) {
			HV *opts = git_ensure_hv(ST(3), "checkout_opts");
			git_hv_to_checkout_opts(opts, &checkout_opts);
		}

		rc = git_merge(
			self -> repository, (const git_annotated_commit **) &merge_head,
			1, &merge_opts, &checkout_opts
		);
		Safefree(checkout_opts.paths.strings);
		git_annotated_commit_free(merge_head);
		git_check_error(rc);

void
branches(self, ...)
	SV *self

	PROTOTYPE: $;$
	PREINIT:
		int rc;

		Branch branch;
		int num_branches = 0;

		git_branch_t type;
		git_branch_iterator *itr;

		Repository repo;

	PPCODE:
		type = GIT_BRANCH_ALL;

		if (items == 2) {
			const char *type_str = git_ensure_pv(ST(1), "type");

			if (strcmp(type_str, "local") == 0)
				type = GIT_BRANCH_LOCAL;
			else if (strcmp(type_str, "remote") == 0)
				type = GIT_BRANCH_REMOTE;
			else if (strcmp(type_str, "all") == 0)
				type = GIT_BRANCH_ALL;
			else
				croak_usage("Invalid branch type '%s'. ",
					"Valid values: 'local', 'remote' or 'all'",
					type_str);
		}

		repo = GIT_SV_TO_PTR(Repository, self);

		rc = git_branch_iterator_new(&itr, repo -> repository, type);
		git_check_error(rc);

		while ((rc = git_branch_next(&branch, &type, itr)) == 0) {
			SV *perl_ref;

			GIT_NEW_OBJ_WITH_MAGIC(
				perl_ref, "Git::Raw::Branch", branch, SvRV(self)
			);

			mXPUSHs(perl_ref);

			num_branches++;
		}

		git_branch_iterator_free(itr);
		git_check_error(rc);

		XSRETURN(num_branches);

void
remotes(self)
	SV *self

	PREINIT:
		int rc;
		size_t i;

		int num_remotes = 0;
		git_strarray remotes;

		Repository repo;

	PPCODE:
		repo = GIT_SV_TO_PTR(Repository, self);

		rc = git_remote_list(&remotes, repo -> repository);
		git_check_error(rc);

		for (i = 0; i < remotes.count; i++) {
			SV *perl_ref;
			git_remote *r = NULL;
			Remote remote = NULL;

			rc = git_remote_lookup(&r, repo -> repository, remotes.strings[i]);
			git_check_error(rc);

			Newxz(remote, 1, git_raw_remote);
			remote -> remote = r;

			GIT_NEW_OBJ_WITH_MAGIC(
				perl_ref, "Git::Raw::Remote", remote, SvRV(self)
			);

			mXPUSHs(perl_ref);

			num_remotes++;
		}

		git_strarray_free(&remotes);

		XSRETURN(num_remotes);

void
refs(self)
	SV *self

	PREINIT:
		int rc;

		Reference ref;
		int num_refs = 0;

		git_reference_iterator *itr;

		Repository repo = NULL;

	PPCODE:
		repo = GIT_SV_TO_PTR(Repository, self);
		rc = git_reference_iterator_new(&itr, repo -> repository);
		git_check_error(rc);

		while ((rc = git_reference_next(&ref, itr)) == 0) {
			SV *perl_ref;

			GIT_NEW_OBJ_WITH_MAGIC(
				perl_ref, "Git::Raw::Reference", ref, SvRV(self)
			);

			mXPUSHs(perl_ref);

			num_refs++;
		}

		git_reference_iterator_free(itr);
		git_check_error(rc);

		XSRETURN(num_refs);

SV *
path(self)
	Repository self

	PREINIT:
		const char *path;

	CODE:
		path = git_repository_path(self -> repository);
		RETVAL = newSVpv(path, 0);

	OUTPUT: RETVAL

SV *
workdir(self, ...)
	Repository self

	PROTOTYPE: $;$

	PREINIT:
		int rc;
		const char *path;

	CODE:
		if (items == 2) {
			const char *new_dir = git_ensure_pv(ST(1), "new_dir");

			rc = git_repository_set_workdir(self -> repository, new_dir, 1);
			git_check_error(rc);
		}

		path = git_repository_workdir(self -> repository);
		RETVAL = newSVpv(path, 0);

	OUTPUT: RETVAL

SV *
blame(self, file)
	SV *self

xs/Repository.xs  view on Meta::CPAN

			repo -> repository,
			commit,
			&opts
		);
		Safefree(opts.checkout_opts.paths.strings);
		git_check_error(rc);

void
revert(self, commit, ...)
	SV *self
	Commit commit

	PROTOTYPE: $$;$;$;$
	PREINIT:
		int rc;

		Repository repo = NULL;
		git_revert_options opts = GIT_REVERT_OPTIONS_INIT;

	CODE:
		if (items >= 3) {
			HV *hopts = git_ensure_hv(ST(2), "merge_opts");
			git_hv_to_merge_opts(hopts, &opts.merge_opts);
		}

		if (items >= 4) {
			HV *hopts = git_ensure_hv(ST(3), "checkout_opts");
			git_hv_to_checkout_opts(hopts, &opts.checkout_opts);
		}

		if (items >= 5) {
			unsigned int parents = git_commit_parentcount(commit);
			int mainline = git_ensure_iv(ST(4), "mainline");

			if (mainline < 0 || mainline > (int) git_commit_parentcount(commit) - 1)
				croak_usage("'mainline' out of range, should be between 0 and %d",
					(int) parents - 1);

			opts.mainline = (unsigned int) mainline;
		}

		repo = GIT_SV_TO_PTR(Repository, self);
		rc = git_revert(
			repo -> repository,
			commit,
			&opts
		);
		Safefree(opts.checkout_opts.paths.strings);
		git_check_error(rc);

void
revparse(self, spec)
	SV *self
	SV *spec

	PREINIT:
		int rc;
		int ctx, count = 0;
		git_revspec rs = {NULL, NULL, 0};

	PPCODE:
		ctx = GIMME_V;

		Repository repo = GIT_SV_TO_PTR(Repository, self);
		rc = git_revparse(&rs, repo -> repository,
			git_ensure_pv(spec, "spec"));
		git_check_error(rc);

		if (ctx != G_VOID) {
			if (ctx == G_ARRAY) {
				mXPUSHs(git_obj_to_sv(rs.from, SvRV(self)));
				if (rs.flags & GIT_REVPARSE_SINGLE) {
					count = 1;
				} else {
					mXPUSHs(git_obj_to_sv(rs.to, SvRV(self)));
					count = 2;
				}
			} else {
				if (rs.flags & GIT_REVPARSE_SINGLE)
					mXPUSHs(newSViv(1));
				else
					mXPUSHs(newSViv(2));

				count = 1;
			}
		}

		if (count == 0) {
			git_object_free(rs.from);
			git_object_free(rs.to);
			XSRETURN_EMPTY;
		}

		XSRETURN(count);

SV *
state(self)
	Repository self

	PREINIT:
		int rc;
		const char *s = NULL;

	CODE:
		rc = git_repository_state(self -> repository);

		switch (rc) {
			case GIT_REPOSITORY_STATE_NONE:
				s = "none";
				break;

			case GIT_REPOSITORY_STATE_MERGE:
				s = "merge";
				break;

			case GIT_REPOSITORY_STATE_REVERT:
				s = "revert";
				break;

			case GIT_REPOSITORY_STATE_CHERRYPICK:
				s = "cherry_pick";



( run in 0.670 second using v1.01-cache-2.11-cpan-5511b514fd6 )