\r
int CGit::GetLog(BYTE_VECTOR& logOut, CString &hash, CTGitPath *path ,int count,int mask)\r
{\r
+ CGitCall_ByteVector gitCall(CString(),&logOut);\r
+ return GetLog(&gitCall,hash,path,count,mask);\r
+}\r
+\r
+//int CGit::GetLog(CGitCall* pgitCall, CString &hash, CTGitPath *path ,int count,int mask)\r
+int CGit::GetLog(CGitCall* pgitCall, CString &hash, CTGitPath *path, int count, int mask)\r
+{\r
\r
CString cmd;\r
CString log;\r
cmd += log;\r
cmd += CString(_T("\" "))+hash+file;\r
\r
- return Run(cmd,&logOut);\r
+ pgitCall->SetCmd(cmd);\r
+\r
+ return Run(pgitCall);\r
+// return Run(cmd,&logOut);\r
}\r
\r
#if 0\r
class CGitCall\r
{\r
public:\r
+ CGitCall(){}\r
CGitCall(CString cmd):m_Cmd(cmd){}\r
\r
CString GetCmd()const{return m_Cmd;}\r
+ void SetCmd(CString cmd){m_Cmd=cmd;}\r
\r
+ //This function is called when command output data is available.\r
//When this function returns 'true' the git command should be aborted.\r
//This behavior is not implemented yet.\r
virtual bool OnOutputData(const BYTE* data, size_t size)=0;\r
\r
};\r
\r
+class CTGitPath;\r
+\r
class CGit\r
{\r
private:\r
int GetMapHashToFriendName(MAP_HASH_NAME &map);\r
\r
//hash is empty means all. -1 means all\r
+\r
+ int GetLog(CGitCall* pgitCall, 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
}\r
\r
+//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
UINT CGitLogListBase::LogThread()\r
{\r
\r
unsigned int updated=0;\r
int percent=0;\r
CRect rect;\r
- while(1)\r
+/* while(1)\r
{\r
for(unsigned int i=0;i<m_logEntries.size();i++)\r
{\r
}\r
if(updated==m_logEntries.size())\r
break;\r
- }\r
\r
+ //m_logEntries.FetchFullInfo(i);\r
+ }\r
+*/\r
+ FetchFullLogInfo();\r
//RefreshCursor();\r
// make sure the filter is applied (if any) now, after we refreshed/fetched\r
// the log messages\r
}\r
}\r
}\r
+\r