OSDN Git Service

'Cherry-pick' commits after combined commits when combine is done
[tortoisegit/TortoiseGitJp.git] / src / Git / GitRev.cpp
index 083f517..6414c10 100644 (file)
@@ -2,11 +2,26 @@
 #include "GitRev.h"\r
 #include "Git.h"\r
 \r
+// provide an ASSERT macro for when compiled without MFC\r
+#if !defined ASSERT\r
+       #ifdef _DEBUG\r
+               #define ASSERT(x) {if(!(x)) _asm{int 0x03}}\r
+       #else\r
+               #define ASSERT(x)       \r
+       #endif\r
+#endif\r
+\r
+\r
 GitRev::GitRev(void)\r
 {\r
        m_Action=0;\r
        m_IsFull = 0;\r
        m_IsUpdateing = 0;\r
+       // fetch local machine timezone info\r
+       if ( GetTimeZoneInformation( &m_TimeZone ) == TIME_ZONE_ID_INVALID )\r
+       {\r
+               ASSERT(false);\r
+       }\r
 }\r
 \r
 GitRev::~GitRev(void)\r
@@ -36,7 +51,7 @@ void GitRev::Clear()
        m_Mark=0;\r
 \r
 }\r
-int GitRev::CopyFrom(GitRev &rev)\r
+int GitRev::CopyFrom(GitRev &rev,bool OmitParentAndMark)\r
 {\r
        m_AuthorName    =rev.m_AuthorName       ;\r
        m_AuthorEmail   =rev.m_AuthorEmail      ;\r
@@ -47,35 +62,49 @@ int GitRev::CopyFrom(GitRev &rev)
        m_Subject               =rev.m_Subject          ;\r
        m_Body                  =rev.m_Body                     ;\r
        m_CommitHash    =rev.m_CommitHash       ;\r
-       m_ParentHash    =rev.m_ParentHash       ;\r
        m_Files                 =rev.m_Files                    ;       \r
        m_Action                =rev.m_Action           ;\r
-       m_Mark                  =rev.m_Mark;\r
+\r
+       if(!OmitParentAndMark)\r
+       {\r
+               m_ParentHash    =rev.m_ParentHash       ;\r
+               m_Mark                  =rev.m_Mark;\r
+       }\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
+       int begintime=0;\r
+       int filebegin=-1;\r
 \r
-       while( pos>=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
+               \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
+                               if(begintime>1)\r
+                                       break;\r
+                               else\r
+                                       this->Clear();\r
                                break;\r
                        case LOG_REV_AUTHOR_NAME:\r
                                this->m_AuthorName = text;\r
@@ -125,30 +154,72 @@ 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
+                               if(filebegin<0)\r
+                                       filebegin=pos;\r
                                break;\r
                        }\r
                }\r
+               \r
+               if(begintime>1)\r
+               {\r
+                       break;\r
+               }\r
+\r
+               //find next string start \r
+               pos=log.findNextString(pos);\r
        }\r
        \r
-       this->m_Files.ParserFromLog(filelist);\r
-       this->m_Action=this->m_Files.GetAction();\r
-       return 0;\r
+       if(filebegin>=0)\r
+       {\r
+               filelist.append(log,filebegin,pos);     \r
+               this->m_Files.ParserFromLog(filelist);\r
+               this->m_Action=this->m_Files.GetAction();\r
+       }\r
+       return pos;\r
 }\r
 \r
 CTime GitRev::ConverFromString(CString input)\r
 {\r
+       // pick up date from string\r
        CTime tm(_wtoi(input.Mid(0,4)),\r
                         _wtoi(input.Mid(5,2)),\r
                         _wtoi(input.Mid(8,2)),\r
                         _wtoi(input.Mid(11,2)),\r
                         _wtoi(input.Mid(14,2)),\r
                         _wtoi(input.Mid(17,2)),\r
-                        _wtoi(input.Mid(20,4)));\r
+                        0);\r
+       // pick up utc offset\r
+       CString sign = input.Mid(20,1);         // + or -\r
+       int hoursOffset =  _wtoi(input.Mid(21,2));\r
+       int minsOffset = _wtoi(input.Mid(23,2));\r
+       if ( sign == "-" )\r
+       {\r
+               hoursOffset = -hoursOffset;\r
+               minsOffset = -minsOffset;\r
+       }\r
+       // make a timespan object with this value\r
+       CTimeSpan offset( 0, hoursOffset, minsOffset, 0 );\r
+       // we have to subtract this from the time given to get UTC\r
+       tm -= offset;\r
+       // get local timezone\r
+       SYSTEMTIME sysTime;\r
+       tm.GetAsSystemTime( sysTime );\r
+       SYSTEMTIME local;\r
+       if ( SystemTimeToTzSpecificLocalTime( &m_TimeZone, &sysTime, &local ) )\r
+       {\r
+               sysTime = local;\r
+       }\r
+       else\r
+       {\r
+               ASSERT(false);\r
+       }\r
+       tm = CTime( sysTime, 0 );\r
        return tm;\r
 }\r
 \r
@@ -157,18 +228,19 @@ 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);\r
+               git->GetLog(onelog,m_CommitHash,NULL,1,CGit::LOG_INFO_STAT|CGit::LOG_INFO_FILESTATE|CGit::LOG_INFO_DETECT_COPYRENAME);\r
                CString oldhash=m_CommitHash;\r
+               GIT_REV_LIST oldlist=this->m_ParentHash;\r
                ParserFromLog(onelog);\r
                \r
                //ASSERT(oldhash==m_CommitHash);\r
                if(oldmark!=0)\r
                        this->m_Mark=oldmark;  //parser full log will cause old mark overwrited. \r
                                                               //So we need keep old bound mark.\r
-\r
+               this->m_ParentHash=oldlist;\r
                InterlockedExchange(&m_IsUpdateing,FALSE);\r
                InterlockedExchange(&m_IsFull,TRUE);\r
                return 0;\r