8 #define MAX_DIRBUFFER 1000
12 GetCurrentDirectory(MAX_DIRBUFFER
,m_CurrentDir
.GetBuffer(MAX_DIRBUFFER
));
19 static char g_Buffer
[4096];
21 int CGit::RunAsync(CString cmd
,PROCESS_INFORMATION
*piOut
,HANDLE
*hReadOut
,CString
*StdioFile
)
23 SECURITY_ATTRIBUTES sa
;
27 sa
.nLength
= sizeof(SECURITY_ATTRIBUTES
);
28 sa
.lpSecurityDescriptor
=NULL
;
29 sa
.bInheritHandle
=TRUE
;
30 if(!CreatePipe(&hRead
,&hWrite
,&sa
,0))
32 return GIT_ERROR_OPEN_PIP
;
37 hStdioFile
=CreateFile(*StdioFile
,GENERIC_WRITE
,FILE_SHARE_READ
| FILE_SHARE_WRITE
,
38 &sa
,CREATE_ALWAYS
,FILE_ATTRIBUTE_NORMAL
,NULL
);
42 PROCESS_INFORMATION pi
;
43 si
.cb
=sizeof(STARTUPINFO
);
48 si
.hStdOutput
=hStdioFile
;
52 si
.wShowWindow
=SW_HIDE
;
53 si
.dwFlags
=STARTF_USESTDHANDLES
|STARTF_USESHOWWINDOW
;
55 if(!CreateProcess(NULL
,(LPWSTR
)cmd
.GetString(), NULL
,NULL
,TRUE
,NULL
,NULL
,(LPWSTR
)m_CurrentDir
.GetString(),&si
,&pi
))
58 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
|FORMAT_MESSAGE_FROM_SYSTEM
,
59 NULL
,GetLastError(),MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
62 return GIT_ERROR_CREATE_PROCESS
;
74 //Must use sperate function to convert ANSI str to union code string
75 //Becuase A2W use stack as internal convert buffer.
76 void CGit::StringAppend(CString
*str
,BYTE
*p
,int code
)
79 str
->Append(A2W_CP((LPCSTR
)p
,code
));
82 BOOL
CGit::IsInitRepos()
86 if(g_Git
.Run(_T("git.exe rev-parse --revs-only HEAD"),&cmdout
,CP_UTF8
))
88 // CMessageBox::Show(NULL,cmdout,_T("TortoiseGit"),MB_OK);
96 int CGit::Run(CString cmd
,BYTE_VECTOR
*vector
)
98 PROCESS_INFORMATION pi
;
100 if(RunAsync(cmd
,&pi
,&hRead
))
101 return GIT_ERROR_CREATE_PROCESS
;
105 while(ReadFile(hRead
,&data
,1,&readnumber
,NULL
))
107 //g_Buffer[readnumber]=0;
108 vector
->push_back(data
);
109 // StringAppend(output,g_Buffer,codes);
113 CloseHandle(pi
.hThread
);
115 WaitForSingleObject(pi
.hProcess
, INFINITE
);
118 if(!GetExitCodeProcess(pi
.hProcess
,&exitcode
))
120 return GIT_ERROR_GET_EXIT_CODE
;
123 CloseHandle(pi
.hProcess
);
129 int CGit::Run(CString cmd
, CString
* output
,int code
)
133 ret
=Run(cmd
,&vector
);
139 StringAppend(output
,&(vector
[0]),code
);
143 CString
CGit::GetUserName(void)
146 Run(_T("git.exe config user.name"),&UserName
,CP_UTF8
);
149 CString
CGit::GetUserEmail(void)
152 Run(_T("git.exe config user.email"),&UserName
,CP_UTF8
);
156 CString
CGit::GetCurrentBranch(void)
159 //Run(_T("git.exe branch"),&branch);
161 int ret
=g_Git
.Run(_T("git.exe branch"),&output
,CP_UTF8
);
169 one
=output
.Tokenize(_T("\n"),pos
);
170 //list.push_back(one.Right(one.GetLength()-2));
171 if(one
[0] == _T('*'))
172 return one
.Right(one
.GetLength()-2);
178 int CGit::BuildOutputFormat(CString
&format
,bool IsFull
)
181 log
.Format(_T("#<%c>%%x00"),LOG_REV_ITEM_BEGIN
);
185 log
.Format(_T("#<%c>%%an%%x00"),LOG_REV_AUTHOR_NAME
);
187 log
.Format(_T("#<%c>%%ae%%x00"),LOG_REV_AUTHOR_EMAIL
);
189 log
.Format(_T("#<%c>%%ai%%x00"),LOG_REV_AUTHOR_DATE
);
191 log
.Format(_T("#<%c>%%cn%%x00"),LOG_REV_COMMIT_NAME
);
193 log
.Format(_T("#<%c>%%ce%%x00"),LOG_REV_COMMIT_EMAIL
);
195 log
.Format(_T("#<%c>%%ci%%x00"),LOG_REV_COMMIT_DATE
);
197 log
.Format(_T("#<%c>%%s%%x00"),LOG_REV_COMMIT_SUBJECT
);
199 log
.Format(_T("#<%c>%%b%%x00"),LOG_REV_COMMIT_BODY
);
202 log
.Format(_T("#<%c>%%m%%H%%x00"),LOG_REV_COMMIT_HASH
);
204 log
.Format(_T("#<%c>%%P%%x00"),LOG_REV_COMMIT_PARENT
);
209 log
.Format(_T("#<%c>%%x00"),LOG_REV_COMMIT_FILE
);
215 int CGit::GetLog(BYTE_VECTOR
& logOut
, CString
&hash
, CTGitPath
*path
,int count
,int mask
)
226 file
.Format(_T(" -- \"%s\""),path
->GetGitPathString());
229 num
.Format(_T("-n%d"),count
);
233 if(mask
& LOG_INFO_STAT
)
234 param
+= _T(" --numstat ");
235 if(mask
& LOG_INFO_FILESTATE
)
236 param
+= _T(" --raw ");
238 if(mask
& LOG_INFO_FULLHISTORY
)
239 param
+= _T(" --full-history ");
241 if(mask
& LOG_INFO_BOUNDARY
)
242 param
+= _T(" --left-right --boundary ");
244 if(mask
& CGit::LOG_INFO_ALL_BRANCH
)
245 param
+= _T(" --all ");
247 if(mask
& CGit::LOG_INFO_DETECT_COPYRENAME
)
250 if(mask
& CGit::LOG_INFO_DETECT_RENAME
)
255 cmd
.Format(_T("git.exe log %s -z --topo-order --parents %s --pretty=format:\""),
258 BuildOutputFormat(log
,!(mask
&CGit::LOG_INFO_ONLY_HASH
));
261 cmd
+= CString(_T("\" "))+hash
+file
;
263 return Run(cmd
,&logOut
);
267 int CGit::GetShortLog(CString
&logOut
,CTGitPath
* path
, int count
)
276 cmd
.Format(_T("git.exe log --left-right --boundary --topo-order -n%d --pretty=format:\""),n
);
277 BuildOutputFormat(log
,false);
280 cmd
+= _T(" -- \"")+path
->GetGitPathString()+_T("\"");
281 //cmd += CString(_T("\" HEAD~40..HEAD"));
282 return Run(cmd
,&logOut
);
287 void GetTempPath(CString
&path
)
289 TCHAR lpPathBuffer
[BUFSIZE
];
291 DWORD dwBufSize
=BUFSIZE
;
292 dwRetVal
= GetTempPath(dwBufSize
, // length of the buffer
293 lpPathBuffer
); // buffer for path
294 if (dwRetVal
> dwBufSize
|| (dwRetVal
== 0))
298 path
.Format(_T("%s"),lpPathBuffer
);
300 CString
GetTempFile()
302 TCHAR lpPathBuffer
[BUFSIZE
];
304 DWORD dwBufSize
=BUFSIZE
;
305 TCHAR szTempName
[BUFSIZE
];
308 dwRetVal
= GetTempPath(dwBufSize
, // length of the buffer
309 lpPathBuffer
); // buffer for path
310 if (dwRetVal
> dwBufSize
|| (dwRetVal
== 0))
314 // Create a temporary file.
315 uRetVal
= GetTempFileName(lpPathBuffer
, // directory for tmp files
316 TEXT("Patch"), // temp file name prefix
317 0, // create unique name
318 szTempName
); // buffer for name
326 return CString(szTempName
);
330 int CGit::RunLogFile(CString cmd
,CString
&filename
)
332 HANDLE hRead
, hWrite
;
335 PROCESS_INFORMATION pi
;
336 si
.cb
=sizeof(STARTUPINFO
);
339 SECURITY_ATTRIBUTES psa
={sizeof(psa
),NULL
,TRUE
};;
340 psa
.bInheritHandle
=TRUE
;
342 HANDLE houtfile
=CreateFile(filename
,GENERIC_WRITE
,FILE_SHARE_READ
| FILE_SHARE_WRITE
,
343 &psa
,CREATE_ALWAYS
,FILE_ATTRIBUTE_NORMAL
,NULL
);
346 si
.wShowWindow
=SW_HIDE
;
347 si
.dwFlags
=STARTF_USESTDHANDLES
|STARTF_USESHOWWINDOW
;
348 si
.hStdOutput
= houtfile
;
350 if(!CreateProcess(NULL
,(LPWSTR
)cmd
.GetString(), NULL
,NULL
,TRUE
,NULL
,NULL
,(LPWSTR
)m_CurrentDir
.GetString(),&si
,&pi
))
353 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
|FORMAT_MESSAGE_FROM_SYSTEM
,
354 NULL
,GetLastError(),MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
357 return GIT_ERROR_CREATE_PROCESS
;
360 WaitForSingleObject(pi
.hProcess
,INFINITE
);
362 CloseHandle(pi
.hThread
);
363 CloseHandle(pi
.hProcess
);
364 CloseHandle(houtfile
);
369 git_revnum_t
CGit::GetHash(CString
&friendname
)
373 cmd
.Format(_T("git.exe rev-parse %s" ),friendname
);
374 Run(cmd
,&out
,CP_UTF8
);
375 int pos
=out
.ReverseFind(_T('\n'));
377 return out
.Left(pos
);
381 int CGit::GetTagList(STRING_VECTOR
&list
)
385 cmd
=_T("git.exe tag -l");
387 ret
=g_Git
.Run(cmd
,&output
,CP_UTF8
);
395 one
=output
.Tokenize(_T("\n"),pos
);
402 int CGit::GetBranchList(STRING_VECTOR
&list
,int *current
,BRANCH_TYPE type
)
406 cmd
=_T("git.exe branch");
408 if(type
==(BRANCH_LOCAL
|BRANCH_REMOTE
))
410 else if(type
==BRANCH_REMOTE
)
414 ret
=g_Git
.Run(cmd
,&output
,CP_UTF8
);
422 one
=output
.Tokenize(_T("\n"),pos
);
423 list
.push_back(one
.Right(one
.GetLength()-2));
424 if(one
[0] == _T('*'))
432 int CGit::GetRemoteList(STRING_VECTOR
&list
)
436 cmd
=_T("git.exe config --get-regexp remote.*.url");
437 ret
=g_Git
.Run(cmd
,&output
,CP_UTF8
);
444 one
=output
.Tokenize(_T("\n"),pos
);
445 int start
=one
.Find(_T("."),0);
449 url
=one
.Right(one
.GetLength()-start
-1);
451 one
=one
.Left(one
.Find(_T("."),0));
459 int CGit::GetMapHashToFriendName(MAP_HASH_NAME
&map
)
463 cmd
=_T("git show-ref -d");
464 ret
=g_Git
.Run(cmd
,&output
,CP_UTF8
);
471 one
=output
.Tokenize(_T("\n"),pos
);
472 int start
=one
.Find(_T(" "),0);
476 name
=one
.Right(one
.GetLength()-start
-1);
479 hash
=one
.Left(start
);
481 map
[hash
].push_back(name
);
488 BOOL
CGit::CheckMsysGitDir()
490 CRegString msysdir
=CRegString(REG_MSYSGIT_PATH
,_T(""),FALSE
,HKEY_LOCAL_MACHINE
);
494 CRegString msysinstalldir
=CRegString(REG_MSYSGIT_INSTALL
,_T(""),FALSE
,HKEY_LOCAL_MACHINE
);
501 //CGit::m_MsysGitPath=str;
503 TCHAR
*oldpath
,*home
;
506 _tdupenv_s(&home
,&size
,_T("HOME"));
510 _tdupenv_s(&home
,&size
,_T("USERPROFILE"));
511 _tputenv_s(_T("HOME"),home
);
515 _tdupenv_s(&oldpath
,&size
,_T("PATH"));
518 path
.Format(_T("%s;"),str
);
521 _tputenv_s(_T("PATH"),path
);
526 cmd
=_T("git.exe --version");
527 if(g_Git
.Run(cmd
,&out
,CP_UTF8
))