static void test_abort(git_annotated_commit *branch, git_annotated_commit *onto) { git_rebase *rebase; git_reference *head_ref, *branch_ref = NULL; git_signature *signature; git_status_list *statuslist; git_reflog *reflog; const git_reflog_entry *reflog_entry; cl_git_pass(git_rebase_open(&rebase, repo)); cl_git_pass(git_signature_new(&signature, "Rebaser", "*****@*****.**", 1404157834, -400)); cl_git_pass(git_rebase_abort(rebase, signature)); cl_assert_equal_i(GIT_REPOSITORY_STATE_NONE, git_repository_state(repo)); /* Make sure the refs are updated appropriately */ cl_git_pass(git_reference_lookup(&head_ref, repo, "HEAD")); if (branch->ref_name == NULL) cl_assert_equal_oid(git_annotated_commit_id(branch), git_reference_target(head_ref)); else { cl_assert_equal_s("refs/heads/beef", git_reference_symbolic_target(head_ref)); cl_git_pass(git_reference_lookup(&branch_ref, repo, git_reference_symbolic_target(head_ref))); cl_assert_equal_oid(git_annotated_commit_id(branch), git_reference_target(branch_ref)); } git_status_list_new(&statuslist, repo, NULL); cl_assert_equal_i(0, git_status_list_entrycount(statuslist)); git_status_list_free(statuslist); /* Make sure the reflogs are updated appropriately */ cl_git_pass(git_reflog_read(&reflog, repo, "HEAD")); cl_assert(reflog_entry = git_reflog_entry_byindex(reflog, 0)); cl_assert_equal_oid(git_annotated_commit_id(onto), git_reflog_entry_id_old(reflog_entry)); cl_assert_equal_oid(git_annotated_commit_id(branch), git_reflog_entry_id_new(reflog_entry)); cl_assert_equal_s("rebase: aborting", git_reflog_entry_message(reflog_entry)); git_reflog_free(reflog); git_reference_free(head_ref); git_reference_free(branch_ref); git_signature_free(signature); git_rebase_free(rebase); }
static void assert_head_reflog(git_repository *repo, size_t idx, const char *old_id, const char *new_id, const char *message) { git_reflog *log; const git_reflog_entry *entry; char id_str[GIT_OID_HEXSZ + 1] = {0}; cl_git_pass(git_reflog_read(&log, repo, GIT_HEAD_FILE)); entry = git_reflog_entry_byindex(log, idx); git_oid_fmt(id_str, git_reflog_entry_id_old(entry)); cl_assert_equal_s(old_id, id_str); git_oid_fmt(id_str, git_reflog_entry_id_new(entry)); cl_assert_equal_s(new_id, id_str); cl_assert_equal_s(message, git_reflog_entry_message(entry)); git_reflog_free(log); }
void test_refs_branches_create__creation_creates_new_reflog(void) { git_reflog *log; const git_reflog_entry *entry; git_signature *sig; cl_git_pass(git_signature_now(&sig, "me", "*****@*****.**")); retrieve_known_commit(&target, repo); cl_git_pass(git_branch_create(&branch, repo, NEW_BRANCH_NAME, target, false, sig, "create!")); cl_git_pass(git_reflog_read(&log, repo, "refs/heads/" NEW_BRANCH_NAME)); cl_assert_equal_i(1, git_reflog_entrycount(log)); entry = git_reflog_entry_byindex(log, 0); cl_assert_equal_s("create!", git_reflog_entry_message(entry)); cl_assert_equal_s("*****@*****.**", git_reflog_entry_committer(entry)->email); git_reflog_free(log); git_signature_free(sig); }
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); }
int git_stash_foreach( git_repository *repo, git_stash_cb callback, void *payload) { git_reference *stash; git_reflog *reflog = NULL; int error; size_t i, max; const git_reflog_entry *entry; error = git_reference_lookup(&stash, repo, GIT_REFS_STASH_FILE); if (error == GIT_ENOTFOUND) { giterr_clear(); return 0; } if (error < 0) goto cleanup; if ((error = git_reflog_read(&reflog, stash)) < 0) goto cleanup; max = git_reflog_entrycount(reflog); for (i = 0; i < max; i++) { entry = git_reflog_entry_byindex(reflog, i); if (callback(i, git_reflog_entry_message(entry), git_reflog_entry_id_new(entry), payload)) { error = GIT_EUSER; break; } } cleanup: git_reference_free(stash); git_reflog_free(reflog); return error; }
PyObject* RefLogIter_iternext(RefLogIter *self) { const git_reflog_entry *entry; RefLogEntry *py_entry; if (self->i < self->size) { entry = git_reflog_entry_byindex(self->reflog, self->i); py_entry = PyObject_New(RefLogEntry, &RefLogEntryType); py_entry->oid_old = git_oid_allocfmt(git_reflog_entry_id_old(entry)); py_entry->oid_new = git_oid_allocfmt(git_reflog_entry_id_new(entry)); py_entry->message = strdup(git_reflog_entry_message(entry)); py_entry->signature = git_signature_dup( git_reflog_entry_committer(entry)); ++(self->i); return (PyObject*) py_entry; } PyErr_SetNone(PyExc_StopIteration); return NULL; }
void test_rebase_merge__commit(void) { git_rebase *rebase; git_reference *branch_ref, *upstream_ref; git_annotated_commit *branch_head, *upstream_head; git_rebase_operation *rebase_operation; git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT; git_oid commit_id, tree_id, parent_id; git_signature *author; git_commit *commit; git_reflog *reflog; const git_reflog_entry *reflog_entry; checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE; cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/beef")); cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/master")); 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_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, NULL)); 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_commit_lookup(&commit, repo, &commit_id)); git_oid_fromstr(&parent_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00"); cl_assert_equal_i(1, git_commit_parentcount(commit)); cl_assert_equal_oid(&parent_id, git_commit_parent_id(commit, 0)); git_oid_fromstr(&tree_id, "4461379789c777d2a6c1f2ee0e9d6c86731b9992"); cl_assert_equal_oid(&tree_id, git_commit_tree_id(commit)); cl_assert_equal_s(NULL, git_commit_message_encoding(commit)); cl_assert_equal_s("Modification 1 to beef\n", git_commit_message(commit)); cl_git_pass(git_signature_new(&author, "Edward Thomson", "*****@*****.**", 1405621769, 0-(4*60))); cl_assert(git_signature__equal(author, git_commit_author(commit))); cl_assert(git_signature__equal(signature, git_commit_committer(commit))); /* Make sure the reflogs are updated appropriately */ cl_git_pass(git_reflog_read(&reflog, repo, "HEAD")); cl_assert(reflog_entry = git_reflog_entry_byindex(reflog, 0)); cl_assert_equal_oid(&parent_id, git_reflog_entry_id_old(reflog_entry)); cl_assert_equal_oid(&commit_id, git_reflog_entry_id_new(reflog_entry)); cl_assert_equal_s("rebase: Modification 1 to beef", git_reflog_entry_message(reflog_entry)); git_reflog_free(reflog); git_signature_free(author); git_commit_free(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 retrieve_previously_checked_out_branch_or_revision(git_object **out, git_reference **base_ref, git_repository *repo, const char *identifier, size_t position) { git_reference *ref = NULL; git_reflog *reflog = NULL; regex_t preg; int error = -1; size_t i, numentries, cur; const git_reflog_entry *entry; const char *msg; regmatch_t regexmatches[2]; git_buf buf = GIT_BUF_INIT; cur = position; if (*identifier != '\0' || *base_ref != NULL) return GIT_EINVALIDSPEC; if (build_regex(&preg, "checkout: moving from (.*) to .*") < 0) return -1; if (git_reference_lookup(&ref, repo, GIT_HEAD_FILE) < 0) goto cleanup; if (git_reflog_read(&reflog, repo, GIT_HEAD_FILE) < 0) goto cleanup; numentries = git_reflog_entrycount(reflog); for (i = 0; i < numentries; i++) { entry = git_reflog_entry_byindex(reflog, i); msg = git_reflog_entry_message(entry); if (!msg) continue; if (regexec(&preg, msg, 2, regexmatches, 0)) continue; cur--; if (cur > 0) continue; git_buf_put(&buf, msg+regexmatches[1].rm_so, regexmatches[1].rm_eo - regexmatches[1].rm_so); if ((error = git_reference_dwim(base_ref, repo, git_buf_cstr(&buf))) == 0) goto cleanup; if (error < 0 && error != GIT_ENOTFOUND) goto cleanup; error = maybe_abbrev(out, repo, git_buf_cstr(&buf)); goto cleanup; } error = GIT_ENOTFOUND; cleanup: git_reference_free(ref); git_buf_free(&buf); regfree(&preg); git_reflog_free(reflog); return error; }
int lgit_current::discover( git_repository *repo ) { int error, retval = 0; const git_oid *oidp; git_oid oid; const char *sym; std::string symbolic_name; cur_repo_ = repo; clear(); // Mark one branch as the checked out one git_reference *ref; if ( ( error = git_repository_head( &ref, repo ) ) < 0 ) { state_ = CURRENT_INVALID_MAIN; MessagesI.AppendMessageT( "Could not determine which branch is currently checked out" ); } else { switch ( git_reference_type( ref ) ) { /* GIT_REF_OID */ case GIT_REF_OID: // Prepare data for .tip_sha oidp = git_reference_target( ref ); if ( !oidp ) { state_ = CURRENT_INVALID_OID; break; } state_ = CURRENT_OID; oid = *oidp; break; /* GIT_REF_SYMBOLIC */ case GIT_REF_SYMBOLIC: sym = git_reference_symbolic_target( ref ); if ( !sym ) { state_ = CURRENT_INVALID_SYM; break; } state_ = CURRENT_SYM; symbolic_name = std::string( sym ); // Also establish OID if ( ( error = git_reference_name_to_id( &oid, repo, symbolic_name.c_str() ) ) < 0 ) { state_ = CURRENT_INVALID_OID2; break; } break; /* DEFAULT */ /* GIT_REF_INVALID */ /* GIT_REF_LISTALL */ default: state_ = CURRENT_INVALID_OTHER; break; } /* * AFTER SWITCH() */ if ( state_ == CURRENT_OID || state_ == CURRENT_SYM ) { char sha[ GIT_OID_HEXSZ + 1 ]; git_oid_fmt( sha, &oid ); sha[ GIT_OID_HEXSZ ] = '\0'; current_oid_ = std::string( sha ); type_ = CURRENT_TYPE_OID; } if ( state_ == CURRENT_OID ) { // Does the reference have any name? const char* refname_cstring = git_reference_name( ref ); if( !refname_cstring ) { refname_cstring = ""; } QString refname = QString::fromUtf8( refname_cstring ).trimmed(); if( refname.isEmpty() || refname == "HEAD" ) { git_reflog *reflog; const git_reflog_entry *reflog_entry; if ( ( error = git_reflog_read( &reflog, repo, "HEAD" ) ) < 0 ) { MessagesI.AppendMessageT( QString( "Could not read reflog, current HEAD will be established as SHA-only" ) + QString( " (no tag name resolution, error code: %1)" ) . arg( error ) ); } else { int count = git_reflog_entrycount( reflog ); int limit_count = 0; for ( int i = 0; i < count; i ++ ) { reflog_entry = git_reflog_entry_byindex( reflog, i ); if( !reflog_entry ) { MessagesI.AppendMessageT( "Problems when reading reflog" ); continue; } oidp = git_reflog_entry_id_new( reflog_entry ); if( 0 == git_oid_cmp( oidp, &oid ) ) { const char* message_cstring = git_reflog_entry_message( reflog_entry ); if( !message_cstring ) { MessagesI.AppendMessageT( "Problems when reading reflog (2)" ); continue; } QString message = QString( message_cstring ); QRegExp rx("checkout: moving from.*to (.*)$"); if( rx.indexIn( message ) != -1 ) { // The target of the catched move message must not be current HEAD's OID prefix if( ! QString::fromStdString( current_oid_ ).startsWith( rx.cap( 1 ) ) ) { current_tag_ = rx.cap( 1 ).toStdString(); type_ = CURRENT_TYPE_TAG; } break; } // Search only 5 OID-matching entries if( ++ limit_count >= 5 ) { break; } } } git_reflog_free( reflog ); } } else { QStringList parts = refname.split( "/", QString::SkipEmptyParts ); current_branch_ = parts.last().toStdString(); type_ = CURRENT_TYPE_BRANCH; } } else if ( state_ == CURRENT_SYM ) { current_branch_ = symbolic_name; } else { MessagesI.AppendMessageT( QString( "Could not determine which branch is currently checked out (error code: %1)" ).arg( state_ ) ); } git_reference_free( ref ); } return retval; }
// create a root commit void test_commit_write__root(void) { git_oid tree_id, commit_id; const git_oid *branch_oid; git_signature *author, *committer; const char *branch_name = "refs/heads/root-commit-branch"; git_tree *tree; git_reflog *log; const git_reflog_entry *entry; git_oid_fromstr(&tree_id, tree_oid); cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_id)); /* create signatures */ cl_git_pass(git_signature_new(&committer, committer_name, committer_email, 123456789, 60)); cl_git_pass(git_signature_new(&author, committer_name, committer_email, 987654321, 90)); /* First we need to update HEAD so it points to our non-existant branch */ cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD")); cl_assert(git_reference_type(head) == GIT_REF_SYMBOLIC); head_old = git__strdup(git_reference_symbolic_target(head)); cl_assert(head_old != NULL); git_reference_free(head); cl_git_pass(git_reference_symbolic_create(&head, g_repo, "HEAD", branch_name, 1, NULL, NULL)); cl_git_pass(git_commit_create_v( &commit_id, /* out id */ g_repo, "HEAD", author, committer, NULL, root_commit_message, tree, 0)); git_object_free((git_object *)tree); git_signature_free(author); /* * The fact that creating a commit works has already been * tested. Here we just make sure it's our commit and that it was * written as a root commit. */ cl_git_pass(git_commit_lookup(&commit, g_repo, &commit_id)); cl_assert(git_commit_parentcount(commit) == 0); cl_git_pass(git_reference_lookup(&branch, g_repo, branch_name)); branch_oid = git_reference_target(branch); cl_git_pass(git_oid_cmp(branch_oid, &commit_id)); cl_assert_equal_s(root_commit_message, git_commit_message(commit)); cl_git_pass(git_reflog_read(&log, g_repo, branch_name)); cl_assert_equal_i(1, git_reflog_entrycount(log)); entry = git_reflog_entry_byindex(log, 0); cl_assert_equal_s(committer->email, git_reflog_entry_committer(entry)->email); cl_assert_equal_s(committer->name, git_reflog_entry_committer(entry)->name); cl_assert_equal_s(root_reflog_message, git_reflog_entry_message(entry)); git_signature_free(committer); git_reflog_free(log); }
int ParserFromRefLog(CString ref, std::vector<GitRev> &refloglist) { refloglist.clear(); if (g_Git.m_IsUseLibGit2) { CAutoRepository repo(g_Git.GetGitRepository()); if (!repo) { MessageBox(nullptr, CGit::GetLibGit2LastErr(_T("Could not open repository.")), _T("TortoiseGit"), MB_ICONERROR); return -1; } CAutoReflog reflog; if (git_reflog_read(reflog.GetPointer(), repo, CUnicodeUtils::GetUTF8(ref)) < 0) { MessageBox(nullptr, CGit::GetLibGit2LastErr(_T("Could not read reflog.")), _T("TortoiseGit"), MB_ICONERROR); return -1; } for (size_t i = 0; i < git_reflog_entrycount(reflog); ++i) { const git_reflog_entry *entry = git_reflog_entry_byindex(reflog, i); if (!entry) continue; GitRev rev; rev.m_CommitHash = (char *)git_reflog_entry_id_new(entry)->id; rev.m_Ref.Format(_T("%s@{%d}"), ref, i); rev.GetCommitterDate() = CTime(git_reflog_entry_committer(entry)->when.time); if (git_reflog_entry_message(entry) != nullptr) { CString one; g_Git.StringAppend(&one, (BYTE *)git_reflog_entry_message(entry)); int message = one.Find(_T(":"), 0); if (message > 0) { rev.m_RefAction = one.Left(message); rev.GetSubject() = one.Mid(message + 1); } } refloglist.push_back(rev); } } else if (g_Git.m_IsUseGitDLL) { git_for_each_reflog_ent(CUnicodeUtils::GetUTF8(ref), AddToRefLoglist, &refloglist); for (size_t i = 0; i < refloglist.size(); ++i) refloglist[i].m_Ref.Format(_T("%s@{%d}"), ref, i); } else { CString cmd, out; GitRev rev; cmd.Format(_T("git.exe reflog show --pretty=\"%%H %%gD: %%gs\" --date=raw %s"), ref); if (g_Git.Run(cmd, &out, NULL, CP_UTF8)) return -1; int i = 0; CString prefix = ref + _T("@{"); int pos = 0; while (pos >= 0) { CString one = out.Tokenize(_T("\n"), pos); int refPos = one.Find(_T(' '), 0); if (refPos < 0) continue; rev.Clear(); CString hashStr = one.Left(refPos); rev.m_CommitHash = hashStr; rev.m_Ref.Format(_T("%s@{%d}"), ref, i++); int prefixPos = one.Find(prefix, refPos + 1); if (prefixPos != refPos + 1) continue; int spacePos = one.Find(_T(' '), prefixPos + prefix.GetLength() + 1); if (spacePos < 0) continue; CString timeStr = one.Mid(prefixPos + prefix.GetLength(), spacePos - prefixPos - prefix.GetLength()); rev.GetCommitterDate() = CTime(_ttoi(timeStr)); int action = one.Find(_T("}: "), spacePos + 1); if (action > 0) { action += 2; int message = one.Find(_T(":"), action); if (message > 0) { rev.m_RefAction = one.Mid(action + 1, message - action - 1); rev.GetSubject() = one.Right(one.GetLength() - message - 1); } } refloglist.push_back(rev); } } return 0; }