Beispiel #1
0
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);
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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);
}
Beispiel #6
0
/**
 * 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;
}
Beispiel #7
0
/* 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);
}
Beispiel #8
0
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;
}
Beispiel #9
0
/*
 * 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);
}
Beispiel #10
0
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);
}
Beispiel #11
0
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);
}
Beispiel #12
0
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;
}
Beispiel #13
0
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);

}
Beispiel #14
0
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;
}
Beispiel #15
0
/*
 * 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);
}
Beispiel #16
0
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);
}
Beispiel #17
0
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;
}
Beispiel #18
0
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 );
}
Beispiel #19
0
/*
 *  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);
}
Beispiel #20
0
/*
 *  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);
}
Beispiel #21
0
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(&current_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;
}
Beispiel #22
0
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;
}
Beispiel #23
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);


}
Beispiel #24
0
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);
}
Beispiel #25
0
/* 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);
}
Beispiel #26
0
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;
}
Beispiel #27
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;
}
Beispiel #28
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(&current_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;
}
Beispiel #29
0
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;
}
Beispiel #30
0
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;
}