OSDN Git Service

Use -z parser at gitlog
authorFrank Li <lznuaa@gmail.com>
Wed, 21 Jan 2009 06:27:55 +0000 (14:27 +0800)
committerFrank Li <lznuaa@gmail.com>
Wed, 21 Jan 2009 06:27:55 +0000 (14:27 +0800)
22 files changed:
src/Git/Git.cpp
src/Git/Git.h
src/Git/Git.vcproj
src/Git/GitRev.cpp
src/Git/GitRev.h
src/Git/GitStatusListCtrl.cpp
src/Git/TGitPath.cpp
src/Git/TGitPath.h
src/Git/gittype.h [new file with mode: 0644]
src/TortoiseGitBlame/TortoiseGitBlameDoc.cpp
src/TortoiseProc/AppUtils.cpp
src/TortoiseProc/Commands/CreateRepositoryCommand.h
src/TortoiseProc/Commands/FormatPatchCommand.cpp
src/TortoiseProc/Commands/ImportPatchCommand.cpp
src/TortoiseProc/Commands/MergeCommand.cpp
src/TortoiseProc/Commands/RemoveCommand.cpp
src/TortoiseProc/Commands/RenameCommand.cpp
src/TortoiseProc/Commands/RevertCommand.cpp
src/TortoiseProc/CommitDlg.cpp
src/TortoiseProc/FileDiffDlg.cpp
src/TortoiseProc/GitDiff.cpp
src/TortoiseProc/LogDataVector.cpp

index d81542b..1a4562d 100644 (file)
@@ -72,17 +72,17 @@ int CGit::RunAsync(CString cmd,PROCESS_INFORMATION *piOut,HANDLE *hReadOut,CStri
 }\r
 //Must use sperate function to convert ANSI str to union code string\r
 //Becuase A2W use stack as internal convert buffer. \r
-void CGit::StringAppend(CString *str,char *p)\r
+void CGit::StringAppend(CString *str,BYTE *p,int code)\r
 {\r
        USES_CONVERSION;\r
-       str->Append(A2W_CP(p,CP_UTF8));\r
+       str->Append(A2W_CP((LPCSTR)p,code));\r
 \r
 }      \r
 BOOL CGit::IsInitRepos()\r
 {\r
        CString cmdout;\r
        cmdout.Empty();\r
-       if(g_Git.Run(_T("git.exe rev-parse --revs-only HEAD"),&cmdout))\r
+       if(g_Git.Run(_T("git.exe rev-parse --revs-only HEAD"),&cmdout,CP_UTF8))\r
        {\r
        //      CMessageBox::Show(NULL,cmdout,_T("TortoiseGit"),MB_OK);\r
                return TRUE;\r
@@ -92,7 +92,7 @@ BOOL CGit::IsInitRepos()
 \r
        return FALSE;\r
 }\r
-int CGit::Run(CString cmd, CString* output)\r
+int CGit::Run(CString cmd,BYTE_VECTOR *vector)\r
 {\r
        PROCESS_INFORMATION pi;\r
        HANDLE hRead;\r
@@ -100,10 +100,12 @@ int CGit::Run(CString cmd, CString* output)
                return GIT_ERROR_CREATE_PROCESS;\r
 \r
        DWORD readnumber;\r
-       while(ReadFile(hRead,g_Buffer,1023,&readnumber,NULL))\r
+       BYTE data;\r
+       while(ReadFile(hRead,&data,1,&readnumber,NULL))\r
        {\r
-               g_Buffer[readnumber]=0;\r
-               StringAppend(output,g_Buffer);\r
+               //g_Buffer[readnumber]=0;\r
+               vector->push_back(data);\r
+//             StringAppend(output,g_Buffer,codes);\r
        }\r
 \r
        \r
@@ -121,18 +123,26 @@ int CGit::Run(CString cmd, CString* output)
 \r
        CloseHandle(hRead);\r
        return exitcode;\r
+\r
+}\r
+int CGit::Run(CString cmd, CString* output,int code)\r
+{\r
+       BYTE_VECTOR vector;\r
+       Run(cmd,&vector);\r
+       StringAppend(output,&(vector[0]),code);\r
+       return 0;\r
 }\r
 \r
 CString CGit::GetUserName(void)\r
 {\r
        CString UserName;\r
-       Run(_T("git.exe config user.name"),&UserName);\r
+       Run(_T("git.exe config user.name"),&UserName,CP_UTF8);\r
        return UserName;\r
 }\r
 CString CGit::GetUserEmail(void)\r
 {\r
        CString UserName;\r
-       Run(_T("git.exe config user.email"),&UserName);\r
+       Run(_T("git.exe config user.email"),&UserName,CP_UTF8);\r
        return UserName;\r
 }\r
 \r
@@ -141,7 +151,7 @@ CString CGit::GetCurrentBranch(void)
        CString output;\r
        //Run(_T("git.exe branch"),&branch);\r
 \r
-       int ret=g_Git.Run(_T("git.exe branch"),&output);\r
+       int ret=g_Git.Run(_T("git.exe branch"),&output,CP_UTF8);\r
        if(!ret)\r
        {               \r
                int pos=0;\r
@@ -195,7 +205,7 @@ int CGit::BuildOutputFormat(CString &format,bool IsFull)
        return 0;\r
 }\r
 \r
-int CGit::GetLog(CString& logOut, CString &hash,  CTGitPath *path ,int count,int mask)\r
+int CGit::GetLog(BYTE_VECTOR& logOut, CString &hash,  CTGitPath *path ,int count,int mask)\r
 {\r
 \r
        CString cmd;\r
@@ -235,7 +245,7 @@ int CGit::GetLog(CString& logOut, CString &hash,  CTGitPath *path ,int count,int
 \r
        param+=hash;\r
 \r
-       cmd.Format(_T("git.exe log %s --topo-order --parents %s --pretty=format:\""),\r
+       cmd.Format(_T("git.exe log %s -z --topo-order --parents %s --pretty=format:\""),\r
                                num,param);\r
 \r
        BuildOutputFormat(log,!(mask&CGit::LOG_INFO_ONLY_HASH));\r
@@ -354,7 +364,7 @@ git_revnum_t CGit::GetHash(CString &friendname)
        CString cmd;\r
        CString out;\r
        cmd.Format(_T("git.exe rev-parse %s" ),friendname);\r
-       Run(cmd,&out);\r
+       Run(cmd,&out,CP_UTF8);\r
        int pos=out.ReverseFind(_T('\n'));\r
        if(pos>0)\r
                return out.Left(pos);\r
@@ -367,7 +377,7 @@ int CGit::GetTagList(STRING_VECTOR &list)
        CString cmd,output;\r
        cmd=_T("git.exe tag -l");\r
        int i=0;\r
-       ret=g_Git.Run(cmd,&output);\r
+       ret=g_Git.Run(cmd,&output,CP_UTF8);\r
        if(!ret)\r
        {               \r
                int pos=0;\r
@@ -394,7 +404,7 @@ int CGit::GetBranchList(STRING_VECTOR &list,int *current,BRANCH_TYPE type)
                cmd+=_T(" -r");\r
 \r
        int i=0;\r
-       ret=g_Git.Run(cmd,&output);\r
+       ret=g_Git.Run(cmd,&output,CP_UTF8);\r
        if(!ret)\r
        {               \r
                int pos=0;\r
@@ -417,7 +427,7 @@ int CGit::GetRemoteList(STRING_VECTOR &list)
        int ret;\r
        CString cmd,output;\r
        cmd=_T("git.exe config  --get-regexp remote.*.url");\r
-       ret=g_Git.Run(cmd,&output);\r
+       ret=g_Git.Run(cmd,&output,CP_UTF8);\r
        if(!ret)\r
        {\r
                int pos=0;\r
@@ -444,7 +454,7 @@ int CGit::GetMapHashToFriendName(MAP_HASH_NAME &map)
        int ret;\r
        CString cmd,output;\r
        cmd=_T("git show-ref -d");\r
-       ret=g_Git.Run(cmd,&output);\r
+       ret=g_Git.Run(cmd,&output,CP_UTF8);\r
        if(!ret)\r
        {\r
                int pos=0;\r
@@ -507,7 +517,7 @@ BOOL CGit::CheckMsysGitDir()
 \r
        CString cmd,out;\r
        cmd=_T("git.exe --version");\r
-       if(g_Git.Run(cmd,&out))\r
+       if(g_Git.Run(cmd,&out,CP_UTF8))\r
        {\r
                return false;\r
        }\r
index b9da969..b7bde0c 100644 (file)
@@ -1,17 +1,8 @@
 #pragma once\r
+#include "GitType.h"\r
 #include "GitRev.h"\r
 #include "GitStatus.h"\r
 #include "GitAdminDir.h"\r
-enum\r
-{\r
-       GIT_SUCCESS=0,\r
-       GIT_ERROR_OPEN_PIP,\r
-       GIT_ERROR_CREATE_PROCESS,\r
-       GIT_ERROR_GET_EXIT_CODE\r
-};\r
-\r
-typedef std::vector<CString> STRING_VECTOR;\r
-typedef std::map<CString, STRING_VECTOR> MAP_HASH_NAME;\r
 \r
 \r
 class CGit\r
@@ -24,7 +15,10 @@ public:
 //     static CString m_MsysGitPath;\r
        CGit(void);\r
        ~CGit(void);\r
-       int Run(CString cmd, CString* output);\r
+       \r
+       int Run(CString cmd, CString* output,int code);\r
+       int Run(CString cmd, BYTE_VECTOR *byte_array);\r
+\r
        int RunAsync(CString cmd,PROCESS_INFORMATION *pi, HANDLE* hRead, CString *StdioFile=NULL);\r
        int RunLogFile(CString cmd, CString &filename);\r
        CString GetUserName(void);\r
@@ -63,13 +57,13 @@ public:
        int GetMapHashToFriendName(MAP_HASH_NAME &map);\r
        \r
        //hash is empty means all. -1 means all\r
-       int GetLog(CString& logOut,CString &hash, CTGitPath *path = NULL,int count=-1,int InfoMask=LOG_INFO_STAT|LOG_INFO_FILESTATE|LOG_INFO_BOUNDARY|LOG_INFO_DETECT_COPYRENAME);\r
+       int GetLog(BYTE_VECTOR& logOut,CString &hash, CTGitPath *path = NULL,int count=-1,int InfoMask=LOG_INFO_STAT|LOG_INFO_FILESTATE|LOG_INFO_BOUNDARY|LOG_INFO_DETECT_COPYRENAME);\r
 \r
        git_revnum_t GetHash(CString &friendname);\r
 \r
        int BuildOutputFormat(CString &format,bool IsFull=TRUE);\r
        //int GetShortLog(CString &log,CTGitPath * path=NULL, int count =-1);\r
-       static void StringAppend(CString *str,char *p);\r
+       static void StringAppend(CString *str,BYTE *p,int code=CP_UTF8);\r
 \r
        BOOL IsInitRepos();\r
        \r
index 0a1be56..109a36e 100644 (file)
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath=".\gittype.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath=".\stdafx.h"\r
                                >\r
                        </File>\r
index d5e9edb..ba9526f 100644 (file)
@@ -53,29 +53,35 @@ int GitRev::CopyFrom(GitRev &rev)
        m_Mark                  =rev.m_Mark;\r
        return 0;\r
 }\r
-int GitRev::ParserFromLog(CString &log)\r
+int GitRev::ParserFromLog(BYTE_VECTOR &log,int start)\r
 {\r
-       int pos=0;\r
+       int pos=start;\r
        CString one;\r
        CString key;\r
        CString text;\r
-       CString filelist;\r
-       TCHAR mode=0;\r
+       BYTE_VECTOR filelist;\r
+       BYTE mode=0;\r
        CTGitPath  path;\r
        this->m_Files.Clear();\r
     m_Action=0;\r
-\r
-       while( pos>=0 )\r
+       int begintime=0;\r
+       while( pos <= log.size() && pos>0)\r
        {\r
-               one=log.Tokenize(_T("\n"),pos);\r
-               if(one[0]==_T('#') && one[1] == _T('<') && one[3] == _T('>'))\r
+               if(begintime>1)\r
+                       break;\r
+               //one=log.Tokenize(_T("\n"),pos);\r
+               if(log[pos]==_T('#') && log[pos+1] == _T('<') && log[pos+3] == _T('>'))\r
                {\r
-                       text = one.Right(one.GetLength()-4);\r
-                       mode = one[2];\r
+                       //text = one.Right(one.GetLength()-4);\r
+                       text.Empty();\r
+                       g_Git.StringAppend(&text,&log[pos+4],CP_UTF8);\r
+                       mode = log[pos+2];\r
+\r
                        switch(mode)\r
                        {\r
                        case LOG_REV_ITEM_BEGIN:\r
                                this->Clear();\r
+                               begintime++;\r
                                break;\r
                        case LOG_REV_AUTHOR_NAME:\r
                                this->m_AuthorName = text;\r
@@ -125,14 +131,16 @@ int GitRev::ParserFromLog(CString &log)
                {\r
                        switch(mode)\r
                        {\r
-                       case LOG_REV_COMMIT_BODY:\r
-                               this->m_Body += one+_T("\n");\r
-                               break;\r
+//                     case LOG_REV_COMMIT_BODY:\r
+//                             this->m_Body += one+_T("\n");\r
+//                             break;\r
                        case LOG_REV_COMMIT_FILE:\r
-                               filelist += one +_T("\n");\r
+                               //filelist += one +_T("\n");\r
+                               filelist.append(log,pos,log.find(0,pos));                               \r
                                break;\r
                        }\r
                }\r
+               pos=log.find(0,pos);\r
        }\r
        \r
        this->m_Files.ParserFromLog(filelist);\r
@@ -157,7 +165,7 @@ int GitRev::SafeFetchFullInfo(CGit *git)
        if(InterlockedExchange(&m_IsUpdateing,TRUE) == FALSE)\r
        {\r
                //GitRev rev;\r
-               CString onelog;\r
+               BYTE_VECTOR onelog;\r
                TCHAR oldmark=this->m_Mark;\r
        \r
                git->GetLog(onelog,m_CommitHash,NULL,1,CGit::LOG_INFO_STAT|CGit::LOG_INFO_FILESTATE|CGit::LOG_INFO_DETECT_COPYRENAME);\r
index 84ca319..45f3755 100644 (file)
@@ -1,4 +1,5 @@
 #pragma once\r
+#include "gittype.h"\r
 #include "GitStatus.h"\r
 #include "AtlTime.h"\r
 \r
@@ -58,7 +59,7 @@ public:
        BOOL IsBoundary(){return m_Mark == _T('-');}\r
 \r
        void Clear();\r
-       int ParserFromLog(CString &log);\r
+       int ParserFromLog(BYTE_VECTOR &log,int start=0);\r
        CTime ConverFromString(CString input);\r
        inline int ParentsCount(){return m_ParentHash.size();}\r
        \r
index 1055bb3..20be5b8 100644 (file)
@@ -301,6 +301,7 @@ BOOL CGitStatusListCtrl::GetStatus ( const CTGitPathList& pathList
                mask|= CGitStatusListCtrl::FILELIST_UNVER;\r
        this->UpdateFileList(mask,bUpdate,(CTGitPathList*)&pathList);\r
 \r
+\r
 #if 0\r
        \r
        int refetchcounter = 0;\r
@@ -2713,7 +2714,7 @@ void CGitStatusListCtrl::OnContextMenuList(CWnd * pWnd, CPoint point)
                                                CString cmd;\r
                                                cmd.Format(_T("git.exe add %s"),path->GetGitPathString());\r
                                                CString output;\r
-                                               if(!g_Git.Run(cmd,&output))\r
+                                               if(!g_Git.Run(cmd,&output,CP_OEMCP))\r
                                                {\r
                                                        path->m_Action = CTGitPath::LOGACTIONS_ADDED;\r
                                                        SetEntryCheck(path,index,true);\r
@@ -5239,7 +5240,7 @@ void CGitStatusListCtrl::NotifyCheck()
 \r
 int CGitStatusListCtrl::UpdateFileList(git_revnum_t hash,CTGitPathList *list)\r
 {\r
-       CString out;\r
+       BYTE_VECTOR out;\r
        this->m_bBusy=TRUE;\r
        m_CurrentVersion=hash;\r
 \r
@@ -5253,7 +5254,8 @@ int CGitStatusListCtrl::UpdateFileList(git_revnum_t hash,CTGitPathList *list)
 \r
                for(int i=0;i<count;i++)\r
                {       \r
-                       CString cmdout;\r
+                       BYTE_VECTOR cmdout;\r
+                       cmdout.clear();\r
                        CString cmd;\r
                        if(list == NULL)\r
                                cmd=(_T("git.exe diff-index --raw HEAD --numstat -C -M"));\r
@@ -5262,21 +5264,23 @@ int CGitStatusListCtrl::UpdateFileList(git_revnum_t hash,CTGitPathList *list)
 \r
                        if(g_Git.Run(cmd,&cmdout))\r
                        {\r
-                               cmdout.Empty();\r
-                               if(g_Git.Run(_T("git.exe rev-parse --revs-only HEAD"),&cmdout))\r
+                               cmdout.clear();\r
+                               CString strout;\r
+                               if(g_Git.Run(_T("git.exe rev-parse --revs-only HEAD"),&strout,CP_UTF8))\r
                                {\r
-                                       CMessageBox::Show(NULL,cmdout,_T("TortoiseGit"),MB_OK);\r
+                                       CMessageBox::Show(NULL,strout,_T("TortoiseGit"),MB_OK);\r
                                        return -1;\r
                                }\r
-                               if(cmdout.IsEmpty())\r
+                               if(strout.IsEmpty())\r
                                        break; //this is initial repositoyr, there are no any history\r
 \r
-                               CMessageBox::Show(NULL,cmdout,_T("TortoiseGit"),MB_OK);\r
+                               CMessageBox::Show(NULL,strout,_T("TortoiseGit"),MB_OK);\r
                                return -1;\r
 \r
                        }\r
 \r
-                       out+=cmdout;\r
+                       //out+=cmdout;\r
+                       out.append(cmdout,0);\r
                }\r
 \r
 \r
@@ -5291,7 +5295,7 @@ int CGitStatusListCtrl::UpdateFileList(git_revnum_t hash,CTGitPathList *list)
 \r
                for(int i=0;i<count;i++)\r
                {       \r
-                       CString cmdout;\r
+                       BYTE_VECTOR cmdout;\r
                        CString cmd;\r
                        if(list == NULL)\r
                                cmd.Format(_T("git.exe diff-tree --raw --numstat -C -M %s"),hash);\r
@@ -5300,7 +5304,7 @@ int CGitStatusListCtrl::UpdateFileList(git_revnum_t hash,CTGitPathList *list)
 \r
                        g_Git.Run(cmd,&cmdout);\r
 \r
-                       out+=cmdout;\r
+                       out.append(cmdout);\r
                }\r
                this->m_StatusFileList.ParserFromLog(out);\r
 \r
index 0d83418..bf0ec78 100644 (file)
@@ -83,18 +83,20 @@ CTGitPath::CTGitPath(const CString& sUnknownPath) :
        m_Action=0;\r
 }\r
 \r
-int CTGitPath::ParserAction(CString action)\r
+int CTGitPath::ParserAction(BYTE action)\r
 {\r
-       action=action.TrimLeft();\r
-       TCHAR c=action.GetAt(0);\r
-       if(c == _T('M'))\r
+       //action=action.TrimLeft();\r
+       //TCHAR c=action.GetAt(0);\r
+       if(action == 'M')\r
                m_Action|= LOGACTIONS_MODIFIED;\r
-       if(c == _T('R'))\r
+       if(action == 'R')\r
                m_Action|= LOGACTIONS_REPLACED;\r
-       if(c == _T('A'))\r
+       if(action == 'A')\r
                m_Action|= LOGACTIONS_ADDED;\r
-       if(c == _T('D'))\r
+       if(action == 'D')\r
                m_Action|= LOGACTIONS_DELETED;\r
+       if(action == 'U')\r
+               m_Action|= LOGACTIONS_UNMERGED;\r
 \r
        return m_Action;\r
 }\r
@@ -856,7 +858,7 @@ int CTGitPathList::FillUnRev(int action,CTGitPathList *list)
                                        ignored,\r
                                        (*list)[i].GetWinPathString());\r
                }\r
-               \r
+#ifdef VECTOR_F                \r
                CString out;\r
                g_Git.Run(cmd,&out);\r
 \r
@@ -872,94 +874,129 @@ int CTGitPathList::FillUnRev(int action,CTGitPathList *list)
                                AddPath(path);\r
                        }\r
                }\r
+#endif\r
        }\r
        return 0;\r
 }\r
-int CTGitPathList::ParserFromLog(CString &log)\r
+int CTGitPathList::ParserFromLog(BYTE_VECTOR &log)\r
 {\r
        this->Clear();\r
        int pos=0;\r
-       CString one;\r
+       //CString one;\r
        CTGitPath path;\r
        m_Action=0;\r
        while( pos>=0 )\r
        {\r
-               one=log.Tokenize(_T("\n"),pos);\r
+               //one=log.Tokenize(_T("\n"),pos);\r
                path.Reset();\r
-               if(one[0]==_T(':'))\r
+               if(log[pos]==_T(':'))\r
                {\r
-                       int tabstart=0;\r
-                       int actionstart=0;\r
-                       CString pathname;\r
-                       CString action;\r
-                       one.Tokenize(_T("\t"),tabstart);\r
-                       if(tabstart >0)\r
+                       int end=log.find(0,pos);\r
+                       int actionstart=-1;\r
+                       int numfile=1;\r
+                       int file1=-1,file2=-1;\r
+                       if( end>0 )\r
                        {\r
-                               action=one.Left(tabstart);\r
-                               actionstart=action.ReverseFind(_T(' '));\r
-                               if(actionstart>0)\r
+                               actionstart=log.find(' ',end-6);\r
+                               pos=actionstart;\r
+                       }\r
+                       if( actionstart>0 )\r
+                       {\r
+                               actionstart++;\r
+\r
+                               file1 = log.find(0,actionstart);\r
+                               if( file1>=0 )\r
                                {\r
-                                       action=action.Right(action.GetLength()-actionstart);\r
+                                       file1++;\r
+                                       pos=file1;\r
                                }\r
-                               pathname=one.Right(one.GetLength()-tabstart);\r
-                                               \r
-                               CTGitPath *GitPath=LookForGitPath(pathname);\r
-                                               \r
-                               if(GitPath)\r
+                               if( log[actionstart] == 'C' || log[actionstart] == 'R' )\r
                                {\r
-                                       this->m_Action|=GitPath->ParserAction(action);  \r
-                                                       \r
-                               }else\r
-                               {       \r
-                                       int ac=path.ParserAction(action);\r
-                                       if(ac & CTGitPath::LOGACTIONS_REPLACED)\r
+                                       file2=file1;\r
+                                       numfile=2;\r
+                                       file1 = log.find(0,file1);\r
+                                       if(file1>=0 )\r
                                        {\r
-                                               CString oldname;\r
-                                               int oldnametab=pathname.Find(_T("\t"));\r
-                                               if(oldnametab>0)\r
-                                                       path.SetFromGit(pathname.Right(pathname.GetLength()-oldnametab-1),&pathname.Left(oldnametab));\r
-                                               else\r
-                                               {\r
-                                                       ASSERT(FALSE);\r
-                                                       path.SetFromGit(pathname);\r
-                                               }\r
-                                       }else\r
-                                               path.SetFromGit(pathname);\r
-                                       path.m_Action=ac;\r
-                                       //action must be set after setfromgit. SetFromGit will clear all status. \r
-                                       this->m_Action|=ac;\r
-                                       AddPath(path);\r
+                                               file1++;\r
+                                               pos=file1;\r
+                                       }\r
+\r
                                }\r
                        }\r
-                                       \r
-               }else\r
-               {\r
+                       \r
+                       CString pathname1;\r
+                       CString pathname2;\r
+\r
+                       if( file1>=0 )\r
+                               g_Git.StringAppend(&pathname1,&log[file1],CP_OEMCP);\r
+                       if( file2>=0 )\r
+                               g_Git.StringAppend(&pathname2,&log[file2],CP_OEMCP);\r
 \r
+                       CTGitPath *GitPath=LookForGitPath(pathname1);\r
+\r
+                       if(GitPath)\r
+                       {\r
+                               this->m_Action|=GitPath->ParserAction( log[actionstart] );      \r
+                                                       \r
+                       }else\r
+                       {       \r
+                               int ac=path.ParserAction(log[actionstart] );\r
+\r
+                               path.SetFromGit(pathname1,&pathname2);\r
+                               path.m_Action=ac;\r
+                                       //action must be set after setfromgit. SetFromGit will clear all status. \r
+                               this->m_Action|=ac;\r
+                               AddPath(path);\r
+                               \r
+                       }\r
+               \r
+                       pos=log.find(0,pos);\r
+                       if(pos>=0)\r
+                       {\r
+                               pos++;\r
+                       }\r
+               }else\r
+               {                       \r
                        int tabstart=0;\r
                        path.Reset();\r
-                       CString StatAdd=(one.Tokenize(_T("\t"),tabstart));\r
-                       if( tabstart< 0)\r
-                               break;\r
-                       CString StatDel=(one.Tokenize(_T("\t"),tabstart));\r
-                       //SetFromGit will reset all context of GitRev\r
-                       one=one.Right(one.GetLength()-tabstart);\r
-                       int rename=one.Find(_T(" => "));\r
-                       if(rename>0)\r
+                       CString StatAdd;\r
+                       CString StatDel;\r
+                       CString file1;\r
+                       CString file2;\r
+\r
+                       tabstart=log.find('\t',pos);\r
+                       if(tabstart >=0)\r
+                       {\r
+                               log[tabstart]=0;\r
+                               pos=tabstart;\r
+                               g_Git.StringAppend(&StatAdd,&log[pos],CP_UTF8);\r
+                       }\r
+\r
+                       tabstart=log.find('\t',pos);\r
+                       if(tabstart >=0)\r
                        {\r
-                               CString basepath;\r
-                               int include_left=one.Find(_T("{"));\r
-                               int include_right=one.Find(_T("}"),rename);\r
-                               if(include_left>0 && include_right>0 )\r
+                               log[tabstart]=0;\r
+                               pos=tabstart;\r
+                               g_Git.StringAppend(&StatDel,&log[pos],CP_UTF8);\r
+                       }\r
+                       \r
+                       if(log[pos] == 0) //rename\r
+                       {\r
+                               pos++;\r
+                               g_Git.StringAppend(&file2,&log[pos],CP_OEMCP);\r
+                               int sec=log.find(0,pos);\r
+                               if(sec>=0)\r
                                {\r
-                                       basepath=one.Left(include_left);\r
-                                       CString newname=basepath+one.Mid(rename+4,include_right-rename-4)+one.Right(one.GetLength()-include_right-1);\r
-                                       CString oldname=basepath+one.Mid(include_left+2,rename-include_left-2)+one.Right(one.GetLength()-include_right-1);\r
-                                       path.SetFromGit(newname,&oldname        );\r
-                               }else\r
-                                       path.SetFromGit(one.Right(one.GetLength()-rename-4),&one.Left(rename));\r
+                                       sec++;\r
+                                       g_Git.StringAppend(&file1,&log[sec],CP_OEMCP);\r
+                               }\r
+\r
                        }else\r
-                               path.SetFromGit(one);\r
-                               \r
+                       {\r
+                               g_Git.StringAppend(&file1,&log[pos],CP_OEMCP);\r
+                       }\r
+                       path.SetFromGit(file1,&file2);\r
+       \r
                        CTGitPath *GitPath=LookForGitPath(path.GetGitPathString());\r
                        if(GitPath)\r
                        {\r
@@ -972,6 +1009,10 @@ int CTGitPathList::ParserFromLog(CString &log)
                                path.m_StatDel=StatDel;\r
                                AddPath(path);\r
                        }\r
+\r
+                       pos=log.find(0,pos);\r
+                       if(pos>=0)\r
+                               pos++;\r
                }\r
 \r
        }\r
index 5b99a67..66d55cb 100644 (file)
@@ -1,4 +1,5 @@
 #pragma once\r
+#include "gittype.h"\r
 \r
 class CTGitPath\r
 {\r
@@ -13,6 +14,7 @@ public:
                LOGACTIONS_MODIFIED     = 0x00000002,\r
                LOGACTIONS_REPLACED     = 0x00000004,\r
                LOGACTIONS_DELETED      = 0x00000008,\r
+               LOGACTIONS_UNMERGED = 0x00000010,\r
                LOGACTIONS_UNVER        = 0x80000000,\r
                LOGACTIONS_IGNORE       = 0x40000000,\r
                LOGACTIONS_CONFLICT = 0x20000000,\r
@@ -22,7 +24,7 @@ public:
        CString m_StatDel;\r
        int             m_Action;\r
        bool    m_Checked;\r
-       int     ParserAction(CString action);\r
+       int     ParserAction(BYTE action);\r
        CString GetActionName();\r
        /**\r
         * Set the path as an UTF8 string with forward slashes\r
@@ -300,7 +302,7 @@ public:
        bool LoadFromFile(const CTGitPath& filename);\r
        bool WriteToFile(const CString& sFilename, bool bANSI = false) const;\r
        CTGitPath * LookForGitPath(CString path);\r
-       int     ParserFromLog(CString &log);\r
+       int     ParserFromLog(BYTE_VECTOR &log);\r
        int FillUnRev(int Action,CTGitPathList *list=NULL);\r
        int GetAction();\r
        /**\r
diff --git a/src/Git/gittype.h b/src/Git/gittype.h
new file mode 100644 (file)
index 0000000..7aded60
--- /dev/null
@@ -0,0 +1,32 @@
+#pragma once\r
+\r
+enum\r
+{\r
+       GIT_SUCCESS=0,\r
+       GIT_ERROR_OPEN_PIP,\r
+       GIT_ERROR_CREATE_PROCESS,\r
+       GIT_ERROR_GET_EXIT_CODE\r
+};\r
+\r
+class CGitByteArray:public std::vector<BYTE>\r
+{\r
+public:\r
+       int find(BYTE data,int start=0)\r
+       {\r
+               for(int i=start;i<size();i++)\r
+                       if( at(i) == data )\r
+                               return i;\r
+               return -1;\r
+       }\r
+       int append( std::vector<BYTE> &v,int start=0,int end=-1)\r
+       {\r
+               if(end<0)\r
+                       end=v.size();\r
+               for(int i=start;i<end;i++)\r
+                       this->push_back(v[i]);\r
+               return 0;\r
+       }\r
+};\r
+typedef std::vector<CString> STRING_VECTOR;\r
+typedef std::map<CString, STRING_VECTOR> MAP_HASH_NAME;\r
+typedef CGitByteArray BYTE_VECTOR;
\ No newline at end of file
index 6811a8c..4105e83 100644 (file)
@@ -95,7 +95,7 @@ BOOL CTortoiseGitBlameDoc::OnOpenDocument(LPCTSTR lpszPathName,CString Rev)
                path.SetFromWin(lpszPathName);\r
                cmd.Format(_T("git.exe blame -s -l %s -- \"%s\""),Rev,path.GetGitPathString());\r
                m_BlameData.Empty();\r
-               if(g_Git.Run(cmd,&m_BlameData))\r
+               if(g_Git.Run(cmd,&m_BlameData,CP_UTF8))\r
                {\r
                        CMessageBox::Show(NULL,CString(_T("Blame Error"))+m_BlameData,_T("TortoiseGitBlame"),MB_OK);\r
 \r
index dae0eb6..575fa72 100644 (file)
@@ -1142,7 +1142,7 @@ bool CAppUtils::CreateBranchTag(bool IsTag,CString *CommitHash)
                                );\r
                }\r
                CString out;\r
-               if(g_Git.Run(cmd,&out))\r
+               if(g_Git.Run(cmd,&out,CP_UTF8))\r
                {\r
                        CMessageBox::Show(NULL,out,_T("TortoiseGit"),MB_OK);\r
                }\r
index 91407d7..4dd86cb 100644 (file)
@@ -38,7 +38,7 @@ public:
                git.m_CurrentDir=this->orgCmdLinePath.GetWinPath();\r
                CString output;\r
 \r
-               if (git.Run(_T("git.exe init-db"),&output))\r
+               if (git.Run(_T("git.exe init-db"),&output,CP_UTF8))\r
                {\r
                        CMessageBox::Show(hwndExplorer, IDS_PROC_REPOCREATEERR, IDS_APPNAME, MB_ICONERROR);\r
                        return false;\r
index 0c1138e..2756b32 100644 (file)
@@ -54,7 +54,7 @@ bool FormatPatchCommand::Execute()
                        );\r
 \r
                CString out;\r
-               if(g_Git.Run(cmd,&out))\r
+               if(g_Git.Run(cmd,&out,CP_OEMCP))\r
                {\r
                        CMessageBox::Show(NULL,out,_T("TortoiseGit"),MB_OK);\r
                }\r
index 67b6570..84ae291 100644 (file)
@@ -37,7 +37,7 @@ bool ImportPatchCommand::Execute()
                {                       \r
                        cmd.Format(_T("git.exe am \"%s\""),dlg.m_PathList[i].GetGitPathString());\r
                        CString output;\r
-                       if(g_Git.Run(cmd,&output))\r
+                       if(g_Git.Run(cmd,&output,CP_OEMCP))\r
                        {\r
                                CMessageBox::Show(NULL,output,_T("TortoiseGit"),MB_OK);\r
                                return FALSE;\r
index 98a569b..2b35fcc 100644 (file)
@@ -43,7 +43,7 @@ bool MergeCommand::Execute()
                        dlg.m_VersionName);\r
 \r
                CString output;\r
-               g_Git.Run(cmd,&output);\r
+               g_Git.Run(cmd,&output,CP_OEMCP);\r
 \r
                CMessageBox::Show(NULL,output,_T("TortoiseGit"),MB_OK);\r
        }\r
index 8c725f7..6cc97c6 100644 (file)
@@ -130,7 +130,7 @@ bool RemoveCommand::Execute()
        for(int nPath = 0; nPath < pathList.GetCount(); nPath++)\r
        {\r
                CString output;\r
-               if(g_Git.Run(cmd+pathList[nPath].GetGitPathString(),&output))\r
+               if(g_Git.Run(cmd+pathList[nPath].GetGitPathString(),&output,CP_OEMCP))\r
                {\r
                        key=CMessageBox::Show(hwndExplorer, output, _T("TortoiseGit"), MB_ICONINFORMATION|MB_OKCANCEL);\r
                        if(key == IDCANCEL)\r
index e05c7d4..e203adc 100644 (file)
@@ -56,7 +56,7 @@ bool RenameCommand::Execute()
                                        cmdLinePath.GetGitPathString(),\r
                                        sNewName);\r
                                                                        \r
-       if(g_Git.Run(cmd,&output))\r
+       if(g_Git.Run(cmd,&output,CP_OEMCP))\r
        {\r
                CMessageBox::Show(hwndExplorer, output, _T("TortoiseGit"), MB_OK);\r
        }\r
index f34779f..62b9a73 100644 (file)
@@ -37,7 +37,7 @@ bool RevertCommand::Execute()
                for(int i=0;i< dlg.m_selectedPathList.GetCount() ;i++)\r
                {\r
                        cmd.Format(_T("git.exe checkout -f -- \"%s\""),dlg.m_selectedPathList[i].GetGitPathString());\r
-                       if(g_Git.Run(cmd,&out))\r
+                       if(g_Git.Run(cmd,&out,CP_OEMCP))\r
                        {\r
                                CMessageBox::Show(NULL,out,_T("TortoiseGit"),MB_OK);\r
                        }\r
index f71be87..4bc7dd1 100644 (file)
@@ -383,7 +383,7 @@ void CCommitDlg::OnOK()
                        }\r
 #endif\r
                        cmd.Format(_T("git.exe update-index -- \"%s\""),entry->GetGitPathString());\r
-                       g_Git.Run(cmd,&out);\r
+                       g_Git.Run(cmd,&out,CP_OEMCP);\r
                        nchecked++;\r
                        //checkedLists.insert(entry->GetGitPathString());\r
 //                     checkedfiles += _T("\"")+entry->GetGitPathString()+_T("\" ");\r
@@ -394,12 +394,12 @@ void CCommitDlg::OnOK()
                        if(entry->m_Action & CTGitPath::LOGACTIONS_ADDED)\r
                        {       //To init git repository, there are not HEAD, so we can use git reset command\r
                                cmd.Format(_T("git.exe rm --cache -- \"%s\""),entry->GetGitPathString());\r
-                               g_Git.Run(cmd,&out);    \r
+                               g_Git.Run(cmd,&out,CP_OEMCP);   \r
                        }\r
                        else\r
                        {\r
                                cmd.Format(_T("git.exe reset -- %s"),entry->GetGitPathString());\r
-                               g_Git.Run(cmd,&out);\r
+                               g_Git.Run(cmd,&out,CP_OEMCP);\r
                        }\r
 \r
                //      uncheckedfiles += _T("\"")+entry->GetGitPathString()+_T("\" ");\r
@@ -451,7 +451,7 @@ void CCommitDlg::OnOK()
        \r
                out =_T("");\r
                cmd.Format(_T("git.exe commit -F \"%s\""), tempfile);\r
-               g_Git.Run(cmd,&out);\r
+               g_Git.Run(cmd,&out,CP_OEMCP);\r
        \r
                CFile::Remove(tempfile);\r
 \r
index 9796df9..fb89fc9 100644 (file)
@@ -258,7 +258,7 @@ UINT CFileDiffDlg::DiffThread()
                cmd.Format(_T("git.exe diff-tree -r --raw -C -M --numstat %s %s"),rev1,m_rev2.m_CommitHash);\r
        }\r
 \r
-       CString out;\r
+       BYTE_VECTOR out;\r
        g_Git.Run(cmd,&out);\r
        this->m_arFileList.ParserFromLog(out);\r
        \r
index cfed705..5a08e47 100644 (file)
@@ -19,7 +19,7 @@ int CGitDiff::Parser(git_revnum_t &rev)
                CString cmd;\r
                cmd.Format(_T("git.exe rev-parse %s"),rev);\r
                CString output;\r
-               if(!g_Git.Run(cmd,&output))\r
+               if(!g_Git.Run(cmd,&output,CP_UTF8))\r
                {\r
                        //int start=output.Find(_T('\n'));\r
                        rev=output.Left(40);\r
index b276d1f..4a1b577 100644 (file)
@@ -66,7 +66,7 @@
 
 int CLogDataVector::ParserShortLog(CTGitPath *path ,CString &hash,int count ,int mask )
 {
-       CString log;
+       BYTE_VECTOR log;
        GitRev rev;
 
        if(g_Git.IsInitRepos())
@@ -79,27 +79,23 @@ int CLogDataVector::ParserShortLog(CTGitPath *path ,CString &hash,int count ,int
 
        g_Git.GetLog(log,hash,path,count,mask);
 
-       if(log.GetLength()==0)
+       if(log.size()==0)
                return 0;
        
        int start=4;
        int length;
-       int next =1;
-       while( next>0 )
+       int next =0;
+       while( next>=0 )
        {
-               next=log.Find(begin,start);
-               if(next >0 )
-                       length = next - start+4;
-               else
-                       length = log.GetLength()-start+4;
-
-               CString onelog =log;
-               onelog=log.Mid(start -4,length);
-               rev.ParserFromLog(onelog);
+               next=rev.ParserFromLog(log,next);
+
                rev.m_Subject=_T("Load .................................");
                this->push_back(rev);
                m_HashMap[rev.m_CommitHash]=size()-1;
-               start = next +4;
+               
+               if(next>0)
+                       next++;
+               //next=log.find(0,next);
        }
 
        return 0;
@@ -112,7 +108,7 @@ int CLogDataVector::FetchFullInfo(int i)
 //CLogDataVector Class
 int CLogDataVector::ParserFromLog(CTGitPath *path ,int count ,int infomask)
 {
-       CString log;
+       BYTE_VECTOR log;
        GitRev rev;
        CString emptyhash;
        g_Git.GetLog(log,emptyhash,path,count,infomask);
@@ -120,7 +116,7 @@ int CLogDataVector::ParserFromLog(CTGitPath *path ,int count ,int infomask)
        CString begin;
        begin.Format(_T("#<%c>"),LOG_REV_ITEM_BEGIN);
        
-       if(log.GetLength()==0)
+       if(log.size()==0)
                return 0;
        
        int start=4;
@@ -128,18 +124,11 @@ int CLogDataVector::ParserFromLog(CTGitPath *path ,int count ,int infomask)
        int next =1;
        while( next>0 )
        {
-               next=log.Find(begin,start);
-               if(next >0 )
-                       length = next - start+4;
-               else
-                       length = log.GetLength()-start+4;
-
-               CString onelog =log;
-               onelog=log.Mid(start -4,length);
-               rev.ParserFromLog(onelog);
+               next=rev.ParserFromLog(log,next);
                this->push_back(rev);
-               m_HashMap[rev.m_CommitHash]=size()-1;
-               start = next +4;
+               m_HashMap[rev.m_CommitHash]=size()-1;           
+               if(next>=0)
+                       next++;
        }
 
        return 0;