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.
23 #include "GitStatus.h"
24 #include "GitAdminDir.h"
39 CString m_MessageFilter
;
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(){}
65 class CEnvironment
:public std::vector
<TCHAR
>
68 void CopyProcessEnvironment();
69 CString
GetEnv(TCHAR
*name
);
70 void SetEnv(TCHAR
* name
, TCHAR
* value
);
77 bool m_IsGitDllInited
;
79 GIT_DIFF m_GitSimpleListDiff
;
81 CComCriticalSection m_critGitDllSec
;
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();
98 int start
= path
.Find(_T('\\'),2);
102 start
= path
.Find(_T('\\'),start
+1);
106 return PathFileExists(path
);
110 return PathFileExists(path
);
112 void CheckAndInitDll()
114 if(!m_IsGitDllInited
)
117 m_IsGitDllInited
=true;
121 GIT_DIFF
GetGitDiff()
127 git_open_diff(&m_GitDiff
,"-C -M -r");
132 GIT_DIFF
GetGitSimpleListDiff()
134 if(m_GitSimpleListDiff
)
135 return m_GitSimpleListDiff
;
138 git_open_diff(&m_GitSimpleListDiff
,"-r -r");
139 return m_GitSimpleListDiff
;
143 BOOL
CheckMsysGitDir();
146 CString
GetHomeDirectory();
147 CString
GetGitLocalConfig();
148 CString
GetGitGlobalConfig();
149 CString
GetGitGlobalXDGConfig();
150 CString
GetGitSystemConfig();
151 static CString ms_LastMsysGitDir
; // the last msysgitdir added to the path, blank if none
152 static int m_LogEncode
;
153 static bool IsBranchNameValid(CString branchname
);
154 static bool IsBranchTagNameUnique(const CString
& name
);
155 static bool BranchTagExists(const CString
& name
, bool isBranch
= true);
156 unsigned int Hash2int(CGitHash
&hash
);
157 // static CString m_MsysGitPath;
159 PROCESS_INFORMATION m_CurrentGitPi
;
164 int Run(CString cmd
, CString
* output
, int code
);
165 int Run(CString cmd
, CString
* output
, CString
* outputErr
, int code
);
166 int Run(CString cmd
, BYTE_VECTOR
*byte_array
, BYTE_VECTOR
*byte_arrayErr
= NULL
);
167 int Run(CGitCall
* pcall
);
170 static DWORD WINAPI
CGit::AsyncReadStdErrThread(LPVOID lpParam
);
171 typedef struct AsyncReadStdErrThreadArguments
175 } ASYNCREADSTDERRTHREADARGS
, *PASYNCREADSTDERRTHREADARGS
;
178 int RunAsync(CString cmd
, PROCESS_INFORMATION
*pi
, HANDLE
* hRead
, HANDLE
*hErrReadOut
, CString
*StdioFile
= NULL
);
179 int RunLogFile(CString cmd
, const CString
&filename
);
181 int GetDiffPath(CTGitPathList
*PathList
, CGitHash
*hash1
, CGitHash
*hash2
, char *arg
=NULL
);
183 int GetGitEncode(TCHAR
* configkey
);
185 bool IsFastForward(const CString
&from
, const CString
&to
, CGitHash
* commonAncestor
= NULL
);
186 CString
GetConfigValue(CString name
, int encoding
=CP_UTF8
, CString
*GitPath
=NULL
,BOOL RemoveCR
=TRUE
);
188 int SetConfigValue(CString key
, CString value
, CONFIG_TYPE type
=CONFIG_LOCAL
, int encoding
=CP_UTF8
, CString
*GitPath
=NULL
);
189 int UnsetConfigValue(CString key
, CONFIG_TYPE type
=CONFIG_LOCAL
, int encoding
=CP_UTF8
, CString
*GitPath
=NULL
);
191 CString
GetUserName(void);
192 CString
GetUserEmail(void);
193 CString
GetCurrentBranch(void);
194 CString
GetSymbolicRef(const wchar_t* symbolicRefName
= L
"HEAD", bool bStripRefsHeads
= true);
195 // read current branch name from HEAD file, returns 0 on success, -1 on failure, 1 detached (branch name "HEAD" returned)
196 int GetCurrentBranchFromFile(const CString
&sProjectRoot
, CString
&sBranchOut
);
197 BOOL
CheckCleanWorkTree();
198 int Revert(CString commit
, CTGitPathList
&list
, bool keep
=true);
199 int Revert(CString commit
, CTGitPath
&path
);
201 bool SetCurrentDir(CString path
, bool submodule
= false)
203 bool b
= m_GitDir
.HasAdminDir(path
, submodule
? false : !!PathIsDirectory(path
), &m_CurrentDir
);
204 if (!b
&& g_GitAdminDir
.IsBareRepo(path
))
209 if(m_CurrentDir
.GetLength() == 2 && m_CurrentDir
[1] == _T(':')) //C: D:
211 m_CurrentDir
+= _T('\\');
215 CString m_CurrentDir
;
221 BRANCH_FETCH_HEAD
= 0x4,
222 BRANCH_LOCAL_F
= BRANCH_LOCAL
| BRANCH_FETCH_HEAD
,
223 BRANCH_ALL
= BRANCH_LOCAL
| BRANCH_REMOTE
,
224 BRANCH_ALL_F
= BRANCH_ALL
| BRANCH_FETCH_HEAD
,
230 LOG_INFO_FILESTATE
=0x2,
232 LOG_INFO_FULLHISTORY
=0x8,
233 LOG_INFO_BOUNDARY
=0x10,
234 LOG_INFO_ALL_BRANCH
=0x20,
235 LOG_INFO_ONLY_HASH
=0x40,
236 LOG_INFO_DETECT_RENAME
=0x80,
237 LOG_INFO_DETECT_COPYRENAME
=0x100,
238 LOG_INFO_FIRST_PARENT
= 0x200,
239 LOG_INFO_NO_MERGE
= 0x400,
240 LOG_INFO_FOLLOW
= 0x800,
241 LOG_INFO_SHOW_MERGEDFILE
=0x1000,
242 LOG_INFO_FULL_DIFF
= 0x2000,
245 int GetRemoteList(STRING_VECTOR
&list
);
246 int GetBranchList(STRING_VECTOR
&list
, int *Current
,BRANCH_TYPE type
=BRANCH_LOCAL
);
247 int GetTagList(STRING_VECTOR
&list
);
248 int GetRemoteTags(CString remote
, STRING_VECTOR
&list
);
249 int GetMapHashToFriendName(MAP_HASH_NAME
&map
);
251 CString
DerefFetchHead();
254 // When branchName == FETCH_HEAD, derefrence it.
255 // A selected branch name got from GetBranchList(), with flag BRANCH_FETCH_HEAD enabled,
256 // should go through this function before it is used.
257 CString
FixBranchName_Mod(CString
& branchName
);
258 CString
FixBranchName(const CString
& branchName
);
260 //hash is empty means all. -1 means all
262 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
,
263 CString
*from
=NULL
,CString
*to
=NULL
);
264 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
,
265 CString
*from
=NULL
,CString
*to
=NULL
);
267 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
,
268 CString
*from
=NULL
,CString
*to
=NULL
, bool paramonly
=false,
269 CFilterData
* filter
=NULL
);
271 CGitHash
GetHash(TCHAR
* friendname
);
272 CGitHash
GetHash(CString ref
){return GetHash(ref
.GetBuffer());}
274 int BuildOutputFormat(CString
&format
,bool IsFull
=TRUE
);
275 //int GetShortLog(const CString &log,CTGitPath * path=NULL, int count =-1);
276 static void StringAppend(CString
*str
,BYTE
*p
,int code
=CP_UTF8
,int length
=-1);
278 BOOL
IsOrphanBranch(CString ref
);
280 int ListConflictFile(CTGitPathList
&list
,CTGitPath
*path
=NULL
);
281 int GetRefList(STRING_VECTOR
&list
);
283 int RefreshGitIndex();
284 int GetOneFile(CString Refname
, CTGitPath
&path
, const CString
&outputfile
);
286 //Example: master -> refs/heads/master
287 CString
GetFullRefName(CString shortRefName
);
288 //Removes 'refs/heads/' or just 'refs'. Example: refs/heads/master -> master
289 static CString
StripRefName(CString refName
);
291 int GetCommitDiffList(const CString
&rev1
,const CString
&rev2
,CTGitPathList
&outpathlist
);
292 int GetInitAddList(CTGitPathList
&outpathlist
);
294 __int64
filetime_to_time_t(const FILETIME
*ft
)
296 long long winTime
= ((long long)ft
->dwHighDateTime
<< 32) + ft
->dwLowDateTime
;
297 winTime
-= 116444736000000000LL; /* Windows to Unix Epoch conversion */
298 winTime
/= 10000000; /* Nano to seconds resolution */
299 return (time_t)winTime
;
302 int GetFileModifyTime(LPCTSTR filename
, __int64
*time
, bool * isDir
=NULL
)
304 WIN32_FILE_ATTRIBUTE_DATA fdata
;
305 if (GetFileAttributesEx(filename
, GetFileExInfoStandard
, &fdata
))
308 *time
= filetime_to_time_t(&fdata
.ftLastWriteTime
);
311 *isDir
= !!( fdata
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
);
318 int GetShortHASHLength();
320 extern void GetTempPath(CString
&path
);
321 extern CString
GetTempFile();