Prevent possible crash if refs could not be read
[TortoiseGit.git] / src / Git / Git.h
blob669b8413c7e8bd718b388d200fa5a78a3ab8e7c4
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2012 - TortoiseGit
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #pragma once
21 #include "GitType.h"
22 #include "GitRev.h"
23 #include "GitStatus.h"
24 #include "GitAdminDir.h"
25 #include "gitdll.h"
27 class CFilterData
29 public:
30 CFilterData()
32 m_From=m_To=-1;
33 m_IsRegex=1;
35 __time64_t m_From;
36 __time64_t m_To;
37 CString m_Author;
38 CString m_Committer;
39 CString m_MessageFilter;
40 BOOL m_IsRegex;
43 class CGitCall
45 public:
46 CGitCall(){}
47 CGitCall(CString cmd):m_Cmd(cmd){}
49 CString GetCmd()const{return m_Cmd;}
50 void SetCmd(CString cmd){m_Cmd=cmd;}
52 //This function is called when command output data is available.
53 //When this function returns 'true' the git command should be aborted.
54 //This behavior is not implemented yet.
55 virtual bool OnOutputData(const BYTE* data, size_t size)=0;
56 virtual bool OnOutputErrData(const BYTE* data, size_t size)=0;
57 virtual void OnEnd(){}
59 private:
60 CString m_Cmd;
64 class CTGitPath;
65 class CEnvironment:public std::vector<TCHAR>
67 public:
68 void CopyProcessEnvironment();
69 CString GetEnv(TCHAR *name);
70 void SetEnv(TCHAR* name, TCHAR* value);
72 class CGit
74 private:
75 GitAdminDir m_GitDir;
76 protected:
77 bool m_IsGitDllInited;
78 GIT_DIFF m_GitDiff;
79 GIT_DIFF m_GitSimpleListDiff;
80 public:
81 CComCriticalSection m_critGitDllSec;
82 bool m_IsUseGitDLL;
83 bool m_IsUseLibGit2;
85 CEnvironment m_Environment;
87 static BOOL GitPathFileExists(const CString &path)
89 if(path[0] == _T('\\') && path[1] == _T('\\'))
90 //it is netshare \\server\sharefoldername
91 // \\server\.git will create smb error log.
93 int length = path.GetLength();
95 if(length<2)
96 return false;
98 int start = path.Find(_T('\\'),2);
99 if(start<0)
100 return false;
102 start = path.Find(_T('\\'),start+1);
103 if(start<0)
104 return false;
106 return PathFileExists(path);
109 else
110 return PathFileExists(path);
112 void CheckAndInitDll()
114 if(!m_IsGitDllInited)
116 git_init();
117 m_IsGitDllInited=true;
121 GIT_DIFF GetGitDiff()
123 if(m_GitDiff)
124 return m_GitDiff;
125 else
127 git_open_diff(&m_GitDiff,"-C -M -r");
128 return m_GitDiff;
132 GIT_DIFF GetGitSimpleListDiff()
134 if(m_GitSimpleListDiff)
135 return m_GitSimpleListDiff;
136 else
138 git_open_diff(&m_GitSimpleListDiff,"-r -r");
139 return m_GitSimpleListDiff;
143 BOOL CheckMsysGitDir();
144 BOOL m_bInitialized;
146 CString GetHomeDirectory();
147 CString GetGitLocalConfig();
148 CString GetGitGlobalConfig();
149 CString GetGitGlobalXDGConfigPath();
150 CString GetGitGlobalXDGConfig();
151 CString GetGitSystemConfig();
152 static CString ms_LastMsysGitDir; // the last msysgitdir added to the path, blank if none
153 static int m_LogEncode;
154 static bool IsBranchNameValid(CString branchname);
155 bool IsBranchTagNameUnique(const CString& name);
156 bool BranchTagExists(const CString& name, bool isBranch = true);
157 unsigned int Hash2int(CGitHash &hash);
158 // static CString m_MsysGitPath;
160 PROCESS_INFORMATION m_CurrentGitPi;
162 CGit(void);
163 ~CGit(void);
165 int Run(CString cmd, CString* output, int code);
166 int Run(CString cmd, CString* output, CString* outputErr, int code);
167 int Run(CString cmd, BYTE_VECTOR *byte_array, BYTE_VECTOR *byte_arrayErr = NULL);
168 int Run(CGitCall* pcall);
170 private:
171 static DWORD WINAPI AsyncReadStdErrThread(LPVOID lpParam);
172 typedef struct AsyncReadStdErrThreadArguments
174 HANDLE fileHandle;
175 CGitCall* pcall;
176 } ASYNCREADSTDERRTHREADARGS, *PASYNCREADSTDERRTHREADARGS;
178 public:
179 int RunAsync(CString cmd, PROCESS_INFORMATION *pi, HANDLE* hRead, HANDLE *hErrReadOut, CString *StdioFile = NULL);
180 int RunLogFile(CString cmd, const CString &filename);
182 int GetDiffPath(CTGitPathList *PathList, CGitHash *hash1, CGitHash *hash2, char *arg=NULL);
184 int GetGitEncode(TCHAR* configkey);
186 bool IsFastForward(const CString &from, const CString &to, CGitHash * commonAncestor = NULL);
187 CString GetConfigValue(CString name, int encoding=CP_UTF8, CString *GitPath=NULL,BOOL RemoveCR=TRUE);
189 int SetConfigValue(CString key, CString value, CONFIG_TYPE type=CONFIG_LOCAL, int encoding=CP_UTF8, CString *GitPath=NULL);
190 int UnsetConfigValue(CString key, CONFIG_TYPE type=CONFIG_LOCAL, int encoding=CP_UTF8, CString *GitPath=NULL);
192 CString GetUserName(void);
193 CString GetUserEmail(void);
194 CString GetCurrentBranch(void);
195 CString GetSymbolicRef(const wchar_t* symbolicRefName = L"HEAD", bool bStripRefsHeads = true);
196 // read current branch name from HEAD file, returns 0 on success, -1 on failure, 1 detached (branch name "HEAD" returned)
197 int GetCurrentBranchFromFile(const CString &sProjectRoot, CString &sBranchOut);
198 BOOL CheckCleanWorkTree();
199 int Revert(CString commit, CTGitPathList &list, bool keep=true);
200 int Revert(CString commit, CTGitPath &path);
202 bool SetCurrentDir(CString path, bool submodule = false)
204 bool b = m_GitDir.HasAdminDir(path, submodule ? false : !!PathIsDirectory(path), &m_CurrentDir);
205 if (!b && g_GitAdminDir.IsBareRepo(path))
207 m_CurrentDir = path;
208 b = true;
210 if(m_CurrentDir.GetLength() == 2 && m_CurrentDir[1] == _T(':')) //C: D:
212 m_CurrentDir += _T('\\');
214 return b;
216 CString m_CurrentDir;
218 typedef enum
220 BRANCH_LOCAL = 0x1,
221 BRANCH_REMOTE = 0x2,
222 BRANCH_FETCH_HEAD = 0x4,
223 BRANCH_LOCAL_F = BRANCH_LOCAL | BRANCH_FETCH_HEAD,
224 BRANCH_ALL = BRANCH_LOCAL | BRANCH_REMOTE,
225 BRANCH_ALL_F = BRANCH_ALL | BRANCH_FETCH_HEAD,
226 }BRANCH_TYPE;
228 typedef enum
230 LOG_INFO_STAT=0x1,
231 LOG_INFO_FILESTATE=0x2,
232 LOG_INFO_PATCH=0x4,
233 LOG_INFO_FULLHISTORY=0x8,
234 LOG_INFO_BOUNDARY=0x10,
235 LOG_INFO_ALL_BRANCH=0x20,
236 LOG_INFO_ONLY_HASH=0x40,
237 LOG_INFO_DETECT_RENAME=0x80,
238 LOG_INFO_DETECT_COPYRENAME=0x100,
239 LOG_INFO_FIRST_PARENT = 0x200,
240 LOG_INFO_NO_MERGE = 0x400,
241 LOG_INFO_FOLLOW = 0x800,
242 LOG_INFO_SHOW_MERGEDFILE=0x1000,
243 LOG_INFO_FULL_DIFF = 0x2000,
244 LOG_INFO_SIMPILFY_BY_DECORATION = 0x4000,
245 }LOG_INFO_MASK;
247 typedef enum
249 LOCAL_BRANCH,
250 REMOTE_BRANCH,
251 TAG,
252 STASH,
253 BISECT_GOOD,
254 BISECT_BAD,
255 NOTES,
256 UNKNOWN,
258 }REF_TYPE;
260 int GetRemoteList(STRING_VECTOR &list);
261 int GetBranchList(STRING_VECTOR &list, int *Current,BRANCH_TYPE type=BRANCH_LOCAL);
262 int GetTagList(STRING_VECTOR &list);
263 int GetRemoteTags(CString remote, STRING_VECTOR &list);
264 int GetMapHashToFriendName(MAP_HASH_NAME &map);
266 CString DerefFetchHead();
268 // FixBranchName():
269 // When branchName == FETCH_HEAD, derefrence it.
270 // A selected branch name got from GetBranchList(), with flag BRANCH_FETCH_HEAD enabled,
271 // should go through this function before it is used.
272 CString FixBranchName_Mod(CString& branchName);
273 CString FixBranchName(const CString& branchName);
275 //hash is empty means all. -1 means all
277 int GetLog(CGitCall* pgitCall, const CString &hash, CTGitPath *path = NULL,int count=-1,int InfoMask=LOG_INFO_FULL_DIFF|LOG_INFO_STAT|LOG_INFO_FILESTATE|LOG_INFO_BOUNDARY|LOG_INFO_DETECT_COPYRENAME|LOG_INFO_SHOW_MERGEDFILE,
278 CString *from=NULL,CString *to=NULL);
279 int GetLog(BYTE_VECTOR& logOut,const CString &hash, CTGitPath *path = NULL,int count=-1,int InfoMask=LOG_INFO_FULL_DIFF|LOG_INFO_STAT|LOG_INFO_FILESTATE|LOG_INFO_BOUNDARY|LOG_INFO_DETECT_COPYRENAME|LOG_INFO_SHOW_MERGEDFILE,
280 CString *from=NULL,CString *to=NULL);
282 CString GetLogCmd(const CString &hash, CTGitPath *path = NULL,int count=-1,int InfoMask=LOG_INFO_FULL_DIFF|LOG_INFO_STAT|LOG_INFO_FILESTATE|LOG_INFO_BOUNDARY|LOG_INFO_DETECT_COPYRENAME|LOG_INFO_SHOW_MERGEDFILE,
283 CString *from=NULL,CString *to=NULL, bool paramonly=false,
284 CFilterData * filter =NULL);
286 CGitHash GetHash(TCHAR* friendname);
287 CGitHash GetHash(CString ref){return GetHash(ref.GetBuffer());}
289 int BuildOutputFormat(CString &format,bool IsFull=TRUE);
290 //int GetShortLog(const CString &log,CTGitPath * path=NULL, int count =-1);
291 static void StringAppend(CString *str,BYTE *p,int code=CP_UTF8,int length=-1);
293 BOOL IsOrphanBranch(CString ref);
294 BOOL IsInitRepos();
295 int ListConflictFile(CTGitPathList &list,CTGitPath *path=NULL);
296 int GetRefList(STRING_VECTOR &list);
298 int RefreshGitIndex();
299 int GetOneFile(CString Refname, CTGitPath &path, const CString &outputfile);
301 //Example: master -> refs/heads/master
302 CString GetFullRefName(CString shortRefName);
303 //Removes 'refs/heads/' or just 'refs'. Example: refs/heads/master -> master
304 static CString StripRefName(CString refName);
306 int GetCommitDiffList(const CString &rev1,const CString &rev2,CTGitPathList &outpathlist);
307 int GetInitAddList(CTGitPathList &outpathlist);
309 __int64 filetime_to_time_t(const FILETIME *ft)
311 long long winTime = ((long long)ft->dwHighDateTime << 32) + ft->dwLowDateTime;
312 winTime -= 116444736000000000LL; /* Windows to Unix Epoch conversion */
313 winTime /= 10000000; /* Nano to seconds resolution */
314 return (time_t)winTime;
317 int GetFileModifyTime(LPCTSTR filename, __int64 *time, bool * isDir=NULL)
319 WIN32_FILE_ATTRIBUTE_DATA fdata;
320 if (GetFileAttributesEx(filename, GetFileExInfoStandard, &fdata))
322 if(time)
323 *time = filetime_to_time_t(&fdata.ftLastWriteTime);
325 if(isDir)
326 *isDir = !!( fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
328 return 0;
330 return -1;
333 int GetShortHASHLength();
335 static BOOL GetShortName(CString ref, CString &shortname, CString prefix)
337 //TRACE(_T("%s %s\r\n"),ref,prefix);
338 if (ref.Left(prefix.GetLength()) == prefix)
340 shortname = ref.Right(ref.GetLength() - prefix.GetLength());
341 if (shortname.Right(3) == _T("^{}"))
342 shortname=shortname.Left(shortname.GetLength() - 3);
343 return TRUE;
345 return FALSE;
348 static CString GetShortName(CString ref, REF_TYPE *type);
350 extern void GetTempPath(CString &path);
351 extern CString GetTempFile();
352 extern DWORD GetTortoiseGitTempPath(DWORD nBufferLength, LPTSTR lpBuffer);
354 extern CGit g_Git;