MCPcopy Create free account
hub / github.com/TortoiseGit/TortoiseGit / HasGITAdminDir

Method HasGITAdminDir

src/TortoiseShell/ShellCache.cpp:427–499  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

425}
426
427BOOL ShellCache::HasGITAdminDir(LPCWSTR path, BOOL bIsDir, CString* ProjectTopDir /*= nullptr*/)
428{
429 const ULONGLONG now = GetTickCount64();
430 if (now >= nextAdmindircacheCleanupTime)
431 {
432 // Clear stale elements in admindircache every now and then
433 nextAdmindircacheCleanupTime = now + 10 * 60 * 1000; // 10 minutes
434 std::erase_if(admindircache, [now](const auto& pair) { return now >= pair.second.timeout; });
435 }
436
437 std::wstring folder(path);
438 if (!bIsDir)
439 {
440 size_t pos = folder.rfind(L'\\');
441 if (pos != std::wstring::npos)
442 folder.erase(pos);
443 }
444 {
445 Locker lock(m_critSec);
446 if (const auto iter = admindircache.find(folder); iter != admindircache.cend())
447 {
448 if (now < iter->second.timeout)
449 {
450 if (ProjectTopDir && iter->second.bHasAdminDir)
451 *ProjectTopDir = iter->second.sProjectRoot.c_str();
452 return iter->second.bHasAdminDir;
453 }
454 }
455 }
456
457 // When explorer calls CShellExt::IsMemberOf for a lot of subfolders, the cache above won't be
458 // effective because folders can be their own repository. But most of the time they are not and
459 // we don't want to waste time searching for ".git" in all our parent folders in that common case.
460 // So, for subfolders that are not bare and with no ".git" inside them, we check the cache again for their parent folder.
461 // This way, all CShellExt::IsMemberOf calls for a given folder will check the cache for that folder
462 // and GitAdminDir::HasAdminDir has to be called at most once.
463 if (bIsDir)
464 {
465 if (size_t pos = folder.rfind(L'\\'); pos != std::wstring::npos)
466 {
467 if (CString folderString(folder.c_str()); !CGit::GitPathFileExists(folderString + L"\\.git") && !GitAdminDir::IsBareRepo(folderString))
468 {
469 folder.erase(pos);
470 Locker lock(m_critSec);
471 if (const auto iter = admindircache.find(folder); iter != admindircache.cend())
472 {
473 if (now < iter->second.timeout)
474 {
475 if (ProjectTopDir && iter->second.bHasAdminDir)
476 *ProjectTopDir = iter->second.sProjectRoot.c_str();
477 return iter->second.bHasAdminDir;
478 }
479 }
480 }
481 }
482 }
483
484 CString sProjectRoot;

Callers 4

IsMemberOfMethod · 0.80
InitializeMethod · 0.80
GetFullStatusMethod · 0.80

Calls 3

eraseMethod · 0.80
cendMethod · 0.80
findMethod · 0.45

Tested by

no test coverage detected