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.
21 #include "UnicodeUtils.h"
22 #include "GitAdminDir.h"
24 GitAdminDir g_GitAdminDir
;
26 GitAdminDir::GitAdminDir()
28 // , m_bVSNETHack(false)
33 GitAdminDir::~GitAdminDir()
39 bool GitAdminDir::Init()
45 m_pool
= svn_pool_create(NULL
);
47 getenv_s(&ret
, NULL
, 0, "GIT_ASP_DOT_NET_HACK");
50 svn_error_clear(svn_wc_set_adm_dir("_git", m_pool
));
59 bool GitAdminDir::Close()
65 svn_pool_destroy(m_pool
);
70 CString
GitAdminDir::GetSuperProjectRoot(const CString
& path
)
72 CString projectroot
=path
;
76 if(CGit::GitPathFileExists(projectroot
+ _T("\\.gitmodules")))
81 projectroot
= projectroot
.Left(projectroot
.ReverseFind('\\'));
83 }while(projectroot
.ReverseFind('\\')>0);
89 bool GitAdminDir::IsAdminDirName(const CString
& name
) const
92 CStringA nameA
= CUnicodeUtils::GetUTF8(name
).MakeLower();
93 return !!svn_wc_is_adm_dir(nameA
, m_pool
);
95 return name
== ".git";
97 CString
GitAdminDir::GetGitTopDir(const CString
& path
)
101 HasAdminDir(path
,!!PathIsDirectory(path
),&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
119 CString sDirName
= path
;
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
130 n
= sDirName
.Find(_T("\\.git"), n
);
136 // check for actual .git dir (and not .gitignore or something else), continue search if false match
138 if (sDirName
[n
] == _T('\\') || sDirName
[n
] == 0)
147 if(CGit::GitPathFileExists(sDirName
+ _T("\\.git")))
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("\\");
159 int x
= sDirName
.ReverseFind(_T('\\'));
163 sDirName
= sDirName
.Left(x
);
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("\\"));
183 CString sDotGitPath
= projectTopDir
+ _T("\\") + g_GitAdminDir
.GetAdminDirName();
184 if (CTGitPath(sDotGitPath
).IsDirectory())
186 sDotGitPath
.TrimRight('\\');
187 sDotGitPath
.Append(_T("\\"));
188 adminDir
= sDotGitPath
;
194 _tfopen_s(&pFile
, sDotGitPath
, _T("r"));
199 char s
[MAX_PATH
+ 8] = {0};
200 fgets(s
, sizeof(s
), pFile
);
204 if (gitPath
.Find(L
"gitdir: ") != 0)
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();
223 bool GitAdminDir::IsAdminDirPath(const CString
& path
) const
227 bool bIsAdminDir
= false;
228 CString lowerpath
= path
;
229 lowerpath
.MakeLower();
232 while ((ind1
= lowerpath
.Find(_T("\\.git"), ind1
))>=0)
235 if (ind
== (lowerpath
.GetLength() - 5))
240 else if (lowerpath
.Find(_T("\\.git\\"), ind
)>=0)
250 bool GitAdminDir::IsBareRepo(const CString
& path
) const
255 if (IsAdminDirPath(path
))
258 if (!PathFileExists(path
+ _T("\\HEAD")) || !PathFileExists(path
+ _T("\\config")))
261 if (!PathFileExists(path
+ _T("\\objects\\")) || !PathFileExists(path
+ _T("\\refs\\")))