Exemple #1
0
static int reference__rename(git_reference **out, git_reference *ref, const char *new_name, int force,
				 const git_signature *signature, const char *message)
{
	git_refname_t normalized;
	bool should_head_be_updated = false;
	int error = 0;

	assert(ref && new_name && signature);

	if ((error = reference_normalize_for_repo(
			normalized, git_reference_owner(ref), new_name)) < 0)
		return error;


	/* Check if we have to update HEAD. */
	if ((error = git_branch_is_head(ref)) < 0)
		return error;

	should_head_be_updated = (error > 0);

	if ((error = git_refdb_rename(out, ref->db, ref->name, normalized, force, signature, message)) < 0)
		return error;

	/* Update HEAD it was pointing to the reference being renamed */
	if (should_head_be_updated &&
		(error = git_repository_set_head(ref->db->repo, normalized)) < 0) {
		giterr_set(GITERR_REFERENCE, "Failed to update HEAD after renaming reference");
		return error;
	}

	return 0;
}
Exemple #2
0
int git_reference_lookup_resolved(
	git_reference **ref_out,
	git_repository *repo,
	const char *name,
	int max_nesting)
{
	char scan_name[GIT_REFNAME_MAX];
	git_ref_t scan_type;
	int error = 0, nesting;
	git_reference *ref = NULL;
	git_refdb *refdb;

	assert(ref_out && repo && name);

	*ref_out = NULL;

	if (max_nesting > MAX_NESTING_LEVEL)
		max_nesting = MAX_NESTING_LEVEL;
	else if (max_nesting < 0)
		max_nesting = DEFAULT_NESTING_LEVEL;

	scan_type = GIT_REF_SYMBOLIC;

	if ((error = reference_normalize_for_repo(
			scan_name, sizeof(scan_name), repo, name)) < 0)
		return error;

	if ((error = git_repository_refdb__weakptr(&refdb, repo)) < 0)
		return error;

	for (nesting = max_nesting;
		 nesting >= 0 && scan_type == GIT_REF_SYMBOLIC;
		 nesting--)
	{
		if (nesting != max_nesting) {
			strncpy(scan_name, ref->target.symbolic, sizeof(scan_name));
			git_reference_free(ref);
		}

		if ((error = git_refdb_lookup(&ref, refdb, scan_name)) < 0)
			return error;

		scan_type = ref->type;
	}

	if (scan_type != GIT_REF_OID && max_nesting != 0) {
		giterr_set(GITERR_REFERENCE,
			"Cannot resolve reference (>%u levels deep)", max_nesting);
		git_reference_free(ref);
		return -1;
	}

	*ref_out = ref;
	return 0;
}
Exemple #3
0
static int reference__rename(git_reference **out, git_reference *ref, const char *new_name, int force,
				 const git_signature *signature, const char *message)
{
	git_repository *repo;
	git_refname_t normalized;
	bool should_head_be_updated = false;
	int error = 0;

	assert(ref && new_name && signature);

	repo = git_reference_owner(ref);

	if ((error = reference_normalize_for_repo(
		normalized, repo, new_name, true)) < 0)
		return error;

	/* Check if we have to update HEAD. */
	if ((error = git_branch_is_head(ref)) < 0)
		return error;

	should_head_be_updated = (error > 0);

	if ((error = git_refdb_rename(out, ref->db, ref->name, normalized, force, signature, message)) < 0)
		return error;

	/* Update HEAD if it was pointing to the reference being renamed */
	if (should_head_be_updated) {
		error = git_repository_set_head(ref->db->repo, normalized);
	} else {
		rename_cb_data payload;
		payload.old_name = ref->name;
		memcpy(&payload.new_name, &normalized, sizeof(normalized));

		error = git_repository_foreach_head(repo, update_wt_heads, &payload);
	}

	return error;
}
Exemple #4
0
static int reference__create(
	git_reference **ref_out,
	git_repository *repo,
	const char *name,
	const git_oid *oid,
	const char *symbolic,
	int force,
	const git_signature *signature,
	const char *log_message,
	const git_oid *old_id,
	const char *old_target)
{
	git_refname_t normalized;
	git_refdb *refdb;
	git_reference *ref = NULL;
	int error = 0;

	assert(repo && name);
	assert(symbolic || signature);

	if (ref_out)
		*ref_out = NULL;

	error = reference_normalize_for_repo(normalized, repo, name);
	if (error < 0)
		return error;

	error = git_repository_refdb__weakptr(&refdb, repo);
	if (error < 0)
		return error;

	if (oid != NULL) {
		git_odb *odb;

		assert(symbolic == NULL);

		/* Sanity check the reference being created - target must exist. */
		if ((error = git_repository_odb__weakptr(&odb, repo)) < 0)
			return error;

		if (!git_odb_exists(odb, oid)) {
			giterr_set(GITERR_REFERENCE,
				"Target OID for the reference doesn't exist on the repository");
			return -1;
		}

		ref = git_reference__alloc(normalized, oid, NULL);
	} else {
		git_refname_t normalized_target;

		if ((error = reference_normalize_for_repo(normalized_target, repo, symbolic)) < 0)
			return error;

		ref = git_reference__alloc_symbolic(normalized, normalized_target);
	}

	GITERR_CHECK_ALLOC(ref);

	if ((error = git_refdb_write(refdb, ref, force, signature, log_message, old_id, old_target)) < 0) {
		git_reference_free(ref);
		return error;
	}

	if (ref_out == NULL)
		git_reference_free(ref);
	else
		*ref_out = ref;

	return 0;
}
Exemple #5
0
static int reference__create(
	git_reference **ref_out,
	git_repository *repo,
	const char *name,
	const git_oid *oid,
	const char *symbolic,
	int force,
	const git_signature *signature,
	const char *log_message,
	const git_oid *old_id,
	const char *old_target)
{
	git_refname_t normalized;
	git_refdb *refdb;
	git_reference *ref = NULL;
	int error = 0;

	assert(repo && name);
	assert(symbolic || signature);

	if (ref_out)
		*ref_out = NULL;

	error = reference_normalize_for_repo(normalized, repo, name, true);
	if (error < 0)
		return error;

	error = git_repository_refdb__weakptr(&refdb, repo);
	if (error < 0)
		return error;

	if (oid != NULL) {
		assert(symbolic == NULL);

		if (!git_object__is_valid(repo, oid, GIT_OBJ_ANY)) {
			giterr_set(GITERR_REFERENCE,
				"target OID for the reference doesn't exist on the repository");
			return -1;
		}

		ref = git_reference__alloc(normalized, oid, NULL);
	} else {
		git_refname_t normalized_target;

		error = reference_normalize_for_repo(normalized_target, repo,
			symbolic, git_reference__enable_symbolic_ref_target_validation);

		if (error < 0)
			return error;

		ref = git_reference__alloc_symbolic(normalized, normalized_target);
	}

	GITERR_CHECK_ALLOC(ref);

	if ((error = git_refdb_write(refdb, ref, force, signature, log_message, old_id, old_target)) < 0) {
		git_reference_free(ref);
		return error;
	}

	if (ref_out == NULL)
		git_reference_free(ref);
	else
		*ref_out = ref;

	return 0;
}