Catch the CMemoryExceptions when loading files in TortoiseMerge
[TortoiseGit.git] / src / Git / GitAdminDir.cpp
blobd790c4f7ddcd8ca652da18cb0f89ab9ea038df7d
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2012 - TortoiseGit
4 // Copyright (C) 2003-2008 - TortoiseSVN
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software Foundation,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "StdAfx.h"
21 #include "UnicodeUtils.h"
22 #include "GitAdminDir.h"
23 #include "Git.h"
24 GitAdminDir g_GitAdminDir;
26 GitAdminDir::GitAdminDir()
27 : m_nInit(0)
28 // , m_bVSNETHack(false)
29 // , m_pool(NULL)
33 GitAdminDir::~GitAdminDir()
35 // if (m_nInit)
36 // (m_pool);
39 bool GitAdminDir::Init()
41 if (m_nInit==0)
43 #if 0
44 m_bVSNETHack = false;
45 m_pool = svn_pool_create(NULL);
46 size_t ret = 0;
47 getenv_s(&ret, NULL, 0, "GIT_ASP_DOT_NET_HACK");
48 if (ret)
50 svn_error_clear(svn_wc_set_adm_dir("_git", m_pool));
51 m_bVSNETHack = true;
53 #endif
55 m_nInit++;
56 return true;
59 bool GitAdminDir::Close()
61 m_nInit--;
62 if (m_nInit>0)
63 return false;
64 #if 0
65 svn_pool_destroy(m_pool);
66 #endif
67 return true;
70 CString GitAdminDir::GetSuperProjectRoot(const CString& path)
72 CString projectroot=path;
76 if(CGit::GitPathFileExists(projectroot + _T("\\.gitmodules")))
78 return projectroot;
81 projectroot = projectroot.Left(projectroot.ReverseFind('\\'));
83 }while(projectroot.ReverseFind('\\')>0);
85 return _T("");
89 bool GitAdminDir::IsAdminDirName(const CString& name) const
91 #if 0
92 CStringA nameA = CUnicodeUtils::GetUTF8(name).MakeLower();
93 return !!svn_wc_is_adm_dir(nameA, m_pool);
94 #endif
95 return name == ".git";
97 CString GitAdminDir::GetGitTopDir(const CString& path)
99 CString str;
100 str=_T("");
101 HasAdminDir(path,!!PathIsDirectory(path),&str);
102 return str;
105 bool GitAdminDir::HasAdminDir(const CString& path) const
107 return HasAdminDir(path, !!PathIsDirectory(path));
110 bool GitAdminDir::HasAdminDir(const CString& path,CString *ProjectTopDir) const
112 return HasAdminDir(path, !!PathIsDirectory(path),ProjectTopDir);
115 bool GitAdminDir::HasAdminDir(const CString& path, bool bDir,CString *ProjectTopDir) const
117 if (path.IsEmpty())
118 return false;
119 CString sDirName = path;
120 if (!bDir)
122 sDirName = path.Left(path.ReverseFind(_T('\\')));
125 // a .git dir or anything inside it should be left out, only interested in working copy files -- Myagi
127 int n = 0;
128 for (;;)
130 n = sDirName.Find(_T("\\.git"), n);
131 if (n < 0)
133 break;
136 // check for actual .git dir (and not .gitignore or something else), continue search if false match
137 n += 5;
138 if (sDirName[n] == _T('\\') || sDirName[n] == 0)
140 return false;
145 for (;;)
147 if(CGit::GitPathFileExists(sDirName + _T("\\.git")))
149 if(ProjectTopDir)
151 *ProjectTopDir=sDirName;
152 // Make sure to add the trailing slash to root paths such as 'C:'
153 if (sDirName.GetLength() == 2 && sDirName[1] == _T(':'))
154 (*ProjectTopDir) += _T("\\");
156 return true;
159 int x = sDirName.ReverseFind(_T('\\'));
160 if (x < 2)
161 break;
163 sDirName = sDirName.Left(x);
166 return false;
170 * Returns the .git-path (if .git is a file, read the repository path and return it)
171 * adminDir always ends with "\"
173 bool GitAdminDir::GetAdminDirPath(const CString &projectTopDir, CString &adminDir) const
175 if (IsBareRepo(projectTopDir))
177 adminDir = projectTopDir;
178 adminDir.TrimRight('\\');
179 adminDir.Append(_T("\\"));
180 return true;
183 CString sDotGitPath = projectTopDir + _T("\\") + g_GitAdminDir.GetAdminDirName();
184 if (CTGitPath(sDotGitPath).IsDirectory())
186 sDotGitPath.TrimRight('\\');
187 sDotGitPath.Append(_T("\\"));
188 adminDir = sDotGitPath;
189 return true;
191 else
193 FILE *pFile;
194 _tfopen_s(&pFile, sDotGitPath, _T("r"));
196 if (!pFile)
197 return false;
199 char s[MAX_PATH + 8] = {0};
200 fgets(s, sizeof(s), pFile);
202 fclose(pFile);
203 CString gitPath(s);
204 if (gitPath.Find(L"gitdir: ") != 0)
205 return -1;
206 gitPath = gitPath.Trim().Mid(8); // 8 = len("gitdir: ")
207 gitPath.Replace('/', '\\');
208 gitPath.TrimRight('\\');
209 gitPath.Append(_T("\\"));
210 if (gitPath.GetLength() > 0 && gitPath[0] == _T('.'))
212 gitPath = projectTopDir + _T("\\") + gitPath;
213 PathCanonicalize(adminDir.GetBuffer(MAX_PATH), gitPath.GetBuffer());
214 adminDir.ReleaseBuffer();
215 gitPath.ReleaseBuffer();
216 return true;
218 adminDir = gitPath;
219 return true;
223 bool GitAdminDir::IsAdminDirPath(const CString& path) const
225 if (path.IsEmpty())
226 return false;
227 bool bIsAdminDir = false;
228 CString lowerpath = path;
229 lowerpath.MakeLower();
230 int ind = -1;
231 int ind1 = 0;
232 while ((ind1 = lowerpath.Find(_T("\\.git"), ind1))>=0)
234 ind = ind1++;
235 if (ind == (lowerpath.GetLength() - 5))
237 bIsAdminDir = true;
238 break;
240 else if (lowerpath.Find(_T("\\.git\\"), ind)>=0)
242 bIsAdminDir = true;
243 break;
247 return bIsAdminDir;
250 bool GitAdminDir::IsBareRepo(const CString& path) const
252 if (path.IsEmpty())
253 return false;
255 if (IsAdminDirPath(path))
256 return false;
258 if (!PathFileExists(path + _T("\\HEAD")) || !PathFileExists(path + _T("\\config")))
259 return false;
261 if (!PathFileExists(path + _T("\\objects\\")) || !PathFileExists(path + _T("\\refs\\")))
262 return false;
264 return true;