From 0344b8b6aef4c814d4bc1a88dc54a1a460b6b91b Mon Sep 17 00:00:00 2001 From: Sup Yut Sum Date: Tue, 23 Feb 2016 22:00:55 +0800 Subject: [PATCH] Support bisect terms Signed-off-by: Sup Yut Sum Signed-off-by: Sven Strickroth --- src/Git/Git.cpp | 60 +++++++++++++++++++++++++++-- src/Git/Git.h | 1 + src/TortoiseProc/Commands/BisectCommand.cpp | 6 +-- test/Cache/stdafx.h | 2 + test/UnitTests/GitTest.cpp | 34 +++++++++++++++- 5 files changed, 95 insertions(+), 8 deletions(-) diff --git a/src/Git/Git.cpp b/src/Git/Git.cpp index 82b3915b7..e0df6659b 100644 --- a/src/Git/Git.cpp +++ b/src/Git/Git.cpp @@ -2801,16 +2801,20 @@ CString CGit::GetShortName(const CString& ref, REF_TYPE *out_type) } else if (CGit::GetShortName(str, shortname, _T("refs/bisect/"))) { - if (shortname.Find(_T("good")) == 0) + CString bisectGood; + CString bisectBad; + g_Git.GetBisectTerms(&bisectGood, &bisectBad); + TCHAR c; + if (shortname.Find(bisectGood) == 0 && ((c = shortname.GetAt(bisectGood.GetLength())) == '-' || c == '\0')) { type = CGit::BISECT_GOOD; - shortname = _T("good"); + shortname = bisectGood; } - if (shortname.Find(_T("bad")) == 0) + if (shortname.Find(bisectBad) == 0 && ((c = shortname.GetAt(bisectBad.GetLength())) == '-' || c == '\0')) { type = CGit::BISECT_BAD; - shortname = _T("bad"); + shortname = bisectBad; } } else if (CGit::GetShortName(str, shortname, _T("refs/notes/"))) @@ -3330,6 +3334,54 @@ int CGit::IsRebaseRunning() return 0; } +void CGit::GetBisectTerms(CString* good, CString* bad) +{ + static CString lastGood; + static CString lastBad; + static ULONGLONG lastRead = 0; + + SCOPE_EXIT + { + if (bad) + *bad = lastBad; + if (good) + *good = lastGood; + }; + +#ifndef GTEST_INCLUDE_GTEST_GTEST_H_ + // add some caching here, because this method might be called multiple times in a short time from LogDlg and RevisionGraph + // as we only read a small file the performance effects should be negligible + if (lastRead + 5000 > GetTickCount64()) + return; +#endif + + lastGood = L"good"; + lastBad = L"bad"; + + CString adminDir; + if (!GitAdminDir::GetAdminDirPath(m_CurrentDir, adminDir)) + return; + + CString termsFile = adminDir + L"BISECT_TERMS"; + CAutoFILE fp; + _tfopen_s(fp.GetPointer(), termsFile, L"rb"); + if (!fp) + return; + char badA[MAX_PATH] = { 0 }; + fgets(badA, MAX_PATH, fp); + size_t len = strlen(badA); + if (len > 0 && badA[len - 1] == '\n') + badA[len - 1] = '\0'; + char goodA[MAX_PATH] = { 0 }; + fgets(goodA, MAX_PATH, fp); + len = strlen(goodA); + if (len > 0 && goodA[len - 1] == '\n') + goodA[len - 1] = '\0'; + lastGood = CUnicodeUtils::GetUnicode(goodA); + lastBad = CUnicodeUtils::GetUnicode(badA); + lastRead = GetTickCount64(); +} + int CGit::GetGitVersion(CString* versiondebug, CString* errStr) { CString version, err; diff --git a/src/Git/Git.h b/src/Git/Git.h index 60fe6eb75..98c8d9e67 100644 --- a/src/Git/Git.h +++ b/src/Git/Git.h @@ -389,6 +389,7 @@ public: /** Returns 0 if no conflict, if a conflict was found and -1 in case of a failure */ int HasWorkingTreeConflicts(git_repository* repo); int IsRebaseRunning(); + void GetBisectTerms(CString* good, CString* bad); int GetRefList(STRING_VECTOR &list); int RefreshGitIndex(); diff --git a/src/TortoiseProc/Commands/BisectCommand.cpp b/src/TortoiseProc/Commands/BisectCommand.cpp index 300b33a9c..ee667b904 100644 --- a/src/TortoiseProc/Commands/BisectCommand.cpp +++ b/src/TortoiseProc/Commands/BisectCommand.cpp @@ -1,6 +1,6 @@ // TortoiseGit - a Windows shell extension for easy version control -// Copyright (C) 2008-2013, 2015 - TortoiseGit +// Copyright (C) 2008-2013, 2015-2016 - TortoiseGit // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -43,9 +43,9 @@ bool BisectCommand::Execute() CString ref; if (this->parser.HasKey(_T("good"))) - op = _T("good"); + g_Git.GetBisectTerms(&op, nullptr); else if (this->parser.HasKey(_T("bad"))) - op = _T("bad"); + g_Git.GetBisectTerms(nullptr, &op); else if (this->parser.HasKey(_T("reset"))) op = _T("reset"); diff --git a/test/Cache/stdafx.h b/test/Cache/stdafx.h index 14090ca2f..639f9a2f4 100644 --- a/test/Cache/stdafx.h +++ b/test/Cache/stdafx.h @@ -45,6 +45,8 @@ using namespace ATL; #pragma warning(pop) #include "SmartLibgit2Ref.h" +#include "scope_exit_noexcept.h" + #include "DebugOutput.h" typedef CComCritSecLock AutoLocker; diff --git a/test/UnitTests/GitTest.cpp b/test/UnitTests/GitTest.cpp index 0b9b4b856..03ad58810 100644 --- a/test/UnitTests/GitTest.cpp +++ b/test/UnitTests/GitTest.cpp @@ -1,6 +1,6 @@ // TortoiseGit - a Windows shell extension for easy version control -// Copyright (C) 2015 - TortoiseGit +// Copyright (C) 2015-2016 - TortoiseGit // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -2112,3 +2112,35 @@ TEST_P(CBasicGitWithEmptyRepositoryFixture, GetWorkingTreeChanges) EXPECT_STREQ(_T("test.txt"), list[1].GetGitPathString()); EXPECT_EQ(CTGitPath::LOGACTIONS_ADDED, list[1].m_Action); } + +TEST_P(CBasicGitWithTestRepoFixture, GetBisectTerms) +{ + if (m_Git.ms_bCygwinGit) + return; + + CString good, bad; + CString output; + + EXPECT_EQ(0, m_Git.Run(_T("git.exe bisect start"), &output, CP_UTF8)); + m_Git.GetBisectTerms(&good, &bad); + EXPECT_STREQ(_T("good"), good); + EXPECT_STREQ(_T("bad"), bad); + + good.Empty(); + bad.Empty(); + m_Git.GetBisectTerms(&good, &bad); + EXPECT_STREQ(_T("good"), good); + EXPECT_STREQ(_T("bad"), bad); + + EXPECT_EQ(0, m_Git.Run(_T("git.exe bisect reset"), &output, CP_UTF8)); + + if (m_Git.GetGitVersion(nullptr, nullptr) < 0x02070000) + return; + + EXPECT_EQ(0, m_Git.Run(_T("git.exe bisect start --term-good=original --term-bad=changed"), &output, CP_UTF8)); + m_Git.GetBisectTerms(&good, &bad); + EXPECT_STREQ(_T("original"), good); + EXPECT_STREQ(_T("changed"), bad); + + EXPECT_EQ(0, m_Git.Run(_T("git.exe bisect reset"), &output, CP_UTF8)); +} -- 2.11.4.GIT