예제 #1
0
int git_commit_create(
		git_oid *oid,
		git_repository *repo,
		const char *update_ref,
		const git_signature *author,
		const git_signature *committer,
		const char *message_encoding,
		const char *message,
		const git_tree *tree,
		int parent_count,
		const git_commit *parents[])
{
	git_buf commit = GIT_BUF_INIT;
	int i;
	git_odb *odb;

	assert(git_object_owner((const git_object *)tree) == repo);

	git_oid__writebuf(&commit, "tree ", git_object_id((const git_object *)tree));

	for (i = 0; i < parent_count; ++i) {
		assert(git_object_owner((const git_object *)parents[i]) == repo);
		git_oid__writebuf(&commit, "parent ", git_object_id((const git_object *)parents[i]));
	}

	git_signature__writebuf(&commit, "author ", author);
	git_signature__writebuf(&commit, "committer ", committer);

	if (message_encoding != NULL)
		git_buf_printf(&commit, "encoding %s\n", message_encoding);

	git_buf_putc(&commit, '\n');

	if (git_buf_puts(&commit, message) < 0)
		goto on_error;

	if (git_repository_odb__weakptr(&odb, repo) < 0)
		goto on_error;

	if (git_odb_write(oid, odb, commit.ptr, commit.size, GIT_OBJ_COMMIT) < 0)
		goto on_error;

	git_buf_free(&commit);

	if (update_ref != NULL)
		return git_reference__update(repo, oid, update_ref);

	return 0;

on_error:
	git_buf_free(&commit);
	giterr_set(GITERR_OBJECT, "Failed to create commit.");
	return -1;
}
예제 #2
0
파일: tag.c 프로젝트: yuanms2/libgit2
static int write_tag_annotation(
    git_oid *oid,
    git_repository *repo,
    const char *tag_name,
    const git_object *target,
    const git_signature *tagger,
    const char *message)
{
    git_buf tag = GIT_BUF_INIT;
    git_odb *odb;

    git_oid__writebuf(&tag, "object ", git_object_id(target));
    git_buf_printf(&tag, "type %s\n", git_object_type2string(git_object_type(target)));
    git_buf_printf(&tag, "tag %s\n", tag_name);
    git_signature__writebuf(&tag, "tagger ", tagger);
    git_buf_putc(&tag, '\n');

    if (git_buf_puts(&tag, message) < 0)
        goto on_error;

    if (git_repository_odb__weakptr(&odb, repo) < 0)
        goto on_error;

    if (git_odb_write(oid, odb, tag.ptr, tag.size, GIT_OBJ_TAG) < 0)
        goto on_error;

    git_buf_free(&tag);
    return 0;

on_error:
    git_buf_free(&tag);
    giterr_set(GITERR_OBJECT, "Failed to create tag annotation.");
    return -1;
}
예제 #3
0
static int git_commit__create_buffer_internal(
	git_buf *out,
	const git_signature *author,
	const git_signature *committer,
	const char *message_encoding,
	const char *message,
	const git_oid *tree,
	git_array_oid_t *parents)
{
	size_t i = 0;
	const git_oid *parent;

	assert(out && tree);

	git_oid__writebuf(out, "tree ", tree);

	for (i = 0; i < git_array_size(*parents); i++) {
		parent = git_array_get(*parents, i);
		git_oid__writebuf(out, "parent ", parent);
	}

	git_signature__writebuf(out, "author ", author);
	git_signature__writebuf(out, "committer ", committer);

	if (message_encoding != NULL)
		git_buf_printf(out, "encoding %s\n", message_encoding);

	git_buf_putc(out, '\n');

	if (git_buf_puts(out, message) < 0)
		goto on_error;

	return 0;

on_error:
	git_buf_dispose(out);
	return -1;
}
예제 #4
0
파일: commit.c 프로젝트: Factoid/sonic-pi
static int git_commit__create_internal(
    git_oid *id,
    git_repository *repo,
    const char *update_ref,
    const git_signature *author,
    const git_signature *committer,
    const char *message_encoding,
    const char *message,
    const git_oid *tree,
    git_commit_parent_callback parent_cb,
    void *parent_payload,
    bool validate)
{
    git_reference *ref = NULL;
    int error = 0, matched_parent = 0;
    const git_oid *current_id = NULL;
    git_buf commit = GIT_BUF_INIT;
    size_t i = 0;
    git_odb *odb;
    const git_oid *parent;

    assert(id && repo && tree && parent_cb);

    if (validate && !git_object__is_valid(repo, tree, GIT_OBJ_TREE))
        return -1;

    if (update_ref) {
        error = git_reference_lookup_resolved(&ref, repo, update_ref, 10);
        if (error < 0 && error != GIT_ENOTFOUND)
            return error;
    }
    giterr_clear();

    if (ref)
        current_id = git_reference_target(ref);

    git_oid__writebuf(&commit, "tree ", tree);

    while ((parent = parent_cb(i, parent_payload)) != NULL) {
        if (validate && !git_object__is_valid(repo, parent, GIT_OBJ_COMMIT)) {
            error = -1;
            goto on_error;
        }

        git_oid__writebuf(&commit, "parent ", parent);
        if (i == 0 && current_id && git_oid_equal(current_id, parent))
            matched_parent = 1;
        i++;
    }

    if (ref && !matched_parent) {
        git_reference_free(ref);
        git_buf_free(&commit);
        giterr_set(GITERR_OBJECT, "failed to create commit: current tip is not the first parent");
        return GIT_EMODIFIED;
    }

    git_signature__writebuf(&commit, "author ", author);
    git_signature__writebuf(&commit, "committer ", committer);

    if (message_encoding != NULL)
        git_buf_printf(&commit, "encoding %s\n", message_encoding);

    git_buf_putc(&commit, '\n');

    if (git_buf_puts(&commit, message) < 0)
        goto on_error;

    if (git_repository_odb__weakptr(&odb, repo) < 0)
        goto on_error;

    if (git_odb_write(id, odb, commit.ptr, commit.size, GIT_OBJ_COMMIT) < 0)
        goto on_error;

    git_buf_free(&commit);

    if (update_ref != NULL) {
        error = git_reference__update_for_commit(
                    repo, ref, update_ref, id, "commit");
        git_reference_free(ref);
        return error;
    }

    return 0;

on_error:
    git_buf_free(&commit);
    return -1;
}
예제 #5
0
int git_commit_create(
		git_oid *oid,
		git_repository *repo,
		const char *update_ref,
		const git_signature *author,
		const git_signature *committer,
		const char *message_encoding,
		const char *message,
		const git_tree *tree,
		int parent_count,
		const git_commit *parents[])
{
	git_buf commit = GIT_BUF_INIT;
	int error, i;

	if (git_object_owner((const git_object *)tree) != repo)
		return git__throw(GIT_EINVALIDARGS, "The given tree does not belong to this repository");

	git_oid__writebuf(&commit, "tree ", git_object_id((const git_object *)tree));

	for (i = 0; i < parent_count; ++i) {
		if (git_object_owner((const git_object *)parents[i]) != repo) {
			error = git__throw(GIT_EINVALIDARGS, "The given parent does not belong to this repository");
			goto cleanup;
		}

		git_oid__writebuf(&commit, "parent ", git_object_id((const git_object *)parents[i]));
	}

	git_signature__writebuf(&commit, "author ", author);
	git_signature__writebuf(&commit, "committer ", committer);

	if (message_encoding != NULL)
		git_buf_printf(&commit, "encoding %s\n", message_encoding);

	git_buf_putc(&commit, '\n');
	git_buf_puts(&commit, message);

	if (git_buf_oom(&commit)) {
		error = git__throw(GIT_ENOMEM, "Not enough memory to build the commit data");
		goto cleanup;
	}

	error = git_odb_write(oid, git_repository_database(repo), commit.ptr, commit.size, GIT_OBJ_COMMIT);
	git_buf_free(&commit);

	if (error == GIT_SUCCESS && update_ref != NULL) {
		git_reference *head;

		error = git_reference_lookup(&head, repo, update_ref);
		if (error < GIT_SUCCESS)
			return git__rethrow(error, "Failed to create commit");

		error = git_reference_resolve(&head, head);
		if (error < GIT_SUCCESS) {
			if (error != GIT_ENOTFOUND)
				return git__rethrow(error, "Failed to create commit");
		/*
		 * The target of the reference was not found. This can happen
		 * just after a repository has been initialized (the master
		 * branch doesn't exist yet, as it doesn't have anything to
		 * point to) or after an orphan checkout, so if the target
		 * branch doesn't exist yet, create it and return.
		 */
			return git_reference_create_oid(&head, repo, git_reference_target(head), oid, 1);
		}

		error = git_reference_set_oid(head, oid);
	}

	if (error < GIT_SUCCESS)
		return git__rethrow(error, "Failed to create commit");

	return GIT_SUCCESS;

cleanup:
	git_buf_free(&commit);
	return error;
}