X-Git-Url: http://git.sourceforge.jp/view?p=tortoisegit%2FTortoiseGitJp.git;a=blobdiff_plain;f=src%2FGit%2FGit.cpp;h=58433c2347f75d976e1d6b7b525e6e8aacc9f547;hp=d81542bb5e284f5e6cda65dd95569ce7282ad5d3;hb=27f44321c909484bffb4b0c9e83ca536f98ecb67;hpb=4329a6273f282eb5a5527dabdd294b508e67a64e diff --git a/src/Git/Git.cpp b/src/Git/Git.cpp index d81542b..58433c2 100644 --- a/src/Git/Git.cpp +++ b/src/Git/Git.cpp @@ -3,8 +3,10 @@ #include "atlconv.h" #include "GitRev.h" #include "registry.h" +#include "GitConfig.h" #define MAX_DIRBUFFER 1000 +CString CGit::ms_LastMsysGitDir; CGit g_Git; CGit::CGit(void) { @@ -21,7 +23,7 @@ int CGit::RunAsync(CString cmd,PROCESS_INFORMATION *piOut,HANDLE *hReadOut,CStri { SECURITY_ATTRIBUTES sa; HANDLE hRead, hWrite; - HANDLE hStdioFile; + HANDLE hStdioFile = NULL; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor=NULL; @@ -72,17 +74,32 @@ int CGit::RunAsync(CString cmd,PROCESS_INFORMATION *piOut,HANDLE *hReadOut,CStri } //Must use sperate function to convert ANSI str to union code string //Becuase A2W use stack as internal convert buffer. -void CGit::StringAppend(CString *str,char *p) +void CGit::StringAppend(CString *str,BYTE *p,int code,int length) { - USES_CONVERSION; - str->Append(A2W_CP(p,CP_UTF8)); + //USES_CONVERSION; + //str->Append(A2W_CP((LPCSTR)p,code)); + WCHAR * buf; + int len ; + if(length<0) + len= strlen((const char*)p); + else + len=length; + //if (len==0) + // return ; + //buf = new WCHAR[len*4 + 1]; + buf = str->GetBuffer(len*4+1+str->GetLength())+str->GetLength(); + SecureZeroMemory(buf, (len*4 + 1)*sizeof(WCHAR)); + MultiByteToWideChar(code, 0, (LPCSTR)p, len, buf, len*4); + str->ReleaseBuffer(); + //str->Append(buf); + //delete buf; } BOOL CGit::IsInitRepos() { CString cmdout; cmdout.Empty(); - if(g_Git.Run(_T("git.exe rev-parse --revs-only HEAD"),&cmdout)) + if(g_Git.Run(_T("git.exe rev-parse --revs-only HEAD"),&cmdout,CP_UTF8)) { // CMessageBox::Show(NULL,cmdout,_T("TortoiseGit"),MB_OK); return TRUE; @@ -92,7 +109,7 @@ BOOL CGit::IsInitRepos() return FALSE; } -int CGit::Run(CString cmd, CString* output) +int CGit::Run(CString cmd,BYTE_VECTOR *vector) { PROCESS_INFORMATION pi; HANDLE hRead; @@ -100,10 +117,12 @@ int CGit::Run(CString cmd, CString* output) return GIT_ERROR_CREATE_PROCESS; DWORD readnumber; - while(ReadFile(hRead,g_Buffer,1023,&readnumber,NULL)) + BYTE data; + while(ReadFile(hRead,&data,1,&readnumber,NULL)) { - g_Buffer[readnumber]=0; - StringAppend(output,g_Buffer); + //g_Buffer[readnumber]=0; + vector->push_back(data); +// StringAppend(output,g_Buffer,codes); } @@ -121,18 +140,33 @@ int CGit::Run(CString cmd, CString* output) CloseHandle(hRead); return exitcode; + +} +int CGit::Run(CString cmd, CString* output,int code) +{ + BYTE_VECTOR vector; + int ret; + ret=Run(cmd,&vector); + + if(ret) + return ret; + + vector.push_back(0); + + StringAppend(output,&(vector[0]),code); + return 0; } CString CGit::GetUserName(void) { CString UserName; - Run(_T("git.exe config user.name"),&UserName); + Run(_T("git.exe config user.name"),&UserName,CP_UTF8); return UserName; } CString CGit::GetUserEmail(void) { CString UserName; - Run(_T("git.exe config user.email"),&UserName); + Run(_T("git.exe config user.email"),&UserName,CP_UTF8); return UserName; } @@ -141,7 +175,7 @@ CString CGit::GetCurrentBranch(void) CString output; //Run(_T("git.exe branch"),&branch); - int ret=g_Git.Run(_T("git.exe branch"),&output); + int ret=g_Git.Run(_T("git.exe branch"),&output,CP_UTF8); if(!ret) { int pos=0; @@ -161,41 +195,41 @@ CString CGit::GetCurrentBranch(void) int CGit::BuildOutputFormat(CString &format,bool IsFull) { CString log; - log.Format(_T("#<%c>%%n"),LOG_REV_ITEM_BEGIN); + log.Format(_T("#<%c>%%x00"),LOG_REV_ITEM_BEGIN); format += log; if(IsFull) { - log.Format(_T("#<%c>%%an%%n"),LOG_REV_AUTHOR_NAME); + log.Format(_T("#<%c>%%an%%x00"),LOG_REV_AUTHOR_NAME); format += log; - log.Format(_T("#<%c>%%ae%%n"),LOG_REV_AUTHOR_EMAIL); + log.Format(_T("#<%c>%%ae%%x00"),LOG_REV_AUTHOR_EMAIL); format += log; - log.Format(_T("#<%c>%%ai%%n"),LOG_REV_AUTHOR_DATE); + log.Format(_T("#<%c>%%ai%%x00"),LOG_REV_AUTHOR_DATE); format += log; - log.Format(_T("#<%c>%%cn%%n"),LOG_REV_COMMIT_NAME); + log.Format(_T("#<%c>%%cn%%x00"),LOG_REV_COMMIT_NAME); format += log; - log.Format(_T("#<%c>%%ce%%n"),LOG_REV_COMMIT_EMAIL); + log.Format(_T("#<%c>%%ce%%x00"),LOG_REV_COMMIT_EMAIL); format += log; - log.Format(_T("#<%c>%%ci%%n"),LOG_REV_COMMIT_DATE); + log.Format(_T("#<%c>%%ci%%x00"),LOG_REV_COMMIT_DATE); format += log; - log.Format(_T("#<%c>%%s%%n"),LOG_REV_COMMIT_SUBJECT); + log.Format(_T("#<%c>%%s%%x00"),LOG_REV_COMMIT_SUBJECT); format += log; - log.Format(_T("#<%c>%%b%%n"),LOG_REV_COMMIT_BODY); + log.Format(_T("#<%c>%%b%%x00"),LOG_REV_COMMIT_BODY); format += log; } - log.Format(_T("#<%c>%%m%%H%%n"),LOG_REV_COMMIT_HASH); + log.Format(_T("#<%c>%%m%%H%%x00"),LOG_REV_COMMIT_HASH); format += log; - log.Format(_T("#<%c>%%P%%n"),LOG_REV_COMMIT_PARENT); + log.Format(_T("#<%c>%%P%%x00"),LOG_REV_COMMIT_PARENT); format += log; if(IsFull) { - log.Format(_T("#<%c>%%n"),LOG_REV_COMMIT_FILE); + log.Format(_T("#<%c>%%x00"),LOG_REV_COMMIT_FILE); format += log; } return 0; } -int CGit::GetLog(CString& logOut, CString &hash, CTGitPath *path ,int count,int mask) +int CGit::GetLog(BYTE_VECTOR& logOut, CString &hash, CTGitPath *path ,int count,int mask) { CString cmd; @@ -233,9 +267,18 @@ int CGit::GetLog(CString& logOut, CString &hash, CTGitPath *path ,int count,int if(mask& CGit::LOG_INFO_DETECT_RENAME ) param += _T(" -M "); + if(mask& CGit::LOG_INFO_FIRST_PARENT ) + param += _T(" --first-parent "); + + if(mask& CGit::LOG_INFO_NO_MERGE ) + param += _T(" --no-merges "); + + if(mask& CGit::LOG_INFO_FOLLOW) + param += _T(" --follow "); + param+=hash; - cmd.Format(_T("git.exe log %s --topo-order --parents %s --pretty=format:\""), + cmd.Format(_T("git.exe log %s -z --topo-order %s --parents --pretty=format:\""), num,param); BuildOutputFormat(log,!(mask&CGit::LOG_INFO_ONLY_HASH)); @@ -312,8 +355,6 @@ CString GetTempFile() int CGit::RunLogFile(CString cmd,CString &filename) { - HANDLE hRead, hWrite; - STARTUPINFO si; PROCESS_INFORMATION pi; si.cb=sizeof(STARTUPINFO); @@ -354,7 +395,7 @@ git_revnum_t CGit::GetHash(CString &friendname) CString cmd; CString out; cmd.Format(_T("git.exe rev-parse %s" ),friendname); - Run(cmd,&out); + Run(cmd,&out,CP_UTF8); int pos=out.ReverseFind(_T('\n')); if(pos>0) return out.Left(pos); @@ -367,7 +408,7 @@ int CGit::GetTagList(STRING_VECTOR &list) CString cmd,output; cmd=_T("git.exe tag -l"); int i=0; - ret=g_Git.Run(cmd,&output); + ret=g_Git.Run(cmd,&output,CP_UTF8); if(!ret) { int pos=0; @@ -394,7 +435,7 @@ int CGit::GetBranchList(STRING_VECTOR &list,int *current,BRANCH_TYPE type) cmd+=_T(" -r"); int i=0; - ret=g_Git.Run(cmd,&output); + ret=g_Git.Run(cmd,&output,CP_UTF8); if(!ret) { int pos=0; @@ -417,7 +458,7 @@ int CGit::GetRemoteList(STRING_VECTOR &list) int ret; CString cmd,output; cmd=_T("git.exe config --get-regexp remote.*.url"); - ret=g_Git.Run(cmd,&output); + ret=g_Git.Run(cmd,&output,CP_UTF8); if(!ret) { int pos=0; @@ -444,7 +485,7 @@ int CGit::GetMapHashToFriendName(MAP_HASH_NAME &map) int ret; CString cmd,output; cmd=_T("git show-ref -d"); - ret=g_Git.Run(cmd,&output); + ret=g_Git.Run(cmd,&output,CP_UTF8); if(!ret) { int pos=0; @@ -470,13 +511,18 @@ int CGit::GetMapHashToFriendName(MAP_HASH_NAME &map) BOOL CGit::CheckMsysGitDir() { - CRegString msysdir=CRegString(_T("Software\\TortoiseGit\\MSysGit"),_T(""),FALSE,HKEY_LOCAL_MACHINE); + CRegString msysdir=CRegString(REG_MSYSGIT_PATH,_T(""),FALSE,HKEY_LOCAL_MACHINE); CString str=msysdir; if(str.IsEmpty()) { - CRegString msysinstalldir=CRegString(_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Git_is1\\InstallLocation"),_T(""),FALSE,HKEY_LOCAL_MACHINE); + CRegString msysinstalldir=CRegString(REG_MSYSGIT_INSTALL,_T(""),FALSE,HKEY_LOCAL_MACHINE); str=msysinstalldir; - str+="\\bin"; + // check it has a trailing blank + if (str.Right(1) != _T("\\")) + { + str += _T("\\"); + } + str+=_T("bin"); msysdir=str; msysdir.write(); @@ -492,22 +538,41 @@ BOOL CGit::CheckMsysGitDir() { _tdupenv_s(&home,&size,_T("USERPROFILE")); _tputenv_s(_T("HOME"),home); - free(home); } + free(home); + //set path _tdupenv_s(&oldpath,&size,_T("PATH")); CString path; + CString unterminated_path = str; // path to msysgit without semicolon + CString oldpath_s = oldpath; path.Format(_T("%s;"),str); - path+=oldpath; - - _tputenv_s(_T("PATH"),path); - + // check msysgit not already in path + if ( oldpath_s.Find( path ) < 0 && oldpath_s.Right( unterminated_path.GetLength() ) != unterminated_path ) + { + // not already there, see if we have to take out one we added last time + if ( ms_LastMsysGitDir != _T("") ) + { + // we have added one so take it out + int index = oldpath_s.Find( ms_LastMsysGitDir ); + if ( index >= 0 ) + { + oldpath_s = oldpath_s.Left( index ) + + oldpath_s.Right( oldpath_s.GetLength() - (index+ms_LastMsysGitDir.GetLength()) ); + } + } + // save the new msysdir path that we are about to add + ms_LastMsysGitDir = path; + // add the new one on the front of the existing path + path+=oldpath_s; + _tputenv_s(_T("PATH"),path); + } free(oldpath); CString cmd,out; cmd=_T("git.exe --version"); - if(g_Git.Run(cmd,&out)) + if(g_Git.Run(cmd,&out,CP_UTF8)) { return false; }