void test_commit_commit__create_unexisting_update_ref(void) { git_oid oid; git_tree *tree; git_commit *commit; git_signature *s; git_reference *ref; git_oid_fromstr(&oid, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"); cl_git_pass(git_commit_lookup(&commit, _repo, &oid)); git_oid_fromstr(&oid, "944c0f6e4dfa41595e6eb3ceecdb14f50fe18162"); cl_git_pass(git_tree_lookup(&tree, _repo, &oid)); cl_git_pass(git_signature_now(&s, "alice", "*****@*****.**")); cl_git_fail(git_reference_lookup(&ref, _repo, "refs/heads/foo/bar")); cl_git_pass(git_commit_create(&oid, _repo, "refs/heads/foo/bar", s, s, NULL, "some msg", tree, 1, (const git_commit **) &commit)); /* fail because the parent isn't the tip of the branch anymore */ cl_git_fail(git_commit_create(&oid, _repo, "refs/heads/foo/bar", s, s, NULL, "some msg", tree, 1, (const git_commit **) &commit)); cl_git_pass(git_reference_lookup(&ref, _repo, "refs/heads/foo/bar")); cl_assert(!git_oid_cmp(&oid, git_reference_target(ref))); git_tree_free(tree); git_commit_free(commit); git_signature_free(s); git_reference_free(ref); }
int git_commit_create_v( 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, ...) { va_list ap; int i, error; const git_commit **parents; parents = git__malloc(parent_count * sizeof(git_commit *)); va_start(ap, parent_count); for (i = 0; i < parent_count; ++i) parents[i] = va_arg(ap, const git_commit *); va_end(ap); error = git_commit_create( oid, repo, update_ref, author, committer, message_encoding, message, tree, parent_count, parents); free((void *)parents); return error; }
static int note_write(git_oid *out, git_repository *repo, const git_signature *author, const git_signature *committer, const char *notes_ref, const char *note, git_tree *commit_tree, const char *target, git_commit **parents) { int error; git_oid oid; git_tree *tree = NULL; // TODO: should we apply filters? /* create note object */ if ((error = git_blob_create_frombuffer(&oid, repo, note, strlen(note))) < 0) goto cleanup; if ((error = manipulate_note_in_tree_r( &tree, repo, commit_tree, &oid, target, 0, insert_note_in_tree_eexists_cb, insert_note_in_tree_enotfound_cb)) < 0) goto cleanup; if (out) git_oid_cpy(out, &oid); error = git_commit_create(&oid, repo, notes_ref, author, committer, NULL, GIT_NOTES_DEFAULT_MSG_ADD, tree, *parents == NULL ? 0 : 1, (const git_commit **) parents); cleanup: git_tree_free(tree); return error; }
bool PmrWorkspace::commit(const char *pMessage, const size_t &pParentCount, const git_commit **pParents) { // Commit everything that is staged git_signature *author = nullptr; QByteArray name = PreferencesInterface::preference(PluginName, SettingsPreferencesName, SettingsPreferencesNameDefault).toByteArray(); QByteArray email = PreferencesInterface::preference(PluginName, SettingsPreferencesEmail, SettingsPreferencesEmailDefault).toByteArray(); git_index *index = nullptr; git_oid treeId; git_tree *tree = nullptr; git_oid commitId; bool res = (git_signature_now(&author, name.data(), email.data()) != GIT_OK) || (git_repository_index(&index, mGitRepository) != GIT_OK) || (git_index_write_tree(&treeId, index) != GIT_OK) || (git_tree_lookup(&tree, mGitRepository, &treeId) != GIT_OK) || (git_commit_create(&commitId, mGitRepository, "HEAD", author, author, nullptr, pMessage, tree, pParentCount, pParents) != GIT_OK); if (tree != nullptr) { git_tree_free(tree); } if (index != nullptr) { git_index_free(index); } if (author != nullptr) { git_signature_free(author); } return !res; }
void test_refs_reflog_messages__branch_birth(void) { git_signature *sig; git_oid id; git_tree *tree; git_reference *ref; const char *msg; size_t nentries, nentries_after; nentries = reflog_entrycount(g_repo, GIT_HEAD_FILE); cl_git_pass(git_signature_now(&sig, "me", "*****@*****.**")); cl_git_pass(git_repository_head(&ref, g_repo)); cl_git_pass(git_reference_peel((git_object **) &tree, ref, GIT_OBJ_TREE)); cl_git_pass(git_repository_set_head(g_repo, "refs/heads/orphan")); nentries_after = reflog_entrycount(g_repo, GIT_HEAD_FILE); cl_assert_equal_i(nentries, nentries_after); msg = "message 2"; cl_git_pass(git_commit_create(&id, g_repo, "HEAD", sig, sig, NULL, msg, tree, 0, NULL)); cl_assert_equal_i(1, reflog_entrycount(g_repo, "refs/heads/orphan")); nentries_after = reflog_entrycount(g_repo, GIT_HEAD_FILE); cl_assert_equal_i(nentries + 1, nentries_after); git_signature_free(sig); git_tree_free(tree); git_reference_free(ref); }
/** * Create a commit * * @param out The oid of the newly created commit * @param repository The repository * @param index The index * @param message The commit message * @param author Who is the author of the commit * @param committer Who is the committer * @return 0 on success, or error code */ int git2r_commit_create( git_oid *out, git_repository *repository, git_index *index, const char *message, git_signature *author, git_signature *committer) { int err; git_oid oid; git_tree *tree = NULL; git_commit **parents = NULL; size_t n_parents = 0; err = git_index_write_tree(&oid, index); if (GIT_OK != err) goto cleanup; err = git_tree_lookup(&tree, repository, &oid); if (GIT_OK != err) goto cleanup; err = git2r_retrieve_parents(&parents, &n_parents, repository); if (GIT_OK != err) goto cleanup; err = git_commit_create( out, repository, "HEAD", author, committer, NULL, message, tree, n_parents, (const git_commit**)parents); if (GIT_OK != err) goto cleanup; err = git_repository_state_cleanup(repository); cleanup: if (parents) git2r_parents_free(parents, n_parents); if (tree) git_tree_free(tree); return err; }
/* git reset --hard 72333f47d4e83616630ff3b0ffe4c0faebcc3c45 * git revert --no-commit d1d403d22cbe24592d725f442835cf46fe60c8ac */ void test_revert_workdir__again_after_automerge(void) { git_commit *head, *commit; git_tree *reverted_tree; git_oid head_oid, revert_oid, reverted_tree_oid, reverted_commit_oid; git_signature *signature; struct merge_index_entry merge_index_entries[] = { { 0100644, "caf99de3a49827117bb66721010eac461b06a80c", 0, "file1.txt" }, { 0100644, "0ab09ea6d4c3634bdf6c221626d8b6f7dd890767", 0, "file2.txt" }, { 0100644, "f4e107c230d08a60fb419d19869f1f282b272d9c", 0, "file3.txt" }, { 0100644, "0f5bfcf58c558d865da6be0281d7795993646cee", 0, "file6.txt" }, }; struct merge_index_entry second_revert_entries[] = { { 0100644, "3a3ef367eaf3fe79effbfb0a56b269c04c2b59fe", 1, "file1.txt" }, { 0100644, "caf99de3a49827117bb66721010eac461b06a80c", 2, "file1.txt" }, { 0100644, "747726e021bc5f44b86de60e3032fd6f9f1b8383", 3, "file1.txt" }, { 0100644, "0ab09ea6d4c3634bdf6c221626d8b6f7dd890767", 0, "file2.txt" }, { 0100644, "f4e107c230d08a60fb419d19869f1f282b272d9c", 0, "file3.txt" }, { 0100644, "0f5bfcf58c558d865da6be0281d7795993646cee", 0, "file6.txt" }, }; git_oid_fromstr(&head_oid, "72333f47d4e83616630ff3b0ffe4c0faebcc3c45"); cl_git_pass(git_commit_lookup(&head, repo, &head_oid)); cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL)); git_oid_fromstr(&revert_oid, "d1d403d22cbe24592d725f442835cf46fe60c8ac"); cl_git_pass(git_commit_lookup(&commit, repo, &revert_oid)); cl_git_pass(git_revert(repo, commit, NULL)); cl_assert(merge_test_index(repo_index, merge_index_entries, 4)); cl_git_pass(git_index_write_tree(&reverted_tree_oid, repo_index)); cl_git_pass(git_tree_lookup(&reverted_tree, repo, &reverted_tree_oid)); cl_git_pass(git_signature_new(&signature, "Reverter", "*****@*****.**", time(NULL), 0)); cl_git_pass(git_commit_create(&reverted_commit_oid, repo, "HEAD", signature, signature, NULL, "Reverted!", reverted_tree, 1, (const git_commit **)&head)); cl_git_pass(git_revert(repo, commit, NULL)); cl_assert(merge_test_index(repo_index, second_revert_entries, 6)); git_signature_free(signature); git_tree_free(reverted_tree); git_commit_free(commit); git_commit_free(head); }
static int commit_worktree( git_oid *w_commit_oid, git_index *index, const git_signature *stasher, const char *message, git_commit *i_commit, git_commit *b_commit, git_commit *u_commit) { int error = 0; git_tree *w_tree = NULL, *i_tree = NULL; const git_commit *parents[] = { NULL, NULL, NULL }; parents[0] = b_commit; parents[1] = i_commit; parents[2] = u_commit; if ((error = git_commit_tree(&i_tree, i_commit)) < 0) goto cleanup; if ((error = git_index_read_tree(index, i_tree)) < 0) goto cleanup; if ((error = build_workdir_tree(&w_tree, index, b_commit)) < 0) goto cleanup; error = git_commit_create( w_commit_oid, git_index_owner(index), NULL, stasher, stasher, NULL, message, w_tree, u_commit ? 3 : 2, parents); cleanup: git_tree_free(i_tree); git_tree_free(w_tree); return error; }
/* * revert the same commit twice (when the first reverts cleanly): * * git revert 2d440f2 * git revert 2d440f2 */ void test_revert_workdir__again_after_edit(void) { git_reference *head_ref; git_commit *orig_head, *commit; git_tree *reverted_tree; git_oid orig_head_oid, revert_oid, reverted_tree_oid, reverted_commit_oid; git_signature *signature; struct merge_index_entry merge_index_entries[] = { { 0100644, "3721552e06c4bdc7d478e0674e6304888545d5fd", 0, "file1.txt" }, { 0100644, "0ab09ea6d4c3634bdf6c221626d8b6f7dd890767", 0, "file2.txt" }, { 0100644, "f4e107c230d08a60fb419d19869f1f282b272d9c", 0, "file3.txt" }, { 0100644, "0f5bfcf58c558d865da6be0281d7795993646cee", 0, "file6.txt" }, }; cl_git_pass(git_repository_head(&head_ref, repo)); cl_git_pass(git_oid_fromstr(&orig_head_oid, "399fb3aba3d9d13f7d40a9254ce4402067ef3149")); cl_git_pass(git_commit_lookup(&orig_head, repo, &orig_head_oid)); cl_git_pass(git_reset(repo, (git_object *)orig_head, GIT_RESET_HARD, NULL)); cl_git_pass(git_oid_fromstr(&revert_oid, "2d440f2b3147d3dc7ad1085813478d6d869d5a4d")); cl_git_pass(git_commit_lookup(&commit, repo, &revert_oid)); cl_git_pass(git_revert(repo, commit, NULL)); cl_assert(merge_test_index(repo_index, merge_index_entries, 4)); cl_git_pass(git_index_write_tree(&reverted_tree_oid, repo_index)); cl_git_pass(git_tree_lookup(&reverted_tree, repo, &reverted_tree_oid)); cl_git_pass(git_signature_new(&signature, "Reverter", "*****@*****.**", time(NULL), 0)); cl_git_pass(git_commit_create(&reverted_commit_oid, repo, "HEAD", signature, signature, NULL, "Reverted!", reverted_tree, 1, (const git_commit **)&orig_head)); cl_git_pass(git_revert(repo, commit, NULL)); cl_assert(merge_test_index(repo_index, merge_index_entries, 4)); git_signature_free(signature); git_tree_free(reverted_tree); git_commit_free(commit); git_commit_free(orig_head); git_reference_free(head_ref); }
void test_refs_reflog_reflog__show_merge_for_merge_commits(void) { git_oid b1_oid; git_oid b2_oid; git_oid merge_commit_oid; git_commit *b1_commit; git_commit *b2_commit; git_signature *s; git_commit *parent_commits[2]; git_tree *tree; git_reflog *log; const git_reflog_entry *entry; cl_git_pass(git_signature_now(&s, "alice", "*****@*****.**")); cl_git_pass(git_reference_name_to_id(&b1_oid, g_repo, "HEAD")); cl_git_pass(git_reference_name_to_id(&b2_oid, g_repo, "refs/heads/test")); cl_git_pass(git_commit_lookup(&b1_commit, g_repo, &b1_oid)); cl_git_pass(git_commit_lookup(&b2_commit, g_repo, &b2_oid)); parent_commits[0] = b1_commit; parent_commits[1] = b2_commit; cl_git_pass(git_commit_tree(&tree, b1_commit)); cl_git_pass(git_commit_create(&merge_commit_oid, g_repo, "HEAD", s, s, NULL, "Merge commit", tree, 2, (const struct git_commit **) parent_commits)); cl_git_pass(git_reflog_read(&log, g_repo, "HEAD")); entry = git_reflog_entry_byindex(log, 0); cl_assert_equal_s(merge_reflog_message, git_reflog_entry_message(entry)); git_reflog_free(log); git_tree_free(tree); git_commit_free(b1_commit); git_commit_free(b2_commit); git_signature_free(s); }
void test_refs_reflog_messages__show_merge_for_merge_commits(void) { git_oid b1_oid; git_oid b2_oid; git_oid merge_commit_oid; git_commit *b1_commit; git_commit *b2_commit; git_signature *s; git_commit *parent_commits[2]; git_tree *tree; cl_git_pass(git_signature_now(&s, "alice", "*****@*****.**")); cl_git_pass(git_reference_name_to_id(&b1_oid, g_repo, "HEAD")); cl_git_pass(git_reference_name_to_id(&b2_oid, g_repo, "refs/heads/test")); cl_git_pass(git_commit_lookup(&b1_commit, g_repo, &b1_oid)); cl_git_pass(git_commit_lookup(&b2_commit, g_repo, &b2_oid)); parent_commits[0] = b1_commit; parent_commits[1] = b2_commit; cl_git_pass(git_commit_tree(&tree, b1_commit)); cl_git_pass(git_commit_create(&merge_commit_oid, g_repo, "HEAD", s, s, NULL, "Merge commit", tree, 2, (const struct git_commit **) parent_commits)); cl_reflog_check_entry(g_repo, GIT_HEAD_FILE, 0, NULL, git_oid_tostr_s(&merge_commit_oid), NULL, "commit (merge): Merge commit"); git_tree_free(tree); git_commit_free(b1_commit); git_commit_free(b2_commit); git_signature_free(s); }
static int commit_untracked( git_commit **u_commit, git_index *index, const git_signature *stasher, const char *message, git_commit *i_commit, uint32_t flags) { git_tree *u_tree = NULL; git_oid u_commit_oid; git_buf msg = GIT_BUF_INIT; int error; if ((error = build_untracked_tree(&u_tree, index, i_commit, flags)) < 0) goto cleanup; if ((error = git_buf_printf(&msg, "untracked files on %s\n", message)) < 0) goto cleanup; if ((error = git_commit_create( &u_commit_oid, git_index_owner(index), NULL, stasher, stasher, NULL, git_buf_cstr(&msg), u_tree, 0, NULL)) < 0) goto cleanup; error = git_commit_lookup(u_commit, git_index_owner(index), &u_commit_oid); cleanup: git_tree_free(u_tree); git_buf_free(&msg); return error; }
void test_repo_head__symref_chain(void) { git_signature *sig; git_oid id; git_tree *tree; git_reference *ref; const char *msg; size_t nentries, nentries_master; nentries = entrycount(repo, GIT_HEAD_FILE); cl_git_pass(git_signature_now(&sig, "me", "*****@*****.**")); cl_git_pass(git_repository_head(&ref, repo)); cl_git_pass(git_reference_peel((git_object **) &tree, ref, GIT_OBJ_TREE)); git_reference_free(ref); nentries_master = entrycount(repo, "refs/heads/master"); msg = "message 1"; cl_git_pass(git_reference_symbolic_create(&ref, repo, "refs/heads/master", "refs/heads/foo", 1, msg)); git_reference_free(ref); cl_assert_equal_i(0, entrycount(repo, "refs/heads/foo")); cl_assert_equal_i(nentries, entrycount(repo, GIT_HEAD_FILE)); cl_assert_equal_i(nentries_master, entrycount(repo, "refs/heads/master")); msg = "message 2"; cl_git_pass(git_commit_create(&id, repo, "HEAD", sig, sig, NULL, msg, tree, 0, NULL)); git_tree_free(tree); cl_assert_equal_i(1, entrycount(repo, "refs/heads/foo")); cl_assert_equal_i(nentries +1, entrycount(repo, GIT_HEAD_FILE)); cl_assert_equal_i(nentries_master, entrycount(repo, "refs/heads/master")); git_signature_free(sig); }
static int commit_index( git_commit **i_commit, git_index *index, const git_signature *stasher, const char *message, const git_commit *parent) { git_tree *i_tree = NULL; git_oid i_commit_oid; git_buf msg = GIT_BUF_INIT; int error; if ((error = build_tree_from_index(&i_tree, index)) < 0) goto cleanup; if ((error = git_buf_printf(&msg, "index on %s\n", message)) < 0) goto cleanup; if ((error = git_commit_create( &i_commit_oid, git_index_owner(index), NULL, stasher, stasher, NULL, git_buf_cstr(&msg), i_tree, 1, &parent)) < 0) goto cleanup; error = git_commit_lookup(i_commit, git_index_owner(index), &i_commit_oid); cleanup: git_tree_free(i_tree); git_buf_free(&msg); return error; }
/* * revert the same commit twice (when the first reverts cleanly): * * git revert 2d440f2 * git revert 2d440f2 */ void test_revert_workdir__again(void) { git_reference *head_ref; git_commit *orig_head; git_tree *reverted_tree; git_oid reverted_tree_oid, reverted_commit_oid; git_signature *signature; struct merge_index_entry merge_index_entries[] = { { 0100644, "7731926a337c4eaba1e2187d90ebfa0a93659382", 0, "file1.txt" }, { 0100644, "0ab09ea6d4c3634bdf6c221626d8b6f7dd890767", 0, "file2.txt" }, { 0100644, "f4e107c230d08a60fb419d19869f1f282b272d9c", 0, "file3.txt" }, { 0100644, "0f5bfcf58c558d865da6be0281d7795993646cee", 0, "file6.txt" }, }; cl_git_pass(git_repository_head(&head_ref, repo)); cl_git_pass(git_reference_peel((git_object **)&orig_head, head_ref, GIT_OBJ_COMMIT)); cl_git_pass(git_reset(repo, (git_object *)orig_head, GIT_RESET_HARD, NULL)); cl_git_pass(git_revert(repo, orig_head, NULL)); cl_assert(merge_test_index(repo_index, merge_index_entries, 4)); cl_git_pass(git_index_write_tree(&reverted_tree_oid, repo_index)); cl_git_pass(git_tree_lookup(&reverted_tree, repo, &reverted_tree_oid)); cl_git_pass(git_signature_new(&signature, "Reverter", "*****@*****.**", time(NULL), 0)); cl_git_pass(git_commit_create(&reverted_commit_oid, repo, "HEAD", signature, signature, NULL, "Reverted!", reverted_tree, 1, (const git_commit **)&orig_head)); cl_git_pass(git_revert(repo, orig_head, NULL)); cl_assert(merge_test_index(repo_index, merge_index_entries, 4)); git_signature_free(signature); git_tree_free(reverted_tree); git_commit_free(orig_head); git_reference_free(head_ref); }
void test_refs_reflog_messages__commit_on_symbolic_ref_updates_head_reflog(void) { git_signature *sig; git_oid id; git_tree *tree; git_reference *ref1, *ref2; const char *msg; size_t nentries_head, nentries_master; nentries_head = reflog_entrycount(g_repo, GIT_HEAD_FILE); cl_git_pass(git_signature_now(&sig, "me", "*****@*****.**")); cl_git_pass(git_repository_head(&ref1, g_repo)); cl_git_pass(git_reference_peel((git_object **) &tree, ref1, GIT_OBJ_TREE)); nentries_master = reflog_entrycount(g_repo, "refs/heads/master"); msg = "message 1"; cl_git_pass(git_reference_symbolic_create(&ref2, g_repo, "refs/heads/master", "refs/heads/foo", 1, msg)); cl_assert_equal_i(0, reflog_entrycount(g_repo, "refs/heads/foo")); cl_assert_equal_i(nentries_head, reflog_entrycount(g_repo, GIT_HEAD_FILE)); cl_assert_equal_i(nentries_master, reflog_entrycount(g_repo, "refs/heads/master")); msg = "message 2"; cl_git_pass(git_commit_create(&id, g_repo, "HEAD", sig, sig, NULL, msg, tree, 0, NULL)); cl_assert_equal_i(1, reflog_entrycount(g_repo, "refs/heads/foo")); cl_assert_equal_i(nentries_head + 1, reflog_entrycount(g_repo, GIT_HEAD_FILE)); cl_assert_equal_i(nentries_master, reflog_entrycount(g_repo, "refs/heads/master")); git_signature_free(sig); git_reference_free(ref1); git_reference_free(ref2); git_tree_free(tree); }
static int note_remove(git_repository *repo, const git_signature *author, const git_signature *committer, const char *notes_ref, git_tree *tree, const char *target, git_commit **parents) { int error; git_tree *tree_after_removal = NULL; git_oid oid; if ((error = manipulate_note_in_tree_r( &tree_after_removal, repo, tree, NULL, target, 0, remove_note_in_tree_eexists_cb, remove_note_in_tree_enotfound_cb)) < 0) goto cleanup; error = git_commit_create(&oid, repo, notes_ref, author, committer, NULL, GIT_NOTES_DEFAULT_MSG_RM, tree_after_removal, *parents == NULL ? 0 : 1, (const git_commit **) parents); cleanup: git_tree_free(tree_after_removal); return error; }
int luagi_commit_create( lua_State *L ) { git_repository** repo = checkrepo( L, 1 ); git_signature *author; int ret = table_to_signature( L, &author, 2 ); git_signature *committer; ret = table_to_signature( L, &committer, 3 ); const char* message = luaL_checkstring( L, 4 ); git_tree** tree = (git_tree**) luaL_checkudata( L, 5, LUAGI_TREE_FUNCS ); // table of parents luaL_checktype( L, 6, LUA_TTABLE ); unsigned int n = luaL_len( L, 6 ); const git_commit* parents[n]; for( unsigned int i = 0; i < n; i++ ) { lua_rawgeti( L, 6, i + 1 ); parents[i] = *( (git_commit**) luaL_checkudata( L, -1, LUAGI_COMMIT_FUNCS ) ); } lua_pop( L, n ); const char* update_ref = luaL_optstring( L, 7, NULL ); const char* encoding = luaL_optstring( L, 8, NULL ); git_oid oid; ret = git_commit_create( &oid, *repo, update_ref, author, committer, encoding, message, *tree, n, parents ); git_signature_free( author ); git_signature_free( committer ); if( ret != 0 ) { return ltk_push_git_error( L ); } return luagi_push_oid( L, &oid ); }
/* * call-seq: * Commit.create(repository, data = {}) -> oid * * Write a new +Commit+ object to +repository+, with the given +data+ * arguments, passed as a +Hash+: * * - +:message+: a string with the full text for the commit's message * - +:committer+ (optional): a hash with the signature for the committer, * defaults to the signature from the configuration * - +:author+ (optional): a hash with the signature for the author, * defaults to the signature from the configuration * - +:parents+: an +Array+ with zero or more parents for this commit, * represented as <tt>Rugged::Commit</tt> instances, or OID +String+. * - +:tree+: the tree for this commit, represented as a <tt>Rugged::Tree</tt> * instance or an OID +String+. * - +:update_ref+ (optional): a +String+ with the name of a reference in the * repository which should be updated to point to this commit (e.g. "HEAD") * * When the commit is successfully written to disk, its +oid+ will be * returned as a hex +String+. * * author = {:email=>"*****@*****.**", :time=>Time.now, :name=>"Vicent Mart\303\255"} * * Rugged::Commit.create(r, * :author => author, * :message => "Hello world\n\n", * :committer => author, * :parents => ["2cb831a8aea28b2c1b9c63385585b864e4d3bad1"], * :tree => some_tree) #=> "f148106ca58764adc93ad4e2d6b1d168422b9796" */ static VALUE rb_git_commit_create(VALUE self, VALUE rb_repo, VALUE rb_data) { int error = 0; struct commit_data commit_data = { Qnil }; git_oid commit_oid; git_repository *repo; Check_Type(rb_data, T_HASH); rugged_check_repo(rb_repo); Data_Get_Struct(rb_repo, git_repository, repo); if ((error = parse_commit_options(&commit_data, repo, rb_data)) < 0) goto cleanup; error = git_commit_create( &commit_oid, repo, commit_data.update_ref, commit_data.author, commit_data.committer, NULL, commit_data.message, commit_data.tree, commit_data.parent_count, commit_data.parents); cleanup: free_commit_options(&commit_data); if (!NIL_P(commit_data.rb_err_obj)) rb_exc_raise(commit_data.rb_err_obj); rugged_exception_check(error); return rugged_create_oid(&commit_oid); }
/* * call-seq: * Commit.create(repository, data = {}) -> oid * * Write a new +Commit+ object to +repository+, with the given +data+ * arguments, passed as a +Hash+: * * - +:message+: a string with the full text for the commit's message * - +:committer+ (optional): a hash with the signature for the committer, * defaults to the signature from the configuration * - +:author+ (optional): a hash with the signature for the author, * defaults to the signature from the configuration * - +:parents+: an +Array+ with zero or more parents for this commit, * represented as <tt>Rugged::Commit</tt> instances, or OID +String+. * - +:tree+: the tree for this commit, represented as a <tt>Rugged::Tree</tt> * instance or an OID +String+. * - +:update_ref+ (optional): a +String+ with the name of a reference in the * repository which should be updated to point to this commit (e.g. "HEAD") * * When the commit is successfully written to disk, its +oid+ will be * returned as a hex +String+. * * author = {:email=>"*****@*****.**", :time=>Time.now, :name=>"Vicent Mart\303\255"} * * Rugged::Commit.create(r, * :author => author, * :message => "Hello world\n\n", * :committer => author, * :parents => ["2cb831a8aea28b2c1b9c63385585b864e4d3bad1"], * :tree => some_tree) #=> "f148106ca58764adc93ad4e2d6b1d168422b9796" */ static VALUE rb_git_commit_create(VALUE self, VALUE rb_repo, VALUE rb_data) { VALUE rb_message, rb_tree, rb_parents, rb_ref; VALUE rb_err_obj = Qnil; int parent_count, i, error = 0; const git_commit **parents = NULL; git_commit **free_list = NULL; git_tree *tree; git_signature *author, *committer; git_oid commit_oid; git_repository *repo; const char *update_ref = NULL; Check_Type(rb_data, T_HASH); rugged_check_repo(rb_repo); Data_Get_Struct(rb_repo, git_repository, repo); rb_ref = rb_hash_aref(rb_data, CSTR2SYM("update_ref")); if (!NIL_P(rb_ref)) { Check_Type(rb_ref, T_STRING); update_ref = StringValueCStr(rb_ref); } rb_message = rb_hash_aref(rb_data, CSTR2SYM("message")); Check_Type(rb_message, T_STRING); committer = rugged_signature_get( rb_hash_aref(rb_data, CSTR2SYM("committer")), repo ); author = rugged_signature_get( rb_hash_aref(rb_data, CSTR2SYM("author")), repo ); rb_parents = rb_hash_aref(rb_data, CSTR2SYM("parents")); Check_Type(rb_parents, T_ARRAY); rb_tree = rb_hash_aref(rb_data, CSTR2SYM("tree")); tree = (git_tree *)rugged_object_get(repo, rb_tree, GIT_OBJ_TREE); parents = alloca(RARRAY_LEN(rb_parents) * sizeof(void *)); free_list = alloca(RARRAY_LEN(rb_parents) * sizeof(void *)); parent_count = 0; for (i = 0; i < (int)RARRAY_LEN(rb_parents); ++i) { VALUE p = rb_ary_entry(rb_parents, i); git_commit *parent = NULL; git_commit *free_ptr = NULL; if (NIL_P(p)) continue; if (TYPE(p) == T_STRING) { git_oid oid; error = git_oid_fromstr(&oid, StringValueCStr(p)); if (error < GIT_OK) goto cleanup; error = git_commit_lookup(&parent, repo, &oid); if (error < GIT_OK) goto cleanup; free_ptr = parent; } else if (rb_obj_is_kind_of(p, rb_cRuggedCommit)) { Data_Get_Struct(p, git_commit, parent); } else { rb_err_obj = rb_exc_new2(rb_eTypeError, "Invalid type for parent object"); goto cleanup; } parents[parent_count] = parent; free_list[parent_count] = free_ptr; parent_count++; } error = git_commit_create( &commit_oid, repo, update_ref, author, committer, NULL, StringValueCStr(rb_message), tree, parent_count, parents); cleanup: git_signature_free(author); git_signature_free(committer); git_object_free((git_object *)tree); for (i = 0; i < parent_count; ++i) git_object_free((git_object *)free_list[i]); if (!NIL_P(rb_err_obj)) rb_exc_raise(rb_err_obj); rugged_exception_check(error); return rugged_create_oid(&commit_oid); }
static int rebase_commit__create( git_commit **out, git_rebase *rebase, git_index *index, git_commit *parent_commit, const git_signature *author, const git_signature *committer, const char *message_encoding, const char *message) { git_rebase_operation *operation; git_commit *current_commit = NULL, *commit = NULL; git_tree *parent_tree = NULL, *tree = NULL; git_oid tree_id, commit_id; int error; operation = git_array_get(rebase->operations, rebase->current); if (git_index_has_conflicts(index)) { giterr_set(GITERR_REBASE, "conflicts have not been resolved"); error = GIT_EUNMERGED; goto done; } if ((error = git_commit_lookup(¤t_commit, rebase->repo, &operation->id)) < 0 || (error = git_commit_tree(&parent_tree, parent_commit)) < 0 || (error = git_index_write_tree_to(&tree_id, index, rebase->repo)) < 0 || (error = git_tree_lookup(&tree, rebase->repo, &tree_id)) < 0) goto done; if (git_oid_equal(&tree_id, git_tree_id(parent_tree))) { giterr_set(GITERR_REBASE, "this patch has already been applied"); error = GIT_EAPPLIED; goto done; } if (!author) author = git_commit_author(current_commit); if (!message) { message_encoding = git_commit_message_encoding(current_commit); message = git_commit_message(current_commit); } if ((error = git_commit_create(&commit_id, rebase->repo, NULL, author, committer, message_encoding, message, tree, 1, (const git_commit **)&parent_commit)) < 0 || (error = git_commit_lookup(&commit, rebase->repo, &commit_id)) < 0) goto done; *out = commit; done: if (error < 0) git_commit_free(commit); git_commit_free(current_commit); git_tree_free(parent_tree); git_tree_free(tree); return error; }
int create_repo(const char *repo_name) { int r; git_repository *repo; git_oid blob_id; git_oid oid; git_oid tree_id; git_signature *author; git_time_t time; git_config *config; git_index *index; git_tree *tree; git_treebuilder *tree_builder; git_treebuilder *empty_tree_builder; char global_config_path[GIT_PATH_MAX]; // create the repository r = git_repository_init(&repo, repo_name, 1); if (r) printf("error in creating repository\n"); printf("Repo created\n"); // set the repository config git_config_new(&config); git_config_find_global(global_config_path, GIT_PATH_MAX); git_config_add_file_ondisk(config, global_config_path, 1); //git_config_set_string(config, "name", "Varun Agrawal"); //git_config_set_string(config, "email", "*****@*****.**"); git_repository_set_config(repo, config); printf("Repo config set\n"); // create a treebuilder r = git_treebuilder_create(&tree_builder, NULL); if (r) printf("error in creting treebuilder\n"); printf("Tree builder created\n"); // ADDING FIRST FILE // create a blob r = git_blob_create_fromdisk(&blob_id, repo, "test1"); if (r) printf("error in creating blob from disk\n"); printf("Blob created\n"); // insert into tree r = git_treebuilder_insert(NULL, tree_builder, "test1", &blob_id, 0100644); if (r) printf("error in inserting into treebuilder\n"); printf("Insert into treebuilder successful\n"); // ADDING SECOND FILE // create a blob r = git_blob_create_fromdisk(&blob_id, repo, "test2"); if (r) printf("error in creating blob from disk\n"); printf("Blob created\n"); // insert into tree r = git_treebuilder_insert(NULL, tree_builder, "test2", &blob_id, 0100644); if (r) printf("error in inserting into treebuilder\n"); printf("Insert into treebuilder successful\n"); // ADDING A EMPTY FOLDER // create a empty tree r = git_treebuilder_create(&empty_tree_builder, NULL); if (r) printf("error in creting empty treebuilder\n"); printf("Empty Tree builder created\n"); // write the empty tree to the repo r = git_treebuilder_write(&tree_id, repo, empty_tree_builder); if (r) printf("error in writing the empty tree to the repo\n"); printf("Writing the empty tree to repo successful\n"); // insert empty tree into the tree r = git_treebuilder_insert(NULL, tree_builder, "test_dir", &tree_id, 0040000); if (r) printf("error in inserting into treebuilder\n"); printf("Insert into treebuilder successful\n"); // write the tree to the repo r = git_treebuilder_write(&oid, repo, tree_builder); if (r) printf("error in writing the tree to the repo\n"); printf("Writing the tree to repo successful\n"); // tree lookup r = git_tree_lookup(&tree, repo, &oid); if (r) printf("error in tree lookup\n"); printf("Tree lookup done\n"); // create a author time = get_time(); r = git_signature_new(&author, "Varun Agrawal", "*****@*****.**", time, -300); if (r) printf("error in creating signature\n"); printf("Author signature created\n"); // create a commit r = git_commit_create( &oid, // object id repo, // repository "HEAD", // update reference, this will update the HEAD to this commit author, // author author, // committer NULL, // message encoding, by default UTF-8 is used "first commit", // message for the commit tree, // the git_tree object which will be used as the tree for this commit. don't know if NULL is valid 0, // number of parents. Don't know what value should be used here NULL); // array of pointers to the parents(git_commit *parents[]) if (r) printf("error in creating a commit\n"); printf("Commit created\n"); git_repository_free(repo); return 0; }
void test_core_merge__demo_create_merge_commit(void) { AGBError * error; agb_error_new(&error); // Here we're going to try to use the merge iterator to create a merge commit that contains the right information. // Note - this version does not recurse into directories. (subtrees) git_treebuilder * builder; git_treebuilder_create(&builder, base_tree); AGBMergeIterator * it = agb_merge__create_iterator(head_tree, branch_tree, base_tree, agb_merge_iterator_options_NONE); for( ; agb_merge_iterator_is_valid(it) ; agb_merge_iterator_next(it) ) { AGBMergeEntry * entry = agb_merge_entry_from_iterator(it); int hasLocalChanged = !agb_git_oid_equal( agb_merge_entry_id(entry,AGB_MERGE_BASE), agb_merge_entry_id(entry,AGB_MERGE_LOCAL) ); int hasRemoteChanged = !agb_git_oid_equal( agb_merge_entry_id(entry,AGB_MERGE_BASE), agb_merge_entry_id(entry,AGB_MERGE_REMOTE) ); printf("-- %s %d %d\n", agb_merge_entry_name(entry), hasLocalChanged, hasRemoteChanged); if( !hasLocalChanged && !hasRemoteChanged) { continue; } if( hasLocalChanged && !hasRemoteChanged) { //We want the head version. if(agb_merge_entry_id(entry,AGB_MERGE_LOCAL) == NULL) { //TODO: Check error message. printf("REMOVING %s from tree\n", agb_merge_entry_name(entry) ); git_treebuilder_remove(builder, agb_merge_entry_name(entry) ); continue; } //TODO: Check for error printf("ADDING OR UPDATING %s to tree\n", agb_merge_entry_name(entry) ); int ok = git_treebuilder_insert(NULL, builder, agb_merge_entry_name(entry), agb_merge_entry_id(entry,AGB_MERGE_LOCAL), agb_merge_entry_filemode(entry,AGB_MERGE_LOCAL) ); if(ok!=0) { printf("Error duting add/update of tree builder: %s\n", giterr_last()->message); abort(); } continue; } if( !hasLocalChanged && hasRemoteChanged) { //We want the head version. if(agb_merge_entry_id(entry,AGB_MERGE_REMOTE) == NULL) { //TODO: Check error message. printf("REMOVING %s from tree\n", agb_merge_entry_name(entry) ); git_treebuilder_remove(builder, agb_merge_entry_name(entry) ); continue; } //TODO: Check for error printf("ADDING OR UPDATING %s to tree\n", agb_merge_entry_name(entry) ); int ok = git_treebuilder_insert(NULL, builder, agb_merge_entry_name(entry), agb_merge_entry_id(entry,AGB_MERGE_REMOTE), agb_merge_entry_filemode(entry,AGB_MERGE_REMOTE) ); if(ok!=0) { printf("Error duting add/update of tree builder: %s\n", giterr_last()->message); abort(); } continue; } printf("CONFLICT %s in tree\n", agb_merge_entry_name(entry) ); //TODO: CONFLICT - Handle it! } // Our tree builder should now be full... // Lets write it out to a tree // //TODO: Check for errors git_oid new_tree_oid = {}; git_treebuilder_write(&new_tree_oid, repo, builder); char hexid[GIT_OID_HEXSZ+1]; printf("Tree SHA is %s\n", git_oid_tostr(hexid,GIT_OID_HEXSZ+1, &new_tree_oid)); git_tree * new_tree = NULL; git_tree_lookup(&new_tree, repo, &new_tree_oid); // Now we need to create the commit. const git_commit** parents = (const git_commit**)malloc(sizeof(git_commit*)*2); parents[0] = head_commit; parents[1] = branch_commit; git_signature * author_signature = NULL; // Time since epoch // TODO: Get these correctly - // Could use git_signature_now instead... { git_time_t author_time = time(NULL); int timezone_offset = 0; int ok; if((ok=git_signature_new(&author_signature,"Someone","*****@*****.**", author_time, timezone_offset))!=0) { agb__error_translate(error,"git_signature_new failed",ok); goto cleanup_error; } } git_oid commit_id; int ok = git_commit_create( &commit_id, repo, NULL, author_signature, author_signature, "UTF-8", "An exciting commit", new_tree, 2, //Two parents parents ); if(ok!=0) { agb__error_translate(error,"git_commit_create failed",ok); goto cleanup_error; } // Then update the refs. //TODO: Do we need to release this ref? git_reference * ref; ok = git_reference_create_matching( &ref, repo, "refs/heads/branch_c", &commit_id, 1, NULL, author_signature, "merged by libagb"); if(ok!=0) { agb__error_translate(error,"git_reference_create failed",ok); goto cleanup_error; } git_signature_free(author_signature); // Now check we got the expected files cl_assert_equal_c('A', test_core_merge__compare_with_parents_merge_base("branch_c", "created_in_a.txt")); cl_assert_equal_c('A', test_core_merge__compare_with_parents_merge_base("branch_c", "created_in_b.txt")); return; cleanup_error: printf("ERROR: %s\n",error->message); if(author_signature) { git_signature_free(author_signature); } cl_fail(error->message); }
void test_checkout_tree__case_changing_rename(void) { git_index *index; git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; git_oid master_id, dir_commit_id, tree_id, commit_id; git_commit *master_commit, *dir_commit; git_tree *tree; git_signature *signature; const git_index_entry *index_entry; bool case_sensitive; assert_on_branch(g_repo, "master"); cl_git_pass(git_repository_index(&index, g_repo)); /* Switch branches and perform a case-changing rename */ opts.checkout_strategy = GIT_CHECKOUT_FORCE; cl_git_pass(git_reference_name_to_id(&dir_commit_id, g_repo, "refs/heads/dir")); cl_git_pass(git_commit_lookup(&dir_commit, g_repo, &dir_commit_id)); cl_git_pass(git_checkout_tree(g_repo, (git_object *)dir_commit, &opts)); cl_git_pass(git_repository_set_head(g_repo, "refs/heads/dir")); cl_assert(git_path_isfile("testrepo/README")); case_sensitive = !git_path_isfile("testrepo/readme"); cl_assert(index_entry = git_index_get_bypath(index, "README", 0)); cl_assert_equal_s("README", index_entry->path); cl_git_pass(git_index_remove_bypath(index, "README")); cl_git_pass(p_rename("testrepo/README", "testrepo/__readme__")); cl_git_pass(p_rename("testrepo/__readme__", "testrepo/readme")); cl_git_append2file("testrepo/readme", "An addendum..."); cl_git_pass(git_index_add_bypath(index, "readme")); cl_git_pass(git_index_write(index)); cl_git_pass(git_index_write_tree(&tree_id, index)); cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_id)); cl_git_pass(git_signature_new(&signature, "Renamer", "*****@*****.**", time(NULL), 0)); cl_git_pass(git_commit_create(&commit_id, g_repo, "refs/heads/dir", signature, signature, NULL, "case-changing rename", tree, 1, (const git_commit **)&dir_commit)); cl_assert(git_path_isfile("testrepo/readme")); if (case_sensitive) cl_assert(!git_path_isfile("testrepo/README")); cl_assert(index_entry = git_index_get_bypath(index, "readme", 0)); cl_assert_equal_s("readme", index_entry->path); /* Switching back to master should rename readme -> README */ opts.checkout_strategy = GIT_CHECKOUT_SAFE; cl_git_pass(git_reference_name_to_id(&master_id, g_repo, "refs/heads/master")); cl_git_pass(git_commit_lookup(&master_commit, g_repo, &master_id)); cl_git_pass(git_checkout_tree(g_repo, (git_object *)master_commit, &opts)); cl_git_pass(git_repository_set_head(g_repo, "refs/heads/master")); assert_on_branch(g_repo, "master"); cl_assert(git_path_isfile("testrepo/README")); if (case_sensitive) cl_assert(!git_path_isfile("testrepo/readme")); cl_assert(index_entry = git_index_get_bypath(index, "README", 0)); cl_assert_equal_s("README", index_entry->path); git_index_free(index); git_signature_free(signature); git_tree_free(tree); git_commit_free(dir_commit); git_commit_free(master_commit); }
/* git reset --hard d3d77487660ee3c0194ee01dc5eaf478782b1c7e * git cherry-pick cfc4f0999a8367568e049af4f72e452d40828a15 * git cherry-pick 964ea3da044d9083181a88ba6701de9e35778bf4 * git cherry-pick a43a050c588d4e92f11a6b139680923e9728477d */ void test_cherrypick_workdir__automerge(void) { git_oid head_oid; git_signature *signature = NULL; size_t i; const char *cherrypick_oids[] = { "cfc4f0999a8367568e049af4f72e452d40828a15", "964ea3da044d9083181a88ba6701de9e35778bf4", "a43a050c588d4e92f11a6b139680923e9728477d", }; struct merge_index_entry merge_index_entries[] = { { 0100644, "38c05a857e831a7e759d83778bfc85d003e21c45", 0, "file1.txt" }, { 0100644, "a661b5dec1004e2c62654ded3762370c27cf266b", 0, "file2.txt" }, { 0100644, "df6b290e0bd6a89b01d69f66687e8abf385283ca", 0, "file3.txt" }, { 0100644, "38c05a857e831a7e759d83778bfc85d003e21c45", 0, "file1.txt" }, { 0100644, "bd8fc3c59fb52d3c8b5907ace7defa5803f82419", 0, "file2.txt" }, { 0100644, "df6b290e0bd6a89b01d69f66687e8abf385283ca", 0, "file3.txt" }, { 0100644, "f06427bee380364bc7e0cb26a9245158e4726ce0", 0, "file1.txt" }, { 0100644, "bd8fc3c59fb52d3c8b5907ace7defa5803f82419", 0, "file2.txt" }, { 0100644, "df6b290e0bd6a89b01d69f66687e8abf385283ca", 0, "file3.txt" }, }; cl_git_pass(git_signature_new(&signature, "Picker", "*****@*****.**", time(NULL), 0)); git_oid_fromstr(&head_oid, "d3d77487660ee3c0194ee01dc5eaf478782b1c7e"); for (i = 0; i < 3; ++i) { git_commit *head = NULL, *commit = NULL; git_oid cherry_oid, cherrypicked_oid, cherrypicked_tree_oid; git_tree *cherrypicked_tree = NULL; cl_git_pass(git_commit_lookup(&head, repo, &head_oid)); cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL)); git_oid_fromstr(&cherry_oid, cherrypick_oids[i]); cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid)); cl_git_pass(git_cherrypick(repo, commit, NULL)); cl_assert(git_path_exists(TEST_REPO_PATH "/.git/CHERRY_PICK_HEAD")); cl_assert(git_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG")); cl_git_pass(git_index_write_tree(&cherrypicked_tree_oid, repo_index)); cl_git_pass(git_tree_lookup(&cherrypicked_tree, repo, &cherrypicked_tree_oid)); cl_git_pass(git_commit_create(&cherrypicked_oid, repo, "HEAD", signature, signature, NULL, "Cherry picked!", cherrypicked_tree, 1, (const git_commit **)&head)); cl_assert(merge_test_index(repo_index, merge_index_entries + i * 3, 3)); git_oid_cpy(&head_oid, &cherrypicked_oid); git_tree_free(cherrypicked_tree); git_commit_free(head); git_commit_free(commit); } git_signature_free(signature); }
int main(int argc, char **argv) { git_repository *repo; git_odb *odb; git_oid oid, tree_id, commit; git_index *index; char hash[41]; int error; char *folder; int folder_size; git_signature *author, *committer; git_tree *tree; git_reference *master; hash[40] = '\0'; if(argc != 2) { printf("usage: migit <path-to-git-repo>\n"); return 1; } folder_size = strlen(argv[1]) + 6; folder = malloc(folder_size); sprintf(folder, "%s/.git", argv[1]); folder[folder_size - 1] = '\0'; create_sample_file(argv[1]); error = git_repository_open(&repo, folder); if(error) { die("could not open repository", error); } odb = git_repository_database(repo); git_odb_write(&oid, odb, content, strlen(content) * sizeof(char), GIT_OBJ_BLOB); error = git_repository_index(&index, repo); if(error) { die("could not open index", error); } error = git_index_add(index, fname, 0); if(error) { die("could not add file to index", error); } assert(git_index_entrycount(index) == 1); error = git_tree_create_fromindex(&tree_id, index); if(error) { die("could not create tree from index", error); } error = git_tree_lookup(&tree, repo, &tree_id); if(error) { die("could not create tree from id", error); } error = git_signature_new(&author, "helino", "*****@*****.**", 12345, 0); if(error) { die("could not create signature for author", error); } error = git_signature_new(&committer, "irock", "*****@*****.**", 12345, 0); if(error) { die("could not create signature for committer", error); } error = git_commit_create(&commit, repo, NULL, author, committer, NULL, "hello git", tree, 0, NULL); if(error) { die("could not commit", error); } git_oid_fmt(hash, &commit); printf("commit: %s\n", hash); error = git_reference_create_oid(&master, repo, "refs/heads/master", &commit, 1); if(error) { die("could not create master reference", error); } git_repository_free(repo); free(folder); return 0; }
int edit_repo(const char *repo_name) { int r; git_repository *repo; git_oid blob_id; git_oid oid; git_oid tree_id; git_signature *author; git_time_t time; git_config *config; git_index *index; git_tree *tree; git_treebuilder *tree_builder; git_treebuilder *empty_tree_builder; git_reference *head; git_commit *commit_parents[1]; char global_config_path[GIT_PATH_MAX]; char out[41]; out[40] = '\0'; // create the repository r = git_repository_open(&repo, repo_name); if (r) printf("error in opening repository\n"); printf("Repo opened\n"); // create a treebuilder r = git_treebuilder_create(&tree_builder, NULL); if (r) printf("error in creting treebuilder\n"); printf("Tree builder created\n"); // ADDING FIRST FILE // create a blob r = git_blob_create_fromdisk(&blob_id, repo, "test2"); if (r) printf("error in creating blob from disk\n"); printf("Blob created\n"); // insert into tree r = git_treebuilder_insert(NULL, tree_builder, "test1", &blob_id, 0100644); if (r) printf("error in inserting into treebuilder\n"); printf("Insert into treebuilder successful\n"); // write the tree to the repo r = git_treebuilder_write(&oid, repo, tree_builder); if (r) printf("error in writing the tree to the repo\n"); printf("Writing the tree to repo successful\n"); // tree lookup r = git_tree_lookup(&tree, repo, &oid); if (r) printf("error in tree lookup\n"); printf("Tree lookup done\n"); // create a author time = get_time(); r = git_signature_new(&author, "Varun Agrawal", "*****@*****.**", time, -300); if (r) printf("error in creating signature\n"); printf("Author signature created\n"); // obtaining the head r = git_repository_head(&head, repo); if (r) printf("error in obtaining the head\n"); r = git_reference_name_to_oid(&oid, repo, git_reference_name(head)); if (r) printf("error in obtaining the ref id of head\n"); printf("Obtained the head id %s\n", git_oid_tostr(out, 41, &oid)); git_commit_lookup(&commit_parents[0], repo, &oid); // create a commit r = git_commit_create( &oid, // object id repo, // repository "HEAD", // update reference, this will update the HEAD to this commit author, // author author, // committer NULL, // message encoding, by default UTF-8 is used "second commit", // message for the commit tree, // the git_tree object which will be used as the tree for this commit. don't know if NULL is valid 1, // number of parents. Don't know what value should be used here commit_parents); // array of pointers to the parents(git_commit *parents[]) if (r) printf("error in creating a commit\n"); printf("Commit created\n"); git_repository_free(repo); return 0; }
static int rebase_commit_merge( git_oid *commit_id, git_rebase *rebase, const git_signature *author, const git_signature *committer, const char *message_encoding, const char *message) { git_index *index = NULL; git_reference *head = NULL; git_commit *current_commit = NULL, *head_commit = NULL, *commit = NULL; git_rebase_operation *operation; git_tree *head_tree = NULL, *tree = NULL; git_diff *diff = NULL; git_oid tree_id; git_buf reflog_msg = GIT_BUF_INIT; char old_idstr[GIT_OID_HEXSZ], new_idstr[GIT_OID_HEXSZ]; int error; operation = git_array_get(rebase->operations, rebase->current); assert(operation); if ((error = git_repository_index(&index, rebase->repo)) < 0) goto done; if (git_index_has_conflicts(index)) { giterr_set(GITERR_REBASE, "Conflicts have not been resolved"); error = GIT_EMERGECONFLICT; goto done; } if ((error = git_commit_lookup(¤t_commit, rebase->repo, &operation->id)) < 0 || (error = git_repository_head(&head, rebase->repo)) < 0 || (error = git_reference_peel((git_object **)&head_commit, head, GIT_OBJ_COMMIT)) < 0 || (error = git_commit_tree(&head_tree, head_commit)) < 0 || (error = git_diff_tree_to_index(&diff, rebase->repo, head_tree, index, NULL)) < 0) goto done; if (git_diff_num_deltas(diff) == 0) { giterr_set(GITERR_REBASE, "This patch has already been applied"); error = GIT_EAPPLIED; goto done; } if ((error = git_index_write_tree(&tree_id, index)) < 0 || (error = git_tree_lookup(&tree, rebase->repo, &tree_id)) < 0) goto done; if (!author) author = git_commit_author(current_commit); if (!message) { message_encoding = git_commit_message_encoding(current_commit); message = git_commit_message(current_commit); } if ((error = git_commit_create(commit_id, rebase->repo, NULL, author, committer, message_encoding, message, tree, 1, (const git_commit **)&head_commit)) < 0 || (error = git_commit_lookup(&commit, rebase->repo, commit_id)) < 0 || (error = git_reference__update_for_commit( rebase->repo, NULL, "HEAD", commit_id, "rebase")) < 0) goto done; git_oid_fmt(old_idstr, git_commit_id(current_commit)); git_oid_fmt(new_idstr, commit_id); error = rebase_setupfile(rebase, REWRITTEN_FILE, O_CREAT|O_WRONLY|O_APPEND, "%.*s %.*s\n", GIT_OID_HEXSZ, old_idstr, GIT_OID_HEXSZ, new_idstr); done: git_buf_free(&reflog_msg); git_commit_free(commit); git_diff_free(diff); git_tree_free(tree); git_tree_free(head_tree); git_commit_free(head_commit); git_commit_free(current_commit); git_reference_free(head); git_index_free(index); return error; }
PyObject * Repository_create_commit(Repository *self, PyObject *args) { Signature *py_author, *py_committer; PyObject *py_oid, *py_message, *py_parents, *py_parent; PyObject *py_result = NULL; PyObject *tmessage; const char *message = NULL; char *update_ref = NULL; char *encoding = NULL; git_oid oid; git_tree *tree = NULL; int parent_count; git_commit **parents = NULL; int err = 0, i = 0; size_t len; if (!PyArg_ParseTuple(args, "zO!O!OOO!|s", &update_ref, &SignatureType, &py_author, &SignatureType, &py_committer, &py_message, &py_oid, &PyList_Type, &py_parents, &encoding)) return NULL; len = py_oid_to_git_oid(py_oid, &oid); if (len == 0) return NULL; message = py_str_borrow_c_str(&tmessage, py_message, encoding); if (message == NULL) return NULL; err = git_tree_lookup_prefix(&tree, self->repo, &oid, len); if (err < 0) { Error_set(err); goto out; } parent_count = (int)PyList_Size(py_parents); parents = malloc(parent_count * sizeof(git_commit*)); if (parents == NULL) { PyErr_SetNone(PyExc_MemoryError); goto out; } for (; i < parent_count; i++) { py_parent = PyList_GET_ITEM(py_parents, i); len = py_oid_to_git_oid(py_parent, &oid); if (len == 0) goto out; err = git_commit_lookup_prefix(&parents[i], self->repo, &oid, len); if (err < 0) { Error_set(err); goto out; } } err = git_commit_create(&oid, self->repo, update_ref, py_author->signature, py_committer->signature, encoding, message, tree, parent_count, (const git_commit**)parents); if (err < 0) { Error_set(err); goto out; } py_result = git_oid_to_python(&oid); out: Py_DECREF(tmessage); git_tree_free(tree); while (i > 0) { i--; git_commit_free(parents[i]); } free(parents); return py_result; }
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; }