void test_reset_mixed__reflog_is_correct(void) { git_buf buf = GIT_BUF_INIT; const char *exp_msg = "commit: Updating test data so we can test inter-hunk-context"; reflog_check(repo, "HEAD", 9, "*****@*****.**", exp_msg); reflog_check(repo, "refs/heads/master", 9, "*****@*****.**", exp_msg); /* Branch not moving, no reflog entry */ cl_git_pass(git_revparse_single(&target, repo, "HEAD^{commit}")); cl_git_pass(git_reset(repo, target, GIT_RESET_MIXED, NULL)); reflog_check(repo, "HEAD", 9, "*****@*****.**", exp_msg); reflog_check(repo, "refs/heads/master", 9, "*****@*****.**", exp_msg); git_object_free(target); target = NULL; /* Moved branch, expect default message */ cl_git_pass(git_revparse_single(&target, repo, "HEAD~^{commit}")); git_buf_clear(&buf); cl_git_pass(git_buf_printf(&buf, "reset: moving to %s", git_oid_tostr_s(git_object_id(target)))); cl_git_pass(git_reset(repo, target, GIT_RESET_MIXED, NULL)); reflog_check(repo, "HEAD", 10, NULL, git_buf_cstr(&buf)); reflog_check(repo, "refs/heads/master", 10, NULL, git_buf_cstr(&buf)); git_buf_free(&buf); }
int git_reset( git_repository *repo, const git_object *target, git_reset_t reset_type, const git_checkout_options *checkout_opts) { return reset(repo, target, git_oid_tostr_s(git_object_id(target)), reset_type, checkout_opts); }
emacs_value egit_tag_id(emacs_env *env, emacs_value _tag) { EGIT_ASSERT_TAG(_tag); git_tag *tag = EGIT_EXTRACT(_tag); const git_oid *oid = git_tag_id(tag); const char *oid_s = git_oid_tostr_s(oid); return EM_STRING(oid_s); }
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); }
emacs_value egit_blame_hunk_commit_id(emacs_env *env, emacs_value _hunk, emacs_value orig) { EGIT_ASSERT_BLAME_HUNK(_hunk); git_blame_hunk *hunk = EGIT_EXTRACT(_hunk); const char *oid_s = git_oid_tostr_s( EM_EXTRACT_BOOLEAN(orig) ? &hunk->final_commit_id : &hunk->orig_commit_id ); return EM_STRING(oid_s); }
void test_stash_save__stashing_updates_the_reflog(void) { assert_object_oid("refs/stash@{0}", NULL, GIT_OBJ_COMMIT); cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_DEFAULT)); assert_object_oid("refs/stash@{0}", git_oid_tostr_s(&stash_tip_oid), GIT_OBJ_COMMIT); assert_object_oid("refs/stash@{1}", NULL, GIT_OBJ_COMMIT); }
Commit Commit::FromGitOid(const class Repository &repo, const git_oid &oid) { git_commit *commit; if (git_commit_lookup(&commit, repo.GetGitPointer(), &oid) != GIT_OK) { string message{"Git commit lookup failed for oid: "}; message += git_oid_tostr_s(&oid); throw message; } return Commit{repo, commit}; }
int egit_tag_foreach_callback(const char *name, git_oid *oid, void *payload) { egit_generic_payload *ctx = (egit_generic_payload*) payload; emacs_env *env = ctx->env; emacs_value args[2]; args[0] = EM_STRING(name); const char *oid_s = git_oid_tostr_s(oid); args[1] = EM_STRING(oid_s); env->funcall(env, ctx->func, 2, args); EM_RETURN_IF_NLE(GIT_EUSER); return 0; }
void test_refs_reflog_messages__creating_branches_default_messages(void) { git_buf buf = GIT_BUF_INIT; git_annotated_commit *annotated; git_object *obj; git_commit *target; git_reference *branch1, *branch2; cl_git_pass(git_revparse_single(&obj, g_repo, "e90810b8df3")); cl_git_pass(git_commit_lookup(&target, g_repo, git_object_id(obj))); git_object_free(obj); cl_git_pass(git_branch_create(&branch1, g_repo, NEW_BRANCH_NAME, target, false)); cl_git_pass(git_buf_printf(&buf, "branch: Created from %s", git_oid_tostr_s(git_commit_id(target)))); cl_reflog_check_entry(g_repo, "refs/heads/" NEW_BRANCH_NAME, 0, GIT_OID_HEX_ZERO, git_oid_tostr_s(git_commit_id(target)), g_email, git_buf_cstr(&buf)); cl_git_pass(git_reference_remove(g_repo, "refs/heads/" NEW_BRANCH_NAME)); cl_git_pass(git_annotated_commit_from_revspec(&annotated, g_repo, "e90810b8df3")); cl_git_pass(git_branch_create_from_annotated(&branch2, g_repo, NEW_BRANCH_NAME, annotated, true)); cl_reflog_check_entry(g_repo, "refs/heads/" NEW_BRANCH_NAME, 0, GIT_OID_HEX_ZERO, git_oid_tostr_s(git_commit_id(target)), g_email, "branch: Created from e90810b8df3"); git_annotated_commit_free(annotated); git_buf_free(&buf); git_commit_free(target); git_reference_free(branch1); git_reference_free(branch2); }
void test_refs_branches_create__default_reflog_message(void) { git_reflog *log; git_buf buf = GIT_BUF_INIT; const git_reflog_entry *entry; git_annotated_commit *annotated; git_signature *sig; git_config *cfg; cl_git_pass(git_repository_config(&cfg, repo)); cl_git_pass(git_config_set_string(cfg, "user.name", "Foo Bar")); cl_git_pass(git_config_set_string(cfg, "user.email", "*****@*****.**")); git_config_free(cfg); cl_git_pass(git_signature_default(&sig, repo)); retrieve_known_commit(&target, repo); cl_git_pass(git_branch_create(&branch, repo, NEW_BRANCH_NAME, target, false)); cl_git_pass(git_reflog_read(&log, repo, "refs/heads/" NEW_BRANCH_NAME)); entry = git_reflog_entry_byindex(log, 0); cl_git_pass(git_buf_printf(&buf, "branch: Created from %s", git_oid_tostr_s(git_commit_id(target)))); cl_assert_equal_s(git_buf_cstr(&buf), git_reflog_entry_message(entry)); cl_assert_equal_s(sig->email, git_reflog_entry_committer(entry)->email); cl_git_pass(git_reference_remove(repo, "refs/heads/" NEW_BRANCH_NAME)); git_reference_free(branch); git_reflog_free(log); git_buf_clear(&buf); cl_git_pass(git_annotated_commit_from_revspec(&annotated, repo, "e90810b8df3")); cl_git_pass(git_branch_create_from_annotated(&branch, repo, NEW_BRANCH_NAME, annotated, true)); cl_git_pass(git_reflog_read(&log, repo, "refs/heads/" NEW_BRANCH_NAME)); entry = git_reflog_entry_byindex(log, 0); cl_git_pass(git_buf_printf(&buf, "branch: Created from e90810b8df3")); cl_assert_equal_s(git_buf_cstr(&buf), git_reflog_entry_message(entry)); cl_assert_equal_s(sig->email, git_reflog_entry_committer(entry)->email); git_annotated_commit_free(annotated); git_buf_free(&buf); git_reflog_free(log); git_signature_free(sig); }
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); }
void test_reset_hard__reflog_is_correct(void) { git_buf buf = GIT_BUF_INIT; git_annotated_commit *annotated; const char *exp_msg = "commit: Add a file which name should appear before the " "\"subdir/\" folder while being dealt with by the treewalker"; reflog_check(repo, "HEAD", 3, "*****@*****.**", exp_msg); reflog_check(repo, "refs/heads/master", 3, "*****@*****.**", exp_msg); /* Branch not moving, no reflog entry */ cl_git_pass(git_revparse_single(&target, repo, "HEAD^{commit}")); cl_git_pass(git_reset(repo, target, GIT_RESET_HARD, NULL)); reflog_check(repo, "HEAD", 3, "*****@*****.**", exp_msg); reflog_check(repo, "refs/heads/master", 3, "*****@*****.**", exp_msg); git_object_free(target); /* Moved branch, expect id in message */ cl_git_pass(git_revparse_single(&target, repo, "HEAD~^{commit}")); cl_git_pass(git_buf_printf(&buf, "reset: moving to %s", git_oid_tostr_s(git_object_id(target)))); cl_git_pass(git_reset(repo, target, GIT_RESET_HARD, NULL)); reflog_check(repo, "HEAD", 4, NULL, git_buf_cstr(&buf)); reflog_check(repo, "refs/heads/master", 4, NULL, git_buf_cstr(&buf)); git_buf_free(&buf); /* Moved branch, expect revspec in message */ exp_msg = "reset: moving to HEAD~^{commit}"; cl_git_pass(git_annotated_commit_from_revspec(&annotated, repo, "HEAD~^{commit}")); cl_git_pass(git_reset_from_annotated(repo, annotated, GIT_RESET_HARD, NULL)); reflog_check(repo, "HEAD", 5, NULL, exp_msg); reflog_check(repo, "refs/heads/master", 5, NULL, exp_msg); git_annotated_commit_free(annotated); }
int git_reset( git_repository *repo, git_object *target, git_reset_t reset_type, git_checkout_options *checkout_opts) { git_object *commit = NULL; git_index *index = NULL; git_tree *tree = NULL; int error = 0; git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; git_buf log_message = GIT_BUF_INIT; assert(repo && target); if (checkout_opts) opts = *checkout_opts; if (git_object_owner(target) != repo) { giterr_set(GITERR_OBJECT, "%s - The given target does not belong to this repository.", ERROR_MSG); return -1; } if (reset_type != GIT_RESET_SOFT && (error = git_repository__ensure_not_bare(repo, reset_type == GIT_RESET_MIXED ? "reset mixed" : "reset hard")) < 0) return error; if ((error = git_object_peel(&commit, target, GIT_OBJ_COMMIT)) < 0 || (error = git_repository_index(&index, repo)) < 0 || (error = git_commit_tree(&tree, (git_commit *)commit)) < 0) goto cleanup; if (reset_type == GIT_RESET_SOFT && (git_repository_state(repo) == GIT_REPOSITORY_STATE_MERGE || git_index_has_conflicts(index))) { giterr_set(GITERR_OBJECT, "%s (soft) in the middle of a merge.", ERROR_MSG); error = GIT_EUNMERGED; goto cleanup; } if ((error = git_buf_printf(&log_message, "reset: moving to %s", git_oid_tostr_s(git_object_id(commit)))) < 0) return error; /* move HEAD to the new target */ if ((error = git_reference__update_terminal(repo, GIT_HEAD_FILE, git_object_id(commit), NULL, git_buf_cstr(&log_message))) < 0) goto cleanup; if (reset_type == GIT_RESET_HARD) { /* overwrite working directory with HEAD */ opts.checkout_strategy = GIT_CHECKOUT_FORCE; if ((error = git_checkout_tree(repo, (git_object *)tree, &opts)) < 0) goto cleanup; } if (reset_type > GIT_RESET_SOFT) { /* reset index to the target content */ if ((error = git_index_read_tree(index, tree)) < 0 || (error = git_index_write(index)) < 0) goto cleanup; if ((error = git_repository_state_cleanup(repo)) < 0) { giterr_set(GITERR_INDEX, "%s - failed to clean up merge data", ERROR_MSG); goto cleanup; } } cleanup: git_object_free(commit); git_index_free(index); git_tree_free(tree); git_buf_free(&log_message); return error; }
void QGit::listCommits(QString object, int length) { QList<QGitCommit> commits; git_repository *repo = nullptr; git_revwalk *walker = nullptr; git_commit *parent = nullptr; git_commit *commit = nullptr; git_diff *diff = nullptr; git_oid oid; int count = 0; int res = 0; QGitError error; try { res = git_repository_open(&repo, m_path.absolutePath().toUtf8().constData()); if (res) { throw QGitError("git_repository_open", res); } res = git_revwalk_new(&walker, repo); if (res) { throw QGitError("git_revwalk_new", res); } if (object.isEmpty()) { res = git_revwalk_push_head(walker); if (res) { length = 0; } } else { res = git_oid_fromstr(&oid, object.toLatin1().constData()); if (res) { throw QGitError("git_oid_fromstr", res); } res = git_revwalk_push(walker, &oid); if (res) { throw QGitError("git_revwalk_push", res); } memset(&oid, 0, sizeof(oid)); git_revwalk_next(&oid, walker); memset(&oid, 0, sizeof(oid)); } while ((!git_revwalk_next(&oid, walker))&&(count < length)) { QGitCommit item; unsigned int parents = 0; QString commit_id; QList<QGitCommitDiffParent> commit_parents; QDateTime commit_time; QGitSignature commit_author; QGitSignature commit_commiter; QString commit_message; res = git_commit_lookup(&commit, repo, &oid); if (res) { throw QGitError("git_commit_lookup", res); } commit_id = QString::fromUtf8(git_oid_tostr_s(&oid)); parents = git_commit_parentcount(commit); for(unsigned int index = 0; index < parents; index++) { git_commit *parent = nullptr; QByteArray parentStr; res = git_commit_parent(&parent, commit, index); if (res) { throw QGitError("git_commit_parent", res); } const git_oid *parent_iod = git_commit_id(parent); parentStr = QByteArray(git_oid_tostr_s(parent_iod)); commit_parents.append(QGitCommitDiffParent(parentStr)); git_commit_free(parent); parent = nullptr; } auto time = git_commit_time(commit); auto timeOffset = git_commit_time_offset(commit); commit_time = QDateTime::fromMSecsSinceEpoch(time * 1000); commit_time.setOffsetFromUtc(timeOffset * 60); QString author_name = QString::fromUtf8(git_commit_author(commit)->name); QString author_email = QString::fromUtf8(git_commit_author(commit)->email); QDateTime author_when = QDateTime::fromMSecsSinceEpoch(git_commit_author(commit)->when.time * 1000); author_when.setOffsetFromUtc(git_commit_author(commit)->when.offset * 60); commit_author = QGitSignature(author_name, author_email, author_when); QString commiter_name = QString::fromUtf8(git_commit_committer(commit)->name); QString commiter_email = QString::fromUtf8(git_commit_committer(commit)->email); QDateTime commiter_when = QDateTime::fromMSecsSinceEpoch(git_commit_committer(commit)->when.time * 1000); commiter_when.setOffsetFromUtc(git_commit_committer(commit)->when.offset * 60); commit_commiter = QGitSignature(commiter_name, commiter_email, commiter_when); commit_message = QString::fromUtf8(git_commit_message(commit)); item = QGitCommit(commit_id, commit_parents, commit_time, commit_author, commit_commiter, commit_message); commits.push_back(item); git_diff_free(diff); diff = nullptr; git_commit_free(parent); parent = nullptr; git_commit_free(commit); commit = nullptr; count++; } } catch(const QGitError &ex) { error = ex; } emit listCommitsReply(commits, error); if (diff) { git_diff_free(diff); diff = nullptr; } if (parent) { git_commit_free(parent); parent = nullptr; } if (walker) { git_revwalk_free(walker); walker = nullptr; } if (repo) { git_repository_free(repo); repo = nullptr; } }