OSDN Git Service

Fix git blame log dialog show nothing
[tortoisegit/TortoiseGitJp.git] / src / TortoiseProc / LogDataVector.cpp
index 08ff2f7..3de4393 100644 (file)
-// TortoiseSVN - a Windows shell extension for easy version control
-
-// Copyright (C) 2007-2008 - TortoiseSVN
-
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software Foundation,
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-//
-/*
-       Description: start-up repository opening and reading
-
-       Author: Marco Costalba (C) 2005-2007
-
-       Copyright: See COPYING file that comes with this distribution
-
-*/
-
-#include "stdafx.h"
-#include "TortoiseProc.h"
-#include "GitLogListBase.h"
-#include "GitRev.h"
-//#include "VssStyle.h"
-#include "IconMenu.h"
-// CGitLogList
-#include "cursor.h"
-#include "InputDlg.h"
-#include "PropDlg.h"
-#include "SVNProgressDlg.h"
-#include "ProgressDlg.h"
-//#include "RepositoryBrowser.h"
-//#include "CopyDlg.h"
-//#include "StatGraphDlg.h"
-#include "Logdlg.h"
-#include "MessageBox.h"
-#include "Registry.h"
-#include "AppUtils.h"
-#include "PathUtils.h"
-#include "StringUtils.h"
-#include "UnicodeUtils.h"
-#include "TempFile.h"
-//#include "GitInfo.h"
-//#include "GitDiff.h"
-#include "IconMenu.h"
-//#include "RevisionRangeDlg.h"
-//#include "BrowseFolder.h"
-//#include "BlameDlg.h"
-//#include "Blame.h"
-//#include "GitHelpers.h"
-#include "GitStatus.h"
-//#include "LogDlgHelper.h"
-//#include "CachedLogInfo.h"
-//#include "RepositoryInfo.h"
-//#include "EditPropertiesDlg.h"
-#include "FileDiffDlg.h"
-
-
-int CLogDataVector::ParserShortLog(CTGitPath *path ,CString &hash,int count ,int mask )
-{
-       BYTE_VECTOR log;
-       GitRev rev;
-
-       if(g_Git.IsInitRepos())
-               return 0;
-
-       CString begin;
-       begin.Format(_T("#<%c>"),LOG_REV_ITEM_BEGIN);
-
-       //g_Git.GetShortLog(log,path,count);
-
-       g_Git.GetLog(log,hash,path,count,mask);
-
-       if(log.size()==0)
-               return 0;
-       
-       int start=4;
-       int length;
-       int next =0;
-       while( next>=0 && next<log.size())
-       {
-               next=rev.ParserFromLog(log,next);
-
-               rev.m_Subject=_T("Load .................................");
-               this->push_back(rev);
-               m_HashMap[rev.m_CommitHash]=size()-1;
-
-               //next=log.find(0,next);
-       }
-
-       return 0;
-
-}
-int CLogDataVector::FetchFullInfo(int i)
-{
-       return at(i).SafeFetchFullInfo(&g_Git);
-}
-//CLogDataVector Class
-int CLogDataVector::ParserFromLog(CTGitPath *path ,int count ,int infomask)
-{
-       BYTE_VECTOR log;
-       GitRev rev;
-       CString emptyhash;
-       g_Git.GetLog(log,emptyhash,path,count,infomask);
-
-       CString begin;
-       begin.Format(_T("#<%c>"),LOG_REV_ITEM_BEGIN);
-       
-       if(log.size()==0)
-               return 0;
-       
-       int start=4;
-       int length;
-       int next =0;
-       while( next>=0 )
-       {
-               next=rev.ParserFromLog(log,next);
-               this->push_back(rev);
-               m_HashMap[rev.m_CommitHash]=size()-1;           
-       }
-
-       return 0;
-}
-
-void CLogDataVector::setLane(CString& sha) 
-{
-       Lanes* l = &(this->m_Lns);
-       int i = m_FirstFreeLane;
-       
-//     QVector<QByteArray> ba;
-//     const ShaString& ss = toPersistentSha(sha, ba);
-//     const ShaVect& shaVec(fh->revOrder);
-
-       for (int cnt = size(); i < cnt; ++i) {
-
-               GitRev* r = &(*this)[i]; 
-               CString &curSha=r->m_CommitHash;
-
-               if (r->m_Lanes.size() == 0)
-                       updateLanes(*r, *l, curSha);
-
-               if (curSha == sha)
-                       break;
-       }
-       m_FirstFreeLane = ++i;
-
-#if 0
-       Lanes* l = &(this->m_Lanes);
-       int i = m_FirstFreeLane;
-       
-       QVector<QByteArray> ba;
-       const ShaString& ss = toPersistentSha(sha, ba);
-       const ShaVect& shaVec(fh->revOrder);
-
-       for (uint cnt = shaVec.count(); i < cnt; ++i) {
-
-               const ShaString& curSha = shaVec[i];
-               Rev* r = m_HashMap[curSha]const_cast<Rev*>(revLookup(curSha, fh));
-               if (r->lanes.count() == 0)
-                       updateLanes(*r, *l, curSha);
-
-               if (curSha == ss)
-                       break;
-       }
-       fh->firstFreeLane = ++i;
-#endif
-}
-
-
-void CLogDataVector::updateLanes(GitRev& c, Lanes& lns, CString &sha) 
-{
-// we could get third argument from c.sha(), but we are in fast path here
-// and c.sha() involves a deep copy, so we accept a little redundancy
-
-       if (lns.isEmpty())
-               lns.init(sha);
-
-       bool isDiscontinuity;
-       bool isFork = lns.isFork(sha, isDiscontinuity);
-       bool isMerge = (c.ParentsCount() > 1);
-       bool isInitial = (c.ParentsCount() == 0);
-
-       if (isDiscontinuity)
-               lns.changeActiveLane(sha); // uses previous isBoundary state
-
-       lns.setBoundary(c.IsBoundary() == TRUE); // update must be here
-       TRACE(_T("%s %d"),c.m_CommitHash,c.IsBoundary());
-
-       if (isFork)
-               lns.setFork(sha);
-       if (isMerge)
-               lns.setMerge(c.m_ParentHash);
-       //if (c.isApplied)
-       //      lns.setApplied();
-       if (isInitial)
-               lns.setInitial();
-
-       lns.getLanes(c.m_Lanes); // here lanes are snapshotted
-
-       CString nextSha = (isInitial) ? CString(_T("")) : QString(c.m_ParentHash[0]);
-
-       lns.nextParent(nextSha);
-
-       //if (c.isApplied)
-       //      lns.afterApplied();
-       if (isMerge)
-               lns.afterMerge();
-       if (isFork)
-               lns.afterFork();
-       if (lns.isBranch())
-               lns.afterBranch();
-
-//     QString tmp = "", tmp2;
-//     for (uint i = 0; i < c.lanes.count(); i++) {
-//             tmp2.setNum(c.lanes[i]);
-//             tmp.append(tmp2 + "-");
-//     }
-//     qDebug("%s %s",tmp.latin1(), c.sha.latin1());
+// TortoiseSVN - a Windows shell extension for easy version control\r
+\r
+// Copyright (C) 2007-2008 - TortoiseSVN\r
+\r
+// This program is free software; you can redistribute it and/or\r
+// modify it under the terms of the GNU General Public License\r
+// as published by the Free Software Foundation; either version 2\r
+// of the License, or (at your option) any later version.\r
+\r
+// This program is distributed in the hope that it will be useful,\r
+// but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+// GNU General Public License for more details.\r
+\r
+// You should have received a copy of the GNU General Public License\r
+// along with this program; if not, write to the Free Software Foundation,\r
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+//\r
+/*\r
+       Description: start-up repository opening and reading\r
+\r
+       Author: Marco Costalba (C) 2005-2007\r
+\r
+       Copyright: See COPYING file that comes with this distribution\r
+\r
+*/\r
+\r
+#include "stdafx.h"\r
+#include "TortoiseProc.h"\r
+#include "GitLogListBase.h"\r
+#include "GitRev.h"\r
+//#include "VssStyle.h"\r
+#include "IconMenu.h"\r
+// CGitLogList\r
+#include "cursor.h"\r
+#include "InputDlg.h"\r
+#include "PropDlg.h"\r
+#include "SVNProgressDlg.h"\r
+#include "ProgressDlg.h"\r
+//#include "RepositoryBrowser.h"\r
+//#include "CopyDlg.h"\r
+//#include "StatGraphDlg.h"\r
+#include "Logdlg.h"\r
+#include "MessageBox.h"\r
+#include "Registry.h"\r
+#include "AppUtils.h"\r
+#include "PathUtils.h"\r
+#include "StringUtils.h"\r
+#include "UnicodeUtils.h"\r
+#include "TempFile.h"\r
+//#include "GitInfo.h"\r
+//#include "GitDiff.h"\r
+#include "IconMenu.h"\r
+//#include "RevisionRangeDlg.h"\r
+//#include "BrowseFolder.h"\r
+//#include "BlameDlg.h"\r
+//#include "Blame.h"\r
+//#include "GitHelpers.h"\r
+#include "GitStatus.h"\r
+//#include "LogDlgHelper.h"\r
+//#include "CachedLogInfo.h"\r
+//#include "RepositoryInfo.h"\r
+//#include "EditPropertiesDlg.h"\r
+#include "FileDiffDlg.h"\r
+#include "GitHash.h"\r
+CGitHashMap a;\r
+\r
+void CLogDataVector::ClearAll()\r
+{\r
+\r
+       clear();\r
+       m_HashMap.clear();\r
+       m_Lns.clear();\r
+\r
+       m_FirstFreeLane=0;\r
+       m_Lns.clear();\r
+\r
+       m_RawlogData.clear();\r
+       m_RawLogStart.clear();\r
+}\r
+\r
+int CLogDataVector::ParserShortLog(CTGitPath *path ,CString &hash,int count ,int mask )\r
+{\r
+       BYTE_VECTOR log;\r
+       GitRev rev;\r
+\r
+       if(g_Git.IsInitRepos())\r
+               return 0;\r
+\r
+       CString begin;\r
+       begin.Format(_T("#<%c>"),LOG_REV_ITEM_BEGIN);\r
+\r
+       //g_Git.GetShortLog(log,path,count);\r
+\r
+       g_Git.GetLog(log,hash,path,count,mask);\r
+\r
+       if(log.size()==0)\r
+               return 0;\r
+       \r
+       int start=4;\r
+       int length;\r
+       int next =0;\r
+       while( next>=0 && next<log.size())\r
+       {\r
+               next=rev.ParserFromLog(log,next);\r
+\r
+               rev.m_Subject=_T("Load .................................");\r
+               this->push_back(rev.m_CommitHash);\r
+\r
+               if(this->m_pLogCache->m_HashMap.IsExist(rev.m_CommitHash))\r
+               {\r
+                       if(!this->m_pLogCache->m_HashMap[rev.m_CommitHash].m_IsFull)\r
+                               this->m_pLogCache->m_HashMap[rev.m_CommitHash].CopyFrom(rev);\r
+               }else\r
+                       this->m_pLogCache->m_HashMap[rev.m_CommitHash].CopyFrom(rev);\r
+\r
+               m_HashMap[rev.m_CommitHash]=size()-1;\r
+\r
+               //next=log.find(0,next);\r
+       }\r
+\r
+       return 0;\r
+\r
+}\r
+int CLogDataVector::FetchShortLog(CTGitPath *path ,CString &hash,int count ,int mask, int ShowWC )\r
+{\r
+       //BYTE_VECTOR log;\r
+       m_RawlogData.clear();\r
+       m_RawLogStart.clear();\r
+\r
+       GitRev rev;\r
+       \r
+       if(g_Git.IsInitRepos())\r
+               return 0;\r
+\r
+       CString begin;\r
+       begin.Format(_T("#<%c>"),LOG_REV_ITEM_BEGIN);\r
+\r
+       //g_Git.GetShortLog(log,path,count);\r
+       ULONGLONG  t1,t2;\r
+       t1=GetTickCount();\r
+       g_Git.GetLog(m_RawlogData, hash,path,count,mask);\r
+       t2=GetTickCount();\r
+\r
+       TRACE(_T("GetLog Time %ld\r\n"),t2-t1);\r
+\r
+       if(m_RawlogData.size()==0)\r
+               return 0;\r
+       \r
+       int start=4;\r
+       int length;\r
+       int next =0;\r
+       t1=GetTickCount();\r
+       int a1=0,b1=0;\r
+\r
+       while( next>=0 && next<m_RawlogData.size())\r
+       {\r
+               static const BYTE dataToFind[]={0,0};\r
+               m_RawLogStart.push_back(next);\r
+               //this->at(i).m_Subject=_T("parser...");\r
+               next=m_RawlogData.findData(dataToFind,2,next+1);\r
+               //next=log.find(0,next);\r
+       }\r
+\r
+       resize(m_RawLogStart.size() + ShowWC);\r
+\r
+       t2=GetTickCount();\r
+\r
+       return 0;\r
+}\r
+int CLogDataVector::FetchFullInfo(int i)\r
+{\r
+       return GetGitRevAt(i).SafeFetchFullInfo(&g_Git);\r
+}\r
+//CLogDataVector Class\r
+int CLogDataVector::ParserFromLog(CTGitPath *path ,int count ,int infomask,CString *from,CString *to)\r
+{\r
+       BYTE_VECTOR log;\r
+       GitRev rev;\r
+       CString emptyhash;\r
+       g_Git.GetLog(log,emptyhash,path,count,infomask,from,to);\r
+\r
+       CString begin;\r
+       begin.Format(_T("#<%c>"),LOG_REV_ITEM_BEGIN);\r
+       \r
+       if(log.size()==0)\r
+               return 0;\r
+       \r
+       int start=4;\r
+       int length;\r
+       int next =0;\r
+       while( next>=0 )\r
+       {\r
+               next=rev.ParserFromLog(log,next);\r
+\r
+               if(this->m_pLogCache->m_HashMap.IsExist(rev.m_CommitHash))\r
+               {\r
+                       if(!this->m_pLogCache->m_HashMap[rev.m_CommitHash].m_IsFull)\r
+                       {\r
+                               this->m_pLogCache->m_HashMap[rev.m_CommitHash].CopyFrom(rev);\r
+                       }\r
+               }else\r
+                       this->m_pLogCache->m_HashMap[rev.m_CommitHash].CopyFrom(rev);\r
+\r
+               this->m_pLogCache->m_HashMap[rev.m_CommitHash].m_IsFull=true;\r
+\r
+               this->push_back(rev.m_CommitHash);\r
+\r
+               m_HashMap[rev.m_CommitHash]=size()-1;           \r
+       }\r
+\r
+       return 0;\r
+}\r
+\r
+int CLogDataVector::ParserFromRefLog(CString ref)\r
+{\r
+       CString cmd,out;\r
+       GitRev rev;\r
+       cmd.Format(_T("git.exe reflog show %s"),ref);\r
+       if(g_Git.Run(cmd,&out,CP_UTF8))\r
+               return -1;\r
+       \r
+       int pos=0;\r
+       while(pos>=0)\r
+       {\r
+               CString one=out.Tokenize(_T("\n"),pos);\r
+               int ref=one.Find(_T(' '),0);\r
+               if(ref<0)\r
+                       continue;\r
+\r
+               rev.Clear();\r
+\r
+               rev.m_CommitHash=g_Git.GetHash(one.Left(ref));\r
+               int action=one.Find(_T(' '),ref+1);\r
+               int message;\r
+               if(action>0)\r
+               {\r
+                       rev.m_Ref=one.Mid(ref+1,action-ref-2);\r
+                       message=one.Find(_T(":"),action);\r
+                       if(message>0)\r
+                       {\r
+                               rev.m_RefAction=one.Mid(action+1,message-action-1);\r
+                               rev.m_Subject=one.Right(one.GetLength()-message-1);\r
+                       }\r
+               }\r
+\r
+               if(this->m_pLogCache->m_HashMap.IsExist(rev.m_CommitHash))\r
+               {\r
+                       if(!this->m_pLogCache->m_HashMap[rev.m_CommitHash].m_IsFull)\r
+                               this->m_pLogCache->m_HashMap[rev.m_CommitHash].CopyFrom(rev);\r
+               }else\r
+                       this->m_pLogCache->m_HashMap[rev.m_CommitHash].CopyFrom(rev);\r
+\r
+       }\r
+       return 0;\r
+}\r
+\r
+void CLogDataVector::setLane(CGitHash& sha) \r
+{\r
+       Lanes* l = &(this->m_Lns);\r
+       int i = m_FirstFreeLane;\r
+       \r
+//     QVector<QByteArray> ba;\r
+//     const ShaString& ss = toPersistentSha(sha, ba);\r
+//     const ShaVect& shaVec(fh->revOrder);\r
+\r
+       for (int cnt = size(); i < cnt; ++i) {\r
+\r
+               GitRev* r = & this->GetGitRevAt(i); \r
+               CGitHash curSha=r->m_CommitHash;\r
+\r
+               if (r->m_Lanes.size() == 0)\r
+                       updateLanes(*r, *l, curSha);\r
+\r
+               if (curSha == sha)\r
+                       break;\r
+       }\r
+       m_FirstFreeLane = ++i;\r
+\r
+#if 0\r
+       Lanes* l = &(this->m_Lanes);\r
+       int i = m_FirstFreeLane;\r
+       \r
+       QVector<QByteArray> ba;\r
+       const ShaString& ss = toPersistentSha(sha, ba);\r
+       const ShaVect& shaVec(fh->revOrder);\r
+\r
+       for (uint cnt = shaVec.count(); i < cnt; ++i) {\r
+\r
+               const ShaString& curSha = shaVec[i];\r
+               Rev* r = m_HashMap[curSha]const_cast<Rev*>(revLookup(curSha, fh));\r
+               if (r->lanes.count() == 0)\r
+                       updateLanes(*r, *l, curSha);\r
+\r
+               if (curSha == ss)\r
+                       break;\r
+       }\r
+       fh->firstFreeLane = ++i;\r
+#endif\r
+}\r
+\r
+\r
+void CLogDataVector::updateLanes(GitRev& c, Lanes& lns, CGitHash &sha) \r
+{\r
+// we could get third argument from c.sha(), but we are in fast path here\r
+// and c.sha() involves a deep copy, so we accept a little redundancy\r
+\r
+       if (lns.isEmpty())\r
+               lns.init(sha);\r
+\r
+       bool isDiscontinuity;\r
+       bool isFork = lns.isFork(sha, isDiscontinuity);\r
+       bool isMerge = (c.ParentsCount() > 1);\r
+       bool isInitial = (c.ParentsCount() == 0);\r
+\r
+       if (isDiscontinuity)\r
+               lns.changeActiveLane(sha); // uses previous isBoundary state\r
+\r
+       lns.setBoundary(c.IsBoundary() == TRUE); // update must be here\r
+       TRACE(_T("%s %d"),c.m_CommitHash.ToString(),c.IsBoundary());\r
+\r
+       if (isFork)\r
+               lns.setFork(sha);\r
+       if (isMerge)\r
+               lns.setMerge(c.m_ParentHash);\r
+       //if (c.isApplied)\r
+       //      lns.setApplied();\r
+       if (isInitial)\r
+               lns.setInitial();\r
+\r
+       lns.getLanes(c.m_Lanes); // here lanes are snapshotted\r
+\r
+       CGitHash nextSha;\r
+       if( !isInitial) \r
+               nextSha = c.m_ParentHash[0];\r
+\r
+       lns.nextParent(nextSha);\r
+\r
+       //if (c.isApplied)\r
+       //      lns.afterApplied();\r
+       if (isMerge)\r
+               lns.afterMerge();\r
+       if (isFork)\r
+               lns.afterFork();\r
+       if (lns.isBranch())\r
+               lns.afterBranch();\r
+\r
+//     QString tmp = "", tmp2;\r
+//     for (uint i = 0; i < c.lanes.count(); i++) {\r
+//             tmp2.setNum(c.lanes[i]);\r
+//             tmp.append(tmp2 + "-");\r
+//     }\r
+//     qDebug("%s %s",tmp.latin1(), c.sha.latin1());\r
 }
\ No newline at end of file