Support bisect terms
[TortoiseGit.git] / test / UnitTests / GitTest.cpp
blob03ad58810cd798ef9bbf459da83b9913b52cb8b6
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2015-2016 - TortoiseGit
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "stdafx.h"
21 #include "Git.h"
22 #include "StringUtils.h"
23 #include "RepositoryFixtures.h"
25 // For performance reason, turn LIBGIT off by default,
26 INSTANTIATE_TEST_CASE_P(CGit, CBasicGitFixture, testing::Values(GIT_CLI, /*LIBGIT,*/ LIBGIT2, LIBGIT2_ALL));
27 INSTANTIATE_TEST_CASE_P(CGit, CBasicGitWithEmptyRepositoryFixture, testing::Values(GIT_CLI, /*LIBGIT,*/ LIBGIT2, LIBGIT2_ALL));
28 INSTANTIATE_TEST_CASE_P(CGit, CBasicGitWithEmptyBareRepositoryFixture, testing::Values(GIT_CLI, /*LIBGIT,*/ LIBGIT2, LIBGIT2_ALL));
29 INSTANTIATE_TEST_CASE_P(CGit, CBasicGitWithTestRepoFixture, testing::Values(GIT_CLI, LIBGIT, LIBGIT2, LIBGIT2_ALL));
30 INSTANTIATE_TEST_CASE_P(CGit, CBasicGitWithTestRepoBareFixture, testing::Values(GIT_CLI, LIBGIT, LIBGIT2, LIBGIT2_ALL));
32 TEST(CGit, RunSet)
34 CString output;
35 CGit cgit;
36 ASSERT_EQ(0, cgit.Run(_T("cmd /c set"), &output, CP_UTF8));
37 ASSERT_FALSE(output.IsEmpty());
38 ASSERT_TRUE(output.Find(_T("windir"))); // should be there on any MS OS ;)
41 TEST(CGit, RunGit)
43 CString output;
44 CGit cgit;
45 ASSERT_EQ(0, cgit.Run(_T("git --version"), &output, CP_UTF8));
46 ASSERT_FALSE(output.IsEmpty());
49 TEST(CGit, RunGit_BashPipe)
51 CString tmpfile = GetTempFile();
52 tmpfile.Replace(L"\\", L"/");
53 ASSERT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)tmpfile, L"testing piping..."));
54 SCOPE_EXIT{ ::DeleteFile(tmpfile); };
55 CString pipefile = GetTempFile();
56 pipefile.Replace(L"\\", L"/");
57 CString pipecmd;
58 pipecmd.Format(L"cat < %s", (LPCTSTR)tmpfile);
59 ASSERT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)pipefile, (LPCTSTR)pipecmd));
60 SCOPE_EXIT{ ::DeleteFile(pipefile); };
61 CString output;
62 CGit cgit;
63 ASSERT_EQ(0, cgit.Run(L"bash.exe " + pipefile, &output, CP_UTF8));
64 ASSERT_STREQ(L"testing piping...", output);
67 TEST(CGit, RunGit_Error)
69 CAutoTempDir tempdir;
70 CGit cgit;
71 cgit.m_CurrentDir = tempdir.GetTempDir();
73 CString output;
74 EXPECT_NE(0, cgit.Run(_T("git-not-found.exe"), &output, CP_UTF8)); // Git for Windows returns 2, cygwin-hack returns 127
75 //EXPECT_TRUE(output.IsEmpty()); with cygwin-hack we get an error message from sh.exe
77 output.Empty();
78 EXPECT_EQ(128, cgit.Run(_T("git.exe add file.txt"), &output, CP_UTF8));
79 EXPECT_TRUE(output.Find(_T("fatal: Not a git repository (or any")) == 0);
82 TEST_P(CBasicGitWithTestRepoBareFixture, RunGit_AbsolutePath)
84 CAutoTempDir tempdir;
86 CString output;
87 EXPECT_EQ(0, m_Git.Run(_T("git archive -o ") + tempdir.GetTempDir() + _T("\\export.zip HEAD"), &output, CP_UTF8));
88 EXPECT_TRUE(output.IsEmpty());
90 EXPECT_TRUE(PathFileExists(tempdir.GetTempDir() + _T("\\export.zip")));
93 TEST(CGit, StringAppend)
95 CGit::StringAppend(nullptr, nullptr); // string may be null
96 CString string = _T("something");
97 CGit::StringAppend(&string, nullptr, CP_UTF8, 0);
98 EXPECT_STREQ(_T("something"), string);
99 const BYTE somebytes[1] = { 0 };
100 CGit::StringAppend(&string, somebytes, CP_UTF8, 0);
101 EXPECT_STREQ(_T("something"), string);
102 CGit::StringAppend(&string, somebytes);
103 EXPECT_STREQ(_T("something"), string);
104 const BYTE moreBytesUTFEight[] = { 0x68, 0x65, 0x6C, 0x6C, 0xC3, 0xB6, 0x0A, 0x00 };
105 CGit::StringAppend(&string, moreBytesUTFEight, CP_UTF8, 3);
106 EXPECT_STREQ(_T("somethinghel"), string);
107 CGit::StringAppend(&string, moreBytesUTFEight + 3, CP_ACP, 1);
108 EXPECT_STREQ(_T("somethinghell"), string);
109 CGit::StringAppend(&string, moreBytesUTFEight);
110 EXPECT_STREQ(_T("somethinghellhellö\n"), string);
111 CGit::StringAppend(&string, moreBytesUTFEight, CP_UTF8, sizeof(moreBytesUTFEight));
112 EXPECT_STREQ(_T("somethinghellhellö\nhellö\n\0"), string);
113 CGit::StringAppend(&string, moreBytesUTFEight, CP_UTF8, 3);
114 EXPECT_STREQ(_T("somethinghellhellö\nhellö\n\0hel"), string);
117 TEST(CGit, GetFileModifyTime)
119 __int64 time = -1;
120 bool isDir = false;
121 __int64 size = -1;
122 EXPECT_EQ(-1, CGit::GetFileModifyTime(L"does-not-exist.txt", &time, &isDir, &size));
124 time = -1;
125 isDir = false;
126 size = -1;
127 EXPECT_EQ(0, CGit::GetFileModifyTime(L"c:\\Windows", &time, &isDir, &size));
128 EXPECT_TRUE(isDir);
130 time = -1;
131 isDir = false;
132 size = -1;
133 EXPECT_EQ(0, CGit::GetFileModifyTime(L"c:\\Windows\\", &time, &isDir, &size));
134 EXPECT_TRUE(isDir);
136 CAutoTempDir tempdir;
137 CString testFile = tempdir.GetTempDir() + L"\\test.txt";
138 EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFile, L"this is testing fileöäü."));
140 time = -1;
141 EXPECT_EQ(0, CGit::GetFileModifyTime(testFile, &time));
142 EXPECT_NE(-1, time);
144 __int64 time2 = -1;
145 isDir = false;
146 size = -1;
147 ULONGLONG ticks = GetTickCount64();
148 EXPECT_EQ(0, CGit::GetFileModifyTime(testFile, &time2, &isDir, &size));
149 EXPECT_EQ(time, time2);
150 EXPECT_FALSE(isDir);
151 EXPECT_EQ(27, size);
153 Sleep(1200);
154 EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFile, L"this is testing fileöü."));
155 __int64 time3 = -1;
156 isDir = false;
157 size = -1;
158 EXPECT_EQ(0, CGit::GetFileModifyTime(testFile, &time3, &isDir, &size));
159 EXPECT_NE(-1, time3);
160 EXPECT_FALSE(isDir);
161 EXPECT_EQ(25, size);
162 EXPECT_TRUE(time3 >= time);
163 EXPECT_TRUE(time3 - time <= 1 + (__int64)(GetTickCount64() - ticks) / 1000);
166 TEST(CGit, LoadTextFile)
168 CAutoTempDir tempdir;
170 CString msg;
171 EXPECT_FALSE(CGit::LoadTextFile(L"does-not-exist.txt", msg));
173 CString testFile = tempdir.GetTempDir() + L"\\test.txt";
174 EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFile, L"this is testing fileöäü."));
175 EXPECT_TRUE(CGit::LoadTextFile(testFile, msg));
176 EXPECT_STREQ(L"this is testing fileöäü.\n", msg);
178 msg.Empty();
179 EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFile, L"this is\r\ntesting\nfileöäü.\r\n\r\n"));
180 EXPECT_TRUE(CGit::LoadTextFile(testFile, msg));
181 EXPECT_STREQ(L"this is\ntesting\nfileöäü.\n", msg);
184 TEST(CGit, IsBranchNameValid)
186 CGit cgit;
187 EXPECT_TRUE(cgit.IsBranchNameValid(_T("master")));
188 EXPECT_TRUE(cgit.IsBranchNameValid(_T("def/master")));
189 EXPECT_FALSE(cgit.IsBranchNameValid(_T("-test")));
190 EXPECT_FALSE(cgit.IsBranchNameValid(_T("jfjf>ff")));
191 EXPECT_FALSE(cgit.IsBranchNameValid(_T("jf ff")));
192 EXPECT_FALSE(cgit.IsBranchNameValid(_T("jf~ff")));
195 TEST(CGit, StripRefName)
197 EXPECT_STREQ(_T("abc"), CGit::StripRefName(_T("abc")));
198 EXPECT_STREQ(_T("bcd"), CGit::StripRefName(_T("refs/bcd")));
199 EXPECT_STREQ(_T("cde"), CGit::StripRefName(_T("refs/heads/cde")));
202 TEST(CGit, CombinePath)
204 CGit cgit;
205 cgit.m_CurrentDir = _T("c:\\something");
206 EXPECT_STREQ(_T("c:\\something"), cgit.CombinePath(_T("")));
207 EXPECT_STREQ(_T("c:\\something\\file.txt"), cgit.CombinePath(_T("file.txt")));
208 EXPECT_STREQ(_T("c:\\something\\sub\\file.txt"), cgit.CombinePath(_T("sub\\file.txt")));
209 EXPECT_STREQ(_T("c:\\something\\subdir\\file2.txt"), cgit.CombinePath(CTGitPath(_T("subdir/file2.txt"))));
212 TEST(CGit, GetShortName)
214 CGit::REF_TYPE type = CGit::UNKNOWN;
215 EXPECT_STREQ(_T("master"), CGit::GetShortName(_T("refs/heads/master"), &type));
216 EXPECT_EQ(CGit::LOCAL_BRANCH, type);
218 type = CGit::UNKNOWN;
219 EXPECT_STREQ(_T("somedir/mastr"), CGit::GetShortName(_T("refs/heads/somedir/mastr"), &type));
220 EXPECT_EQ(CGit::LOCAL_BRANCH, type);
222 type = CGit::BISECT_BAD; // do not use UNKNOWN here to make sure it gets set
223 EXPECT_STREQ(_T("svn/something"), CGit::GetShortName(_T("refs/svn/something"), &type));
224 EXPECT_EQ(CGit::UNKNOWN, type);
226 type = CGit::UNKNOWN;
227 EXPECT_STREQ(_T("origin/master"), CGit::GetShortName(_T("refs/remotes/origin/master"), &type));
228 EXPECT_EQ(CGit::REMOTE_BRANCH, type);
230 type = CGit::UNKNOWN;
231 EXPECT_STREQ(_T("origin/sub/master"), CGit::GetShortName(_T("refs/remotes/origin/sub/master"), &type));
232 EXPECT_EQ(CGit::REMOTE_BRANCH, type);
234 type = CGit::UNKNOWN;
235 EXPECT_STREQ(_T("release1"), CGit::GetShortName(_T("refs/tags/release1"), &type));
236 EXPECT_EQ(CGit::TAG, type);
238 type = CGit::UNKNOWN;
239 EXPECT_STREQ(_T("releases/v1"), CGit::GetShortName(_T("refs/tags/releases/v1"), &type));
240 EXPECT_EQ(CGit::TAG, type);
242 type = CGit::UNKNOWN;
243 EXPECT_STREQ(_T("release2"), CGit::GetShortName(_T("refs/tags/release2^{}"), &type));
244 EXPECT_EQ(CGit::ANNOTATED_TAG, type);
246 type = CGit::UNKNOWN;
247 EXPECT_STREQ(_T("releases/v2"), CGit::GetShortName(_T("refs/tags/releases/v2^{}"), &type));
248 EXPECT_EQ(CGit::ANNOTATED_TAG, type);
250 type = CGit::UNKNOWN;
251 EXPECT_STREQ(_T("stash"), CGit::GetShortName(_T("refs/stash"), &type));
252 EXPECT_EQ(CGit::STASH, type);
254 type = CGit::BISECT_BAD; // do not use UNKNOWN here to make sure it gets set
255 EXPECT_STREQ(_T("something"), CGit::GetShortName(_T("refs/something"), &type));
256 EXPECT_EQ(CGit::UNKNOWN, type);
258 type = CGit::BISECT_BAD; // do not use UNKNOWN here to make sure it gets set
259 EXPECT_STREQ(_T("sth"), CGit::GetShortName(_T("sth"), &type));
260 EXPECT_EQ(CGit::UNKNOWN, type);
262 type = CGit::UNKNOWN;
263 EXPECT_STREQ(_T("good"), CGit::GetShortName(_T("refs/bisect/good"), &type));
264 EXPECT_EQ(CGit::BISECT_GOOD, type);
266 type = CGit::UNKNOWN;
267 EXPECT_STREQ(_T("good"), CGit::GetShortName(_T("refs/bisect/good-5809ac97a1115a8380b1d6bb304b62cd0b0fa9bb"), &type));
268 EXPECT_EQ(CGit::BISECT_GOOD, type);
270 type = CGit::UNKNOWN;
271 EXPECT_STREQ(_T("bad"), CGit::GetShortName(_T("refs/bisect/bad"), &type));
272 EXPECT_EQ(CGit::BISECT_BAD, type);
274 type = CGit::UNKNOWN;
275 EXPECT_STREQ(_T("bad"), CGit::GetShortName(_T("refs/bisect/bad-5809ac97a1115a8380b1d6bb304b62cd0b0fd9bb"), &type));
276 EXPECT_EQ(CGit::BISECT_BAD, type);
278 type = CGit::UNKNOWN;
279 EXPECT_STREQ(_T("ab"), CGit::GetShortName(_T("refs/notes/ab"), &type));
280 EXPECT_EQ(CGit::NOTES, type);
282 type = CGit::UNKNOWN;
283 EXPECT_STREQ(_T("a/b"), CGit::GetShortName(_T("refs/notes/a/b"), &type));
284 EXPECT_EQ(CGit::NOTES, type);
287 TEST(CGit, GetRepository)
289 CAutoTempDir tempdir;
290 CGit cgit;
291 cgit.m_CurrentDir = tempdir.GetTempDir();
293 CAutoRepository repo = cgit.GetGitRepository();
294 EXPECT_FALSE(repo.IsValid());
296 cgit.m_CurrentDir = tempdir.GetTempDir() + _T("\\aöäüb");
297 ASSERT_TRUE(CreateDirectory(cgit.m_CurrentDir, nullptr));
299 CString output;
300 EXPECT_EQ(0, cgit.Run(_T("git.exe init"), &output, CP_UTF8));
301 EXPECT_FALSE(output.IsEmpty());
303 CAutoRepository repo2 = cgit.GetGitRepository(); // this tests GetGitRepository as well as m_Git.GetGitPathStringA
304 EXPECT_TRUE(repo2.IsValid());
306 cgit.m_CurrentDir = tempdir.GetTempDir() + _T("\\aöäüb.git");
307 ASSERT_TRUE(CreateDirectory(cgit.m_CurrentDir, nullptr));
309 output.Empty();
310 EXPECT_EQ(0, cgit.Run(_T("git.exe init --bare"), &output, CP_UTF8));
311 EXPECT_FALSE(output.IsEmpty());
313 CAutoRepository repo3 = cgit.GetGitRepository(); // this tests GetGitRepository as well as m_Git.GetGitPathStringA
314 EXPECT_TRUE(repo3.IsValid());
317 TEST_P(CBasicGitWithEmptyRepositoryFixture, IsInitRepos_GetInitAddList)
319 EXPECT_STREQ(_T("master"), m_Git.GetCurrentBranch());
321 CString output;
322 CString testFile = m_Dir.GetTempDir() + L"\\test.txt";
324 CTGitPathList addedFiles;
326 EXPECT_TRUE(m_Git.IsInitRepos());
327 EXPECT_EQ(0, m_Git.GetInitAddList(addedFiles));
328 EXPECT_TRUE(addedFiles.IsEmpty());
330 EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFile, L"this is testing file."));
331 EXPECT_EQ(0, m_Git.GetInitAddList(addedFiles));
332 EXPECT_TRUE(addedFiles.IsEmpty());
333 EXPECT_EQ(0, m_Git.Run(_T("git.exe add test.txt"), &output, CP_UTF8));
334 EXPECT_TRUE(output.IsEmpty());
335 EXPECT_EQ(0, m_Git.GetInitAddList(addedFiles));
336 ASSERT_EQ(1, addedFiles.GetCount());
337 EXPECT_STREQ(_T("test.txt"), addedFiles[0].GetGitPathString());
339 output.Empty();
340 EXPECT_EQ(0, m_Git.Run(_T("git.exe commit -m \"Add test.txt\""), &output, CP_UTF8));
341 EXPECT_FALSE(output.IsEmpty());
343 EXPECT_FALSE(m_Git.IsInitRepos());
345 EXPECT_STREQ(_T("master"), m_Git.GetCurrentBranch());
348 TEST_P(CBasicGitWithTestRepoFixture, IsInitRepos)
350 EXPECT_FALSE(m_Git.IsInitRepos());
352 CString output;
353 EXPECT_EQ(0, m_Git.Run(_T("git.exe checkout --orphan orphanic"), &output, CP_UTF8));
354 EXPECT_FALSE(output.IsEmpty());
356 EXPECT_TRUE(m_Git.IsInitRepos());
359 TEST_P(CBasicGitWithTestRepoFixture, HasWorkingTreeConflicts)
361 CString output;
362 EXPECT_EQ(0, m_Git.Run(_T("git.exe reset --hard master"), &output, CP_UTF8));
363 EXPECT_FALSE(output.IsEmpty());
365 EXPECT_EQ(FALSE, m_Git.HasWorkingTreeConflicts());
367 output.Empty();
368 EXPECT_EQ(0, m_Git.Run(_T("git.exe merge forconflict"), &output, CP_UTF8));
369 EXPECT_FALSE(output.IsEmpty());
370 EXPECT_EQ(FALSE, m_Git.HasWorkingTreeConflicts());
372 output.Empty();
373 EXPECT_EQ(1, m_Git.Run(_T("git.exe merge simple-conflict"), &output, CP_UTF8));
374 EXPECT_FALSE(output.IsEmpty());
375 EXPECT_EQ(TRUE, m_Git.HasWorkingTreeConflicts());
377 output.Empty();
378 EXPECT_EQ(0, m_Git.Run(_T("git.exe reset --hard master"), &output, CP_UTF8));
379 EXPECT_FALSE(output.IsEmpty());
381 output.Empty();
382 EXPECT_EQ(0, m_Git.Run(_T("git.exe checkout forconflict"), &output, CP_UTF8));
383 EXPECT_FALSE(output.IsEmpty());
385 output.Empty();
386 EXPECT_EQ(1, m_Git.Run(_T("git.exe merge simple-conflict"), &output, CP_UTF8));
387 EXPECT_FALSE(output.IsEmpty());
388 EXPECT_EQ(TRUE, m_Git.HasWorkingTreeConflicts());
391 TEST_P(CBasicGitWithTestRepoFixture, GetCurrentBranch)
393 EXPECT_STREQ(_T("master"), m_Git.GetCurrentBranch());
394 EXPECT_STREQ(_T("master"), m_Git.GetCurrentBranch(true));
396 CString output;
397 EXPECT_EQ(0, m_Git.Run(_T("git.exe checkout simple-conflict"), &output, CP_UTF8));
398 EXPECT_STREQ(_T("simple-conflict"), m_Git.GetCurrentBranch());
399 EXPECT_STREQ(_T("simple-conflict"), m_Git.GetCurrentBranch(true));
401 EXPECT_EQ(0, m_Git.Run(_T("git.exe checkout subdir/branch"), &output, CP_UTF8));
402 EXPECT_STREQ(_T("subdir/branch"), m_Git.GetCurrentBranch());
403 EXPECT_STREQ(_T("subdir/branch"), m_Git.GetCurrentBranch(true));
405 EXPECT_EQ(0, m_Git.Run(_T("git.exe checkout 560deea87853158b22d0c0fd73f60a458d47838a"), &output, CP_UTF8));
406 EXPECT_STREQ(_T("(no branch)"), m_Git.GetCurrentBranch());
407 EXPECT_STREQ(_T("560deea87853158b22d0c0fd73f60a458d47838a"), m_Git.GetCurrentBranch(true));
409 output.Empty();
410 EXPECT_EQ(0, m_Git.Run(_T("git.exe checkout --orphan orphanic"), &output, CP_UTF8));
411 EXPECT_FALSE(output.IsEmpty());
413 EXPECT_STREQ(_T("orphanic"), m_Git.GetCurrentBranch());
414 EXPECT_STREQ(_T("orphanic"), m_Git.GetCurrentBranch(true));
417 TEST_P(CBasicGitWithTestRepoBareFixture, GetCurrentBranch)
419 EXPECT_STREQ(_T("master"), m_Git.GetCurrentBranch());
420 EXPECT_STREQ(_T("master"), m_Git.GetCurrentBranch(true));
423 static void BranchTagExists_IsBranchTagNameUnique(CGit& m_Git)
425 EXPECT_TRUE(m_Git.BranchTagExists(_T("master"), true));
426 EXPECT_FALSE(m_Git.BranchTagExists(_T("origin/master"), true));
427 EXPECT_FALSE(m_Git.BranchTagExists(_T("normal-tag"), true));
428 EXPECT_FALSE(m_Git.BranchTagExists(_T("also-signed"), true));
429 EXPECT_FALSE(m_Git.BranchTagExists(_T("wuseldusel"), true));
431 EXPECT_FALSE(m_Git.BranchTagExists(_T("master"), false));
432 EXPECT_TRUE(m_Git.BranchTagExists(_T("normal-tag"), false));
433 EXPECT_TRUE(m_Git.BranchTagExists(_T("also-signed"), false));
434 EXPECT_FALSE(m_Git.BranchTagExists(_T("wuseldusel"), false));
436 EXPECT_TRUE(m_Git.IsBranchTagNameUnique(_T("master")));
437 EXPECT_TRUE(m_Git.IsBranchTagNameUnique(_T("simpleconflict")));
438 EXPECT_TRUE(m_Git.IsBranchTagNameUnique(_T("normal-tag")));
439 EXPECT_TRUE(m_Git.IsBranchTagNameUnique(_T("also-signed")));
440 EXPECT_TRUE(m_Git.IsBranchTagNameUnique(_T("origin/master")));
442 CString output;
443 EXPECT_EQ(0, m_Git.Run(_T("git.exe tag master HEAD~2"), &output, CP_UTF8));
444 EXPECT_TRUE(output.IsEmpty());
446 EXPECT_EQ(0, m_Git.Run(_T("git.exe branch normal-tag HEAD~2"), &output, CP_UTF8));
447 EXPECT_TRUE(output.IsEmpty());
449 EXPECT_FALSE(m_Git.IsBranchTagNameUnique(_T("master")));
450 EXPECT_FALSE(m_Git.IsBranchTagNameUnique(_T("normal-tag")));
451 EXPECT_TRUE(m_Git.IsBranchTagNameUnique(_T("also-signed")));
454 TEST_P(CBasicGitWithTestRepoFixture, BranchTagExists_IsBranchTagNameUnique)
456 BranchTagExists_IsBranchTagNameUnique(m_Git);
459 TEST_P(CBasicGitWithTestRepoBareFixture, BranchTagExists_IsBranchTagNameUnique)
461 BranchTagExists_IsBranchTagNameUnique(m_Git);
464 static void GetFullRefName(CGit& m_Git)
466 EXPECT_STREQ(_T(""), m_Git.GetFullRefName(_T("does_not_exist")));
467 EXPECT_STREQ(_T("refs/heads/master"), m_Git.GetFullRefName(_T("master")));
468 EXPECT_STREQ(_T("refs/remotes/origin/master"), m_Git.GetFullRefName(_T("origin/master")));
469 EXPECT_STREQ(_T("refs/tags/normal-tag"), m_Git.GetFullRefName(_T("normal-tag")));
470 EXPECT_STREQ(_T("refs/tags/also-signed"), m_Git.GetFullRefName(_T("also-signed")));
472 CString output;
473 EXPECT_EQ(0, m_Git.Run(_T("git.exe tag master HEAD~2"), &output, CP_UTF8));
474 EXPECT_TRUE(output.IsEmpty());
475 EXPECT_STREQ(_T(""), m_Git.GetFullRefName(_T("master")));
476 EXPECT_STREQ(_T("refs/remotes/origin/master"), m_Git.GetFullRefName(_T("origin/master")));
478 EXPECT_EQ(0, m_Git.Run(_T("git.exe branch normal-tag HEAD~2"), &output, CP_UTF8));
479 EXPECT_TRUE(output.IsEmpty());
480 EXPECT_STREQ(_T(""), m_Git.GetFullRefName(_T("normal-tag")));
482 EXPECT_EQ(0, m_Git.Run(_T("git.exe branch origin/master HEAD~2"), &output, CP_UTF8));
483 EXPECT_TRUE(output.IsEmpty());
484 EXPECT_STREQ(_T(""), m_Git.GetFullRefName(_T("origin/master")));
487 TEST_P(CBasicGitWithTestRepoFixture, GetFullRefName)
489 GetFullRefName(m_Git);
491 CString output;
492 EXPECT_EQ(0, m_Git.Run(_T("git.exe checkout --orphan orphanic"), &output, CP_UTF8));
493 EXPECT_FALSE(output.IsEmpty());
494 EXPECT_STREQ(_T(""), m_Git.GetFullRefName(_T("orphanic")));
497 TEST_P(CBasicGitWithTestRepoBareFixture, GetFullRefName)
499 GetFullRefName(m_Git);
502 TEST_P(CBasicGitWithEmptyRepositoryFixture, GetRemoteTrackedBranch)
504 CString remote, branch;
505 m_Git.GetRemoteTrackedBranchForHEAD(remote, branch);
506 EXPECT_TRUE(remote.IsEmpty());
507 EXPECT_TRUE(branch.IsEmpty());
509 m_Git.GetRemoteTrackedBranch(_T("master"), remote, branch);
510 EXPECT_TRUE(remote.IsEmpty());
511 EXPECT_TRUE(branch.IsEmpty());
513 m_Git.GetRemoteTrackedBranch(_T("non-existing"), remote, branch);
514 EXPECT_TRUE(remote.IsEmpty());
515 EXPECT_TRUE(branch.IsEmpty());
518 static void GetRemoteTrackedBranch(CGit& m_Git)
520 CString remote, branch;
521 m_Git.GetRemoteTrackedBranchForHEAD(remote, branch);
522 EXPECT_STREQ(_T("origin"), remote);
523 EXPECT_STREQ(_T("master"), branch);
525 remote.Empty();
526 branch.Empty();
527 m_Git.GetRemoteTrackedBranch(_T("master"), remote, branch);
528 EXPECT_STREQ(_T("origin"), remote);
529 EXPECT_STREQ(_T("master"), branch);
531 remote.Empty();
532 branch.Empty();
533 m_Git.GetRemoteTrackedBranch(_T("non-existing"), remote, branch);
534 EXPECT_TRUE(remote.IsEmpty());
535 EXPECT_TRUE(branch.IsEmpty());
538 TEST_P(CBasicGitWithTestRepoFixture, GetRemoteTrackedBranch)
540 GetRemoteTrackedBranch(m_Git);
543 TEST_P(CBasicGitWithTestRepoBareFixture, GetRemoteTrackedBranch)
545 GetRemoteTrackedBranch(m_Git);
548 static void CanParseRev(CGit& m_Git)
550 EXPECT_TRUE(m_Git.CanParseRev(_T("")));
551 EXPECT_TRUE(m_Git.CanParseRev(_T("HEAD")));
552 EXPECT_TRUE(m_Git.CanParseRev(_T("master")));
553 EXPECT_TRUE(m_Git.CanParseRev(_T("heads/master")));
554 EXPECT_TRUE(m_Git.CanParseRev(_T("refs/heads/master")));
555 EXPECT_TRUE(m_Git.CanParseRev(_T("master~1")));
556 EXPECT_TRUE(m_Git.CanParseRev(_T("master forconflict")));
557 EXPECT_TRUE(m_Git.CanParseRev(_T("origin/master..master")));
558 EXPECT_TRUE(m_Git.CanParseRev(_T("origin/master...master")));
559 EXPECT_TRUE(m_Git.CanParseRev(_T("49ecdfff36bfe2b9b499b33e5034f427e2fa54dd")));
560 EXPECT_FALSE(m_Git.CanParseRev(_T("non-existing")));
561 EXPECT_TRUE(m_Git.CanParseRev(_T("normal-tag")));
562 EXPECT_TRUE(m_Git.CanParseRev(_T("tags/normal-tag")));
563 EXPECT_TRUE(m_Git.CanParseRev(_T("refs/tags/normal-tag")));
564 EXPECT_TRUE(m_Git.CanParseRev(_T("all-files-signed")));
565 EXPECT_TRUE(m_Git.CanParseRev(_T("all-files-signed^{}")));
567 EXPECT_FALSE(m_Git.CanParseRev(_T("orphanic")));
570 TEST_P(CBasicGitWithTestRepoFixture, CanParseRev)
572 CanParseRev(m_Git);
574 CString output;
575 EXPECT_EQ(0, m_Git.Run(_T("git.exe checkout --orphan orphanic"), &output, CP_UTF8));
576 EXPECT_FALSE(output.IsEmpty());
577 EXPECT_FALSE(m_Git.CanParseRev(_T("")));
578 EXPECT_FALSE(m_Git.CanParseRev(_T("HEAD")));
579 EXPECT_FALSE(m_Git.CanParseRev(_T("orphanic")));
580 EXPECT_TRUE(m_Git.CanParseRev(_T("master")));
583 TEST_P(CBasicGitWithTestRepoBareFixture, CanParseRev)
585 CanParseRev(m_Git);
588 static void FETCHHEAD(CGit& m_Git, bool isBare)
590 CString repoDir = m_Git.m_CurrentDir;
591 if (!isBare)
592 repoDir += _T("\\.git");
594 STRING_VECTOR list;
595 EXPECT_EQ(0, m_Git.GetBranchList(list, nullptr));
596 EXPECT_EQ(5, list.size());
597 list.clear();
598 EXPECT_EQ(0, m_Git.GetBranchList(list, nullptr, CGit::BRANCH_LOCAL_F));
599 EXPECT_EQ(5, list.size());
601 EXPECT_STREQ(_T("HEAD"), m_Git.FixBranchName(_T("HEAD")));
602 EXPECT_STREQ(_T("master"), m_Git.FixBranchName(_T("master")));
603 EXPECT_STREQ(_T("non-existing"), m_Git.FixBranchName(_T("non-existing")));
604 CString branch = _T("master");
605 EXPECT_STREQ(_T("master"), m_Git.FixBranchName_Mod(branch));
606 EXPECT_STREQ(_T("master"), branch);
607 branch = _T("non-existing");
608 EXPECT_STREQ(_T("non-existing"), m_Git.FixBranchName_Mod(branch));
609 EXPECT_STREQ(_T("non-existing"), branch);
610 CGitHash hash;
611 EXPECT_NE(0, m_Git.GetHash(hash, _T("FETCH_HEAD")));
613 CString testFile = repoDir + L"\\FETCH_HEAD";
614 EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFile, L"b9ef30183497cdad5c30b88d32dc1bed7951dfeb branch 'master' of https://code.google.com/p/tortoisegit\n737878a4e2eabfa4fab580867c2b060c70999d31 not-for-merge branch 'extend_hooks' of https://code.google.com/p/tortoisegit\n"));
616 list.clear();
617 EXPECT_EQ(0, m_Git.GetBranchList(list, nullptr));
618 EXPECT_EQ(5, list.size());
619 list.clear();
620 EXPECT_EQ(0, m_Git.GetBranchList(list, nullptr, CGit::BRANCH_LOCAL_F));
621 EXPECT_EQ(6, list.size());
623 EXPECT_STREQ(_T("master"), m_Git.FixBranchName(_T("master")));
624 EXPECT_STREQ(_T("non-existing"), m_Git.FixBranchName(_T("non-existing")));
625 EXPECT_STREQ(_T("b9ef30183497cdad5c30b88d32dc1bed7951dfeb"), m_Git.FixBranchName(_T("FETCH_HEAD")));
626 branch = _T("HEAD");
627 EXPECT_STREQ(_T("HEAD"), m_Git.FixBranchName_Mod(branch));
628 EXPECT_STREQ(_T("HEAD"), branch);
629 branch = _T("master");
630 EXPECT_STREQ(_T("master"), m_Git.FixBranchName_Mod(branch));
631 EXPECT_STREQ(_T("master"), branch);
632 branch = _T("non-existing");
633 EXPECT_STREQ(_T("non-existing"), m_Git.FixBranchName_Mod(branch));
634 EXPECT_STREQ(_T("non-existing"), branch);
635 branch = _T("FETCH_HEAD");
636 EXPECT_STREQ(_T("b9ef30183497cdad5c30b88d32dc1bed7951dfeb"), m_Git.FixBranchName_Mod(branch));
637 EXPECT_STREQ(_T("b9ef30183497cdad5c30b88d32dc1bed7951dfeb"), branch);
638 EXPECT_EQ(0, m_Git.GetHash(hash, _T("FETCH_HEAD")));
639 EXPECT_STREQ(_T("b9ef30183497cdad5c30b88d32dc1bed7951dfeb"), hash.ToString());
641 EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFile, L"737878a4e2eabfa4fab580867c2b060c70999d31 not-for-merge branch 'extend_hooks' of https://code.google.com/p/tortoisegit\nb9ef30183497cdad5c30b88d32dc1bed7951dfeb branch 'master' of https://code.google.com/p/tortoisegit\n"));
643 list.clear();
644 EXPECT_EQ(0, m_Git.GetBranchList(list, nullptr));
645 EXPECT_EQ(5, list.size());
646 list.clear();
647 EXPECT_EQ(0, m_Git.GetBranchList(list, nullptr, CGit::BRANCH_LOCAL_F));
648 EXPECT_EQ(6, list.size());
650 EXPECT_STREQ(_T("b9ef30183497cdad5c30b88d32dc1bed7951dfeb"), m_Git.FixBranchName(_T("FETCH_HEAD")));
651 branch = _T("FETCH_HEAD");
652 EXPECT_STREQ(_T("b9ef30183497cdad5c30b88d32dc1bed7951dfeb"), m_Git.FixBranchName_Mod(branch));
653 EXPECT_STREQ(_T("b9ef30183497cdad5c30b88d32dc1bed7951dfeb"), branch);
654 // libgit2 fails here
655 //EXPECT_EQ(0, m_Git.GetHash(hash, _T("FETCH_HEAD")));
656 //EXPECT_STREQ(_T("b9ef30183497cdad5c30b88d32dc1bed7951dfeb"), hash.ToString());
659 TEST_P(CBasicGitWithTestRepoFixture, FETCHHEAD)
661 FETCHHEAD(m_Git, false);
664 TEST_P(CBasicGitWithTestRepoBareFixture, FETCHHEAD)
666 FETCHHEAD(m_Git, true);
669 TEST_P(CBasicGitWithTestRepoFixture, IsFastForward)
671 CGitHash commonAncestor;
672 EXPECT_TRUE(m_Git.IsFastForward(_T("origin/master"), _T("master"), &commonAncestor));
673 EXPECT_STREQ(_T("a9d53b535cb49640a6099860ac4999f5a0857b91"), commonAncestor.ToString());
675 EXPECT_FALSE(m_Git.IsFastForward(_T("simple-conflict"), _T("master"), &commonAncestor));
676 EXPECT_STREQ(_T("b02add66f48814a73aa2f0876d6bbc8662d6a9a8"), commonAncestor.ToString());
679 static void GetHash(CGit& m_Git)
681 CGitHash hash;
682 EXPECT_EQ(0, m_Git.GetHash(hash, _T("HEAD")));
683 EXPECT_STREQ(_T("7c3cbfe13a929d2291a574dca45e4fd2d2ac1aa6"), hash.ToString());
684 EXPECT_EQ(0, m_Git.GetHash(hash, _T("HEAD~1")));
685 EXPECT_STREQ(_T("1fc3c9688e27596d8717b54f2939dc951568f6cb"), hash.ToString());
686 EXPECT_EQ(0, m_Git.GetHash(hash, _T("ff1fbef1a54a9849afd4a5e94d2ca4d80d5b96c2")));
687 EXPECT_STREQ(_T("ff1fbef1a54a9849afd4a5e94d2ca4d80d5b96c2"), hash.ToString());
688 EXPECT_EQ(0, m_Git.GetHash(hash, _T("master")));
689 EXPECT_STREQ(_T("7c3cbfe13a929d2291a574dca45e4fd2d2ac1aa6"), hash.ToString());
690 EXPECT_EQ(0, m_Git.GetHash(hash, _T("origin/master")));
691 EXPECT_STREQ(_T("a9d53b535cb49640a6099860ac4999f5a0857b91"), hash.ToString());
692 EXPECT_EQ(0, m_Git.GetHash(hash, _T("49ecdfff36bfe2b9b499b33e5034f427e2fa54dd")));
693 EXPECT_STREQ(_T("49ecdfff36bfe2b9b499b33e5034f427e2fa54dd"), hash.ToString());
694 EXPECT_EQ(0, m_Git.GetHash(hash, _T("normal-tag")));
695 EXPECT_STREQ(_T("b9ef30183497cdad5c30b88d32dc1bed7951dfeb"), hash.ToString());
696 EXPECT_EQ(0, m_Git.GetHash(hash, _T("all-files-signed")));
697 EXPECT_STREQ(_T("ab555b2776c6b700ad93848d0dd050e7d08be779"), hash.ToString()); // maybe we need automatically to dereference it
698 EXPECT_EQ(0, m_Git.GetHash(hash, _T("all-files-signed^{}")));
699 EXPECT_STREQ(_T("313a41bc88a527289c87d7531802ab484715974f"), hash.ToString());
701 EXPECT_NE(0, m_Git.GetHash(hash, _T("non-existing")));
704 TEST_P(CBasicGitWithTestRepoFixture, GetHash)
706 GetHash(m_Git);
709 TEST_P(CBasicGitWithTestRepoBareFixture, GetHash)
711 GetHash(m_Git);
714 TEST_P(CBasicGitWithEmptyRepositoryFixture, GetHash_EmptyRepo)
716 CGitHash hash;
717 EXPECT_EQ(0, m_Git.GetHash(hash, _T("HEAD")));
718 EXPECT_TRUE(hash.IsEmpty());
721 TEST_P(CBasicGitWithEmptyRepositoryFixture, GetEmptyBranchesTagsRefs)
723 STRING_VECTOR branches;
724 int current = -2;
725 EXPECT_EQ(0, m_Git.GetBranchList(branches, &current));
726 EXPECT_TRUE(branches.empty());
727 EXPECT_EQ(-2, current); // not touched
729 EXPECT_EQ(0, m_Git.GetBranchList(branches, &current, CGit::BRANCH_ALL));
730 EXPECT_TRUE(branches.empty());
731 EXPECT_EQ(-2, current); // not touched
733 STRING_VECTOR tags;
734 EXPECT_EQ(0, m_Git.GetTagList(tags));
735 EXPECT_TRUE(tags.empty());
737 STRING_VECTOR refs;
738 EXPECT_EQ(0, m_Git.GetRefList(refs));
739 EXPECT_TRUE(refs.empty());
741 MAP_HASH_NAME map;
742 EXPECT_EQ(0, m_Git.GetMapHashToFriendName(map));
743 EXPECT_TRUE(map.empty());
745 STRING_VECTOR remotes;
746 EXPECT_EQ(0, m_Git.GetRemoteList(remotes));
747 EXPECT_TRUE(remotes.empty());
750 static void GetBranchesTagsRefs(CGit& m_Git, config testConfig)
752 STRING_VECTOR branches;
753 int current = -2;
754 EXPECT_EQ(0, m_Git.GetBranchList(branches, &current));
755 ASSERT_EQ(5, branches.size());
756 EXPECT_EQ(1, current);
757 EXPECT_STREQ(_T("forconflict"), branches[0]);
758 EXPECT_STREQ(_T("master"), branches[1]);
759 EXPECT_STREQ(_T("master2"), branches[2]);
760 EXPECT_STREQ(_T("simple-conflict"), branches[3]);
761 EXPECT_STREQ(_T("subdir/branch"), branches[4]);
763 branches.clear();
764 current = -2;
765 EXPECT_EQ(0, m_Git.GetBranchList(branches, &current, CGit::BRANCH_ALL));
766 ASSERT_EQ(6, branches.size());
767 EXPECT_EQ(1, current);
768 EXPECT_STREQ(_T("forconflict"), branches[0]);
769 EXPECT_STREQ(_T("master"), branches[1]);
770 EXPECT_STREQ(_T("master2"), branches[2]);
771 EXPECT_STREQ(_T("simple-conflict"), branches[3]);
772 EXPECT_STREQ(_T("subdir/branch"), branches[4]);
773 EXPECT_STREQ(_T("remotes/origin/master"), branches[5]);
775 branches.clear();
776 current = -2;
777 EXPECT_EQ(0, m_Git.GetBranchList(branches, &current, CGit::BRANCH_REMOTE));
778 ASSERT_EQ(1, branches.size());
779 EXPECT_EQ(-2, current); // not touched
780 EXPECT_STREQ(_T("remotes/origin/master"), branches[0]);
782 STRING_VECTOR tags;
783 EXPECT_EQ(0, m_Git.GetTagList(tags));
784 ASSERT_EQ(3, tags.size());
785 EXPECT_STREQ(_T("all-files-signed"), tags[0]);
786 EXPECT_STREQ(_T("also-signed"), tags[1]);
787 EXPECT_STREQ(_T("normal-tag"), tags[2]);
789 STRING_VECTOR refs;
790 EXPECT_EQ(0, m_Git.GetRefList(refs));
791 ASSERT_EQ(11, refs.size());
792 EXPECT_STREQ(_T("refs/heads/forconflict"), refs[0]);
793 EXPECT_STREQ(_T("refs/heads/master"), refs[1]);
794 EXPECT_STREQ(_T("refs/heads/master2"), refs[2]);
795 EXPECT_STREQ(_T("refs/heads/simple-conflict"), refs[3]);
796 EXPECT_STREQ(_T("refs/heads/subdir/branch"), refs[4]);
797 EXPECT_STREQ(_T("refs/notes/commits"), refs[5]);
798 EXPECT_STREQ(_T("refs/remotes/origin/master"), refs[6]);
799 EXPECT_STREQ(_T("refs/stash"), refs[7]);
800 EXPECT_STREQ(_T("refs/tags/all-files-signed"), refs[8]);
801 EXPECT_STREQ(_T("refs/tags/also-signed"), refs[9]);
802 EXPECT_STREQ(_T("refs/tags/normal-tag"), refs[10]);
804 MAP_HASH_NAME map;
805 EXPECT_EQ(0, m_Git.GetMapHashToFriendName(map));
806 if (testConfig == GIT_CLI || testConfig == LIBGIT)
807 ASSERT_EQ(12, map.size()); // also contains the undereferenced tags with hashes
808 else
809 ASSERT_EQ(10, map.size());
811 ASSERT_EQ(1, map[CGitHash(L"7c3cbfe13a929d2291a574dca45e4fd2d2ac1aa6")].size());
812 EXPECT_STREQ(_T("refs/heads/master"), map[CGitHash(L"7c3cbfe13a929d2291a574dca45e4fd2d2ac1aa6")][0]);
813 ASSERT_EQ(1, map[CGitHash(L"4c5c93d2a0b368bc4570d5ec02ab03b9c4334d44")].size());
814 EXPECT_STREQ(_T("refs/heads/subdir/branch"), map[CGitHash(L"4c5c93d2a0b368bc4570d5ec02ab03b9c4334d44")][0]);
815 ASSERT_EQ(1, map[CGitHash(L"5e702e1712aa6f8cd8e0328a87be006f3a923710")].size());
816 EXPECT_STREQ(_T("refs/notes/commits"), map[CGitHash(L"5e702e1712aa6f8cd8e0328a87be006f3a923710")][0]);
817 ASSERT_EQ(1, map[CGitHash(L"18da7c332dcad0f37f9977d9176dce0b0c66f3eb")].size());
818 EXPECT_STREQ(_T("refs/stash"), map[CGitHash(L"18da7c332dcad0f37f9977d9176dce0b0c66f3eb")][0]);
819 ASSERT_EQ(1, map[CGitHash(L"c5b89de0335fd674e2e421ac4543098cb2f22cde")].size());
820 EXPECT_STREQ(_T("refs/heads/simple-conflict"), map[CGitHash(L"c5b89de0335fd674e2e421ac4543098cb2f22cde")][0]);
821 ASSERT_EQ(1, map[CGitHash(L"10385764a4d42d7428bbeb245015f8f338fc1e40")].size());
822 EXPECT_STREQ(_T("refs/heads/forconflict"), map[CGitHash(L"10385764a4d42d7428bbeb245015f8f338fc1e40")][0]);
823 ASSERT_EQ(2, map[CGitHash(L"49ecdfff36bfe2b9b499b33e5034f427e2fa54dd")].size());
824 EXPECT_STREQ(_T("refs/heads/master2"), map[CGitHash(L"49ecdfff36bfe2b9b499b33e5034f427e2fa54dd")][0]);
825 EXPECT_STREQ(_T("refs/tags/also-signed^{}"), map[CGitHash(L"49ecdfff36bfe2b9b499b33e5034f427e2fa54dd")][1]);
826 ASSERT_EQ(1, map[CGitHash(L"b9ef30183497cdad5c30b88d32dc1bed7951dfeb")].size());//
827 EXPECT_STREQ(_T("refs/tags/normal-tag"), map[CGitHash(L"b9ef30183497cdad5c30b88d32dc1bed7951dfeb")][0]);
828 ASSERT_EQ(1, map[CGitHash(L"a9d53b535cb49640a6099860ac4999f5a0857b91")].size());
829 EXPECT_STREQ(_T("refs/remotes/origin/master"), map[CGitHash(L"a9d53b535cb49640a6099860ac4999f5a0857b91")][0]);
830 ASSERT_EQ(1, map[CGitHash(L"313a41bc88a527289c87d7531802ab484715974f")].size());
831 EXPECT_STREQ(_T("refs/tags/all-files-signed^{}"), map[CGitHash(L"313a41bc88a527289c87d7531802ab484715974f")][0]);
833 STRING_VECTOR remotes;
834 EXPECT_EQ(0, m_Git.GetRemoteList(remotes));
835 ASSERT_EQ(1, remotes.size());
836 EXPECT_STREQ(_T("origin"), remotes[0]);
838 EXPECT_EQ(-1, m_Git.DeleteRef(_T("refs/tags/gibbednet")));
839 branches.clear();
840 EXPECT_EQ(0, m_Git.GetBranchList(branches, nullptr, CGit::BRANCH_ALL));
841 EXPECT_EQ(6, branches.size());
842 tags.clear();
843 EXPECT_EQ(0, m_Git.GetTagList(tags));
844 EXPECT_EQ(3, tags.size());
845 refs.clear();
846 EXPECT_EQ(0, m_Git.GetRefList(refs));
847 EXPECT_EQ(11, refs.size());
849 EXPECT_EQ(-1, m_Git.DeleteRef(_T("refs/heads/gibbednet")));
850 branches.clear();
851 EXPECT_EQ(0, m_Git.GetBranchList(branches, nullptr, CGit::BRANCH_ALL));
852 EXPECT_EQ(6, branches.size());
853 tags.clear();
854 EXPECT_EQ(0, m_Git.GetTagList(tags));
855 EXPECT_EQ(3, tags.size());
856 refs.clear();
857 EXPECT_EQ(0, m_Git.GetRefList(refs));
858 EXPECT_EQ(11, refs.size());
860 EXPECT_EQ(-1, m_Git.DeleteRef(_T("refs/remotes/origin/gibbednet")));
861 branches.clear();
862 EXPECT_EQ(0, m_Git.GetBranchList(branches, nullptr, CGit::BRANCH_ALL));
863 EXPECT_EQ(6, branches.size());
864 tags.clear();
865 EXPECT_EQ(0, m_Git.GetTagList(tags));
866 EXPECT_EQ(3, tags.size());
867 refs.clear();
868 EXPECT_EQ(0, m_Git.GetRefList(refs));
869 EXPECT_EQ(11, refs.size());
871 EXPECT_EQ(0, m_Git.DeleteRef(_T("refs/tags/normal-tag")));
872 branches.clear();
873 EXPECT_EQ(0, m_Git.GetBranchList(branches, nullptr, CGit::BRANCH_ALL));
874 EXPECT_EQ(6, branches.size());
875 tags.clear();
876 EXPECT_EQ(0, m_Git.GetTagList(tags));
877 EXPECT_EQ(2, tags.size());
878 refs.clear();
879 EXPECT_EQ(0, m_Git.GetRefList(refs));
880 EXPECT_EQ(10, refs.size());
882 EXPECT_EQ(0, m_Git.DeleteRef(_T("refs/tags/all-files-signed^{}")));
883 branches.clear();
884 EXPECT_EQ(0, m_Git.GetBranchList(branches, nullptr, CGit::BRANCH_ALL));
885 EXPECT_EQ(6, branches.size());
886 tags.clear();
887 EXPECT_EQ(0, m_Git.GetTagList(tags));
888 EXPECT_EQ(1, tags.size());
889 refs.clear();
890 EXPECT_EQ(0, m_Git.GetRefList(refs));
891 EXPECT_EQ(9, refs.size());
893 EXPECT_EQ(0, m_Git.DeleteRef(_T("refs/heads/subdir/branch")));
894 branches.clear();
895 EXPECT_EQ(0, m_Git.GetBranchList(branches, nullptr, CGit::BRANCH_ALL));
896 EXPECT_EQ(5, branches.size());
897 tags.clear();
898 EXPECT_EQ(0, m_Git.GetTagList(tags));
899 EXPECT_EQ(1, tags.size());
900 refs.clear();
901 EXPECT_EQ(0, m_Git.GetRefList(refs));
902 EXPECT_EQ(8, refs.size());
904 EXPECT_EQ(0, m_Git.DeleteRef(_T("refs/remotes/origin/master")));
905 branches.clear();
906 EXPECT_EQ(0, m_Git.GetBranchList(branches, nullptr, CGit::BRANCH_ALL));
907 EXPECT_EQ(4, branches.size());
908 tags.clear();
909 EXPECT_EQ(0, m_Git.GetTagList(tags));
910 EXPECT_EQ(1, tags.size());
911 refs.clear();
912 EXPECT_EQ(0, m_Git.GetRefList(refs));
913 EXPECT_EQ(7, refs.size());
916 TEST_P(CBasicGitWithTestRepoFixture, GetBranchesTagsRefs)
918 GetBranchesTagsRefs(m_Git, GetParam());
921 TEST_P(CBasicGitWithTestRepoBareFixture, GetBranchesTagsRefs)
923 GetBranchesTagsRefs(m_Git, GetParam());
926 TEST_P(CBasicGitWithTestRepoFixture, GetBranchList_orphan)
928 CString output;
929 EXPECT_EQ(0, m_Git.Run(_T("git.exe checkout --orphan orphanic"), &output, CP_UTF8));
930 EXPECT_FALSE(output.IsEmpty());
932 STRING_VECTOR branches;
933 int current = -2;
934 EXPECT_EQ(0, m_Git.GetBranchList(branches, &current));
935 ASSERT_EQ(5, branches.size());
936 EXPECT_EQ(-2, current);
937 EXPECT_STREQ(_T("forconflict"), branches[0]);
938 EXPECT_STREQ(_T("master"), branches[1]);
939 EXPECT_STREQ(_T("master2"), branches[2]);
940 EXPECT_STREQ(_T("simple-conflict"), branches[3]);
941 EXPECT_STREQ(_T("subdir/branch"), branches[4]);
944 TEST_P(CBasicGitWithTestRepoFixture, GetBranchList_detachedhead)
946 CString output;
947 EXPECT_EQ(0, m_Git.Run(_T("git.exe checkout a9d53b535cb49640a6099860ac4999f5a0857b91"), &output, CP_UTF8));
948 EXPECT_FALSE(output.IsEmpty());
950 STRING_VECTOR branches;
951 int current = -2;
952 EXPECT_EQ(0, m_Git.GetBranchList(branches, &current));
953 ASSERT_EQ(5, branches.size());
954 EXPECT_EQ(-2, current);
955 EXPECT_STREQ(_T("forconflict"), branches[0]);
956 EXPECT_STREQ(_T("master"), branches[1]);
957 EXPECT_STREQ(_T("master2"), branches[2]);
958 EXPECT_STREQ(_T("simple-conflict"), branches[3]);
959 EXPECT_STREQ(_T("subdir/branch"), branches[4]);
961 // cygwin fails here
962 if (CGit::ms_bCygwinGit)
963 return;
965 output.Empty();
966 EXPECT_EQ(0, m_Git.Run(_T("git.exe checkout -b (HEAD a9d53b535cb49640a6099860ac4999f5a0857b91"), &output, CP_UTF8));
967 EXPECT_FALSE(output.IsEmpty());
969 branches.clear();
970 current = -2;
971 EXPECT_EQ(0, m_Git.GetBranchList(branches, &current));
972 ASSERT_EQ(6, branches.size());
973 EXPECT_EQ(0, current);
974 EXPECT_STREQ(_T("(HEAD"), branches[0]);
975 EXPECT_STREQ(_T("forconflict"), branches[1]);
976 EXPECT_STREQ(_T("master"), branches[2]);
977 EXPECT_STREQ(_T("master2"), branches[3]);
978 EXPECT_STREQ(_T("simple-conflict"), branches[4]);
979 EXPECT_STREQ(_T("subdir/branch"), branches[5]);
982 TEST_P(CBasicGitWithEmptyBareRepositoryFixture, GetEmptyBranchesTagsRefs)
984 EXPECT_STREQ(_T("master"), m_Git.GetCurrentBranch());
986 STRING_VECTOR branches;
987 int current = -2;
988 EXPECT_EQ(0, m_Git.GetBranchList(branches, &current));
989 EXPECT_TRUE(branches.empty());
990 EXPECT_EQ(-2, current); // not touched
992 EXPECT_EQ(0, m_Git.GetBranchList(branches, &current, CGit::BRANCH_ALL));
993 EXPECT_TRUE(branches.empty());
994 EXPECT_EQ(-2, current); // not touched
996 STRING_VECTOR tags;
997 EXPECT_EQ(0, m_Git.GetTagList(tags));
998 EXPECT_TRUE(tags.empty());
1000 STRING_VECTOR refs;
1001 EXPECT_EQ(0, m_Git.GetRefList(refs));
1002 EXPECT_TRUE(refs.empty());
1004 MAP_HASH_NAME map;
1005 EXPECT_EQ(0, m_Git.GetMapHashToFriendName(map));
1006 EXPECT_TRUE(map.empty());
1008 STRING_VECTOR remotes;
1009 EXPECT_EQ(0, m_Git.GetRemoteList(remotes));
1010 EXPECT_TRUE(remotes.empty());
1013 TEST_P(CBasicGitWithEmptyRepositoryFixture, CheckCleanWorkTree)
1015 // this test is known to fail with cygwin and also not enabled by default
1016 if (GetParam() == LIBGIT2_ALL && CGit::ms_bCygwinGit)
1017 return;
1019 CString output;
1020 CString testFile = m_Dir.GetTempDir() + L"\\test.txt";
1021 EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFile, L"this is testing file."));
1022 EXPECT_EQ(0, m_Git.Run(_T("git.exe add test.txt"), &output, CP_UTF8));
1023 output.Empty();
1024 EXPECT_EQ(0, m_Git.Run(_T("git.exe commit -m \"Add test.txt\""), &output, CP_UTF8));
1025 // repo with 1 versioned file
1026 EXPECT_FALSE(output.IsEmpty());
1027 EXPECT_TRUE(m_Git.CheckCleanWorkTree());
1028 EXPECT_TRUE(m_Git.CheckCleanWorkTree(true));
1030 EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFile, L"Overwriting this testing file."));
1031 // repo with 1 modified versioned file
1032 EXPECT_FALSE(m_Git.CheckCleanWorkTree());
1033 EXPECT_FALSE(m_Git.CheckCleanWorkTree(true));
1035 output.Empty();
1036 EXPECT_EQ(0, m_Git.Run(_T("git.exe add test.txt"), &output, CP_UTF8));
1037 // repo with 1 modified versioned and staged file
1038 EXPECT_TRUE(output.IsEmpty());
1039 EXPECT_FALSE(m_Git.CheckCleanWorkTree());
1040 EXPECT_TRUE(m_Git.CheckCleanWorkTree(true));
1042 EXPECT_EQ(0, m_Git.Run(_T("git.exe commit -m \"Modified test.txt\""), &output, CP_UTF8));
1043 testFile = m_Dir.GetTempDir() + L"\\test2.txt";
1044 EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFile, L"this is ANOTHER testing file."));
1045 EXPECT_TRUE(m_Git.CheckCleanWorkTree());
1046 EXPECT_TRUE(m_Git.CheckCleanWorkTree(true));
1048 EXPECT_EQ(0, m_Git.Run(_T("git.exe checkout --orphan orphanic"), &output, CP_UTF8));
1049 EXPECT_FALSE(output.IsEmpty());
1050 EXPECT_FALSE(m_Git.CheckCleanWorkTree());
1051 EXPECT_FALSE(m_Git.CheckCleanWorkTree(true));
1054 TEST(CGit, CEnvironment)
1056 CEnvironment env;
1057 EXPECT_TRUE(env.empty());
1058 env.SetEnv(_T("not-found"), nullptr);
1059 EXPECT_STREQ(_T(""), env.GetEnv(L"test"));
1060 env.SetEnv(L"key1", L"value1");
1061 EXPECT_STREQ(_T("value1"), env.GetEnv(L"key1"));
1062 EXPECT_STREQ(_T("value1"), env.GetEnv(L"kEy1")); // check case insensitivity
1063 EXPECT_FALSE(env.empty());
1064 EXPECT_STREQ(_T("value1"), env.GetEnv(L"key1"));
1065 env.SetEnv(L"key1", nullptr); // delete first
1066 EXPECT_TRUE(env.empty());
1067 env.SetEnv(L"key1", L"value1");
1068 EXPECT_STREQ(_T("value1"), env.GetEnv(L"key1"));
1069 env.SetEnv(L"key2", L"value2");
1070 EXPECT_STREQ(_T("value1"), env.GetEnv(L"key1"));
1071 EXPECT_STREQ(_T("value2"), env.GetEnv(L"key2"));
1072 env.SetEnv(_T("not-found"), nullptr);
1073 EXPECT_STREQ(_T("value1"), env.GetEnv(L"key1"));
1074 EXPECT_STREQ(_T("value2"), env.GetEnv(L"key2"));
1075 env.SetEnv(_T("key2"), nullptr); // delete last
1076 EXPECT_STREQ(_T("value1"), env.GetEnv(L"key1"));
1077 EXPECT_STREQ(_T(""), env.GetEnv(L"key2"));
1078 env.SetEnv(L"key3", L"value3");
1079 EXPECT_STREQ(_T("value1"), env.GetEnv(L"key1"));
1080 EXPECT_STREQ(_T("value3"), env.GetEnv(L"key3"));
1081 env.SetEnv(L"key4", L"value4");
1082 env.SetEnv(_T("value3"), nullptr); // delete middle
1083 EXPECT_STREQ(_T("value1"), env.GetEnv(L"key1"));
1084 EXPECT_STREQ(_T("value4"), env.GetEnv(L"key4"));
1085 env.SetEnv(L"key5", L"value5");
1086 EXPECT_STREQ(_T("value1"), env.GetEnv(L"key1"));
1087 EXPECT_STREQ(_T("value4"), env.GetEnv(L"key4"));
1088 EXPECT_STREQ(_T("value5"), env.GetEnv(L"key5"));
1089 env.SetEnv(L"key4", L"value4a");
1090 EXPECT_STREQ(_T("value1"), env.GetEnv(L"key1"));
1091 EXPECT_STREQ(_T("value4a"), env.GetEnv(L"key4"));
1092 EXPECT_STREQ(_T("value5"), env.GetEnv(L"key5"));
1093 env.SetEnv(L"key5", L"value5a");
1094 EXPECT_STREQ(_T("value1"), env.GetEnv(L"key1"));
1095 EXPECT_STREQ(_T("value4a"), env.GetEnv(L"key4"));
1096 EXPECT_STREQ(_T("value5a"), env.GetEnv(L"key5"));
1097 #pragma warning(push)
1098 #pragma warning(disable: 4996)
1099 CString windir = _wgetenv(L"windir");
1100 #pragma warning(pop)
1101 env.CopyProcessEnvironment();
1102 EXPECT_STREQ(windir, env.GetEnv(L"windir"));
1103 EXPECT_STREQ(_T("value1"), env.GetEnv(L"key1"));
1104 EXPECT_STREQ(_T("value4a"), env.GetEnv(L"key4"));
1105 EXPECT_STREQ(_T("value5a"), env.GetEnv(L"key5"));
1106 env.clear();
1107 EXPECT_TRUE(env.empty());
1108 EXPECT_STREQ(_T(""), env.GetEnv(L"key4"));
1109 env.CopyProcessEnvironment();
1110 EXPECT_STREQ(windir, env.GetEnv(L"windir"));
1112 env.clear();
1113 CString path = L"c:\\windows;c:\\windows\\system32";
1114 env.SetEnv(L"PATH", path);
1115 env.AddToPath(L"");
1116 EXPECT_STREQ(path, env.GetEnv(L"PATH"));
1117 env.AddToPath(L"c:\\windows");
1118 EXPECT_STREQ(path, env.GetEnv(L"PATH"));
1119 env.AddToPath(L"c:\\windows\\");
1120 EXPECT_STREQ(path, env.GetEnv(L"PATH"));
1121 env.AddToPath(L"c:\\windows\\system32");
1122 EXPECT_STREQ(path, env.GetEnv(L"PATH"));
1123 env.AddToPath(L"c:\\windows\\system32\\");
1124 EXPECT_STREQ(path, env.GetEnv(L"PATH"));
1125 path += L";c:\\windows\\system";
1126 env.AddToPath(L"c:\\windows\\system");
1127 EXPECT_STREQ(path, env.GetEnv(L"PATH"));
1128 path += L";c:\\test";
1129 env.AddToPath(L"c:\\test\\");
1130 EXPECT_STREQ(path, env.GetEnv(L"PATH"));
1131 env.AddToPath(L"c:\\test\\");
1132 EXPECT_STREQ(path, env.GetEnv(L"PATH"));
1133 env.AddToPath(L"c:\\test");
1134 EXPECT_STREQ(path, env.GetEnv(L"PATH"));
1135 path = L"c:\\windows;c:\\windows\\system32;";
1136 env.SetEnv(L"PATH", path);
1137 env.AddToPath(L"");
1138 EXPECT_STREQ(path, env.GetEnv(L"PATH"));
1139 env.AddToPath(L"c:\\test");
1140 path += L"c:\\test";
1141 EXPECT_STREQ(path, env.GetEnv(L"PATH"));
1144 static void GetOneFile(CGit& m_Git)
1146 CString tmpFile = GetTempFile();
1147 EXPECT_EQ(0, m_Git.GetOneFile(L"b9ef30183497cdad5c30b88d32dc1bed7951dfeb", CTGitPath(L"utf8-nobom.txt"), tmpFile));
1148 CString fileContents;
1149 EXPECT_EQ(true, CStringUtils::ReadStringFromTextFile(tmpFile, fileContents));
1150 struct _stat32 stat_buf = { 0 };
1151 EXPECT_EQ(0, _wstat32(tmpFile, &stat_buf));
1152 EXPECT_EQ(139, stat_buf.st_size);
1153 EXPECT_EQ(108, fileContents.GetLength());
1154 EXPECT_STREQ(_T("ä#äf34ööcöä߀9875oe\r\nfgdjkglsfdg\r\nöäöü45g\r\nfdgi&§$%&hfdsgä\r\nä#äf34öööä߀9875oe\r\nöäcüpfgmfdg\r\n€fgfdsg\r\n45\r\näü"), fileContents);
1155 ::DeleteFile(tmpFile);
1158 TEST_P(CBasicGitWithTestRepoFixture, GetOneFile)
1160 GetOneFile(m_Git);
1162 // clean&smudge filters are not available for GetOneFile without libigt2
1163 if (GetParam() == GIT_CLI || GetParam() == LIBGIT)
1164 return;
1166 CString cleanFilterFilename = m_Git.m_CurrentDir + L"\\clean_filter_openssl";
1167 EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)cleanFilterFilename, L"#!/bin/bash\nopenssl enc -base64 -aes-256-ecb -S FEEDDEADBEEF -k PASS_FIXED"));
1168 CString smudgeFilterFilename = m_Git.m_CurrentDir + L"\\smudge_filter_openssl";
1169 EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)smudgeFilterFilename, L"#!/bin/bash\nopenssl enc -d -base64 -aes-256-ecb -k PASS_FIXED"));
1171 CAutoRepository repo(m_Git.GetGitRepository());
1172 ASSERT_TRUE(repo.IsValid());
1173 CAutoConfig config(repo);
1174 ASSERT_TRUE(config.IsValid());
1175 CStringA path = CUnicodeUtils::GetUTF8(m_Git.m_CurrentDir);
1176 path.Replace('\\', '/');
1177 EXPECT_EQ(0, git_config_set_string(config, "filter.openssl.clean", path + "/clean_filter_openssl"));
1178 EXPECT_EQ(0, git_config_set_string(config, "filter.openssl.smudge", path + "/smudge_filter_openssl"));
1179 EXPECT_EQ(0, git_config_set_bool(config, "filter.openssl.required", 1));
1181 CString attributesFile = m_Git.m_CurrentDir + L"\\.gitattributes";
1182 EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)attributesFile, L"*.enc filter=openssl\n"));
1184 CString encryptedFileOne = m_Git.m_CurrentDir + L"\\1.enc";
1185 EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)encryptedFileOne, L"This should be encrypted...\nAnd decrypted on the fly\n"));
1187 CString encryptedFileTwo = m_Git.m_CurrentDir + L"\\2.enc";
1188 EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)encryptedFileTwo, L"This should also be encrypted...\nAnd also decrypted on the fly\n"));
1190 CString output;
1191 EXPECT_EQ(0, m_Git.Run(_T("git.exe add 1.enc"), &output, CP_UTF8));
1192 EXPECT_TRUE(output.IsEmpty());
1194 CAutoIndex index;
1195 ASSERT_EQ(0, git_repository_index(index.GetPointer(), repo));
1196 EXPECT_EQ(0, git_index_add_bypath(index, "2.enc"));
1197 EXPECT_EQ(0, git_index_write(index));
1199 EXPECT_EQ(0, m_Git.Run(_T("git.exe commit -m \"Message\""), &output, CP_UTF8));
1200 EXPECT_FALSE(output.IsEmpty());
1202 CString fileContents;
1203 CString tmpFile = GetTempFile();
1204 EXPECT_EQ(0, m_Git.GetOneFile(L"HEAD", CTGitPath(L"1.enc"), tmpFile));
1205 EXPECT_EQ(true, CStringUtils::ReadStringFromTextFile(tmpFile, fileContents));
1206 EXPECT_STREQ(_T("This should be encrypted...\nAnd decrypted on the fly\n"), fileContents);
1207 ::DeleteFile(tmpFile);
1209 fileContents.Empty();
1210 tmpFile = GetTempFile();
1211 EXPECT_EQ(0, m_Git.GetOneFile(L"HEAD", CTGitPath(L"2.enc"), tmpFile));
1212 EXPECT_EQ(true, CStringUtils::ReadStringFromTextFile(tmpFile, fileContents));
1213 EXPECT_STREQ(_T("This should also be encrypted...\nAnd also decrypted on the fly\n"), fileContents);
1214 ::DeleteFile(tmpFile);
1216 EXPECT_TRUE(::DeleteFile(attributesFile));
1218 fileContents.Empty();
1219 tmpFile = GetTempFile();
1220 EXPECT_EQ(0, m_Git.GetOneFile(L"HEAD", CTGitPath(L"1.enc"), tmpFile));
1221 EXPECT_EQ(true, CStringUtils::ReadStringFromTextFile(tmpFile, fileContents));
1222 EXPECT_STREQ(_T("U2FsdGVkX1/+7d6tvu8AABwbE+Xy7U4l5boTKjIgUkYHONqmYHD+0e6k35MgtUGx\ns11nq1QuKeFCW5wFWNSj1WcHg2n4W59xfnB7RkSSIDQ=\n"), fileContents);
1223 ::DeleteFile(tmpFile);
1225 fileContents.Empty();
1226 tmpFile = GetTempFile();
1227 EXPECT_EQ(0, m_Git.GetOneFile(L"HEAD", CTGitPath(L"2.enc"), tmpFile));
1228 EXPECT_EQ(true, CStringUtils::ReadStringFromTextFile(tmpFile, fileContents));
1229 EXPECT_STREQ(_T("U2FsdGVkX1/+7d6tvu8AAIDDx8qi/l0qzkSMsS2YLt8tYK1oWzj8+o78fXH0/tlO\nCRVrKqTvh9eUFklY8QFYfZfj01zBkFat+4zrW+1rV4Q=\n"), fileContents);
1230 ::DeleteFile(tmpFile);
1233 TEST_P(CBasicGitWithTestRepoBareFixture, GetOneFile)
1235 GetOneFile(m_Git);
1238 static void GetBranchDescriptions(CGit& m_Git)
1240 MAP_STRING_STRING descriptions;
1241 EXPECT_EQ(0, m_Git.GetBranchDescriptions(descriptions));
1242 EXPECT_EQ(0, descriptions.size());
1244 g_Git.SetConfigValue(_T("branch.master.description"), _T("test"));
1245 g_Git.SetConfigValue(_T("branch.subdir/branch.description"), _T("multi\nline"));
1247 EXPECT_EQ(0, m_Git.GetBranchDescriptions(descriptions));
1248 ASSERT_EQ(2, descriptions.size());
1249 EXPECT_STREQ(_T("test"), descriptions[L"master"]);
1250 EXPECT_STREQ(_T("multi\nline"), descriptions[L"subdir/branch"]);
1253 TEST_P(CBasicGitWithEmptyRepositoryFixture, GetBranchDescriptions)
1255 GetBranchDescriptions(m_Git);
1258 TEST_P(CBasicGitWithEmptyBareRepositoryFixture, GetBranchDescriptions)
1260 GetBranchDescriptions(m_Git);
1263 TEST_P(CBasicGitWithTestRepoFixture, Config)
1265 EXPECT_STREQ(_T(""), m_Git.GetConfigValue(_T("not-found")));
1266 EXPECT_STREQ(_T("default"), m_Git.GetConfigValue(_T("not-found"), _T("default")));
1268 EXPECT_STREQ(_T("false"), m_Git.GetConfigValue(_T("core.bare")));
1269 EXPECT_STREQ(_T("false"), m_Git.GetConfigValue(_T("core.bare"), _T("default-value"))); // value exist, so default does not match
1270 EXPECT_STREQ(_T("true"), m_Git.GetConfigValue(_T("core.ignorecase")));
1271 EXPECT_STREQ(_T("0"), m_Git.GetConfigValue(_T("core.repositoryformatversion")));
1272 EXPECT_STREQ(_T("https://example.com/git/testing"), m_Git.GetConfigValue(_T("remote.origin.url")));
1274 EXPECT_EQ(false, m_Git.GetConfigValueBool(_T("not-found")));
1275 EXPECT_EQ(true, m_Git.GetConfigValueBool(_T("not-found"), true));
1276 EXPECT_EQ(false, m_Git.GetConfigValueBool(_T("core.bare")));
1277 EXPECT_EQ(false, m_Git.GetConfigValueBool(_T("core.bare"), true)); // value exist, so default does not match
1278 EXPECT_EQ(false, m_Git.GetConfigValueBool(_T("core.repositoryformatversion")));
1279 EXPECT_EQ(false, m_Git.GetConfigValueBool(_T("remote.origin.url")));
1280 EXPECT_EQ(true, m_Git.GetConfigValueBool(_T("core.ignorecase")));
1282 CString values[] = { _T(""), _T(" "), _T("ending-with-space "), _T(" starting with-space"), _T("test1"), _T("some\\backslashes\\in\\it"), _T("with \" doublequote"), _T("with backslash before \\\" doublequote"), _T("with'quote"), _T("multi\nline"), _T("no-multi\\nline"), _T("new line at end\n") };
1283 for (int i = 0; i < _countof(values); ++i)
1285 CString key;
1286 key.Format(_T("re-read.test%d"), i);
1287 EXPECT_EQ(0, m_Git.SetConfigValue(key, values[i]));
1288 EXPECT_STREQ(values[i], m_Git.GetConfigValue(key));
1291 m_Git.SetConfigValue(_T("booltest.true1"), _T("1"));
1292 m_Git.SetConfigValue(_T("booltest.true2"), _T("100"));
1293 m_Git.SetConfigValue(_T("booltest.true3"), _T("-2"));
1294 m_Git.SetConfigValue(_T("booltest.true4"), _T("yes"));
1295 m_Git.SetConfigValue(_T("booltest.true5"), _T("yEs"));
1296 m_Git.SetConfigValue(_T("booltest.true6"), _T("true"));
1297 m_Git.SetConfigValue(_T("booltest.true7"), _T("on"));
1298 for (int i = 1; i <= 7; ++i)
1300 CString key;
1301 key.Format(_T("booltest.true%d"), i);
1302 EXPECT_EQ(true, m_Git.GetConfigValueBool(key));
1304 m_Git.SetConfigValue(_T("booltest.false1"), _T("0"));
1305 EXPECT_EQ(false, m_Git.GetConfigValueBool(_T("booltest.false1")));
1306 m_Git.SetConfigValue(_T("booltest.false2"), _T(""));
1307 EXPECT_EQ(false, m_Git.GetConfigValueBool(_T("booltest.false2")));
1309 EXPECT_EQ(0, m_Git.GetConfigValueInt32(_T("does-not-exist")));
1310 EXPECT_EQ(15, m_Git.GetConfigValueInt32(_T("does-not-exist"), 15));
1311 EXPECT_EQ(0, m_Git.GetConfigValueInt32(_T("core.repositoryformatversion")));
1312 EXPECT_EQ(0, m_Git.GetConfigValueInt32(_T("core.repositoryformatversion"), 42)); // value exist, so default should not be returned
1313 EXPECT_EQ(1, m_Git.GetConfigValueInt32(_T("booltest.true1")));
1314 EXPECT_EQ(100, m_Git.GetConfigValueInt32(_T("booltest.true2")));
1315 EXPECT_EQ(-2, m_Git.GetConfigValueInt32(_T("booltest.true3")));
1316 EXPECT_EQ(0, m_Git.GetConfigValueInt32(_T("booltest.true4")));
1317 EXPECT_EQ(42, m_Git.GetConfigValueInt32(_T("booltest.true4"), 42));
1318 EXPECT_EQ(0, m_Git.GetConfigValueInt32(_T("booltest.true8")));
1319 EXPECT_EQ(42, m_Git.GetConfigValueInt32(_T("booltest.true8"), 42));
1321 EXPECT_NE(0, m_Git.UnsetConfigValue(_T("does-not-exist")));
1322 EXPECT_STREQ(_T("false"), m_Git.GetConfigValue(_T("core.bare")));
1323 EXPECT_STREQ(_T("true"), m_Git.GetConfigValue(_T("core.ignorecase")));
1324 EXPECT_EQ(0, m_Git.UnsetConfigValue(_T("core.bare")));
1325 EXPECT_STREQ(_T("default"), m_Git.GetConfigValue(_T("core.bare"), _T("default")));
1326 EXPECT_STREQ(_T("true"), m_Git.GetConfigValue(_T("core.ignorecase")));
1328 CString gitConfig = m_Git.m_CurrentDir + L"\\.git\\config";
1329 EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)gitConfig, L"[booltest]\nistrue"));
1330 EXPECT_EQ(true, m_Git.GetConfigValueBool(L"booltest.istrue"));
1333 TEST_P(CBasicGitWithTestRepoFixture, GetWorkingTreeChanges)
1335 if (GetParam() != 0)
1336 return;
1338 // adding ansi2.txt (as a copy of ansi.txt) produces a warning
1339 m_Git.SetConfigValue(_T("core.autocrlf"), _T("false"));
1341 CString output;
1342 EXPECT_EQ(0, m_Git.Run(_T("git.exe reset --hard master"), &output, CP_UTF8));
1343 EXPECT_FALSE(output.IsEmpty());
1345 CTGitPathList filter(CTGitPath(_T("copy")));
1347 // no changes
1348 CTGitPathList list;
1349 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, nullptr));
1350 EXPECT_TRUE(list.IsEmpty());
1351 list.Clear();
1352 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, nullptr));
1353 ASSERT_EQ(1, list.GetCount());
1354 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
1355 EXPECT_STREQ(_T("ascii.txt"), list[0].GetGitPathString());
1356 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1357 list.Clear();
1358 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, &filter));
1359 EXPECT_TRUE(list.IsEmpty());
1360 list.Clear();
1361 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, &filter));
1362 ASSERT_EQ(1, list.GetCount());
1363 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
1364 EXPECT_STREQ(_T("ascii.txt"), list[0].GetGitPathString());
1365 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1367 // untracked file
1368 CString testFile = m_Git.m_CurrentDir + L"\\untracked-file.txt";
1369 EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFile, L"*.enc filter=openssl\n"));
1370 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, nullptr));
1371 EXPECT_TRUE(list.IsEmpty());
1372 list.Clear();
1373 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, nullptr));
1374 ASSERT_EQ(1, list.GetCount());
1375 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
1376 EXPECT_STREQ(_T("ascii.txt"), list[0].GetGitPathString());
1377 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1378 list.Clear();
1379 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, &filter));
1380 EXPECT_TRUE(list.IsEmpty());
1381 list.Clear();
1382 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, &filter));
1383 ASSERT_EQ(1, list.GetCount());
1384 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
1385 EXPECT_STREQ(_T("ascii.txt"), list[0].GetGitPathString());
1386 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1388 // untracked file in sub-directory
1389 testFile = m_Git.m_CurrentDir + L"\\copy\\untracked-file.txt";
1390 EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFile, L"*.enc filter=openssl\n"));
1391 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, nullptr));
1392 EXPECT_TRUE(list.IsEmpty());
1393 list.Clear();
1394 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, nullptr));
1395 ASSERT_EQ(1, list.GetCount());
1396 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
1397 EXPECT_STREQ(_T("ascii.txt"), list[0].GetGitPathString());
1398 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1399 list.Clear();
1400 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, &filter));
1401 EXPECT_TRUE(list.IsEmpty());
1402 list.Clear();
1403 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, &filter));
1404 ASSERT_EQ(1, list.GetCount());
1405 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
1406 EXPECT_STREQ(_T("ascii.txt"), list[0].GetGitPathString());
1407 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1409 // modified file in sub-directory
1410 testFile = m_Git.m_CurrentDir + L"\\copy\\utf8-nobom.txt";
1411 EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFile, L"*.enc filter=openssl\n"));
1412 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, nullptr));
1413 ASSERT_EQ(1, list.GetCount());
1414 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
1415 EXPECT_STREQ(_T("copy/utf8-nobom.txt"), list[0].GetGitPathString());
1416 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1417 list.Clear();
1418 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, nullptr));
1419 ASSERT_EQ(2, list.GetCount());
1420 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
1421 EXPECT_STREQ(_T("ascii.txt"), list[0].GetGitPathString());
1422 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1423 EXPECT_STREQ(_T("copy/utf8-nobom.txt"), list[1].GetGitPathString());
1424 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[1].m_Action);
1425 list.Clear();
1426 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, &filter));
1427 ASSERT_EQ(1, list.GetCount());
1428 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
1429 EXPECT_STREQ(_T("copy/utf8-nobom.txt"), list[0].GetGitPathString());
1430 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1431 list.Clear();
1432 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, &filter));
1433 ASSERT_EQ(2, list.GetCount());
1434 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
1435 EXPECT_STREQ(_T("ascii.txt"), list[0].GetGitPathString());
1436 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1437 EXPECT_STREQ(_T("copy/utf8-nobom.txt"), list[1].GetGitPathString());
1438 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[1].m_Action);
1440 // two modified files, one in root and one in sub-directory
1441 output.Empty();
1442 EXPECT_EQ(0, m_Git.Run(_T("git.exe reset --hard master"), &output, CP_UTF8));
1443 EXPECT_FALSE(output.IsEmpty());
1444 testFile = m_Git.m_CurrentDir + L"\\utf8-bom.txt";
1445 EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFile, L"*.enc filter=openssl\n"));
1446 testFile = m_Git.m_CurrentDir + L"\\copy\\utf8-nobom.txt";
1447 EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFile, L"*.enc filter=openssl\n"));
1448 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, nullptr));
1449 ASSERT_EQ(2, list.GetCount());
1450 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
1451 EXPECT_STREQ(_T("copy/utf8-nobom.txt"), list[0].GetGitPathString());
1452 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1453 EXPECT_STREQ(_T("utf8-bom.txt"), list[1].GetGitPathString());
1454 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[1].m_Action);
1455 list.Clear();
1456 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, nullptr));
1457 ASSERT_EQ(3, list.GetCount());
1458 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
1459 EXPECT_STREQ(_T("ascii.txt"), list[0].GetGitPathString());
1460 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1461 EXPECT_STREQ(_T("copy/utf8-nobom.txt"), list[1].GetGitPathString());
1462 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[1].m_Action);
1463 EXPECT_STREQ(_T("utf8-bom.txt"), list[2].GetGitPathString());
1464 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[2].m_Action);
1465 list.Clear();
1466 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, &filter));
1467 ASSERT_EQ(1, list.GetCount());
1468 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
1469 EXPECT_STREQ(_T("copy/utf8-nobom.txt"), list[0].GetGitPathString());
1470 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1471 list.Clear();
1472 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, &filter));
1473 ASSERT_EQ(2, list.GetCount());
1474 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
1475 EXPECT_STREQ(_T("ascii.txt"), list[0].GetGitPathString());
1476 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1477 EXPECT_STREQ(_T("copy/utf8-nobom.txt"), list[1].GetGitPathString());
1478 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[1].m_Action);
1480 // Staged modified file
1481 output.Empty();
1482 EXPECT_EQ(0, m_Git.Run(_T("git.exe reset --hard master"), &output, CP_UTF8));
1483 EXPECT_FALSE(output.IsEmpty());
1484 testFile = m_Git.m_CurrentDir + L"\\utf8-nobom.txt";
1485 EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFile, L"*.enc filter=openssl\n"));
1486 output.Empty();
1487 EXPECT_EQ(0, m_Git.Run(_T("git.exe add utf8-nobom.txt"), &output, CP_UTF8));
1488 EXPECT_TRUE(output.IsEmpty());
1489 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, nullptr));
1490 ASSERT_EQ(1, list.GetCount());
1491 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
1492 EXPECT_STREQ(_T("utf8-nobom.txt"), list[0].GetGitPathString());
1493 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1494 list.Clear();
1495 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, nullptr));
1496 ASSERT_EQ(2, list.GetCount());
1497 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
1498 EXPECT_STREQ(_T("ascii.txt"), list[0].GetGitPathString());
1499 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1500 EXPECT_STREQ(_T("utf8-nobom.txt"), list[1].GetGitPathString());
1501 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[1].m_Action);
1502 list.Clear();
1503 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, &filter));
1504 ASSERT_EQ(1, list.GetCount());
1505 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
1506 EXPECT_STREQ(_T("utf8-nobom.txt"), list[0].GetGitPathString());
1507 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1508 list.Clear();
1509 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, &filter));
1510 ASSERT_EQ(2, list.GetCount());
1511 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
1512 EXPECT_STREQ(_T("ascii.txt"), list[0].GetGitPathString());
1513 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1514 EXPECT_STREQ(_T("utf8-nobom.txt"), list[1].GetGitPathString());
1515 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[1].m_Action);
1517 // Staged modified file in subfolder
1518 output.Empty();
1519 EXPECT_EQ(0, m_Git.Run(_T("git.exe reset --hard master"), &output, CP_UTF8));
1520 EXPECT_FALSE(output.IsEmpty());
1521 testFile = m_Git.m_CurrentDir + L"\\copy\\utf8-nobom.txt";
1522 EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFile, L"*.enc filter=openssl\n"));
1523 output.Empty();
1524 EXPECT_EQ(0, m_Git.Run(_T("git.exe add copy/utf8-nobom.txt"), &output, CP_UTF8));
1525 EXPECT_TRUE(output.IsEmpty());
1526 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, nullptr));
1527 ASSERT_EQ(1, list.GetCount());
1528 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
1529 EXPECT_STREQ(_T("copy/utf8-nobom.txt"), list[0].GetGitPathString());
1530 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1531 list.Clear();
1532 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, nullptr));
1533 ASSERT_EQ(2, list.GetCount());
1534 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
1535 EXPECT_STREQ(_T("ascii.txt"), list[0].GetGitPathString());
1536 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1537 EXPECT_STREQ(_T("copy/utf8-nobom.txt"), list[1].GetGitPathString());
1538 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[1].m_Action);
1539 list.Clear();
1540 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, &filter));
1541 ASSERT_EQ(1, list.GetCount());
1542 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
1543 EXPECT_STREQ(_T("copy/utf8-nobom.txt"), list[0].GetGitPathString());
1544 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1545 list.Clear();
1546 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, &filter));
1547 ASSERT_EQ(2, list.GetCount());
1548 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
1549 EXPECT_STREQ(_T("ascii.txt"), list[0].GetGitPathString());
1550 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1551 EXPECT_STREQ(_T("copy/utf8-nobom.txt"), list[1].GetGitPathString());
1552 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[1].m_Action);
1554 // Modified file modified after staging
1555 output.Empty();
1556 EXPECT_EQ(0, m_Git.Run(_T("git.exe reset --hard master"), &output, CP_UTF8));
1557 EXPECT_FALSE(output.IsEmpty());
1558 testFile = m_Git.m_CurrentDir + L"\\copy\\utf8-nobom.txt";
1559 EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFile, L"*.enc filter=openssl\n"));
1560 output.Empty();
1561 EXPECT_EQ(0, m_Git.Run(_T("git.exe add copy/utf8-nobom.txt"), &output, CP_UTF8));
1562 EXPECT_TRUE(output.IsEmpty());
1563 EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFile, L"now with different content after staging"));
1564 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, nullptr));
1565 ASSERT_EQ(1, list.GetCount());
1566 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
1567 EXPECT_STREQ(_T("copy/utf8-nobom.txt"), list[0].GetGitPathString());
1568 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1569 list.Clear();
1570 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, nullptr));
1571 ASSERT_EQ(2, list.GetCount());
1572 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
1573 EXPECT_STREQ(_T("ascii.txt"), list[0].GetGitPathString());
1574 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1575 EXPECT_STREQ(_T("copy/utf8-nobom.txt"), list[1].GetGitPathString());
1576 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[1].m_Action);
1577 list.Clear();
1578 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, &filter));
1579 ASSERT_EQ(1, list.GetCount());
1580 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
1581 EXPECT_STREQ(_T("copy/utf8-nobom.txt"), list[0].GetGitPathString());
1582 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1583 list.Clear();
1584 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, &filter));
1585 ASSERT_EQ(2, list.GetCount());
1586 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
1587 EXPECT_STREQ(_T("ascii.txt"), list[0].GetGitPathString());
1588 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1589 EXPECT_STREQ(_T("copy/utf8-nobom.txt"), list[1].GetGitPathString());
1590 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[1].m_Action);
1592 // Missing file
1593 output.Empty();
1594 EXPECT_EQ(0, m_Git.Run(_T("git.exe reset --hard master"), &output, CP_UTF8));
1595 EXPECT_FALSE(output.IsEmpty());
1596 EXPECT_TRUE(::DeleteFile(m_Dir.GetTempDir()+_T("\\copy\\ansi.txt")));
1597 list.Clear();
1598 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, nullptr));
1599 ASSERT_EQ(1, list.GetCount());
1600 EXPECT_EQ(CTGitPath::LOGACTIONS_DELETED, list.GetAction());
1601 EXPECT_STREQ(_T("copy/ansi.txt"), list[0].GetGitPathString());
1602 EXPECT_EQ(CTGitPath::LOGACTIONS_DELETED | CTGitPath::LOGACTIONS_MISSING, list[0].m_Action);
1603 list.Clear();
1604 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, nullptr));
1605 ASSERT_EQ(2, list.GetCount());
1606 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED | CTGitPath::LOGACTIONS_DELETED, list.GetAction());
1607 EXPECT_STREQ(_T("ascii.txt"), list[0].GetGitPathString());
1608 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1609 EXPECT_STREQ(_T("copy/ansi.txt"), list[1].GetGitPathString());
1610 EXPECT_EQ(CTGitPath::LOGACTIONS_DELETED | CTGitPath::LOGACTIONS_MISSING, list[1].m_Action);
1611 list.Clear();
1612 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, &filter));
1613 ASSERT_EQ(1, list.GetCount());
1614 EXPECT_EQ(CTGitPath::LOGACTIONS_DELETED, list.GetAction());
1615 EXPECT_STREQ(_T("copy/ansi.txt"), list[0].GetGitPathString());
1616 EXPECT_EQ(CTGitPath::LOGACTIONS_DELETED | CTGitPath::LOGACTIONS_MISSING, list[0].m_Action);
1617 list.Clear();
1618 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, &filter));
1619 ASSERT_EQ(2, list.GetCount());
1620 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED | CTGitPath::LOGACTIONS_DELETED, list.GetAction());
1621 EXPECT_STREQ(_T("ascii.txt"), list[0].GetGitPathString());
1622 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1623 EXPECT_STREQ(_T("copy/ansi.txt"), list[1].GetGitPathString());
1624 EXPECT_EQ(CTGitPath::LOGACTIONS_DELETED | CTGitPath::LOGACTIONS_MISSING, list[1].m_Action);
1626 // deleted file, also deleted in index
1627 output.Empty();
1628 EXPECT_EQ(0, m_Git.Run(_T("git.exe reset --hard master"), &output, CP_UTF8));
1629 EXPECT_FALSE(output.IsEmpty());
1630 output.Empty();
1631 EXPECT_EQ(0, m_Git.Run(_T("git.exe rm copy/ansi.txt"), &output, CP_UTF8));
1632 EXPECT_FALSE(output.IsEmpty());
1633 list.Clear();
1634 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, nullptr));
1635 ASSERT_EQ(1, list.GetCount());
1636 EXPECT_EQ(CTGitPath::LOGACTIONS_DELETED, list.GetAction());
1637 EXPECT_STREQ(_T("copy/ansi.txt"), list[0].GetGitPathString());
1638 EXPECT_EQ(CTGitPath::LOGACTIONS_DELETED, list[0].m_Action);
1639 list.Clear();
1640 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, nullptr));
1641 ASSERT_EQ(2, list.GetCount());
1642 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED | CTGitPath::LOGACTIONS_DELETED, list.GetAction());
1643 EXPECT_STREQ(_T("ascii.txt"), list[0].GetGitPathString());
1644 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1645 EXPECT_STREQ(_T("copy/ansi.txt"), list[1].GetGitPathString());
1646 EXPECT_EQ(CTGitPath::LOGACTIONS_DELETED, list[1].m_Action);
1647 list.Clear();
1648 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, &filter));
1649 ASSERT_EQ(1, list.GetCount());
1650 EXPECT_EQ(CTGitPath::LOGACTIONS_DELETED, list.GetAction());
1651 EXPECT_STREQ(_T("copy/ansi.txt"), list[0].GetGitPathString());
1652 EXPECT_EQ(CTGitPath::LOGACTIONS_DELETED, list[0].m_Action);
1653 list.Clear();
1654 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, &filter));
1655 ASSERT_EQ(2, list.GetCount());
1656 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED | CTGitPath::LOGACTIONS_DELETED, list.GetAction());
1657 EXPECT_STREQ(_T("ascii.txt"), list[0].GetGitPathString());
1658 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1659 EXPECT_STREQ(_T("copy/ansi.txt"), list[1].GetGitPathString());
1660 EXPECT_EQ(CTGitPath::LOGACTIONS_DELETED, list[1].m_Action);
1662 // file deleted in index, but still on disk
1663 output.Empty();
1664 EXPECT_EQ(0, m_Git.Run(_T("git.exe reset --hard master"), &output, CP_UTF8));
1665 EXPECT_FALSE(output.IsEmpty());
1666 output.Empty();
1667 EXPECT_EQ(0, m_Git.Run(_T("git.exe rm --cached copy/ansi.txt"), &output, CP_UTF8));
1668 EXPECT_FALSE(output.IsEmpty());
1669 list.Clear();
1670 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, nullptr));
1671 ASSERT_EQ(1, list.GetCount());
1672 EXPECT_EQ(CTGitPath::LOGACTIONS_DELETED, list.GetAction());
1673 EXPECT_STREQ(_T("copy/ansi.txt"), list[0].GetGitPathString());
1674 EXPECT_EQ(CTGitPath::LOGACTIONS_DELETED, list[0].m_Action);
1675 list.Clear();
1676 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, nullptr));
1677 ASSERT_EQ(2, list.GetCount());
1678 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED | CTGitPath::LOGACTIONS_DELETED, list.GetAction());
1679 EXPECT_STREQ(_T("ascii.txt"), list[0].GetGitPathString());
1680 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1681 EXPECT_STREQ(_T("copy/ansi.txt"), list[1].GetGitPathString());
1682 EXPECT_EQ(CTGitPath::LOGACTIONS_DELETED, list[1].m_Action);
1683 list.Clear();
1684 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, &filter));
1685 ASSERT_EQ(1, list.GetCount());
1686 EXPECT_EQ(CTGitPath::LOGACTIONS_DELETED, list.GetAction());
1687 EXPECT_STREQ(_T("copy/ansi.txt"), list[0].GetGitPathString());
1688 EXPECT_EQ(CTGitPath::LOGACTIONS_DELETED, list[0].m_Action);
1689 list.Clear();
1690 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, &filter));
1691 ASSERT_EQ(2, list.GetCount());
1692 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED | CTGitPath::LOGACTIONS_DELETED, list.GetAction());
1693 EXPECT_STREQ(_T("ascii.txt"), list[0].GetGitPathString());
1694 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1695 EXPECT_STREQ(_T("copy/ansi.txt"), list[1].GetGitPathString());
1696 EXPECT_EQ(CTGitPath::LOGACTIONS_DELETED, list[1].m_Action);
1698 // file deleted in index, but still on disk, but modified
1699 output.Empty();
1700 EXPECT_EQ(0, m_Git.Run(_T("git.exe reset --hard master"), &output, CP_UTF8));
1701 EXPECT_FALSE(output.IsEmpty());
1702 output.Empty();
1703 EXPECT_EQ(0, m_Git.Run(_T("git.exe rm --cached copy/ansi.txt"), &output, CP_UTF8));
1704 EXPECT_FALSE(output.IsEmpty());
1705 testFile = m_Git.m_CurrentDir + L"\\copy\\ansi.txt";
1706 EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFile, L"*.enc filter=openssl\n"));
1707 list.Clear();
1708 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, nullptr));
1709 ASSERT_EQ(1, list.GetCount());
1710 EXPECT_EQ(CTGitPath::LOGACTIONS_DELETED, list.GetAction());
1711 EXPECT_STREQ(_T("copy/ansi.txt"), list[0].GetGitPathString());
1712 EXPECT_EQ(CTGitPath::LOGACTIONS_DELETED, list[0].m_Action);
1713 list.Clear();
1714 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, nullptr));
1715 ASSERT_EQ(2, list.GetCount());
1716 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED | CTGitPath::LOGACTIONS_DELETED, list.GetAction());
1717 EXPECT_STREQ(_T("ascii.txt"), list[0].GetGitPathString());
1718 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1719 EXPECT_STREQ(_T("copy/ansi.txt"), list[1].GetGitPathString());
1720 EXPECT_EQ(CTGitPath::LOGACTIONS_DELETED, list[1].m_Action);
1721 list.Clear();
1722 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, &filter));
1723 ASSERT_EQ(1, list.GetCount());
1724 EXPECT_EQ(CTGitPath::LOGACTIONS_DELETED, list.GetAction());
1725 EXPECT_STREQ(_T("copy/ansi.txt"), list[0].GetGitPathString());
1726 EXPECT_EQ(CTGitPath::LOGACTIONS_DELETED, list[0].m_Action);
1727 list.Clear();
1728 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, &filter));
1729 ASSERT_EQ(2, list.GetCount());
1730 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED | CTGitPath::LOGACTIONS_DELETED, list.GetAction());
1731 EXPECT_STREQ(_T("ascii.txt"), list[0].GetGitPathString());
1732 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1733 EXPECT_STREQ(_T("copy/ansi.txt"), list[1].GetGitPathString());
1734 EXPECT_EQ(CTGitPath::LOGACTIONS_DELETED, list[1].m_Action);
1736 // renamed file in same folder
1737 output.Empty();
1738 EXPECT_EQ(0, m_Git.Run(_T("git.exe reset --hard master"), &output, CP_UTF8));
1739 EXPECT_FALSE(output.IsEmpty());
1740 output.Empty();
1741 EXPECT_EQ(0, m_Git.Run(_T("git.exe mv ansi.txt ansi2.txt"), &output, CP_UTF8));
1742 EXPECT_TRUE(output.IsEmpty());
1743 list.Clear();
1744 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, nullptr));
1745 ASSERT_EQ(1, list.GetCount());
1746 EXPECT_EQ(CTGitPath::LOGACTIONS_REPLACED, list.GetAction());
1747 EXPECT_STREQ(_T("ansi2.txt"), list[0].GetGitPathString());
1748 EXPECT_EQ(CTGitPath::LOGACTIONS_REPLACED, list[0].m_Action);
1749 list.Clear();
1750 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, nullptr));
1751 ASSERT_EQ(2, list.GetCount());
1752 EXPECT_EQ(CTGitPath::LOGACTIONS_REPLACED | CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
1753 EXPECT_STREQ(_T("ansi2.txt"), list[0].GetGitPathString());
1754 EXPECT_EQ(CTGitPath::LOGACTIONS_REPLACED, list[0].m_Action);
1755 EXPECT_STREQ(_T("ascii.txt"), list[1].GetGitPathString());
1756 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[1].m_Action);
1757 list.Clear();
1758 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, &filter));
1759 ASSERT_EQ(1, list.GetCount());
1760 EXPECT_EQ(CTGitPath::LOGACTIONS_REPLACED, list.GetAction());
1761 EXPECT_STREQ(_T("ansi2.txt"), list[0].GetGitPathString());
1762 EXPECT_EQ(CTGitPath::LOGACTIONS_REPLACED, list[0].m_Action);
1763 list.Clear();
1764 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, &filter));
1765 ASSERT_EQ(2, list.GetCount());
1766 EXPECT_EQ(CTGitPath::LOGACTIONS_REPLACED | CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
1767 EXPECT_STREQ(_T("ansi2.txt"), list[0].GetGitPathString());
1768 EXPECT_EQ(CTGitPath::LOGACTIONS_REPLACED, list[0].m_Action);
1769 EXPECT_STREQ(_T("ascii.txt"), list[1].GetGitPathString());
1770 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[1].m_Action);
1772 // added and staged new file
1773 output.Empty();
1774 EXPECT_EQ(0, m_Git.Run(_T("git.exe reset --hard master"), &output, CP_UTF8));
1775 EXPECT_FALSE(output.IsEmpty());
1776 testFile = m_Git.m_CurrentDir + L"\\copy\\test-file.txt";
1777 EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFile, L"*.enc filter=openssl\n"));
1778 output.Empty();
1779 EXPECT_EQ(0, m_Git.Run(_T("git.exe add copy/test-file.txt"), &output, CP_UTF8));
1780 EXPECT_TRUE(output.IsEmpty());
1781 list.Clear();
1782 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, nullptr));
1783 ASSERT_EQ(1, list.GetCount());
1784 EXPECT_EQ(CTGitPath::LOGACTIONS_ADDED, list.GetAction());
1785 EXPECT_STREQ(_T("copy/test-file.txt"), list[0].GetGitPathString());
1786 EXPECT_EQ(CTGitPath::LOGACTIONS_ADDED, list[0].m_Action);
1787 list.Clear();
1788 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, nullptr));
1789 ASSERT_EQ(2, list.GetCount());
1790 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED | CTGitPath::LOGACTIONS_ADDED, list.GetAction());
1791 EXPECT_STREQ(_T("ascii.txt"), list[0].GetGitPathString());
1792 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1793 EXPECT_STREQ(_T("copy/test-file.txt"), list[1].GetGitPathString());
1794 EXPECT_EQ(CTGitPath::LOGACTIONS_ADDED, list[1].m_Action);
1795 list.Clear();
1796 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, &filter));
1797 ASSERT_EQ(1, list.GetCount());
1798 EXPECT_EQ(CTGitPath::LOGACTIONS_ADDED, list.GetAction());
1799 EXPECT_STREQ(_T("copy/test-file.txt"), list[0].GetGitPathString());
1800 EXPECT_EQ(CTGitPath::LOGACTIONS_ADDED, list[0].m_Action);
1801 list.Clear();
1802 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, &filter));
1803 ASSERT_EQ(2, list.GetCount());
1804 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED | CTGitPath::LOGACTIONS_ADDED, list.GetAction());
1805 EXPECT_STREQ(_T("ascii.txt"), list[0].GetGitPathString());
1806 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1807 EXPECT_STREQ(_T("copy/test-file.txt"), list[1].GetGitPathString());
1808 EXPECT_EQ(CTGitPath::LOGACTIONS_ADDED, list[1].m_Action);
1810 // file copied and staged
1811 output.Empty();
1812 EXPECT_EQ(0, m_Git.Run(_T("git.exe reset --hard master"), &output, CP_UTF8));
1813 EXPECT_FALSE(output.IsEmpty());
1814 testFile = m_Git.m_CurrentDir + L"\\ansi.txt";
1815 EXPECT_TRUE(CopyFile(m_Git.m_CurrentDir + L"\\ansi.txt", m_Git.m_CurrentDir + L"\\ansi2.txt", TRUE));
1816 output.Empty();
1817 EXPECT_EQ(0, m_Git.Run(_T("git.exe add ansi2.txt"), &output, CP_UTF8));
1818 EXPECT_TRUE(output.IsEmpty());
1819 list.Clear();
1820 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, nullptr));
1821 ASSERT_EQ(1, list.GetCount());
1822 EXPECT_EQ(CTGitPath::LOGACTIONS_ADDED, list.GetAction());
1823 EXPECT_STREQ(_T("ansi2.txt"), list[0].GetGitPathString());
1824 EXPECT_EQ(CTGitPath::LOGACTIONS_ADDED, list[0].m_Action);
1825 list.Clear();
1826 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, nullptr));
1827 ASSERT_EQ(2, list.GetCount());
1828 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED | CTGitPath::LOGACTIONS_ADDED, list.GetAction());
1829 EXPECT_STREQ(_T("ansi2.txt"), list[0].GetGitPathString());
1830 EXPECT_EQ(CTGitPath::LOGACTIONS_ADDED, list[0].m_Action);
1831 EXPECT_STREQ(_T("ascii.txt"), list[1].GetGitPathString());
1832 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[1].m_Action);
1833 list.Clear();
1834 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, &filter));
1835 ASSERT_EQ(1, list.GetCount());
1836 EXPECT_EQ(CTGitPath::LOGACTIONS_ADDED, list.GetAction());
1837 EXPECT_STREQ(_T("ansi2.txt"), list[0].GetGitPathString());
1838 EXPECT_EQ(CTGitPath::LOGACTIONS_ADDED, list[0].m_Action);
1839 list.Clear();
1840 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, &filter));
1841 ASSERT_EQ(2, list.GetCount());
1842 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED | CTGitPath::LOGACTIONS_ADDED, list.GetAction());
1843 EXPECT_STREQ(_T("ansi2.txt"), list[0].GetGitPathString());
1844 EXPECT_EQ(CTGitPath::LOGACTIONS_ADDED, list[0].m_Action);
1845 EXPECT_STREQ(_T("ascii.txt"), list[1].GetGitPathString());
1846 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[1].m_Action);
1848 // file renamed + moved to sub-folder
1849 output.Empty();
1850 EXPECT_EQ(0, m_Git.Run(_T("git.exe reset --hard master"), &output, CP_UTF8));
1851 EXPECT_FALSE(output.IsEmpty());
1852 output.Empty();
1853 EXPECT_EQ(0, m_Git.Run(_T("git.exe mv ansi.txt copy/ansi2.txt"), &output, CP_UTF8));
1854 EXPECT_TRUE(output.IsEmpty());
1855 list.Clear();
1856 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, nullptr));
1857 ASSERT_EQ(1, list.GetCount());
1858 EXPECT_EQ(CTGitPath::LOGACTIONS_REPLACED, list.GetAction());
1859 EXPECT_STREQ(_T("copy/ansi2.txt"), list[0].GetGitPathString());
1860 EXPECT_EQ(CTGitPath::LOGACTIONS_REPLACED, list[0].m_Action);
1861 list.Clear();
1862 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, nullptr));
1863 ASSERT_EQ(2, list.GetCount());
1864 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED | CTGitPath::LOGACTIONS_REPLACED, list.GetAction());
1865 EXPECT_STREQ(_T("ascii.txt"), list[0].GetGitPathString());
1866 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1867 EXPECT_STREQ(_T("copy/ansi2.txt"), list[1].GetGitPathString());
1868 EXPECT_EQ(CTGitPath::LOGACTIONS_REPLACED, list[1].m_Action);
1869 list.Clear();
1870 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, &filter));
1871 ASSERT_EQ(1, list.GetCount());
1872 EXPECT_EQ(CTGitPath::LOGACTIONS_REPLACED | CTGitPath::LOGACTIONS_ADDED, list.GetAction());
1873 EXPECT_STREQ(_T("copy/ansi2.txt"), list[0].GetGitPathString());
1874 EXPECT_EQ(CTGitPath::LOGACTIONS_REPLACED | CTGitPath::LOGACTIONS_ADDED, list[0].m_Action); // TODO
1875 list.Clear();
1876 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, &filter));
1877 ASSERT_EQ(2, list.GetCount());
1878 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED | CTGitPath::LOGACTIONS_REPLACED | CTGitPath::LOGACTIONS_ADDED, list.GetAction());
1879 EXPECT_STREQ(_T("ascii.txt"), list[0].GetGitPathString());
1880 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1881 EXPECT_STREQ(_T("copy/ansi2.txt"), list[1].GetGitPathString());
1882 EXPECT_EQ(CTGitPath::LOGACTIONS_REPLACED | CTGitPath::LOGACTIONS_ADDED, list[1].m_Action); // TODO
1884 // conflicting files
1885 output.Empty();
1886 EXPECT_EQ(0, m_Git.Run(_T("git.exe reset --hard master"), &output, CP_UTF8));
1887 EXPECT_FALSE(output.IsEmpty());
1888 output.Empty();
1889 EXPECT_EQ(0, m_Git.Run(_T("git.exe merge forconflict"), &output, CP_UTF8));
1890 EXPECT_FALSE(output.IsEmpty());
1891 output.Empty();
1892 EXPECT_EQ(1, m_Git.Run(_T("git.exe merge simple-conflict"), &output, CP_UTF8));
1893 EXPECT_FALSE(output.IsEmpty());
1894 list.Clear();
1895 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, nullptr));
1896 ASSERT_EQ(1, list.GetCount());
1897 EXPECT_EQ(CTGitPath::LOGACTIONS_UNMERGED | CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
1898 EXPECT_STREQ(_T("ansi.txt"), list[0].GetGitPathString());
1899 EXPECT_EQ(CTGitPath::LOGACTIONS_UNMERGED | CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1900 list.Clear();
1901 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, nullptr));
1902 ASSERT_EQ(7, list.GetCount());
1903 EXPECT_EQ(CTGitPath::LOGACTIONS_UNMERGED | CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
1904 EXPECT_STREQ(_T("ansi.txt"), list[0].GetGitPathString());
1905 EXPECT_EQ(CTGitPath::LOGACTIONS_UNMERGED | CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1906 EXPECT_STREQ(_T("utf16-be-bom.txt"), list[1].GetGitPathString());
1907 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[1].m_Action);
1908 EXPECT_STREQ(_T("utf16-be-nobom.txt"), list[2].GetGitPathString());
1909 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[2].m_Action);
1910 EXPECT_STREQ(_T("utf16-le-bom.txt"), list[3].GetGitPathString());
1911 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[3].m_Action);
1912 EXPECT_STREQ(_T("utf16-le-nobom.txt"), list[4].GetGitPathString());
1913 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[4].m_Action);
1914 EXPECT_STREQ(_T("utf8-bom.txt"), list[5].GetGitPathString());
1915 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[5].m_Action);
1916 EXPECT_STREQ(_T("utf8-nobom.txt"), list[6].GetGitPathString());
1917 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[6].m_Action);
1918 list.Clear();
1919 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, &filter));
1920 ASSERT_EQ(1, list.GetCount());
1921 EXPECT_EQ(CTGitPath::LOGACTIONS_UNMERGED, list.GetAction());
1922 EXPECT_STREQ(_T("ansi.txt"), list[0].GetGitPathString());
1923 EXPECT_EQ(CTGitPath::LOGACTIONS_UNMERGED, list[0].m_Action);
1924 list.Clear();
1925 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, &filter));
1926 ASSERT_EQ(7, list.GetCount());
1927 EXPECT_EQ(CTGitPath::LOGACTIONS_UNMERGED | CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
1928 EXPECT_STREQ(_T("ansi.txt"), list[0].GetGitPathString());
1929 EXPECT_EQ(CTGitPath::LOGACTIONS_UNMERGED, list[0].m_Action);
1930 EXPECT_STREQ(_T("utf16-be-bom.txt"), list[1].GetGitPathString());
1931 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[1].m_Action);
1932 EXPECT_STREQ(_T("utf16-be-nobom.txt"), list[2].GetGitPathString());
1933 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[2].m_Action);
1934 EXPECT_STREQ(_T("utf16-le-bom.txt"), list[3].GetGitPathString());
1935 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[3].m_Action);
1936 EXPECT_STREQ(_T("utf16-le-nobom.txt"), list[4].GetGitPathString());
1937 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[4].m_Action);
1938 EXPECT_STREQ(_T("utf8-bom.txt"), list[5].GetGitPathString());
1939 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[5].m_Action);
1940 EXPECT_STREQ(_T("utf8-nobom.txt"), list[6].GetGitPathString());
1941 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[6].m_Action);
1944 TEST_P(CBasicGitWithTestRepoFixture, GetWorkingTreeChanges_DeleteModifyConflict_DeletedRemotely)
1946 if (GetParam() != 0)
1947 return;
1949 CString output;
1950 EXPECT_EQ(0, m_Git.Run(_T("git.exe reset --hard master"), &output, CP_UTF8));
1951 EXPECT_FALSE(output.IsEmpty());
1953 output.Empty();
1954 EXPECT_EQ(0, m_Git.Run(_T("git.exe checkout forconflict"), &output, CP_UTF8));
1955 EXPECT_FALSE(output.IsEmpty());
1956 output.Empty();
1957 EXPECT_EQ(0, m_Git.Run(_T("git.exe rm ansi.txt"), &output, CP_UTF8));
1958 EXPECT_FALSE(output.IsEmpty());
1959 output.Empty();
1960 EXPECT_EQ(0, m_Git.Run(_T("git.exe commit -m \"Prepare conflict case\""), &output, CP_UTF8));
1961 EXPECT_FALSE(output.IsEmpty());
1962 output.Empty();
1963 EXPECT_EQ(0, m_Git.Run(_T("git.exe checkout simple-conflict"), &output, CP_UTF8));
1964 EXPECT_FALSE(output.IsEmpty());
1965 output.Empty();
1966 EXPECT_EQ(1, m_Git.Run(_T("git.exe merge forconflict"), &output, CP_UTF8));
1967 EXPECT_FALSE(output.IsEmpty());
1969 CTGitPathList filter(CTGitPath(_T("copy")));
1971 CTGitPathList list;
1972 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, nullptr));
1973 ASSERT_EQ(7, list.GetCount());
1974 EXPECT_EQ(CTGitPath::LOGACTIONS_UNMERGED | CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
1975 EXPECT_STREQ(_T("ansi.txt"), list[0].GetGitPathString());
1976 EXPECT_EQ(CTGitPath::LOGACTIONS_UNMERGED | CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1977 EXPECT_STREQ(_T("utf16-be-bom.txt"), list[1].GetGitPathString());
1978 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[1].m_Action);
1979 EXPECT_STREQ(_T("utf16-be-nobom.txt"), list[2].GetGitPathString());
1980 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[2].m_Action);
1981 EXPECT_STREQ(_T("utf16-le-bom.txt"), list[3].GetGitPathString());
1982 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[3].m_Action);
1983 EXPECT_STREQ(_T("utf16-le-nobom.txt"), list[4].GetGitPathString());
1984 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[4].m_Action);
1985 EXPECT_STREQ(_T("utf8-bom.txt"), list[5].GetGitPathString());
1986 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[5].m_Action);
1987 EXPECT_STREQ(_T("utf8-nobom.txt"), list[6].GetGitPathString());
1988 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[6].m_Action);
1989 list.Clear();
1990 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, nullptr));
1991 ASSERT_EQ(7, list.GetCount());
1992 EXPECT_EQ(CTGitPath::LOGACTIONS_UNMERGED | CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
1993 EXPECT_STREQ(_T("ansi.txt"), list[0].GetGitPathString());
1994 EXPECT_EQ(CTGitPath::LOGACTIONS_UNMERGED | CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
1995 EXPECT_STREQ(_T("utf16-be-bom.txt"), list[1].GetGitPathString());
1996 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[1].m_Action);
1997 EXPECT_STREQ(_T("utf16-be-nobom.txt"), list[2].GetGitPathString());
1998 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[2].m_Action);
1999 EXPECT_STREQ(_T("utf16-le-bom.txt"), list[3].GetGitPathString());
2000 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[3].m_Action);
2001 EXPECT_STREQ(_T("utf16-le-nobom.txt"), list[4].GetGitPathString());
2002 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[4].m_Action);
2003 EXPECT_STREQ(_T("utf8-bom.txt"), list[5].GetGitPathString());
2004 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[5].m_Action);
2005 EXPECT_STREQ(_T("utf8-nobom.txt"), list[6].GetGitPathString());
2006 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[6].m_Action);
2007 list.Clear();
2008 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, &filter));
2009 ASSERT_EQ(7, list.GetCount());
2010 EXPECT_EQ(CTGitPath::LOGACTIONS_UNMERGED | CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
2011 EXPECT_STREQ(_T("ansi.txt"), list[0].GetGitPathString());
2012 EXPECT_EQ(CTGitPath::LOGACTIONS_UNMERGED, list[0].m_Action);
2013 EXPECT_STREQ(_T("utf16-be-bom.txt"), list[1].GetGitPathString());
2014 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[1].m_Action);
2015 EXPECT_STREQ(_T("utf16-be-nobom.txt"), list[2].GetGitPathString());
2016 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[2].m_Action);
2017 EXPECT_STREQ(_T("utf16-le-bom.txt"), list[3].GetGitPathString());
2018 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[3].m_Action);
2019 EXPECT_STREQ(_T("utf16-le-nobom.txt"), list[4].GetGitPathString());
2020 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[4].m_Action);
2021 EXPECT_STREQ(_T("utf8-bom.txt"), list[5].GetGitPathString());
2022 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[5].m_Action);
2023 EXPECT_STREQ(_T("utf8-nobom.txt"), list[6].GetGitPathString());
2024 EXPECT_EQ(CTGitPath::LOGACTIONS_MODIFIED, list[6].m_Action);
2027 TEST_P(CBasicGitWithTestRepoFixture, GetWorkingTreeChanges_DeleteModifyConflict_DeletedLocally)
2029 if (GetParam() != 0)
2030 return;
2032 CString output;
2033 EXPECT_EQ(0, m_Git.Run(_T("git.exe reset --hard master"), &output, CP_UTF8));
2034 EXPECT_FALSE(output.IsEmpty());
2036 output.Empty();
2037 EXPECT_EQ(0, m_Git.Run(_T("git.exe checkout forconflict"), &output, CP_UTF8));
2038 EXPECT_FALSE(output.IsEmpty());
2039 output.Empty();
2040 EXPECT_EQ(0, m_Git.Run(_T("git.exe rm ansi.txt"), &output, CP_UTF8));
2041 EXPECT_FALSE(output.IsEmpty());
2042 output.Empty();
2043 EXPECT_EQ(0, m_Git.Run(_T("git.exe commit -m \"Prepare conflict case\""), &output, CP_UTF8));
2044 EXPECT_FALSE(output.IsEmpty());
2045 output.Empty();
2046 EXPECT_EQ(1, m_Git.Run(_T("git.exe merge simple-conflict"), &output, CP_UTF8));
2047 EXPECT_FALSE(output.IsEmpty());
2049 CTGitPathList filter(CTGitPath(_T("copy")));
2051 CTGitPathList list;
2052 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, nullptr));
2053 ASSERT_EQ(1, list.GetCount());
2054 EXPECT_EQ(CTGitPath::LOGACTIONS_UNMERGED | CTGitPath::LOGACTIONS_ADDED, list.GetAction());
2055 EXPECT_STREQ(_T("ansi.txt"), list[0].GetGitPathString());
2056 EXPECT_EQ(CTGitPath::LOGACTIONS_UNMERGED | CTGitPath::LOGACTIONS_ADDED, list[0].m_Action);
2057 list.Clear();
2058 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, true, nullptr));
2059 ASSERT_EQ(1, list.GetCount());
2060 EXPECT_EQ(CTGitPath::LOGACTIONS_UNMERGED | CTGitPath::LOGACTIONS_MODIFIED, list.GetAction());
2061 EXPECT_STREQ(_T("ansi.txt"), list[0].GetGitPathString());
2062 EXPECT_EQ(CTGitPath::LOGACTIONS_UNMERGED | CTGitPath::LOGACTIONS_MODIFIED, list[0].m_Action);
2063 list.Clear();
2064 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, &filter));
2065 ASSERT_EQ(1, list.GetCount());
2066 EXPECT_EQ(CTGitPath::LOGACTIONS_UNMERGED, list.GetAction());
2067 EXPECT_STREQ(_T("ansi.txt"), list[0].GetGitPathString());
2068 EXPECT_EQ(CTGitPath::LOGACTIONS_UNMERGED, list[0].m_Action);
2071 TEST_P(CBasicGitWithEmptyRepositoryFixture, GetWorkingTreeChanges)
2073 if (GetParam() != 0)
2074 return;
2076 CTGitPathList list;
2077 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, nullptr));
2078 EXPECT_TRUE(list.IsEmpty());
2080 CString testFile = m_Dir.GetTempDir() + L"\\test.txt";
2081 EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFile, L"this is testing file."));
2082 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, nullptr));
2083 EXPECT_TRUE(list.IsEmpty());
2084 CString output;
2085 EXPECT_EQ(0, m_Git.Run(_T("git.exe add test.txt"), &output, CP_UTF8));
2086 EXPECT_TRUE(output.IsEmpty());
2087 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, nullptr));
2088 ASSERT_EQ(1, list.GetCount());
2089 // EXPECT_EQ(CTGitPath::LOGACTIONS_ADDED, list.GetAction()); // we do not care here for the list action, as its only used in GitLogListBase and there we re-calculate it in AsyncDiffThread
2090 EXPECT_STREQ(_T("test.txt"), list[0].GetGitPathString());
2091 EXPECT_EQ(CTGitPath::LOGACTIONS_ADDED, list[0].m_Action);
2093 CTGitPathList filter(CTGitPath(_T("copy")));
2094 list.Clear();
2095 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, &filter));
2096 ASSERT_EQ(1, list.GetCount());
2097 // EXPECT_EQ(CTGitPath::LOGACTIONS_ADDED, list.GetAction()); // we do not care here for the list action, as its only used in GitLogListBase and there we re-calculate it in AsyncDiffThread
2098 EXPECT_STREQ(_T("test.txt"), list[0].GetGitPathString());
2099 EXPECT_EQ(CTGitPath::LOGACTIONS_ADDED, list[0].m_Action);
2101 list.Clear();
2102 EXPECT_TRUE(::CreateDirectory(m_Dir.GetTempDir() + L"\\copy", nullptr));
2103 testFile = m_Dir.GetTempDir() + L"\\copy\\test2.txt";
2104 EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFile, L"this is another testing file."));
2105 EXPECT_EQ(0, m_Git.Run(_T("git.exe add copy/test2.txt"), &output, CP_UTF8));
2106 EXPECT_TRUE(output.IsEmpty());
2107 EXPECT_EQ(0, m_Git.GetWorkingTreeChanges(list, false, &filter));
2108 ASSERT_EQ(2, list.GetCount());
2109 // EXPECT_EQ(CTGitPath::LOGACTIONS_ADDED, list.GetAction()); // we do not care here for the list action, as its only used in GitLogListBase and there we re-calculate it in AsyncDiffThread
2110 EXPECT_STREQ(_T("copy/test2.txt"), list[0].GetGitPathString());
2111 EXPECT_EQ(CTGitPath::LOGACTIONS_ADDED, list[0].m_Action);
2112 EXPECT_STREQ(_T("test.txt"), list[1].GetGitPathString());
2113 EXPECT_EQ(CTGitPath::LOGACTIONS_ADDED, list[1].m_Action);
2116 TEST_P(CBasicGitWithTestRepoFixture, GetBisectTerms)
2118 if (m_Git.ms_bCygwinGit)
2119 return;
2121 CString good, bad;
2122 CString output;
2124 EXPECT_EQ(0, m_Git.Run(_T("git.exe bisect start"), &output, CP_UTF8));
2125 m_Git.GetBisectTerms(&good, &bad);
2126 EXPECT_STREQ(_T("good"), good);
2127 EXPECT_STREQ(_T("bad"), bad);
2129 good.Empty();
2130 bad.Empty();
2131 m_Git.GetBisectTerms(&good, &bad);
2132 EXPECT_STREQ(_T("good"), good);
2133 EXPECT_STREQ(_T("bad"), bad);
2135 EXPECT_EQ(0, m_Git.Run(_T("git.exe bisect reset"), &output, CP_UTF8));
2137 if (m_Git.GetGitVersion(nullptr, nullptr) < 0x02070000)
2138 return;
2140 EXPECT_EQ(0, m_Git.Run(_T("git.exe bisect start --term-good=original --term-bad=changed"), &output, CP_UTF8));
2141 m_Git.GetBisectTerms(&good, &bad);
2142 EXPECT_STREQ(_T("original"), good);
2143 EXPECT_STREQ(_T("changed"), bad);
2145 EXPECT_EQ(0, m_Git.Run(_T("git.exe bisect reset"), &output, CP_UTF8));