/** * Returns the .git-path (if .git is a file, read the repository path and return it) * adminDir always ends with "\" */ bool GitAdminDir::GetAdminDirPath(const CString &projectTopDir, CString& adminDir) { if (IsBareRepo(projectTopDir)) { adminDir = projectTopDir; adminDir.TrimRight('\\'); adminDir.Append(_T("\\")); return true; } CString sDotGitPath = projectTopDir + _T("\\") + GetAdminDirName(); if (CTGitPath(sDotGitPath).IsDirectory()) { sDotGitPath.TrimRight('\\'); sDotGitPath.Append(_T("\\")); adminDir = sDotGitPath; return true; } else { CString result = ReadGitLink(projectTopDir, sDotGitPath); if (result.IsEmpty()) return false; adminDir = result + _T("\\"); return true; } }
bool GitAdminDir::HasAdminDir(const CString& path, bool bDir,CString *ProjectTopDir) const { if (path.IsEmpty()) return false; CString sDirName = path; if (!bDir) { // e.g "C:\" if (path.GetLength() <= 3) return false; sDirName = path.Left(path.ReverseFind(_T('\\'))); } // a .git dir or anything inside it should be left out, only interested in working copy files -- Myagi { int n = 0; for (;;) { n = sDirName.Find(_T("\\.git"), n); if (n < 0) { break; } // check for actual .git dir (and not .gitignore or something else), continue search if false match n += 5; if (sDirName[n] == _T('\\') || sDirName[n] == 0) { return false; } } } for (;;) { if(CGit::GitPathFileExists(sDirName + _T("\\.git"))) { if(ProjectTopDir) { *ProjectTopDir=sDirName; // Make sure to add the trailing slash to root paths such as 'C:' if (sDirName.GetLength() == 2 && sDirName[1] == _T(':')) (*ProjectTopDir) += _T("\\"); } return true; } else if (IsBareRepo(sDirName)) return false; int x = sDirName.ReverseFind(_T('\\')); if (x < 2) break; sDirName = sDirName.Left(x); } return false; }
bool GitAdminDir::HasAdminDir(const CString& path, bool bDir, CString* ProjectTopDir, bool* IsAdminDirPath) { if (path.IsEmpty()) return false; CString sDirName = path; if (!bDir) { // e.g "C:\" if (path.GetLength() <= 3) return false; sDirName.Truncate(max(0, sDirName.ReverseFind(L'\\'))); } // a .git dir or anything inside it should be left out, only interested in working copy files -- Myagi int n = 0; for (;;) { n = sDirName.Find(L"\\.git", n); if (n < 0) break; // check for actual .git dir (and not .gitignore or something else), continue search if false match n += 5; if (sDirName[n] == L'\\' || sDirName[n] == 0) { if (IsAdminDirPath) *IsAdminDirPath = true; return false; } } for (;;) { if (CGit::GitPathFileExists(sDirName + L"\\.git")) { if(ProjectTopDir) { *ProjectTopDir=sDirName; // Make sure to add the trailing slash to root paths such as 'C:' if (sDirName.GetLength() == 2 && sDirName[1] == L':') (*ProjectTopDir) += L'\\'; } return true; } else if (IsBareRepo(sDirName)) return false; int x = sDirName.ReverseFind(L'\\'); if (x < 2) break; sDirName.Truncate(x); // don't check for \\COMPUTERNAME\.git if (sDirName[0] == L'\\' && sDirName[1] == L'\\' && sDirName.Find(L'\\', 2) < 0) break; } return false; }
/** * Returns the .git-path (if .git is a file, read the repository path and return it) * adminDir always ends with "\" */ bool GitAdminDir::GetAdminDirPath(const CString &projectTopDir, CString &adminDir) const { if (IsBareRepo(projectTopDir)) { adminDir = projectTopDir; adminDir.TrimRight('\\'); adminDir.Append(_T("\\")); return true; } CString sDotGitPath = projectTopDir + _T("\\") + g_GitAdminDir.GetAdminDirName(); if (CTGitPath(sDotGitPath).IsDirectory()) { sDotGitPath.TrimRight('\\'); sDotGitPath.Append(_T("\\")); adminDir = sDotGitPath; return true; } else { FILE *pFile; _tfopen_s(&pFile, sDotGitPath, _T("r")); if (!pFile) return false; int size = 65536; std::unique_ptr<char[]> buffer(new char[size]); SecureZeroMemory(buffer.get(), size); fread(buffer.get(), sizeof(char), size, pFile); fclose(pFile); CStringA gitPathA(buffer.get()); if (gitPathA.Left(8) != "gitdir: ") return false; CString gitPath = CUnicodeUtils::GetUnicode(gitPathA.Trim().Mid(8)); // 8 = len("gitdir: ") gitPath.Replace('/', '\\'); gitPath.TrimRight('\\'); gitPath.Append(_T("\\")); if (gitPath.GetLength() > 0 && gitPath[0] == _T('.')) { gitPath = projectTopDir + _T("\\") + gitPath; PathCanonicalize(adminDir.GetBuffer(MAX_PATH), gitPath.GetBuffer()); adminDir.ReleaseBuffer(); gitPath.ReleaseBuffer(); return true; } adminDir = gitPath; return true; } }
bool GitAdminDir::GetWorktreeAdminDirPath(const CString& projectTopDir, CString& adminDir) { if (IsBareRepo(projectTopDir)) { adminDir = CPathUtils::BuildPathWithPathDelimiter(projectTopDir); return true; } CString sDotGitPath = CPathUtils::BuildPathWithPathDelimiter(projectTopDir) + GetAdminDirName(); if (CTGitPath(sDotGitPath).IsDirectory()) { adminDir = CPathUtils::BuildPathWithPathDelimiter(sDotGitPath); return true; } else { CString result = ReadGitLink(projectTopDir, sDotGitPath); if (result.IsEmpty()) return false; adminDir = CPathUtils::BuildPathWithPathDelimiter(result); return true; } }
bool GitAdminDir::IsWorkingTreeOrBareRepo(const CString& path) { return HasAdminDir(path) || IsBareRepo(path); }
bool GitAdminDir::HasAdminDir(const CString& path, bool bDir, CString* ProjectTopDir, bool* IsAdminDirPath) { if (path.IsEmpty()) return false; CString sDirName = path; if (!bDir) { // e.g "C:\" if (path.GetLength() <= 3) return false; sDirName.Truncate(max(0, sDirName.ReverseFind(L'\\'))); } // a .git dir or anything inside it should be left out, only interested in working copy files -- Myagi int n = 0; for (;;) { n = sDirName.Find(L"\\.git", n); if (n < 0) break; // check for actual .git dir (and not .gitignore or something else), continue search if false match n += 5; if (sDirName[n] == L'\\' || sDirName[n] == 0) { if (IsAdminDirPath) *IsAdminDirPath = true; return false; } } for (;;) { if (CGit::GitPathFileExists(sDirName + L"\\.git")) { // Make sure to add the trailing slash to root paths such as 'C:' if (sDirName.GetLength() == 2 && sDirName[1] == L':') sDirName += L'\\'; if (ProjectTopDir) *ProjectTopDir = sDirName; /* This code is not necessary in TGitCache as there are further checks for valid repos, however, * TODO: Optimize for usage in TGitCache */ #ifndef TGITCACHE CString adminDir; if (!GetAdminDirPath(sDirName, adminDir)) return false; if (!PathFileExists(adminDir + L"\\HEAD") || !PathFileExists(adminDir + L"\\config")) return false; if (!PathFileExists(adminDir + L"\\objects\\") || !PathFileExists(adminDir + L"\\refs\\")) return false; #endif return true; } else if (IsBareRepo(sDirName)) return false; int x = sDirName.ReverseFind(L'\\'); if (x < 2) break; sDirName.Truncate(x); // don't check for \\COMPUTERNAME\.git if (sDirName[0] == L'\\' && sDirName[1] == L'\\' && sDirName.Find(L'\\', 2) < 0) break; } return false; }