5 #include "registry.h"
\r
7 #define MAX_DIRBUFFER 1000
\r
11 GetCurrentDirectory(MAX_DIRBUFFER,m_CurrentDir.GetBuffer(MAX_DIRBUFFER));
\r
18 static char g_Buffer[4096];
\r
20 int CGit::RunAsync(CString cmd,PROCESS_INFORMATION *piOut,HANDLE *hReadOut,CString *StdioFile)
\r
22 SECURITY_ATTRIBUTES sa;
\r
23 HANDLE hRead, hWrite;
\r
26 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
\r
27 sa.lpSecurityDescriptor=NULL;
\r
28 sa.bInheritHandle=TRUE;
\r
29 if(!CreatePipe(&hRead,&hWrite,&sa,0))
\r
31 return GIT_ERROR_OPEN_PIP;
\r
36 hStdioFile=CreateFile(*StdioFile,GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,
\r
37 &sa,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
\r
41 PROCESS_INFORMATION pi;
\r
42 si.cb=sizeof(STARTUPINFO);
\r
43 GetStartupInfo(&si);
\r
45 si.hStdError=hWrite;
\r
47 si.hStdOutput=hStdioFile;
\r
49 si.hStdOutput=hWrite;
\r
51 si.wShowWindow=SW_HIDE;
\r
52 si.dwFlags=STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
\r
54 if(!CreateProcess(NULL,(LPWSTR)cmd.GetString(), NULL,NULL,TRUE,NULL,NULL,(LPWSTR)m_CurrentDir.GetString(),&si,&pi))
\r
57 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
\r
58 NULL,GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
\r
61 return GIT_ERROR_CREATE_PROCESS;
\r
64 CloseHandle(hWrite);
\r
73 //Must use sperate function to convert ANSI str to union code string
\r
74 //Becuase A2W use stack as internal convert buffer.
\r
75 void CGit::StringAppend(CString *str,char *p)
\r
78 str->Append(A2W_CP(p,CP_UTF8));
\r
81 BOOL CGit::IsInitRepos()
\r
85 if(g_Git.Run(_T("git.exe rev-parse --revs-only HEAD"),&cmdout))
\r
87 // CMessageBox::Show(NULL,cmdout,_T("TortoiseGit"),MB_OK);
\r
90 if(cmdout.IsEmpty())
\r
95 int CGit::Run(CString cmd, CString* output)
\r
97 PROCESS_INFORMATION pi;
\r
99 if(RunAsync(cmd,&pi,&hRead))
\r
100 return GIT_ERROR_CREATE_PROCESS;
\r
103 while(ReadFile(hRead,g_Buffer,1023,&readnumber,NULL))
\r
105 g_Buffer[readnumber]=0;
\r
106 StringAppend(output,g_Buffer);
\r
110 CloseHandle(pi.hThread);
\r
112 WaitForSingleObject(pi.hProcess, INFINITE);
\r
115 if(!GetExitCodeProcess(pi.hProcess,&exitcode))
\r
117 return GIT_ERROR_GET_EXIT_CODE;
\r
120 CloseHandle(pi.hProcess);
\r
122 CloseHandle(hRead);
\r
126 CString CGit::GetUserName(void)
\r
129 Run(_T("git.exe config user.name"),&UserName);
\r
132 CString CGit::GetUserEmail(void)
\r
135 Run(_T("git.exe config user.email"),&UserName);
\r
139 CString CGit::GetCurrentBranch(void)
\r
142 //Run(_T("git.exe branch"),&branch);
\r
144 int ret=g_Git.Run(_T("git.exe branch"),&output);
\r
152 one=output.Tokenize(_T("\n"),pos);
\r
153 //list.push_back(one.Right(one.GetLength()-2));
\r
154 if(one[0] == _T('*'))
\r
155 return one.Right(one.GetLength()-2);
\r
158 return CString("");
\r
161 int CGit::BuildOutputFormat(CString &format,bool IsFull)
\r
164 log.Format(_T("#<%c>%%n"),LOG_REV_ITEM_BEGIN);
\r
168 log.Format(_T("#<%c>%%an%%n"),LOG_REV_AUTHOR_NAME);
\r
170 log.Format(_T("#<%c>%%ae%%n"),LOG_REV_AUTHOR_EMAIL);
\r
172 log.Format(_T("#<%c>%%ai%%n"),LOG_REV_AUTHOR_DATE);
\r
174 log.Format(_T("#<%c>%%cn%%n"),LOG_REV_COMMIT_NAME);
\r
176 log.Format(_T("#<%c>%%ce%%n"),LOG_REV_COMMIT_EMAIL);
\r
178 log.Format(_T("#<%c>%%ci%%n"),LOG_REV_COMMIT_DATE);
\r
180 log.Format(_T("#<%c>%%s%%n"),LOG_REV_COMMIT_SUBJECT);
\r
182 log.Format(_T("#<%c>%%b%%n"),LOG_REV_COMMIT_BODY);
\r
185 log.Format(_T("#<%c>%%m%%H%%n"),LOG_REV_COMMIT_HASH);
\r
187 log.Format(_T("#<%c>%%P%%n"),LOG_REV_COMMIT_PARENT);
\r
192 log.Format(_T("#<%c>%%n"),LOG_REV_COMMIT_FILE);
\r
198 int CGit::GetLog(CString& logOut, CString &hash, CTGitPath *path ,int count,int mask)
\r
209 file.Format(_T(" -- \"%s\""),path->GetGitPathString());
\r
212 num.Format(_T("-n%d"),count);
\r
216 if(mask& LOG_INFO_STAT )
\r
217 param += _T(" --numstat ");
\r
218 if(mask& LOG_INFO_FILESTATE)
\r
219 param += _T(" --raw ");
\r
221 if(mask& LOG_INFO_FULLHISTORY)
\r
222 param += _T(" --full-history ");
\r
224 if(mask& LOG_INFO_BOUNDARY)
\r
225 param += _T("--left-right --boundary ");
\r
229 cmd.Format(_T("git.exe log %s -C --topo-order --parents %s --pretty=format:\""),
\r
232 BuildOutputFormat(log);
\r
234 cmd += CString(_T("\" "))+hash+file;
\r
236 return Run(cmd,&logOut);
\r
240 int CGit::GetShortLog(CString &logOut,CTGitPath * path, int count)
\r
249 cmd.Format(_T("git.exe log --left-right --boundary --topo-order -n%d --pretty=format:\""),n);
\r
250 BuildOutputFormat(log,false);
\r
251 cmd += log+_T("\"");
\r
253 cmd+= _T(" -- \"")+path->GetGitPathString()+_T("\"");
\r
254 //cmd += CString(_T("\" HEAD~40..HEAD"));
\r
255 return Run(cmd,&logOut);
\r
258 #define BUFSIZE 512
\r
259 void GetTempPath(CString &path)
\r
261 TCHAR lpPathBuffer[BUFSIZE];
\r
263 DWORD dwBufSize=BUFSIZE;
\r
264 dwRetVal = GetTempPath(dwBufSize, // length of the buffer
\r
265 lpPathBuffer); // buffer for path
\r
266 if (dwRetVal > dwBufSize || (dwRetVal == 0))
\r
270 path.Format(_T("%s"),lpPathBuffer);
\r
272 CString GetTempFile()
\r
274 TCHAR lpPathBuffer[BUFSIZE];
\r
276 DWORD dwBufSize=BUFSIZE;
\r
277 TCHAR szTempName[BUFSIZE];
\r
280 dwRetVal = GetTempPath(dwBufSize, // length of the buffer
\r
281 lpPathBuffer); // buffer for path
\r
282 if (dwRetVal > dwBufSize || (dwRetVal == 0))
\r
286 // Create a temporary file.
\r
287 uRetVal = GetTempFileName(lpPathBuffer, // directory for tmp files
\r
288 TEXT("Patch"), // temp file name prefix
\r
289 0, // create unique name
\r
290 szTempName); // buffer for name
\r
298 return CString(szTempName);
\r
302 int CGit::RunLogFile(CString cmd,CString &filename)
\r
304 HANDLE hRead, hWrite;
\r
307 PROCESS_INFORMATION pi;
\r
308 si.cb=sizeof(STARTUPINFO);
\r
309 GetStartupInfo(&si);
\r
311 SECURITY_ATTRIBUTES psa={sizeof(psa),NULL,TRUE};;
\r
312 psa.bInheritHandle=TRUE;
\r
314 HANDLE houtfile=CreateFile(filename,GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,
\r
315 &psa,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
\r
318 si.wShowWindow=SW_HIDE;
\r
319 si.dwFlags=STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
\r
320 si.hStdOutput = houtfile;
\r
322 if(!CreateProcess(NULL,(LPWSTR)cmd.GetString(), NULL,NULL,TRUE,NULL,NULL,(LPWSTR)m_CurrentDir.GetString(),&si,&pi))
\r
325 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
\r
326 NULL,GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
\r
329 return GIT_ERROR_CREATE_PROCESS;
\r
332 WaitForSingleObject(pi.hProcess,INFINITE);
\r
334 CloseHandle(pi.hThread);
\r
335 CloseHandle(pi.hProcess);
\r
336 CloseHandle(houtfile);
\r
337 return GIT_SUCCESS;
\r
341 git_revnum_t CGit::GetHash(CString &friendname)
\r
345 cmd.Format(_T("git.exe rev-parse %s" ),friendname);
\r
347 int pos=out.ReverseFind(_T('\n'));
\r
349 return out.Left(pos);
\r
353 int CGit::GetTagList(STRING_VECTOR &list)
\r
356 CString cmd,output;
\r
357 cmd=_T("git.exe tag -l");
\r
359 ret=g_Git.Run(cmd,&output);
\r
367 one=output.Tokenize(_T("\n"),pos);
\r
368 list.push_back(one);
\r
374 int CGit::GetBranchList(STRING_VECTOR &list,int *current,BRANCH_TYPE type)
\r
377 CString cmd,output;
\r
378 cmd=_T("git.exe branch");
\r
380 if(type==(BRANCH_LOCAL|BRANCH_REMOTE))
\r
382 else if(type==BRANCH_REMOTE)
\r
386 ret=g_Git.Run(cmd,&output);
\r
394 one=output.Tokenize(_T("\n"),pos);
\r
395 list.push_back(one.Right(one.GetLength()-2));
\r
396 if(one[0] == _T('*'))
\r
404 int CGit::GetRemoteList(STRING_VECTOR &list)
\r
407 CString cmd,output;
\r
408 cmd=_T("git.exe config --get-regexp remote.*.url");
\r
409 ret=g_Git.Run(cmd,&output);
\r
416 one=output.Tokenize(_T("\n"),pos);
\r
417 int start=one.Find(_T("."),0);
\r
421 url=one.Right(one.GetLength()-start-1);
\r
423 one=one.Left(one.Find(_T("."),0));
\r
424 list.push_back(one);
\r
431 int CGit::GetMapHashToFriendName(MAP_HASH_NAME &map)
\r
434 CString cmd,output;
\r
435 cmd=_T("git show-ref -d");
\r
436 ret=g_Git.Run(cmd,&output);
\r
443 one=output.Tokenize(_T("\n"),pos);
\r
444 int start=one.Find(_T(" "),0);
\r
448 name=one.Right(one.GetLength()-start-1);
\r
451 hash=one.Left(start);
\r
453 map[hash].push_back(name);
\r
460 BOOL CGit::CheckMsysGitDir()
\r
462 CRegString msysdir=CRegString(_T("Software\\TortoiseGit\\MSysGit"),_T(""),FALSE,HKEY_LOCAL_MACHINE);
\r
463 CString str=msysdir;
\r
466 CRegString msysinstalldir=CRegString(_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Git_is1\\InstallLocation"),_T(""),FALSE,HKEY_LOCAL_MACHINE);
\r
467 str=msysinstalldir;
\r
473 //CGit::m_MsysGitPath=str;
\r
475 TCHAR *oldpath,*home;
\r
478 _tdupenv_s(&home,&size,_T("HOME"));
\r
482 _tdupenv_s(&home,&size,_T("USERPROFILE"));
\r
483 _tputenv_s(_T("HOME"),home);
\r
487 _tdupenv_s(&oldpath,&size,_T("PATH"));
\r
490 path.Format(_T("%s;"),str);
\r
493 _tputenv_s(_T("PATH"),path);
\r
498 cmd=_T("git.exe --version");
\r
499 if(g_Git.Run(cmd,&out))
\r