Added "--all" parameter for stash save
[TortoiseGit.git] / src / Git / GitAdminDir.cpp
blobaecdb18b5c0eed528e745aa2dde34a0653a0d2c1
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()
30 GitAdminDir::~GitAdminDir()
34 CString GitAdminDir::GetSuperProjectRoot(const CString& path)
36 CString projectroot=path;
40 if(CGit::GitPathFileExists(projectroot + _T("\\.gitmodules")))
42 return projectroot;
45 projectroot = projectroot.Left(projectroot.ReverseFind('\\'));
47 }while(projectroot.ReverseFind('\\')>0);
49 return _T("");
53 CString GitAdminDir::GetGitTopDir(const CString& path)
55 CString str;
56 str=_T("");
57 HasAdminDir(path,!!PathIsDirectory(path),&str);
58 return str;
61 bool GitAdminDir::HasAdminDir(const CString& path) const
63 return HasAdminDir(path, !!PathIsDirectory(path));
66 bool GitAdminDir::HasAdminDir(const CString& path,CString *ProjectTopDir) const
68 return HasAdminDir(path, !!PathIsDirectory(path),ProjectTopDir);
71 bool GitAdminDir::HasAdminDir(const CString& path, bool bDir,CString *ProjectTopDir) const
73 if (path.IsEmpty())
74 return false;
75 CString sDirName = path;
76 if (!bDir)
78 sDirName = path.Left(path.ReverseFind(_T('\\')));
81 // a .git dir or anything inside it should be left out, only interested in working copy files -- Myagi
83 int n = 0;
84 for (;;)
86 n = sDirName.Find(_T("\\.git"), n);
87 if (n < 0)
89 break;
92 // check for actual .git dir (and not .gitignore or something else), continue search if false match
93 n += 5;
94 if (sDirName[n] == _T('\\') || sDirName[n] == 0)
96 return false;
101 for (;;)
103 if(CGit::GitPathFileExists(sDirName + _T("\\.git")))
105 if(ProjectTopDir)
107 *ProjectTopDir=sDirName;
108 // Make sure to add the trailing slash to root paths such as 'C:'
109 if (sDirName.GetLength() == 2 && sDirName[1] == _T(':'))
110 (*ProjectTopDir) += _T("\\");
112 return true;
115 int x = sDirName.ReverseFind(_T('\\'));
116 if (x < 2)
117 break;
119 sDirName = sDirName.Left(x);
122 return false;
126 * Returns the .git-path (if .git is a file, read the repository path and return it)
127 * adminDir always ends with "\"
129 bool GitAdminDir::GetAdminDirPath(const CString &projectTopDir, CString &adminDir) const
131 if (IsBareRepo(projectTopDir))
133 adminDir = projectTopDir;
134 adminDir.TrimRight('\\');
135 adminDir.Append(_T("\\"));
136 return true;
139 CString sDotGitPath = projectTopDir + _T("\\") + g_GitAdminDir.GetAdminDirName();
140 if (CTGitPath(sDotGitPath).IsDirectory())
142 sDotGitPath.TrimRight('\\');
143 sDotGitPath.Append(_T("\\"));
144 adminDir = sDotGitPath;
145 return true;
147 else
149 FILE *pFile;
150 _tfopen_s(&pFile, sDotGitPath, _T("r"));
152 if (!pFile)
153 return false;
155 char s[MAX_PATH + 8] = {0};
156 fgets(s, sizeof(s), pFile);
158 fclose(pFile);
159 CString gitPath(s);
160 if (gitPath.Find(L"gitdir: ") != 0)
161 return false;
162 gitPath = gitPath.Trim().Mid(8); // 8 = len("gitdir: ")
163 gitPath.Replace('/', '\\');
164 gitPath.TrimRight('\\');
165 gitPath.Append(_T("\\"));
166 if (gitPath.GetLength() > 0 && gitPath[0] == _T('.'))
168 gitPath = projectTopDir + _T("\\") + gitPath;
169 PathCanonicalize(adminDir.GetBuffer(MAX_PATH), gitPath.GetBuffer());
170 adminDir.ReleaseBuffer();
171 gitPath.ReleaseBuffer();
172 return true;
174 adminDir = gitPath;
175 return true;
179 bool GitAdminDir::IsAdminDirPath(const CString& path) const
181 if (path.IsEmpty())
182 return false;
183 bool bIsAdminDir = false;
184 CString lowerpath = path;
185 lowerpath.MakeLower();
186 int ind = -1;
187 int ind1 = 0;
188 while ((ind1 = lowerpath.Find(_T("\\.git"), ind1))>=0)
190 ind = ind1++;
191 if (ind == (lowerpath.GetLength() - 5))
193 bIsAdminDir = true;
194 break;
196 else if (lowerpath.Find(_T("\\.git\\"), ind)>=0)
198 bIsAdminDir = true;
199 break;
203 return bIsAdminDir;
206 bool GitAdminDir::IsBareRepo(const CString& path) const
208 if (path.IsEmpty())
209 return false;
211 if (IsAdminDirPath(path))
212 return false;
214 if (!PathFileExists(path + _T("\\HEAD")) || !PathFileExists(path + _T("\\config")))
215 return false;
217 if (!PathFileExists(path + _T("\\objects\\")) || !PathFileExists(path + _T("\\refs\\")))
218 return false;
220 return true;