OSDN Git Service

merge original branch.
[tortoisegit/TortoiseGitJp.git] / src / TortoiseProc / GitLogListBase.cpp
index 33d45b9..b74a59b 100644 (file)
@@ -58,6 +58,8 @@ CGitLogListBase::CGitLogListBase():CHintListCtrl()
        , m_pStoreSelection(NULL)\r
        , m_nSelectedFilter(LOGFILTER_ALL)\r
        , m_bVista(false)\r
+       , m_bShowWC(false)\r
+       , m_logEntries(&m_LogCache)\r
 {\r
        // use the default GUI font, create a copy of it and\r
        // change the copy to BOLD (leave the rest of the font\r
@@ -72,8 +74,13 @@ CGitLogListBase::CGitLogListBase():CHintListCtrl()
 \r
        m_IsIDReplaceAction=FALSE;\r
 \r
-       m_wcRev.m_CommitHash=GIT_REV_ZERO;\r
-       m_wcRev.m_Subject=_T("Working Copy");\r
+       this->m_critSec.Init();\r
+       m_wcRev.m_CommitHash.Empty();\r
+       m_wcRev.m_Subject=_T("Working dir changes");\r
+       m_wcRev.m_ParentHash.clear();\r
+       m_wcRev.m_Mark=_T('-');\r
+       m_wcRev.m_IsUpdateing=FALSE;\r
+       m_wcRev.m_IsFull = TRUE;\r
 \r
        m_hModifiedIcon = (HICON)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_ACTIONMODIFIED), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);\r
        m_hReplacedIcon = (HICON)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_ACTIONREPLACED), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);\r
@@ -173,7 +180,7 @@ END_MESSAGE_MAP()
 \r
 void CGitLogListBase::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct)\r
 {\r
-       // TODO: ÔÚ´ËÌí¼ÓÏûÏ¢´¦Àí³ÌÐò´úÂëºÍ/»òµ÷ÓÃĬÈÏÖµ\r
+       // TODO: ï¾\94ï¾\9aï½´ï¾\8bï¾\8c�ï¾\93ï¾\8fûï¾\8f「エヲï¾\80�ï¾\8cï¾\90òï½´úï¾\82�ï¾\8d/ï½»òï½µ÷ï¾\93ï¾\83ï¾\84ャï¾\88ï¾\8fï¾\96ï½µ\r
 \r
        CListCtrl::OnMeasureItem(nIDCtl, lpMeasureItemStruct);\r
 }\r
@@ -206,7 +213,7 @@ void CGitLogListBase::InsertGitColumn()
 {\r
        CString temp;\r
 \r
-       int c = ((CHeaderCtrl*)(GetDlgItem(0)))->GetItemCount()-1;\r
+       int c = GetHeaderCtrl()->GetItemCount()-1;\r
        \r
        while (c>=0)\r
                DeleteColumn(c--);\r
@@ -315,7 +322,7 @@ void CGitLogListBase::ResizeAllListCtrlCols()
 \r
 BOOL CGitLogListBase::GetShortName(CString ref, CString &shortname,CString prefix)\r
 {\r
-       TRACE(_T("%s %s\r\n"),ref,prefix);\r
+       //TRACE(_T("%s %s\r\n"),ref,prefix);\r
        if(ref.Left(prefix.GetLength()) ==  prefix)\r
        {\r
                shortname = ref.Right(ref.GetLength()-prefix.GetLength());\r
@@ -396,7 +403,7 @@ void CGitLogListBase::FillBackGround(HDC hdc, int Index,CRect &rect)
                                brush = ::CreateSolidBrush(RGB(156,156,156));\r
                        else if(pLogEntry->m_Action&CTGitPath::LOGACTIONS_REBASE_EDIT)\r
                                brush = ::CreateSolidBrush(RGB(200,200,128));\r
-                       else \r
+                       else\r
                                brush = ::CreateSolidBrush(::GetSysColor(COLOR_WINDOW));\r
                }\r
                if (brush == NULL)\r
@@ -849,7 +856,7 @@ void CGitLogListBase::DrawGraph(HDC hdc,CRect &rect,INT_PTR index)
                        continue;\r
 \r
                COLORREF color = i == activeLane ? activeColor : m_LineColors[i % Lanes::COLORS_NUM];\r
-               paintGraphLane(hdc, rect.Height(),ln, x1, x2, color,activeColor, rect.top);\r
+               paintGraphLane(hdc, rect.Height(),ln, x1+rect.left, x2+rect.left, color,activeColor, rect.top);\r
        }\r
 \r
 #if 0\r
@@ -873,7 +880,6 @@ void CGitLogListBase::DrawGraph(HDC hdc,CRect &rect,INT_PTR index)
        }\r
 #endif\r
 \r
-       TRACE(_T("index %d %d\r\n"),index,data->m_Lanes.size());\r
 }\r
 \r
 void CGitLogListBase::OnNMCustomdrawLoglist(NMHDR *pNMHDR, LRESULT *pResult)\r
@@ -929,7 +935,7 @@ void CGitLogListBase::OnNMCustomdrawLoglist(NMHDR *pNMHDR, LRESULT *pResult)
                                                pLVCD->clrTextBk = RGB(156,156,156);\r
                                        else if(data->m_Action&CTGitPath::LOGACTIONS_REBASE_EDIT)\r
                                                pLVCD->clrTextBk  = RGB(200,200,128);\r
-                                       else \r
+                                       else\r
                                                pLVCD->clrTextBk  = ::GetSysColor(COLOR_WINDOW);\r
 \r
                                        if(data->m_Action&CTGitPath::LOGACTIONS_REBASE_CURRENT)\r
@@ -938,7 +944,7 @@ void CGitLogListBase::OnNMCustomdrawLoglist(NMHDR *pNMHDR, LRESULT *pResult)
                                                *pResult = CDRF_NOTIFYSUBITEMDRAW | CDRF_NEWFONT;\r
                                        }\r
 \r
-                                       if(data->m_CommitHash == m_HeadHash)\r
+                                       if(data->m_CommitHash.ToString() == m_HeadHash)\r
                                        {\r
                                                SelectObject(pLVCD->nmcd.hdc, m_boldFont);\r
                                                *pResult = CDRF_NOTIFYSUBITEMDRAW | CDRF_NEWFONT;\r
@@ -946,13 +952,15 @@ void CGitLogListBase::OnNMCustomdrawLoglist(NMHDR *pNMHDR, LRESULT *pResult)
 \r
 //                                     if ((data->childStackDepth)||(m_mergedRevs.find(data->Rev) != m_mergedRevs.end()))\r
 //                                             crText = GetSysColor(COLOR_GRAYTEXT);\r
-//                                     if (data->Rev == m_wcRev)\r
-//                                     {\r
-//                                             SelectObject(pLVCD->nmcd.hdc, m_boldFont);\r
+//                                     \r
+                                       if (data->m_CommitHash.IsEmpty())\r
+                                       {\r
+                                               //crText = GetSysColor(RGB(200,200,0));\r
+                                               //SelectObject(pLVCD->nmcd.hdc, m_boldFont);\r
                                                // We changed the font, so we're returning CDRF_NEWFONT. This\r
                                                // tells the control to recalculate the extent of the text.\r
-//                                             *pResult = CDRF_NOTIFYSUBITEMDRAW | CDRF_NEWFONT;\r
-//                                     }\r
+                                               *pResult = CDRF_NOTIFYSUBITEMDRAW | CDRF_NEWFONT;\r
+                                       }\r
                                }\r
                        }\r
                        if (m_arShownList.GetCount() == (INT_PTR)pLVCD->nmcd.dwItemSpec)\r
@@ -978,9 +986,19 @@ void CGitLogListBase::OnNMCustomdrawLoglist(NMHDR *pNMHDR, LRESULT *pResult)
                                {\r
                                        CRect rect;\r
                                        GetSubItemRect(pLVCD->nmcd.dwItemSpec, pLVCD->iSubItem, LVIR_BOUNDS, rect);\r
+                                       if(pLVCD->iSubItem == 0)\r
+                                       {\r
+                                               CRect second;\r
+                                               GetSubItemRect(pLVCD->nmcd.dwItemSpec, pLVCD->iSubItem+1, LVIR_BOUNDS, second);\r
+                                               rect.right=second.left;\r
+                                       }\r
                                        \r
+                                       //TRACE(_T("A Graphic left %d right %d\r\n"),rect.left,rect.right);\r
                                        FillBackGround(pLVCD->nmcd.hdc, (INT_PTR)pLVCD->nmcd.dwItemSpec,rect);\r
-                                       DrawGraph(pLVCD->nmcd.hdc,rect,pLVCD->nmcd.dwItemSpec);\r
+                                       \r
+                                       GitRev* data = (GitRev*)m_arShownList.GetAt(pLVCD->nmcd.dwItemSpec);\r
+                                       if( !data ->m_CommitHash.IsEmpty())\r
+                                               DrawGraph(pLVCD->nmcd.hdc,rect,pLVCD->nmcd.dwItemSpec);\r
 \r
                                        *pResult = CDRF_SKIPDEFAULT;\r
                                        return;\r
@@ -1013,7 +1031,8 @@ void CGitLogListBase::OnNMCustomdrawLoglist(NMHDR *pNMHDR, LRESULT *pResult)
                                                return;\r
 \r
                                        }\r
-                               }\r
+\r
+                               }       \r
                        }\r
                        \r
                        if (pLVCD->iSubItem == 1)\r
@@ -1035,6 +1054,7 @@ void CGitLogListBase::OnNMCustomdrawLoglist(NMHDR *pNMHDR, LRESULT *pResult)
                                GitRev* pLogEntry = reinterpret_cast<GitRev *>(m_arShownList.GetAt(pLVCD->nmcd.dwItemSpec));\r
                                CRect rect;\r
                                GetSubItemRect(pLVCD->nmcd.dwItemSpec, pLVCD->iSubItem, LVIR_BOUNDS, rect);\r
+                               //TRACE(_T("Action left %d right %d\r\n"),rect.left,rect.right);\r
                                // Get the selected state of the\r
                                // item being drawn.                                                    \r
 \r
@@ -1133,7 +1153,7 @@ void CGitLogListBase::OnLvnGetdispinfoLoglist(NMHDR *pNMHDR, LRESULT *pResult)
                        lstrcpyn(pItem->pszText, (LPCTSTR)pLogEntry->m_AuthorName, pItem->cchTextMax);\r
                break;\r
        case this->LOGLIST_DATE: //Date\r
-               if (pLogEntry)\r
+               if ( pLogEntry && (!pLogEntry->m_CommitHash.IsEmpty()) )\r
                        lstrcpyn(pItem->pszText,\r
                                CAppUtils::FormatDateAndTime( pLogEntry->m_AuthorDate, m_DateFormat, true, m_bRelativeTimes ), \r
                                pItem->cchTextMax);\r
@@ -1256,8 +1276,9 @@ void CGitLogListBase::OnContextMenu(CWnd* pWnd, CPoint point)
 \r
                if (GetSelectedCount() == 1)\r
                {\r
+                       \r
                        {\r
-                               if (m_hasWC)\r
+                               if( !pSelLogEntry->m_CommitHash.IsEmpty())\r
                                {\r
                                        if(m_ContextMenuMask&GetContextMenuBit(ID_COMPARE))\r
                                                popup.AppendMenuIcon(ID_COMPARE, IDS_LOG_POPUP_COMPARE, IDI_DIFF);\r
@@ -1268,6 +1289,10 @@ void CGitLogListBase::OnContextMenu(CWnd* pWnd, CPoint point)
                                        // But until that's implemented, the context menu entry for\r
                                        // this feature is commented out.\r
                                        //popup.AppendMenu(ID_BLAMECOMPARE, IDS_LOG_POPUP_BLAMECOMPARE, IDI_BLAME);\r
+                               }else\r
+                               {\r
+                                       if(m_ContextMenuMask&GetContextMenuBit(ID_COMMIT))\r
+                                               popup.AppendMenuIcon(ID_COMMIT, IDS_LOG_POPUP_COMMIT, IDI_COMMIT);\r
                                }\r
                                if(m_ContextMenuMask&GetContextMenuBit(ID_GNUDIFF1))\r
                                        popup.AppendMenuIcon(ID_GNUDIFF1, IDS_LOG_POPUP_GNUDIFF_CH, IDI_DIFF);\r
@@ -1303,30 +1328,33 @@ void CGitLogListBase::OnContextMenu(CWnd* pWnd, CPoint point)
                        format.LoadString(IDS_RESET_TO_THIS_FORMAT);\r
                        str.Format(format,g_Git.GetCurrentBranch());\r
 \r
-                       if(m_ContextMenuMask&GetContextMenuBit(ID_RESET))\r
-                               popup.AppendMenuIcon(ID_RESET,str,IDI_REVERT);\r
+                       if(!pSelLogEntry->m_CommitHash.IsEmpty())\r
+                       {\r
+                               if(m_ContextMenuMask&GetContextMenuBit(ID_RESET))\r
+                                       popup.AppendMenuIcon(ID_RESET,str,IDI_REVERT);\r
 \r
-                       if(m_ContextMenuMask&GetContextMenuBit(ID_SWITCHTOREV))\r
-                               popup.AppendMenuIcon(ID_SWITCHTOREV, IDS_SWITCH_TO_THIS , IDI_SWITCH);\r
+                               if(m_ContextMenuMask&GetContextMenuBit(ID_SWITCHTOREV))\r
+                                       popup.AppendMenuIcon(ID_SWITCHTOREV, IDS_SWITCH_TO_THIS , IDI_SWITCH);\r
 \r
-                       if(m_ContextMenuMask&GetContextMenuBit(ID_CREATE_BRANCH))\r
-                               popup.AppendMenuIcon(ID_CREATE_BRANCH, IDS_CREATE_BRANCH_AT_THIS , IDI_COPY);\r
+                               if(m_ContextMenuMask&GetContextMenuBit(ID_CREATE_BRANCH))\r
+                                       popup.AppendMenuIcon(ID_CREATE_BRANCH, IDS_CREATE_BRANCH_AT_THIS , IDI_COPY);\r
 \r
-                       if(m_ContextMenuMask&GetContextMenuBit(ID_CREATE_TAG))\r
-                               popup.AppendMenuIcon(ID_CREATE_TAG,IDS_CREATE_TAG_AT_THIS , IDI_COPY);\r
+                               if(m_ContextMenuMask&GetContextMenuBit(ID_CREATE_TAG))\r
+                                       popup.AppendMenuIcon(ID_CREATE_TAG,IDS_CREATE_TAG_AT_THIS , IDI_COPY);\r
                        \r
-                       format.LoadString(IDS_REBASE_THIS_FORMAT);\r
-                       str.Format(format,g_Git.GetCurrentBranch());\r
+                               format.LoadString(IDS_REBASE_THIS_FORMAT);\r
+                               str.Format(format,g_Git.GetCurrentBranch());\r
 \r
-                       if(pSelLogEntry->m_CommitHash != m_HeadHash)\r
-                               if(m_ContextMenuMask&GetContextMenuBit(ID_REBASE_TO_VERSION))\r
-                                       popup.AppendMenuIcon(ID_REBASE_TO_VERSION, str , IDI_REBASE);                   \r
+                               if(pSelLogEntry->m_CommitHash != m_HeadHash)\r
+                                       if(m_ContextMenuMask&GetContextMenuBit(ID_REBASE_TO_VERSION))\r
+                                               popup.AppendMenuIcon(ID_REBASE_TO_VERSION, str , IDI_REBASE);                   \r
 \r
-                       if(m_ContextMenuMask&GetContextMenuBit(ID_EXPORT))\r
-                               popup.AppendMenuIcon(ID_EXPORT,IDS_EXPORT_TO_THIS, IDI_EXPORT); \r
+                               if(m_ContextMenuMask&GetContextMenuBit(ID_EXPORT))\r
+                                       popup.AppendMenuIcon(ID_EXPORT,IDS_EXPORT_TO_THIS, IDI_EXPORT); \r
                        \r
 \r
-                       popup.AppendMenu(MF_SEPARATOR, NULL);\r
+                               popup.AppendMenu(MF_SEPARATOR, NULL);\r
+                       }\r
 \r
                }\r
 \r
@@ -1365,7 +1393,7 @@ void CGitLogListBase::OnContextMenu(CWnd* pWnd, CPoint point)
                                popup.AppendMenu(MF_SEPARATOR, NULL);\r
                }\r
 \r
-               if ( GetSelectedCount() >0 )\r
+               if ( GetSelectedCount() >0 && (!pSelLogEntry->m_CommitHash.IsEmpty()))\r
                {\r
                        if ( IsSelectionContinuous() && GetSelectedCount() >= 2 )\r
                        {\r
@@ -1380,7 +1408,7 @@ void CGitLogListBase::OnContextMenu(CWnd* pWnd, CPoint point)
                                                CString hash=g_Git.GetHash(head);\r
                                                hash=hash.Left(40);\r
                                                GitRev* pLastEntry = reinterpret_cast<GitRev*>(m_arShownList.GetAt(LastSelect));\r
-                                               if(pLastEntry->m_CommitHash == hash)\r
+                                               if(pLastEntry->m_CommitHash.ToString() == hash)\r
                                                        popup.AppendMenuIcon(ID_COMBINE_COMMIT,IDS_COMBINE_TO_ONE,IDI_COMBINE);\r
                                        }\r
                                }\r
@@ -1388,7 +1416,7 @@ void CGitLogListBase::OnContextMenu(CWnd* pWnd, CPoint point)
                        if(m_ContextMenuMask&GetContextMenuBit(ID_CHERRY_PICK))\r
                                popup.AppendMenuIcon(ID_CHERRY_PICK, IDS_CHERRY_PICK_VERSION, IDI_EXPORT);\r
 \r
-                       if(GetSelectedCount()<=2)\r
+                       if(GetSelectedCount()<=2 || (IsSelectionContinuous() && GetSelectedCount() > 0))\r
                                if(m_ContextMenuMask&GetContextMenuBit(ID_CREATE_PATCH))\r
                                        popup.AppendMenuIcon(ID_CREATE_PATCH, IDS_CREATE_PATCH, IDI_PATCH);\r
                        \r
@@ -1700,13 +1728,13 @@ int CGitLogListBase::FillGitLog(CTGitPath *path,int info,CString *from,CString *
        {\r
                if(m_IsOldFirst)\r
                {\r
-                       m_logEntries[m_logEntries.size()-i-1].m_IsFull=TRUE;\r
-                       this->m_arShownList.Add(&m_logEntries[m_logEntries.size()-i-1]);\r
+                       m_logEntries.GetGitRevAt(m_logEntries.size()-i-1).m_IsFull=TRUE;\r
+                       this->m_arShownList.Add(&m_logEntries.GetGitRevAt(m_logEntries.size()-i-1));\r
                \r
                }else\r
                {\r
-                       m_logEntries[i].m_IsFull=TRUE;\r
-                       this->m_arShownList.Add(&m_logEntries[i]);\r
+                       m_logEntries.GetGitRevAt(i).m_IsFull=TRUE;\r
+                       this->m_arShownList.Add(&m_logEntries.GetGitRevAt(i));\r
                }\r
        }\r
 \r
@@ -1716,11 +1744,14 @@ int CGitLogListBase::FillGitLog(CTGitPath *path,int info,CString *from,CString *
 \r
 }\r
 \r
-int CGitLogListBase::FillGitShortLog()\r
+int CGitLogListBase::BeginFetchLog()\r
 {\r
        ClearText();\r
 \r
        this->m_logEntries.ClearAll();\r
+       git_init();\r
+\r
+       this->m_LogCache.ClearAllParent();\r
 \r
        m_LogCache.FetchCacheIndex(g_Git.m_CurrentDir);\r
 \r
@@ -1734,30 +1765,33 @@ int CGitLogListBase::FillGitShortLog()
        int mask;\r
        mask = CGit::LOG_INFO_ONLY_HASH | CGit::LOG_INFO_BOUNDARY;\r
 //     if(this->m_bAllBranch)\r
-       mask |= m_ShowMask;\r
-\r
-       this->m_logEntries.FetchShortLog(path,m_StartRef,-1,mask);\r
+       mask |= m_ShowMask ;\r
        \r
+       this->m_arShownList.RemoveAll();\r
+\r
+       if(m_bShowWC)\r
+       {\r
+               this->m_logEntries.insert(m_logEntries.begin(),this->m_wcRev.m_CommitHash);\r
+               this->m_LogCache.m_HashMap[m_wcRev.m_CommitHash]=m_wcRev;\r
+       }\r
+\r
+       CString cmd=g_Git.GetLogCmd(m_StartRef,path,-1,mask,NULL,NULL,true);\r
+\r
        //this->m_logEntries.ParserFromLog();\r
        if(IsInWorkingThread())\r
+       {\r
                PostMessage(LVM_SETITEMCOUNT, (WPARAM) this->m_logEntries.size(),(LPARAM) LVSICF_NOINVALIDATEALL);\r
+       }\r
        else\r
+       {\r
                SetItemCountEx(this->m_logEntries.size());\r
-\r
-       this->m_arShownList.RemoveAll();\r
-\r
-       for(unsigned int i=0;i<m_logEntries.size();i++)\r
+       }\r
+       \r
+       if(git_open_log(&m_DllGitLog,CUnicodeUtils::GetMulti(cmd,CP_ACP).GetBuffer()))\r
        {\r
-               m_logEntries[i].m_Subject=_T("parser...");\r
-               if(this->m_IsOldFirst)\r
-               {\r
-                       this->m_arShownList.Add(&m_logEntries[m_logEntries.size()-1-i]);\r
-\r
-               }else\r
-               {\r
-                       this->m_arShownList.Add(&m_logEntries[i]);\r
-               }\r
+               return -1;\r
        }\r
+\r
        return 0;\r
 }\r
 \r
@@ -1836,11 +1870,14 @@ void CGitLogListBase::GetTimeRange(CTime &oldest, CTime &latest)
        latest=CTime(1971,1,2,0,0,0);\r
        for(unsigned int i=0;i<m_logEntries.size();i++)\r
        {\r
-               if(m_logEntries[i].m_AuthorDate.GetTime() < oldest.GetTime())\r
-                       oldest = m_logEntries[i].m_AuthorDate.GetTime();\r
+               if(m_logEntries[i].IsEmpty())\r
+                       continue;\r
+\r
+               if(m_logEntries.GetGitRevAt(i).m_AuthorDate.GetTime() < oldest.GetTime())\r
+                       oldest = m_logEntries.GetGitRevAt(i).m_AuthorDate.GetTime();\r
 \r
-               if(m_logEntries[i].m_AuthorDate.GetTime() > latest.GetTime())\r
-                       latest = m_logEntries[i].m_AuthorDate.GetTime();\r
+               if(m_logEntries.GetGitRevAt(i).m_AuthorDate.GetTime() > latest.GetTime())\r
+                       latest = m_logEntries.GetGitRevAt(i).m_AuthorDate.GetTime();\r
 \r
        }\r
 }\r
@@ -1894,17 +1931,18 @@ public:
                }\r
                //Set updating\r
                int rev=itRev->second;\r
-               GitRev* revInVector=&m_ploglist->m_logEntries[rev];\r
+               GitRev* revInVector=&m_ploglist->m_logEntries.GetGitRevAt(rev);\r
 \r
 \r
                if(revInVector->m_IsFull)\r
                        return;\r
 \r
-               if(!m_ploglist->m_LogCache.GetCacheData(m_ploglist->m_logEntries[rev]))\r
+               GitRev *pRev= m_ploglist->m_LogCache.GetCacheData(m_ploglist->m_logEntries[rev]);\r
+               if(pRev)\r
                {\r
                        ++m_CollectedCount;\r
-                       InterlockedExchange(&m_ploglist->m_logEntries[rev].m_IsUpdateing,FALSE);\r
-                       InterlockedExchange(&m_ploglist->m_logEntries[rev].m_IsFull,TRUE);\r
+                       InterlockedExchange(&pRev->m_IsUpdateing,FALSE);\r
+                       InterlockedExchange(&pRev->m_IsFull,TRUE);\r
                        ::PostMessage(m_ploglist->m_hWnd,MSG_LOADED,(WPARAM)rev,0);\r
                        return;\r
                }\r
@@ -1956,6 +1994,7 @@ void CGitLogListBase::FetchFullLogInfo(CString &from, CString &to)
 {\r
        CGitCall_FetchFullLogInfo fetcher(this);\r
        int mask=\r
+               CGit::LOG_INFO_FULL_DIFF|\r
                CGit::LOG_INFO_STAT|\r
                CGit::LOG_INFO_FILESTATE|\r
                CGit::LOG_INFO_DETECT_COPYRENAME|\r
@@ -1979,22 +2018,23 @@ void CGitLogListBase::FetchLastLogInfo()
        {\r
                for(unsigned int i=0;i<m_logEntries.size();i++)\r
                {\r
-                       if(m_logEntries[i].m_IsFull)\r
+                       if(m_logEntries.GetGitRevAt(i).m_IsFull)\r
                                continue;\r
 \r
-                       if(m_LogCache.GetCacheData(m_logEntries[i]))\r
+                       GitRev *pRev = m_LogCache.GetCacheData(m_logEntries[i]);\r
+                       if(pRev == NULL)\r
                        {\r
                                if(!m_logEntries.FetchFullInfo(i))\r
                                {\r
                                        updated++;\r
                                }\r
-                               m_LogCache.AddCacheEntry(m_logEntries[i]);\r
+                               m_LogCache.AddCacheEntry(m_logEntries.GetGitRevAt(i));\r
 \r
                        }else\r
                        {\r
                                updated++;\r
-                               InterlockedExchange(&m_logEntries[i].m_IsUpdateing,FALSE);\r
-                               InterlockedExchange(&m_logEntries[i].m_IsFull,TRUE);\r
+                               InterlockedExchange(&pRev->m_IsUpdateing,FALSE);\r
+                               InterlockedExchange(&pRev->m_IsFull,TRUE);\r
                        }\r
                        \r
                        ::PostMessage(m_hWnd,MSG_LOADED,(WPARAM)i,0);\r
@@ -2011,7 +2051,102 @@ void CGitLogListBase::FetchLastLogInfo()
 \r
 UINT CGitLogListBase::LogThread()\r
 {\r
+       ::PostMessage(this->GetParent()->m_hWnd,MSG_LOAD_PERCENTAGE,(WPARAM) GITLOG_START,0);\r
+       \r
+       InterlockedExchange(&m_bThreadRunning, TRUE);\r
+       InterlockedExchange(&m_bNoDispUpdates, TRUE);\r
+\r
+       ULONGLONG  t1,t2;\r
+       \r
+       if(BeginFetchLog())\r
+               return -1;\r
+\r
+       TRACE(_T("\n===Begin===\n"));\r
+       //Update work copy item;\r
+       if( m_logEntries.size() > 0)\r
+       {\r
+               GitRev *pRev = &m_logEntries.GetGitRevAt(0);\r
+               \r
+               m_arShownList.Add(pRev);\r
+\r
+               if( pRev->m_CommitHash.IsEmpty() )\r
+               {\r
+                       pRev->m_Files.Clear();\r
+                       pRev->m_ParentHash.clear();\r
+                       pRev->m_ParentHash.push_back(m_HeadHash);\r
+                       g_Git.GetCommitDiffList(pRev->m_CommitHash.ToString(),this->m_HeadHash.ToString(), pRev->m_Files);\r
+                       pRev->m_Action =0;\r
+               \r
+                       for(int j=0;j< pRev->m_Files.GetCount();j++)\r
+                       pRev->m_Action |= pRev->m_Files[j].m_Action;\r
+                       \r
+                       pRev->m_Body.Format(_T("%d files changed"),m_logEntries.GetGitRevAt(0).m_Files.GetCount());\r
+                       ::PostMessage(m_hWnd,MSG_LOADED,(WPARAM)0,0);\r
+               }\r
+       }\r
+\r
+       InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
+\r
+       git_get_log_firstcommit(m_DllGitLog);\r
+       int total = git_get_log_estimate_commit_count(m_DllGitLog);\r
+       GIT_COMMIT commit;\r
+       t1=GetTickCount();\r
+\r
+       int oldsize=m_logEntries.size();\r
+       while( git_get_log_nextcommit(this->m_DllGitLog,&commit) == 0)\r
+       {\r
+               //printf("%s\r\n",commit.m_Subject);\r
+               if(m_bExitThread)\r
+                       break;\r
+\r
+               CGitHash hash = (char*)commit.m_hash ;\r
+                       \r
+               GitRev *pRev = m_LogCache.GetCacheData(hash);\r
+               \r
+               if(pRev == NULL || !pRev->m_IsFull)\r
+               {\r
+                       pRev->ParserFromCommit(&commit);\r
+                       pRev->ParserParentFromCommit(&commit);\r
+                       pRev->SafeFetchFullInfo(&g_Git);\r
+                                               \r
+               }else\r
+               {\r
+                       ASSERT(pRev->m_CommitHash == hash);\r
+                       pRev->ParserParentFromCommit(&commit);\r
+               }\r
+#ifdef DEBUG           \r
+               pRev->DbgPrint();\r
+               TRACE(_T("\n"));\r
+#endif\r
+               git_free_commit(&commit);\r
 \r
+               this->m_critSec.Lock();\r
+               m_logEntries.push_back(hash);\r
+               m_arShownList.Add(pRev);\r
+               this->m_critSec.Unlock();\r
+\r
+               if(t2-t1>500 || (m_logEntries.size()-oldsize >100))\r
+               {\r
+                       //update UI\r
+                       int percent=m_logEntries.size()*100/total + GITLOG_START+1;\r
+                       if(percent > 99)\r
+                               percent =99;\r
+                       if(percent < GITLOG_START)\r
+                               percent = GITLOG_START +1;\r
+\r
+                       oldsize = m_logEntries.size();\r
+                       PostMessage(LVM_SETITEMCOUNT, (WPARAM) this->m_logEntries.size(),(LPARAM) LVSICF_NOINVALIDATEALL|LVSICF_NOSCROLL);\r
+                       ::PostMessage(this->GetParent()->m_hWnd,MSG_LOAD_PERCENTAGE,(WPARAM) percent,0);\r
+               }               \r
+       }\r
+       \r
+       //Update UI;\r
+       PostMessage(LVM_SETITEMCOUNT, (WPARAM) this->m_logEntries.size(),(LPARAM) LVSICF_NOINVALIDATEALL|LVSICF_NOSCROLL);\r
+       ::PostMessage(this->GetParent()->m_hWnd,MSG_LOAD_PERCENTAGE,(WPARAM) GITLOG_END,0);\r
+\r
+       InterlockedExchange(&m_bThreadRunning, FALSE);\r
+\r
+#if 0\r
 //     if(m_ProcCallBack)\r
 //             m_ProcCallBack(m_ProcData,GITLOG_START);\r
        ::PostMessage(this->GetParent()->m_hWnd,MSG_LOAD_PERCENTAGE,(WPARAM) GITLOG_START,0);\r
@@ -2041,21 +2176,38 @@ UINT CGitLogListBase::LogThread()
        int update=0;\r
        for(int i=0;i<m_logEntries.size();i++)\r
        {\r
-               start=this->m_logEntries[i].ParserFromLog(m_logEntries.m_RawlogData,start);\r
-               m_logEntries.m_HashMap[m_logEntries[i].m_CommitHash]=i;\r
+               if( i==0 && m_logEntries.GetGitRevAt(i).m_CommitHash.IsEmpty() )\r
+               {\r
+                       m_logEntries.GetGitRevAt(i).m_Files.Clear();\r
+                       m_logEntries.GetGitRevAt(i).m_ParentHash.clear();\r
+                       m_logEntries.GetGitRevAt(i).m_ParentHash.push_back(m_HeadHash);\r
+                       g_Git.GetCommitDiffList(m_logEntries.GetGitRevAt(i).m_CommitHash.ToString(),this->m_HeadHash,m_logEntries.GetGitRevAt(i).m_Files);\r
+                       m_logEntries.GetGitRevAt(i).m_Action =0;\r
+                       for(int j=0;j< m_logEntries.GetGitRevAt(i).m_Files.GetCount();j++)\r
+                               m_logEntries.GetGitRevAt(i).m_Action |= m_logEntries.GetGitRevAt(i).m_Files[j].m_Action;\r
+                       \r
+                       m_logEntries.GetGitRevAt(i).m_Body.Format(_T("%d files changed"),m_logEntries.GetGitRevAt(i).m_Files.GetCount());\r
+                       ::PostMessage(m_hWnd,MSG_LOADED,(WPARAM)0,0);\r
+                       continue;\r
+               }\r
 \r
-               if(m_LogCache.GetCacheData(m_logEntries[i]))\r
+               start=this->m_logEntries.GetGitRevAt(i).ParserFromLog(m_logEntries.m_RawlogData,start);\r
+               m_logEntries.m_HashMap[m_logEntries.GetGitRevAt(i).m_CommitHash.ToString()]=i;\r
+\r
+               if(m_LogCache.GetCacheData(m_logEntries.GetGitRevAt(i)))\r
                {\r
                        if(firstcommit.IsEmpty())\r
-                               firstcommit=m_logEntries[i].m_CommitHash;\r
-                       lastcommit=m_logEntries[i].m_CommitHash;\r
+                               firstcommit=m_logEntries.GetGitRevAt(i).m_CommitHash.ToString();\r
+                       lastcommit=m_logEntries.GetGitRevAt(i).m_CommitHash.ToString();\r
 \r
                }else\r
                {\r
-                       InterlockedExchange(&m_logEntries[i].m_IsUpdateing,FALSE);\r
-                       InterlockedExchange(&m_logEntries[i].m_IsFull,TRUE);\r
+                       InterlockedExchange(&m_logEntries.GetGitRevAt(i).m_IsUpdateing,FALSE);\r
+                       InterlockedExchange(&m_logEntries.GetGitRevAt(i).m_IsFull,TRUE);\r
                        update++;\r
                }\r
+               ::PostMessage(m_hWnd,MSG_LOADED,(WPARAM) i, 0);\r
+\r
                if(start<0)\r
                        break;\r
                if(start>=m_logEntries.m_RawlogData.size())\r
@@ -2064,7 +2216,6 @@ UINT CGitLogListBase::LogThread()
                int percent=i*30/m_logEntries.size() + GITLOG_START+1;\r
 \r
                ::PostMessage(GetParent()->m_hWnd,MSG_LOAD_PERCENTAGE,(WPARAM) percent, 0);\r
-               ::PostMessage(m_hWnd,MSG_LOADED,(WPARAM) i, 0);\r
 \r
                if(this->m_bExitThread)\r
                {       \r
@@ -2114,7 +2265,7 @@ UINT CGitLogListBase::LogThread()
        ::PostMessage(this->GetParent()->m_hWnd,MSG_LOAD_PERCENTAGE,(WPARAM) GITLOG_END,0);\r
 \r
        InterlockedExchange(&m_bThreadRunning, FALSE);\r
-\r
+#endif\r
        return 0;\r
 }\r
 \r
@@ -2127,7 +2278,8 @@ void CGitLogListBase::Refresh()
                if(ret == WAIT_TIMEOUT)\r
                        TerminateThread();\r
        }\r
-\r
+       \r
+       this->SetItemCountEx(0);\r
        this->Clear();\r
 \r
        //Update branch and Tag info\r
@@ -2135,7 +2287,7 @@ void CGitLogListBase::Refresh()
        //Assume Thread have exited\r
        //if(!m_bThreadRunning)\r
        {\r
-               this->SetItemCountEx(0);\r
+               \r
                m_logEntries.clear();\r
                m_bExitThread=FALSE;\r
                InterlockedExchange(&m_bThreadRunning, TRUE);\r
@@ -2193,17 +2345,17 @@ void CGitLogListBase::RecalculateShownList(CPtrArray * pShownlist)
 #endif\r
                        if ((m_nSelectedFilter == LOGFILTER_ALL)||(m_nSelectedFilter == LOGFILTER_MESSAGES))\r
                        {\r
-                               ATLTRACE(_T("messge = \"%s\"\n"),m_logEntries[i].m_Subject);\r
-                               if (regex_search(wstring((LPCTSTR)m_logEntries[i].m_Subject), pat, flags)&&IsEntryInDateRange(i))\r
+                               ATLTRACE(_T("messge = \"%s\"\n"),m_logEntries.GetGitRevAt(i).m_Subject);\r
+                               if (regex_search(wstring((LPCTSTR)m_logEntries.GetGitRevAt(i).m_Subject), pat, flags)&&IsEntryInDateRange(i))\r
                                {\r
-                                       pShownlist->Add(&m_logEntries[i]);\r
+                                       pShownlist->Add(&m_logEntries.GetGitRevAt(i));\r
                                        continue;\r
                                }\r
 \r
-                               ATLTRACE(_T("messge = \"%s\"\n"),m_logEntries[i].m_Body);\r
-                               if (regex_search(wstring((LPCTSTR)m_logEntries[i].m_Body), pat, flags)&&IsEntryInDateRange(i))\r
+                               ATLTRACE(_T("messge = \"%s\"\n"),m_logEntries.GetGitRevAt(i).m_Body);\r
+                               if (regex_search(wstring((LPCTSTR)m_logEntries.GetGitRevAt(i).m_Body), pat, flags)&&IsEntryInDateRange(i))\r
                                {\r
-                                       pShownlist->Add(&m_logEntries[i]);\r
+                                       pShownlist->Add(&m_logEntries.GetGitRevAt(i));\r
                                        continue;\r
                                }\r
                        }\r
@@ -2241,18 +2393,18 @@ void CGitLogListBase::RecalculateShownList(CPtrArray * pShownlist)
 #endif\r
                        if ((m_nSelectedFilter == LOGFILTER_ALL)||(m_nSelectedFilter == LOGFILTER_AUTHORS))\r
                        {\r
-                               if (regex_search(wstring((LPCTSTR)m_logEntries[i].m_AuthorName), pat, flags)&&IsEntryInDateRange(i))\r
+                               if (regex_search(wstring((LPCTSTR)m_logEntries.GetGitRevAt(i).m_AuthorName), pat, flags)&&IsEntryInDateRange(i))\r
                                {\r
-                                       pShownlist->Add(&m_logEntries[i]);\r
+                                       pShownlist->Add(&m_logEntries.GetGitRevAt(i));\r
                                        continue;\r
                                }\r
                        }\r
                        if ((m_nSelectedFilter == LOGFILTER_ALL)||(m_nSelectedFilter == LOGFILTER_REVS))\r
                        {\r
-                               sRev.Format(_T("%s"), m_logEntries[i].m_CommitHash);\r
+                               sRev.Format(_T("%s"), m_logEntries.GetGitRevAt(i).m_CommitHash.ToString());\r
                                if (regex_search(wstring((LPCTSTR)sRev), pat, flags)&&IsEntryInDateRange(i))\r
                                {\r
-                                       pShownlist->Add(&m_logEntries[i]);\r
+                                       pShownlist->Add(&m_logEntries.GetGitRevAt(i));\r
                                        continue;\r
                                }\r
                        }\r
@@ -2276,20 +2428,20 @@ void CGitLogListBase::RecalculateShownList(CPtrArray * pShownlist)
 #endif\r
                        if ((m_nSelectedFilter == LOGFILTER_ALL)||(m_nSelectedFilter == LOGFILTER_MESSAGES))\r
                        {\r
-                               CString msg = m_logEntries[i].m_Subject;\r
+                               CString msg = m_logEntries.GetGitRevAt(i).m_Subject;\r
 \r
                                msg = msg.MakeLower();\r
                                if ((msg.Find(find) >= 0)&&(IsEntryInDateRange(i)))\r
                                {\r
-                                       pShownlist->Add(&m_logEntries[i]);\r
+                                       pShownlist->Add(&m_logEntries.GetGitRevAt(i));\r
                                        continue;\r
                                }\r
-                               msg = m_logEntries[i].m_Body;\r
+                               msg = m_logEntries.GetGitRevAt(i).m_Body;\r
 \r
                                msg = msg.MakeLower();\r
                                if ((msg.Find(find) >= 0)&&(IsEntryInDateRange(i)))\r
                                {\r
-                                       pShownlist->Add(&m_logEntries[i]);\r
+                                       pShownlist->Add(&m_logEntries.GetGitRevAt(i));\r
                                        continue;\r
                                }\r
                        }\r
@@ -2331,20 +2483,20 @@ void CGitLogListBase::RecalculateShownList(CPtrArray * pShownlist)
 #endif\r
                        if ((m_nSelectedFilter == LOGFILTER_ALL)||(m_nSelectedFilter == LOGFILTER_AUTHORS))\r
                        {\r
-                               CString msg = m_logEntries[i].m_AuthorName;\r
+                               CString msg = m_logEntries.GetGitRevAt(i).m_AuthorName;\r
                                msg = msg.MakeLower();\r
                                if ((msg.Find(find) >= 0)&&(IsEntryInDateRange(i)))\r
                                {\r
-                                       pShownlist->Add(&m_logEntries[i]);\r
+                                       pShownlist->Add(&m_logEntries.GetGitRevAt(i));\r
                                        continue;\r
                                }\r
                        }\r
                        if ((m_nSelectedFilter == LOGFILTER_ALL)||(m_nSelectedFilter == LOGFILTER_REVS))\r
                        {\r
-                               sRev.Format(_T("%s"), m_logEntries[i].m_CommitHash);\r
+                               sRev.Format(_T("%s"), m_logEntries.GetGitRevAt(i).m_CommitHash.ToString());\r
                                if ((sRev.Find(find) >= 0)&&(IsEntryInDateRange(i)))\r
                                {\r
-                                       pShownlist->Add(&m_logEntries[i]);\r
+                                       pShownlist->Add(&m_logEntries.GetGitRevAt(i));\r
                                        continue;\r
                                }\r
                        }\r
@@ -2355,7 +2507,7 @@ void CGitLogListBase::RecalculateShownList(CPtrArray * pShownlist)
 \r
 BOOL CGitLogListBase::IsEntryInDateRange(int i)\r
 {\r
-       __time64_t time = m_logEntries[i].m_AuthorDate.GetTime();\r
+       __time64_t time = m_logEntries.GetGitRevAt(i).m_AuthorDate.GetTime();\r
        if ((time >= m_From.GetTime())&&(time <= m_To.GetTime()))\r
                return TRUE;\r
 \r
@@ -2453,6 +2605,11 @@ LRESULT CGitLogListBase::OnLoad(WPARAM wParam,LPARAM lParam)
        int i=(int)wParam;\r
        this->GetItemRect(i,&rect,LVIR_BOUNDS);\r
        this->InvalidateRect(rect);\r
+\r
+       if(this->GetItemState(i,LVIF_STATE) & LVIS_SELECTED)\r
+       {\r
+               int i=0;\r
+       }\r
        return 0;\r
 }\r
 \r
@@ -2486,9 +2643,9 @@ int CGitLogListBase::GetHeadIndex()
                GitRev *pRev = (GitRev*)m_arShownList[i];\r
                if(pRev)\r
                {\r
-                       if(pRev->m_CommitHash == m_HeadHash )\r
+                       if(pRev->m_CommitHash.ToString() == m_HeadHash )\r
                                return i;\r
                }\r
        }\r
        return -1;\r
-}
\ No newline at end of file
+}\r