+//Helper class for FetchFullLogInfo()\r
+class CGitCall_FetchFullLogInfo : public CGitCall\r
+{\r
+public:\r
+ CGitCall_FetchFullLogInfo(CGitLogListBase* ploglist):m_ploglist(ploglist),m_CollectedCount(0){}\r
+ virtual bool OnOutputData(const BYTE* data, size_t size)\r
+ {\r
+ //Add received data to byte collector\r
+ m_ByteCollector.append(data,size);\r
+\r
+ //Find loginfo endmarker\r
+ static const BYTE dataToFind[]={0,0};\r
+ int found=m_ByteCollector.findData(dataToFind,2);\r
+ if(found<0)\r
+ return m_ploglist->m_bExitThread;//Not found\r
+ found+=2;//Position after loginfo end-marker\r
+\r
+ //Prepare data for OnLogInfo and call it\r
+ BYTE_VECTOR logInfo;\r
+ logInfo.append(&*m_ByteCollector.begin(),found);\r
+ OnLogInfo(logInfo);\r
+\r
+ //Remove loginfo from bytecollector\r
+ m_ByteCollector.erase(m_ByteCollector.begin(),m_ByteCollector.begin()+found);\r
+\r
+ return m_ploglist->m_bExitThread;\r
+ }\r
+\r
+ void OnLogInfo(BYTE_VECTOR& logInfo)\r
+ {\r
+ GitRev fullRev;\r
+ fullRev.ParserFromLog(logInfo);\r
+ MAP_HASH_REV::iterator itRev=m_ploglist->m_logEntries.m_HashMap.find(fullRev.m_CommitHash);\r
+ if(itRev==m_ploglist->m_logEntries.m_HashMap.end())\r
+ {\r
+ //Should not occur, only when Git-tree updated in the mean time. (Race condition)\r
+ return;//Ignore\r
+ }\r
+ //Set updating\r
+ int rev=itRev->second;\r
+ GitRev* revInVector=&m_ploglist->m_logEntries[rev];\r
+\r
+\r
+// fullRev.m_IsUpdateing=TRUE;\r
+// fullRev.m_IsFull=TRUE;\r
+\r
+\r
+ if(InterlockedExchange(&revInVector->m_IsUpdateing,TRUE))\r
+ return;//Cannot update this row now. Ignore.\r
+ TCHAR oldmark=revInVector->m_Mark;\r
+ GIT_REV_LIST oldlist=revInVector->m_ParentHash;\r
+// CString oldhash=m_CommitHash;\r
+\r
+ //Parse new rev info\r
+ revInVector->ParserFromLog(logInfo);\r
+\r
+ if(oldmark!=0)\r
+ revInVector->m_Mark=oldmark; //parser full log will cause old mark overwrited. \r
+ //So we need keep old bound mark.\r
+ revInVector->m_ParentHash=oldlist;\r
+\r
+ //Reset updating\r
+ InterlockedExchange(&revInVector->m_IsUpdateing,FALSE);\r
+\r
+ //Notify listcontrol and update progress bar\r
+ ++m_CollectedCount;\r
+\r
+ ::PostMessage(m_ploglist->m_hWnd,MSG_LOADED,(WPARAM)rev,0);\r
+\r
+ DWORD percent=m_CollectedCount*98/m_ploglist->m_logEntries.size() + GITLOG_START+1;\r
+ if(percent == GITLOG_END)\r
+ percent = GITLOG_END -1;\r
+ \r
+ ::PostMessage(m_ploglist->GetParent()->m_hWnd,MSG_LOAD_PERCENTAGE,(WPARAM) percent,0);\r
+ }\r
+\r
+ CGitLogListBase* m_ploglist;\r
+ BYTE_VECTOR m_ByteCollector;\r
+ int m_CollectedCount;\r
+\r
+};\r
+\r
+void CGitLogListBase::FetchFullLogInfo()\r
+{\r
+ CGitCall_FetchFullLogInfo fetcher(this);\r
+ g_Git.GetLog(&fetcher,CString(),NULL,-1,CGit::LOG_INFO_STAT|CGit::LOG_INFO_FILESTATE|CGit::LOG_INFO_DETECT_COPYRENAME);\r
+}\r
+\r