int AddToRefLoglist(unsigned char * /*osha1*/, unsigned char *nsha1, const char * /*name*/, unsigned long time, int /*sz*/, const char *msg, void *data) { std::vector<GitRev> *vector = (std::vector<GitRev> *)data; GitRev rev; rev.m_CommitHash = (char *)nsha1; rev.GetCommitterDate() = CTime(time); CString one; g_Git.StringAppend(&one, (BYTE *)msg); int message = one.Find(_T(":"), 0); if (message > 0) { rev.m_RefAction = one.Left(message); rev.GetSubject() = one.Mid(message + 1); } vector->insert(vector->begin(), rev); return 0; }
void GetRevParsingTests() { GitRev rev; EXPECT_TRUE(rev.m_CommitHash.IsEmpty()); EXPECT_EQ(0, rev.GetCommit(_T("HEAD"))); EXPECT_STREQ(_T("7c3cbfe13a929d2291a574dca45e4fd2d2ac1aa6"), rev.m_CommitHash.ToString()); EXPECT_STREQ(_T("Sven Strickroth"), rev.GetAuthorName()); EXPECT_STREQ(_T("*****@*****.**"), rev.GetAuthorEmail()); EXPECT_STREQ(_T("2015-03-07 18:03:58"), rev.GetAuthorDate().FormatGmt(L"%Y-%m-%d %H:%M:%S")); EXPECT_STREQ(_T("Sven Strickroth"), rev.GetCommitterName()); EXPECT_STREQ(_T("*****@*****.**"), rev.GetCommitterEmail()); EXPECT_STREQ(_T("2015-03-07 18:03:58"), rev.GetCommitterDate().FormatGmt(L"%Y-%m-%d %H:%M:%S")); EXPECT_STREQ(_T("Changed ASCII file"), rev.GetSubject()); EXPECT_STREQ(_T(""), rev.GetBody()); EXPECT_TRUE(rev.GetLastErr().IsEmpty()); EXPECT_EQ(0, rev.ParentsCount()); EXPECT_EQ(0, rev.GetParentFromHash(rev.m_CommitHash)); ASSERT_EQ(1, rev.ParentsCount()); EXPECT_STREQ(_T("1fc3c9688e27596d8717b54f2939dc951568f6cb"), rev.m_ParentHash[0].ToString()); EXPECT_TRUE(rev.GetLastErr().IsEmpty()); rev.Clear(); EXPECT_EQ(0, rev.GetCommit(GitRev::GetWorkingCopy())); EXPECT_TRUE(rev.m_CommitHash.IsEmpty()); EXPECT_STREQ(_T(""), rev.GetAuthorName()); EXPECT_STREQ(_T(""), rev.GetAuthorEmail()); EXPECT_STREQ(_T(""), rev.GetCommitterName()); EXPECT_STREQ(_T(""), rev.GetCommitterEmail()); EXPECT_STREQ(_T("Working Copy"), rev.GetSubject()); EXPECT_STREQ(_T(""), rev.GetBody()); EXPECT_EQ(0, rev.ParentsCount()); EXPECT_TRUE(rev.GetLastErr().IsEmpty()); rev.Clear(); EXPECT_TRUE(rev.GetLastErr().IsEmpty()); EXPECT_EQ(0, rev.GetCommit(_T("aa5b97f89cea6863222823c8289ce392d06d1691"))); EXPECT_STREQ(_T("aa5b97f89cea6863222823c8289ce392d06d1691"), rev.m_CommitHash.ToString()); EXPECT_STREQ(_T("Another dummy with ümlaut"), rev.GetAuthorName()); EXPECT_STREQ(_T("*****@*****.**"), rev.GetAuthorEmail()); EXPECT_STREQ(_T("2015-03-14 22:30:06"), rev.GetAuthorDate().FormatGmt(L"%Y-%m-%d %H:%M:%S")); EXPECT_STREQ(_T("Another dummy with ümlaut"), rev.GetCommitterName()); EXPECT_STREQ(_T("*****@*****.**"), rev.GetCommitterEmail()); EXPECT_STREQ(_T("2015-03-14 22:30:06"), rev.GetCommitterDate().FormatGmt(L"%Y-%m-%d %H:%M:%S")); EXPECT_STREQ(_T("Subject line"), rev.GetSubject()); EXPECT_STREQ(_T("\nalso some more lines\n\nhere in body\n\nSigned-off-by: Another dummy with ümlaut <*****@*****.**>\n"), rev.GetBody()); EXPECT_TRUE(rev.GetLastErr().IsEmpty()); rev.Clear(); EXPECT_TRUE(rev.m_CommitHash.IsEmpty()); EXPECT_EQ(0, rev.GetCommit(_T("1fc3c9688e27596d8717b54f2939dc951568f6cb"))); EXPECT_STREQ(_T("1fc3c9688e27596d8717b54f2939dc951568f6cb"), rev.m_CommitHash.ToString()); EXPECT_STREQ(_T("Some other User"), rev.GetAuthorName()); EXPECT_STREQ(_T("*****@*****.**"), rev.GetAuthorEmail()); EXPECT_STREQ(_T("2015-03-07 18:03:39"), rev.GetAuthorDate().FormatGmt(L"%Y-%m-%d %H:%M:%S")); EXPECT_STREQ(_T("Sven Strickroth"), rev.GetCommitterName()); EXPECT_STREQ(_T("*****@*****.**"), rev.GetCommitterEmail()); EXPECT_STREQ(_T("2015-03-07 18:03:39"), rev.GetCommitterDate().FormatGmt(L"%Y-%m-%d %H:%M:%S")); EXPECT_STREQ(_T("Added an ascii file"), rev.GetSubject()); EXPECT_STREQ(_T(""), rev.GetBody()); EXPECT_TRUE(rev.GetLastErr().IsEmpty()); rev.Clear(); EXPECT_EQ(-1, rev.GetCommit(_T("does-not-exist"))); EXPECT_FALSE(rev.GetLastErr().IsEmpty()); EXPECT_TRUE(rev.m_CommitHash.IsEmpty()); rev.Clear(); CGitHash hash(_T("aa5b97f89cea6863222823c8289ce392d06d1691")); EXPECT_EQ(0, rev.GetCommitFromHash(hash)); EXPECT_EQ(hash, rev.m_CommitHash); EXPECT_STREQ(_T("Another dummy with ümlaut"), rev.GetAuthorName()); EXPECT_STREQ(_T("*****@*****.**"), rev.GetAuthorEmail()); EXPECT_STREQ(_T("2015-03-14 22:30:06"), rev.GetAuthorDate().FormatGmt(L"%Y-%m-%d %H:%M:%S")); EXPECT_STREQ(_T("Another dummy with ümlaut"), rev.GetCommitterName()); EXPECT_STREQ(_T("*****@*****.**"), rev.GetCommitterEmail()); EXPECT_STREQ(_T("2015-03-14 22:30:06"), rev.GetCommitterDate().FormatGmt(L"%Y-%m-%d %H:%M:%S")); EXPECT_STREQ(_T("Subject line"), rev.GetSubject()); EXPECT_STREQ(_T("\nalso some more lines\n\nhere in body\n\nSigned-off-by: Another dummy with ümlaut <*****@*****.**>\n"), rev.GetBody()); EXPECT_TRUE(rev.GetLastErr().IsEmpty()); rev.Clear(); EXPECT_EQ(0, rev.GetCommit(_T("8d1ebbcc7eeb63af10ff8bcf7712afb9fcc90b8a"))); EXPECT_STREQ(_T("8d1ebbcc7eeb63af10ff8bcf7712afb9fcc90b8a"), rev.m_CommitHash.ToString()); EXPECT_STREQ(_T("Sven Strickroth"), rev.GetAuthorName()); EXPECT_STREQ(_T("*****@*****.**"), rev.GetAuthorEmail()); EXPECT_STREQ(_T("2015-03-04 17:50:24"), rev.GetAuthorDate().FormatGmt(L"%Y-%m-%d %H:%M:%S")); EXPECT_STREQ(_T("Sven Strickroth"), rev.GetCommitterName()); EXPECT_STREQ(_T("*****@*****.**"), rev.GetCommitterEmail()); EXPECT_STREQ(_T("2015-03-04 17:50:24"), rev.GetCommitterDate().FormatGmt(L"%Y-%m-%d %H:%M:%S")); EXPECT_STREQ(_T("Merge branch 'for-merge' into subdir/branch"), rev.GetSubject()); EXPECT_STREQ(_T(""), rev.GetBody()); EXPECT_EQ(0, rev.ParentsCount()); EXPECT_EQ(0, rev.GetParentFromHash(rev.m_CommitHash)); ASSERT_EQ(2, rev.ParentsCount()); EXPECT_STREQ(_T("3686b9cf74f1a4ef96d6bfe736595ef9abf0fb8d"), rev.m_ParentHash[0].ToString()); EXPECT_STREQ(_T("1ce788330fd3a306c8ad37654063ceee13a7f172"), rev.m_ParentHash[1].ToString()); EXPECT_TRUE(rev.GetLastErr().IsEmpty()); rev.Clear(); EXPECT_TRUE(rev.m_CommitHash.IsEmpty()); EXPECT_EQ(0, rev.GetCommit(_T("844309789a13614b52d5e7cbfe6350dd73d1dc72"))); // root-commit EXPECT_STREQ(_T("844309789a13614b52d5e7cbfe6350dd73d1dc72"), rev.m_CommitHash.ToString()); EXPECT_STREQ(_T("Sven Strickroth"), rev.GetAuthorName()); EXPECT_STREQ(_T("*****@*****.**"), rev.GetAuthorEmail()); EXPECT_STREQ(_T("2015-03-04 17:35:13"), rev.GetAuthorDate().FormatGmt(L"%Y-%m-%d %H:%M:%S")); EXPECT_STREQ(_T("Sven Strickroth"), rev.GetCommitterName()); EXPECT_STREQ(_T("*****@*****.**"), rev.GetCommitterEmail()); EXPECT_STREQ(_T("2015-03-04 17:35:13"), rev.GetCommitterDate().FormatGmt(L"%Y-%m-%d %H:%M:%S")); EXPECT_STREQ(_T("added ansi file"), rev.GetSubject()); EXPECT_STREQ(_T(""), rev.GetBody()); EXPECT_TRUE(rev.GetLastErr().IsEmpty()); EXPECT_EQ(0, rev.ParentsCount()); EXPECT_EQ(0, rev.GetParentFromHash(rev.m_CommitHash)); EXPECT_EQ(0, rev.ParentsCount()); EXPECT_TRUE(rev.GetLastErr().IsEmpty()); rev.Clear(); // GPG signed commit which was also amended with different dates EXPECT_EQ(0, rev.GetCommit(_T("subdir/branch"))); EXPECT_STREQ(_T("4c5c93d2a0b368bc4570d5ec02ab03b9c4334d44"), rev.m_CommitHash.ToString()); EXPECT_STREQ(_T("Sven Strickroth"), rev.GetAuthorName()); EXPECT_STREQ(_T("*****@*****.**"), rev.GetAuthorEmail()); EXPECT_STREQ(_T("2015-03-16 12:52:29"), rev.GetAuthorDate().FormatGmt(L"%Y-%m-%d %H:%M:%S")); EXPECT_STREQ(_T("Sven Strickroth"), rev.GetCommitterName()); EXPECT_STREQ(_T("*****@*****.**"), rev.GetCommitterEmail()); EXPECT_STREQ(_T("2015-03-16 13:06:08"), rev.GetCommitterDate().FormatGmt(L"%Y-%m-%d %H:%M:%S")); EXPECT_STREQ(_T("Several actions"), rev.GetSubject()); EXPECT_STREQ(_T("\n* amended with different date\n* make utf16-be-nobom.txt a symlink ti ascii.txt\n* remove utf8-bom.txt\n* Copied ascii.txt\n\nSigned-off-by: Sven Strickroth <*****@*****.**>\n"), rev.GetBody()); EXPECT_TRUE(rev.GetLastErr().IsEmpty()); EXPECT_EQ(0, rev.ParentsCount()); EXPECT_EQ(0, rev.GetParentFromHash(rev.m_CommitHash)); ASSERT_EQ(1, rev.ParentsCount()); EXPECT_STREQ(_T("aa5b97f89cea6863222823c8289ce392d06d1691"), rev.m_ParentHash[0].ToString()); EXPECT_TRUE(rev.GetLastErr().IsEmpty()); }
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; }