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; }
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; }
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; }
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; }
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; }