/** * We still need to fail if part of the namespace is * still in use. */ void test_refs_branches_create__name_vs_namespace_fail(void) { const char * name; struct item { const char *first; const char *first_alternate; const char *second; }; static const struct item item[] = { { "level_one/level_two", "level_one/alternate", "level_one" }, { "a/b/c/d/e", "a/b/c/d/alternate", "a/b/c/d" }, { "ss/tt/uu/vv/ww", "ss/alternate", "ss" }, { NULL, NULL, NULL }, }; const struct item *p; retrieve_known_commit(&target, repo); for (p=item; p->first; p++) { cl_git_pass(git_branch_create(&branch, repo, p->first, target, 0, NULL, NULL)); cl_git_pass(git_oid_cmp(git_reference_target(branch), git_commit_id(target))); cl_git_pass(git_branch_name(&name, branch)); cl_assert_equal_s(name, p->first); cl_git_pass(git_branch_delete(branch)); git_reference_free(branch); branch = NULL; cl_git_pass(git_branch_create(&branch, repo, p->first_alternate, target, 0, NULL, NULL)); cl_git_pass(git_oid_cmp(git_reference_target(branch), git_commit_id(target))); cl_git_pass(git_branch_name(&name, branch)); cl_assert_equal_s(name, p->first_alternate); /* we do not delete the alternate. */ git_reference_free(branch); branch = NULL; cl_git_fail(git_branch_create(&branch, repo, p->second, target, 0, NULL, NULL)); git_reference_free(branch); branch = NULL; } }
static bool same_suspect(git_blame__origin *a, git_blame__origin *b) { if (a == b) return true; if (git_oid_cmp(git_commit_id(a->commit), git_commit_id(b->commit))) return false; return 0 == strcmp(a->path, b->path); }
/** * Verify that we can create a branch with a name that matches the * namespace of a previously delete branch. * * git branch level_one/level_two * git branch -D level_one/level_two * git branch level_one * * We expect the delete to have deleted the files: * ".git/refs/heads/level_one/level_two" * ".git/logs/refs/heads/level_one/level_two" * It may or may not have deleted the (now empty) * containing directories. To match git.git behavior, * the second create needs to implicilty delete the * directories and create the new files. * "refs/heads/level_one" * "logs/refs/heads/level_one" * * We should not fail to create the branch or its * reflog because of an obsolete namespace container * directory. */ void test_refs_branches_create__name_vs_namespace(void) { const char * name; struct item { const char *first; const char *second; }; static const struct item item[] = { { "level_one/level_two", "level_one" }, { "a/b/c/d/e", "a/b/c/d" }, { "ss/tt/uu/vv/ww", "ss" }, /* And one test case that is deeper. */ { "xx1/xx2/xx3/xx4", "xx1/xx2/xx3/xx4/xx5/xx6" }, { NULL, NULL }, }; const struct item *p; retrieve_known_commit(&target, repo); for (p=item; p->first; p++) { cl_git_pass(git_branch_create(&branch, repo, p->first, target, 0, NULL, NULL)); cl_git_pass(git_oid_cmp(git_reference_target(branch), git_commit_id(target))); cl_git_pass(git_branch_name(&name, branch)); cl_assert_equal_s(name, p->first); cl_git_pass(git_branch_delete(branch)); git_reference_free(branch); branch = NULL; cl_git_pass(git_branch_create(&branch, repo, p->second, target, 0, NULL, NULL)); git_reference_free(branch); branch = NULL; } }
void test_refs_branches_create__can_create_a_local_branch(void) { retrieve_known_commit(&target, repo); cl_git_pass(git_branch_create(&branch, repo, NEW_BRANCH_NAME, target, 0, NULL, NULL)); cl_git_pass(git_oid_cmp(git_reference_target(branch), git_commit_id(target))); }
int git_branch_create( git_reference **ref_out, git_repository *repository, const char *branch_name, const git_commit *commit, int force) { git_reference *branch = NULL; git_buf canonical_branch_name = GIT_BUF_INIT; int error = -1; assert(branch_name && commit && ref_out); assert(git_object_owner((const git_object *)commit) == repository); if (git_buf_joinpath(&canonical_branch_name, GIT_REFS_HEADS_DIR, branch_name) < 0) goto cleanup; error = git_reference_create(&branch, repository, git_buf_cstr(&canonical_branch_name), git_commit_id(commit), force); if (!error) *ref_out = branch; cleanup: git_buf_free(&canonical_branch_name); return error; }
void CGitPropertyPage::DisplayCommit(const git_commit* commit, UINT hashLabel, UINT subjectLabel, UINT authorLabel, UINT dateLabel) { if (commit == NULL) { SetDlgItemText(m_hwnd, hashLabel, _T("")); SetDlgItemText(m_hwnd, subjectLabel, _T("")); SetDlgItemText(m_hwnd, authorLabel, _T("")); SetDlgItemText(m_hwnd, dateLabel, _T("")); return; } int encode = CP_UTF8; const char * encodingString = git_commit_message_encoding(commit); if (encodingString != NULL) encode = CUnicodeUtils::GetCPCode(CUnicodeUtils::GetUnicode(encodingString)); const git_signature * author = git_commit_author(commit); CString authorName = CUnicodeUtils::GetUnicode(author->name, encode); CString message = CUnicodeUtils::GetUnicode(git_commit_message(commit), encode); int start = 0; message = message.Tokenize(L"\n", start); SetDlgItemText(m_hwnd, hashLabel, CGitHash((char*)(git_commit_id(commit)->id)).ToString()); SetDlgItemText(m_hwnd, subjectLabel, message); SetDlgItemText(m_hwnd, authorLabel, authorName); CString authorDate; Time64ToTimeString(author->when.time, authorDate.GetBufferSetLength(200), 200); SetDlgItemText(m_hwnd, dateLabel, authorDate); }
/** Helper to print a commit object. */ static void print_commit(git_commit *commit) { char buf[GIT_OID_HEXSZ + 1]; int i, count; const git_signature *sig; const char *scan, *eol; git_oid_tostr(buf, sizeof(buf), git_commit_id(commit)); printf("commit %s\n", buf); if ((count = (int)git_commit_parentcount(commit)) > 1) { printf("Merge:"); for (i = 0; i < count; ++i) { git_oid_tostr(buf, 8, git_commit_parent_id(commit, i)); printf(" %s", buf); } printf("\n"); } if ((sig = git_commit_author(commit)) != NULL) { printf("Author: %s <%s>\n", sig->name, sig->email); print_time(&sig->when, "Date: "); } printf("\n"); for (scan = git_commit_message(commit); scan && *scan; ) { for (eol = scan; *eol && *eol != '\n'; ++eol) /* find eol */; printf(" %.*s\n", (int)(eol - scan), scan); scan = *eol ? eol + 1 : NULL; } printf("\n"); }
//go through history using the revwalker object bool MainWindow::walkHistory(git_commit* commit) { git_commit* wcommit; const char* cmsg; const git_oid* oid = git_commit_id(commit); git_oid commit_oid; git_oid_cpy(&commit_oid, oid); git_revwalk* walker; git_revwalk_new(&walker, repo); git_revwalk_sorting(walker, GIT_SORT_TOPOLOGICAL | GIT_SORT_TIME); git_revwalk_push(walker, &commit_oid); while (git_revwalk_next(&commit_oid, walker) == 0) { int error = git_commit_lookup(&wcommit, repo, &commit_oid); cmsg = git_commit_message(wcommit); qDebug() << "Commit msg = " << cmsg; git_commit_free(wcommit); } git_revwalk_free(walker); }
void test_object_tag_read__parse_without_message(void) { // read and parse a tag without a message field git_repository *short_tag_repo; git_tag *short_tag; git_commit *commit; git_oid id, id_commit; // TODO: This is a little messy cl_git_pass(git_repository_open(&short_tag_repo, cl_fixture("short_tag.git"))); git_oid_fromstr(&id, short_tag_id); git_oid_fromstr(&id_commit, short_tagged_commit); cl_git_pass(git_tag_lookup(&short_tag, short_tag_repo, &id)); cl_assert(short_tag != NULL); cl_assert_equal_s(git_tag_name(short_tag), "no_description"); cl_assert(git_oid_cmp(&id, git_tag_id(short_tag)) == 0); cl_assert(short_tag->message == NULL); cl_git_pass(git_tag_target((git_object **)&commit, short_tag)); cl_assert(commit != NULL); cl_assert(git_oid_cmp(&id_commit, git_commit_id(commit)) == 0); git_tag_free(short_tag); git_commit_free(commit); git_repository_free(short_tag_repo); }
void test_object_tag_read__parse(void) { // read and parse a tag from the repository git_tag *tag1, *tag2; git_commit *commit; git_oid id1, id2, id_commit; git_oid_fromstr(&id1, tag1_id); git_oid_fromstr(&id2, tag2_id); git_oid_fromstr(&id_commit, tagged_commit); cl_git_pass(git_tag_lookup(&tag1, g_repo, &id1)); cl_assert_equal_s(git_tag_name(tag1), "test"); cl_assert(git_tag_type(tag1) == GIT_OBJ_TAG); cl_git_pass(git_tag_target((git_object **)&tag2, tag1)); cl_assert(tag2 != NULL); cl_assert(git_oid_cmp(&id2, git_tag_id(tag2)) == 0); cl_git_pass(git_tag_target((git_object **)&commit, tag2)); cl_assert(commit != NULL); cl_assert(git_oid_cmp(&id_commit, git_commit_id(commit)) == 0); git_tag_free(tag1); git_tag_free(tag2); git_commit_free(commit); }
static void get_annotated_commit(git_annotated_commit **annotated_commit, VALUE rb_repo, VALUE rb_value) { git_repository *repo; int error; rugged_check_repo(rb_repo); Data_Get_Struct(rb_repo, git_repository, repo); if (rb_obj_is_kind_of(rb_value, rb_cRuggedCommit)) { const git_commit * commit; const git_oid * oid; Data_Get_Struct(rb_value, git_commit, commit); oid = git_commit_id(commit); error = git_annotated_commit_lookup(annotated_commit, repo, oid); } else if (rb_obj_is_kind_of(rb_value, rb_cRuggedReference)) { const git_reference * ref; Data_Get_Struct(rb_value, git_reference, ref); error = git_annotated_commit_from_ref(annotated_commit, repo, ref); } else if (TYPE(rb_value) == T_STRING) { error = git_annotated_commit_from_revspec(annotated_commit, repo, StringValueCStr(rb_value)); } else { rb_raise(rb_eTypeError, "Expecting a Rugged::Reference, Rugged::Commit or String instance"); } rugged_exception_check(error); }
void test_object_tag_read__parse_without_tagger(void) { // read and parse a tag without a tagger field git_repository *bad_tag_repo; git_tag *bad_tag; git_commit *commit; git_oid id, id_commit; // TODO: This is a little messy cl_git_pass(git_repository_open(&bad_tag_repo, cl_fixture("bad_tag.git"))); git_oid_fromstr(&id, bad_tag_id); git_oid_fromstr(&id_commit, badly_tagged_commit); cl_git_pass(git_tag_lookup(&bad_tag, bad_tag_repo, &id)); cl_assert(bad_tag != NULL); cl_assert_equal_s(git_tag_name(bad_tag), "e90810b"); cl_assert(git_oid_cmp(&id, git_tag_id(bad_tag)) == 0); cl_assert(bad_tag->tagger == NULL); cl_git_pass(git_tag_target((git_object **)&commit, bad_tag)); cl_assert(commit != NULL); cl_assert(git_oid_cmp(&id_commit, git_commit_id(commit)) == 0); git_tag_free(bad_tag); git_commit_free(commit); git_repository_free(bad_tag_repo); }
static int rebase_commit_inmemory( git_oid *commit_id, git_rebase *rebase, const git_signature *author, const git_signature *committer, const char *message_encoding, const char *message) { git_commit *commit = NULL; int error = 0; assert(rebase->index); assert(rebase->last_commit); assert(rebase->current < rebase->operations.size); if ((error = rebase_commit__create(&commit, rebase, rebase->index, rebase->last_commit, author, committer, message_encoding, message)) < 0) goto done; git_commit_free(rebase->last_commit); rebase->last_commit = commit; git_oid_cpy(commit_id, git_commit_id(commit)); done: if (error < 0) git_commit_free(commit); return error; }
int git_commit__writeback(git_commit *commit, git_odb_source *src) { unsigned int i; if (commit->tree == NULL) return GIT_EMISSINGOBJDATA; git__write_oid(src, "tree", git_tree_id(commit->tree)); for (i = 0; i < commit->parents.length; ++i) { git_commit *parent; parent = git_vector_get(&commit->parents, i); git__write_oid(src, "parent", git_commit_id(parent)); } if (commit->author == NULL) return GIT_EMISSINGOBJDATA; git_signature__write(src, "author", commit->author); if (commit->committer == NULL) return GIT_EMISSINGOBJDATA; git_signature__write(src, "committer", commit->committer); if (commit->message != NULL) git__source_printf(src, "\n%s", commit->message); /* Mark the commit as having all attributes */ commit->full_parse = 1; return GIT_SUCCESS; }
/** * Init slots in S4 class git_commit * * @param source a commit object * @param repo S4 class git_repository that contains the blob * @param dest S4 class git_commit to initialize * @return void */ void git2r_commit_init(git_commit *source, SEXP repo, SEXP dest) { const char *message; const char *summary; const git_signature *author; const git_signature *committer; char sha[GIT_OID_HEXSZ + 1]; git_oid_fmt(sha, git_commit_id(source)); sha[GIT_OID_HEXSZ] = '\0'; SET_SLOT(dest, Rf_install("sha"), mkString(sha)); author = git_commit_author(source); if (author) git2r_signature_init(author, GET_SLOT(dest, Rf_install("author"))); committer = git_commit_committer(source); if (committer) git2r_signature_init(committer, GET_SLOT(dest, Rf_install("committer"))); summary = git_commit_summary(source); if (summary) SET_SLOT(dest, Rf_install("summary"), mkString(summary)); message = git_commit_message(source); if (message) SET_SLOT(dest, Rf_install("message"), mkString(message)); SET_SLOT(dest, Rf_install("repo"), repo); }
int GitRev::ParserFromCommit(const git_commit* commit) { Clear(); int encode = CP_UTF8; const char* encodingstr = git_commit_message_encoding(commit); if (encodingstr) encode = CUnicodeUtils::GetCPCode(CUnicodeUtils::GetUnicode(encodingstr)); m_CommitHash = git_commit_id(commit)->id; const git_signature* author = git_commit_author(commit); m_AuthorDate = author->when.time; m_AuthorEmail = CUnicodeUtils::GetUnicode(author->email, encode); m_AuthorName = CUnicodeUtils::GetUnicode(author->name, encode); const git_signature* committer = git_commit_committer(commit); m_CommitterDate = committer->when.time; m_CommitterEmail = CUnicodeUtils::GetUnicode(committer->email, encode); m_CommitterName = CUnicodeUtils::GetUnicode(committer->name, encode); const char* msg = git_commit_message_raw(commit); const char* body = strchr(msg, '\n'); if (!body) m_Subject = CUnicodeUtils::GetUnicode(msg, encode); else { m_Subject = CUnicodeUtils::GetUnicode(CStringA(msg, (int)(body - msg)), encode); m_Body = CUnicodeUtils::GetUnicode(body + 1, encode); } return 0; }
void test_diff_format_email__invalid_no(void) { git_oid oid; git_commit *commit = NULL; git_diff *diff = NULL; git_diff_format_email_options opts = GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT; git_buf buf = GIT_BUF_INIT; git_oid_fromstr(&oid, "9264b96c6d104d0e07ae33d3007b6a48246c6f92"); cl_git_pass(git_commit_lookup(&commit, repo, &oid)); opts.id = git_commit_id(commit); opts.author = git_commit_author(commit); opts.summary = git_commit_summary(commit); opts.patch_no = 2; opts.total_patches = 1; cl_git_pass(git_diff__commit(&diff, repo, commit, NULL)); cl_git_fail(git_diff_format_email(&buf, diff, &opts)); cl_git_fail(git_diff_commit_as_email(&buf, repo, commit, 2, 1, 0, NULL)); cl_git_fail(git_diff_commit_as_email(&buf, repo, commit, 0, 0, 0, NULL)); git_diff_free(diff); git_commit_free(commit); git_buf_free(&buf); }
static void assert_email_match( const char *expected, const char *oidstr, git_diff_format_email_options *opts) { git_oid oid; git_commit *commit = NULL; git_diff *diff = NULL; git_buf buf = GIT_BUF_INIT; git_oid_fromstr(&oid, oidstr); cl_git_pass(git_commit_lookup(&commit, repo, &oid)); opts->id = git_commit_id(commit); opts->author = git_commit_author(commit); if (!opts->summary) opts->summary = git_commit_summary(commit); cl_git_pass(git_diff__commit(&diff, repo, commit, NULL)); cl_git_pass(git_diff_format_email(&buf, diff, opts)); cl_assert_equal_s(expected, git_buf_cstr(&buf)); git_buf_clear(&buf); cl_git_pass(git_diff_commit_as_email( &buf, repo, commit, 1, 1, opts->flags, NULL)); cl_assert_equal_s(expected, git_buf_cstr(&buf)); git_diff_free(diff); git_commit_free(commit); git_buf_free(&buf); }
// ReadTree is/must only be executed on an empty list int CGitHeadFileList::ReadTree() { CAutoWriteLock lock(m_SharedMutex); ATLASSERT(empty()); CAutoRepository repository(m_Gitdir); CAutoCommit commit; CAutoTree tree; bool ret = repository; ret = ret && !git_commit_lookup(commit.GetPointer(), repository, (const git_oid*)m_Head.m_hash); ret = ret && !git_commit_tree(tree.GetPointer(), commit); try { ret = ret && !ReadTreeRecursive(*repository, tree, "", CGitHeadFileList::CallBack, this); } catch (const std::bad_alloc& ex) { CTraceToOutputDebugString::Instance()(__FUNCTION__ ": Catched exception inside ReadTreeRecursive: %s\n", ex.what()); return -1; } if (!ret) { clear(); m_LastModifyTimeHead = 0; return -1; } std::sort(this->begin(), this->end(), SortTree); m_TreeHash = git_commit_id(commit)->id; return 0; }
void git_blame__like_git(git_blame *blame, uint32_t opt) { while (true) { git_blame__entry *ent; git_blame__origin *suspect = NULL; /* Find a suspect to break down */ for (ent = blame->ent; !suspect && ent; ent = ent->next) if (!ent->guilty) suspect = ent->suspect; if (!suspect) return; /* all done */ /* We'll use this suspect later in the loop, so hold on to it for now. */ origin_incref(suspect); pass_blame(blame, suspect, opt); /* Take responsibility for the remaining entries */ for (ent = blame->ent; ent; ent = ent->next) { if (same_suspect(ent->suspect, suspect)) { ent->guilty = true; ent->is_boundary = !git_oid_cmp( git_commit_id(suspect->commit), &blame->options.oldest_commit); } } origin_decref(suspect); } coalesce(blame); }
void test_refs_branches_create__can_force_create_over_an_existing_branch(void) { retrieve_known_commit(&target, repo); cl_git_pass(git_branch_create(&branch, repo, "br2", target, 1, NULL, NULL)); cl_git_pass(git_oid_cmp(git_reference_target(branch), git_commit_id(target))); cl_assert_equal_s("refs/heads/br2", git_reference_name(branch)); }
int git_revert( git_repository *repo, git_commit *commit, const git_revert_options *given_opts) { git_revert_options opts; git_reference *our_ref = NULL; git_commit *our_commit = NULL; char commit_oidstr[GIT_OID_HEXSZ + 1]; const char *commit_msg; git_buf their_label = GIT_BUF_INIT; git_index *index = NULL; git_indexwriter indexwriter = GIT_INDEXWRITER_INIT; int error; assert(repo && commit); GITERR_CHECK_VERSION(given_opts, GIT_REVERT_OPTIONS_VERSION, "git_revert_options"); if ((error = git_repository__ensure_not_bare(repo, "revert")) < 0) return error; git_oid_fmt(commit_oidstr, git_commit_id(commit)); commit_oidstr[GIT_OID_HEXSZ] = '\0'; if ((commit_msg = git_commit_summary(commit)) == NULL) { error = -1; goto on_error; } if ((error = git_buf_printf(&their_label, "parent of %.7s... %s", commit_oidstr, commit_msg)) < 0 || (error = revert_normalize_opts(repo, &opts, given_opts, git_buf_cstr(&their_label))) < 0 || (error = git_indexwriter_init_for_operation(&indexwriter, repo, &opts.checkout_opts.checkout_strategy)) < 0 || (error = write_revert_head(repo, commit_oidstr)) < 0 || (error = write_merge_msg(repo, commit_oidstr, commit_msg)) < 0 || (error = git_repository_head(&our_ref, repo)) < 0 || (error = git_reference_peel((git_object **)&our_commit, our_ref, GIT_OBJ_COMMIT)) < 0 || (error = git_revert_commit(&index, repo, commit, our_commit, opts.mainline, &opts.merge_opts)) < 0 || (error = git_merge__check_result(repo, index)) < 0 || (error = git_merge__append_conflicts_to_merge_msg(repo, index)) < 0 || (error = git_checkout_index(repo, index, &opts.checkout_opts)) < 0 || (error = git_indexwriter_commit(&indexwriter)) < 0) goto on_error; goto done; on_error: revert_state_cleanup(repo); done: git_indexwriter_cleanup(&indexwriter); git_index_free(index); git_commit_free(our_commit); git_reference_free(our_ref); git_buf_free(&their_label); return error; }
static void test_copy_note( const git_rebase_options *opts, bool should_exist) { git_rebase *rebase; git_reference *branch_ref, *upstream_ref; git_annotated_commit *branch_head, *upstream_head; git_commit *branch_commit; git_rebase_operation *rebase_operation; git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT; git_oid note_id, commit_id; git_note *note = NULL; int error; checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE; cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/gravy")); cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/veal")); cl_git_pass(git_annotated_commit_from_ref(&branch_head, repo, branch_ref)); cl_git_pass(git_annotated_commit_from_ref(&upstream_head, repo, upstream_ref)); cl_git_pass(git_reference_peel((git_object **)&branch_commit, branch_ref, GIT_OBJ_COMMIT)); /* Add a note to a commit */ cl_git_pass(git_note_create(¬e_id, repo, "refs/notes/test", git_commit_author(branch_commit), git_commit_committer(branch_commit), git_commit_id(branch_commit), "This is a commit note.", 0)); cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, opts)); cl_git_pass(git_rebase_next(&rebase_operation, rebase, &checkout_opts)); cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature, NULL, NULL)); cl_git_pass(git_rebase_finish(rebase, signature, opts)); cl_assert_equal_i(GIT_REPOSITORY_STATE_NONE, git_repository_state(repo)); if (should_exist) { cl_git_pass(git_note_read(¬e, repo, "refs/notes/test", &commit_id)); cl_assert_equal_s("This is a commit note.", git_note_message(note)); } else { cl_git_fail(error = git_note_read(¬e, repo, "refs/notes/test", &commit_id)); cl_assert_equal_i(GIT_ENOTFOUND, error); } git_note_free(note); git_commit_free(branch_commit); git_annotated_commit_free(branch_head); git_annotated_commit_free(upstream_head); git_reference_free(branch_ref); git_reference_free(upstream_ref); git_rebase_free(rebase); }
static int cherry_pick_seterr(git_commit *commit, const char *fmt) { char commit_oidstr[GIT_OID_HEXSZ + 1]; giterr_set(GITERR_CHERRYPICK, fmt, git_oid_tostr(commit_oidstr, GIT_OID_HEXSZ + 1, git_commit_id(commit))); return -1; }
int git_branch_create( git_reference **ref_out, git_repository *repository, const char *branch_name, const git_commit *commit, int force) { return create_branch(ref_out, repository, branch_name, commit, git_oid_tostr_s(git_commit_id(commit)), force); }
static const git_oid *commit_parent_from_varargs(size_t curr, void *payload) { commit_parent_varargs *data = payload; const git_commit *commit; if (curr >= data->total) return NULL; commit = va_arg(data->args, const git_commit *); return commit ? git_commit_id(commit) : NULL; }
int merge_trees_from_branches( git_index **index, git_repository *repo, const char *ours_name, const char *theirs_name, git_merge_tree_opts *opts) { git_commit *our_commit, *their_commit, *ancestor_commit = NULL; git_tree *our_tree, *their_tree, *ancestor_tree = NULL; git_oid our_oid, their_oid, ancestor_oid; git_buf branch_buf = GIT_BUF_INIT; int error; git_buf_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, ours_name); cl_git_pass(git_reference_name_to_id(&our_oid, repo, branch_buf.ptr)); cl_git_pass(git_commit_lookup(&our_commit, repo, &our_oid)); git_buf_clear(&branch_buf); git_buf_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, theirs_name); cl_git_pass(git_reference_name_to_id(&their_oid, repo, branch_buf.ptr)); cl_git_pass(git_commit_lookup(&their_commit, repo, &their_oid)); error = git_merge_base(&ancestor_oid, repo, git_commit_id(our_commit), git_commit_id(their_commit)); if (error != GIT_ENOTFOUND) { cl_git_pass(error); cl_git_pass(git_commit_lookup(&ancestor_commit, repo, &ancestor_oid)); cl_git_pass(git_commit_tree(&ancestor_tree, ancestor_commit)); } cl_git_pass(git_commit_tree(&our_tree, our_commit)); cl_git_pass(git_commit_tree(&their_tree, their_commit)); cl_git_pass(git_merge_trees(index, repo, ancestor_tree, our_tree, their_tree, opts)); git_buf_free(&branch_buf); git_tree_free(our_tree); git_tree_free(their_tree); git_tree_free(ancestor_tree); git_commit_free(our_commit); git_commit_free(their_commit); git_commit_free(ancestor_commit); 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_rebase_operation *operation; git_reference *head = NULL; git_commit *head_commit = NULL, *commit = NULL; git_index *index = NULL; 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 = rebase_ensure_not_dirty(rebase->repo, false, true, GIT_EUNMERGED)) < 0 || (error = git_repository_head(&head, rebase->repo)) < 0 || (error = git_reference_peel((git_object **)&head_commit, head, GIT_OBJ_COMMIT)) < 0 || (error = git_repository_index(&index, rebase->repo)) < 0 || (error = rebase_commit__create(&commit, rebase, index, head_commit, author, committer, message_encoding, message)) < 0 || (error = git_reference__update_for_commit( rebase->repo, NULL, "HEAD", git_commit_id(commit), "rebase")) < 0) goto done; git_oid_fmt(old_idstr, &operation->id); git_oid_fmt(new_idstr, git_commit_id(commit)); if ((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)) < 0) goto done; git_oid_cpy(commit_id, git_commit_id(commit)); done: git_index_free(index); git_reference_free(head); git_commit_free(head_commit); git_commit_free(commit); return error; }
static int create_branch( git_reference **ref_out, git_repository *repository, const char *branch_name, const git_commit *commit, const char *from, int force) { int is_unmovable_head = 0; git_reference *branch = NULL; git_buf canonical_branch_name = GIT_BUF_INIT, log_message = GIT_BUF_INIT; int error = -1; int bare = git_repository_is_bare(repository); assert(branch_name && commit && ref_out); assert(git_object_owner((const git_object *)commit) == repository); if (force && !bare && git_branch_lookup(&branch, repository, branch_name, GIT_BRANCH_LOCAL) == 0) { error = git_branch_is_head(branch); git_reference_free(branch); branch = NULL; if (error < 0) goto cleanup; is_unmovable_head = error; } if (is_unmovable_head && force) { giterr_set(GITERR_REFERENCE, "Cannot force update branch '%s' as it is " "the current HEAD of the repository.", branch_name); error = -1; goto cleanup; } if (git_buf_joinpath(&canonical_branch_name, GIT_REFS_HEADS_DIR, branch_name) < 0) goto cleanup; if (git_buf_printf(&log_message, "branch: Created from %s", from) < 0) goto cleanup; error = git_reference_create(&branch, repository, git_buf_cstr(&canonical_branch_name), git_commit_id(commit), force, git_buf_cstr(&log_message)); if (!error) *ref_out = branch; cleanup: git_buf_free(&canonical_branch_name); git_buf_free(&log_message); return error; }
static const git_oid *commit_parent_from_array(size_t curr, void *payload) { commit_parent_data *data = payload; const git_commit *commit; if (curr >= data->total) return NULL; commit = data->parents[curr]; if (git_commit_owner(commit) != data->repo) return NULL; return git_commit_id(commit); }