OSDN Git Service

Fix git blame log dialog show nothing
[tortoisegit/TortoiseGitJp.git] / src / TortoiseProc / LogDataVector.cpp
1 // TortoiseSVN - a Windows shell extension for easy version control\r
2 \r
3 // Copyright (C) 2007-2008 - TortoiseSVN\r
4 \r
5 // This program is free software; you can redistribute it and/or\r
6 // modify it under the terms of the GNU General Public License\r
7 // as published by the Free Software Foundation; either version 2\r
8 // of the License, or (at your option) any later version.\r
9 \r
10 // This program is distributed in the hope that it will be useful,\r
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13 // GNU General Public License for more details.\r
14 \r
15 // You should have received a copy of the GNU General Public License\r
16 // along with this program; if not, write to the Free Software Foundation,\r
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
18 //\r
19 /*\r
20         Description: start-up repository opening and reading\r
21 \r
22         Author: Marco Costalba (C) 2005-2007\r
23 \r
24         Copyright: See COPYING file that comes with this distribution\r
25 \r
26 */\r
27 \r
28 #include "stdafx.h"\r
29 #include "TortoiseProc.h"\r
30 #include "GitLogListBase.h"\r
31 #include "GitRev.h"\r
32 //#include "VssStyle.h"\r
33 #include "IconMenu.h"\r
34 // CGitLogList\r
35 #include "cursor.h"\r
36 #include "InputDlg.h"\r
37 #include "PropDlg.h"\r
38 #include "SVNProgressDlg.h"\r
39 #include "ProgressDlg.h"\r
40 //#include "RepositoryBrowser.h"\r
41 //#include "CopyDlg.h"\r
42 //#include "StatGraphDlg.h"\r
43 #include "Logdlg.h"\r
44 #include "MessageBox.h"\r
45 #include "Registry.h"\r
46 #include "AppUtils.h"\r
47 #include "PathUtils.h"\r
48 #include "StringUtils.h"\r
49 #include "UnicodeUtils.h"\r
50 #include "TempFile.h"\r
51 //#include "GitInfo.h"\r
52 //#include "GitDiff.h"\r
53 #include "IconMenu.h"\r
54 //#include "RevisionRangeDlg.h"\r
55 //#include "BrowseFolder.h"\r
56 //#include "BlameDlg.h"\r
57 //#include "Blame.h"\r
58 //#include "GitHelpers.h"\r
59 #include "GitStatus.h"\r
60 //#include "LogDlgHelper.h"\r
61 //#include "CachedLogInfo.h"\r
62 //#include "RepositoryInfo.h"\r
63 //#include "EditPropertiesDlg.h"\r
64 #include "FileDiffDlg.h"\r
65 #include "GitHash.h"\r
66 CGitHashMap a;\r
67 \r
68 void CLogDataVector::ClearAll()\r
69 {\r
70 \r
71         clear();\r
72         m_HashMap.clear();\r
73         m_Lns.clear();\r
74 \r
75         m_FirstFreeLane=0;\r
76         m_Lns.clear();\r
77 \r
78         m_RawlogData.clear();\r
79         m_RawLogStart.clear();\r
80 }\r
81 \r
82 int CLogDataVector::ParserShortLog(CTGitPath *path ,CString &hash,int count ,int mask )\r
83 {\r
84         BYTE_VECTOR log;\r
85         GitRev rev;\r
86 \r
87         if(g_Git.IsInitRepos())\r
88                 return 0;\r
89 \r
90         CString begin;\r
91         begin.Format(_T("#<%c>"),LOG_REV_ITEM_BEGIN);\r
92 \r
93         //g_Git.GetShortLog(log,path,count);\r
94 \r
95         g_Git.GetLog(log,hash,path,count,mask);\r
96 \r
97         if(log.size()==0)\r
98                 return 0;\r
99         \r
100         int start=4;\r
101         int length;\r
102         int next =0;\r
103         while( next>=0 && next<log.size())\r
104         {\r
105                 next=rev.ParserFromLog(log,next);\r
106 \r
107                 rev.m_Subject=_T("Load .................................");\r
108                 this->push_back(rev.m_CommitHash);\r
109 \r
110                 if(this->m_pLogCache->m_HashMap.IsExist(rev.m_CommitHash))\r
111                 {\r
112                         if(!this->m_pLogCache->m_HashMap[rev.m_CommitHash].m_IsFull)\r
113                                 this->m_pLogCache->m_HashMap[rev.m_CommitHash].CopyFrom(rev);\r
114                 }else\r
115                         this->m_pLogCache->m_HashMap[rev.m_CommitHash].CopyFrom(rev);\r
116 \r
117                 m_HashMap[rev.m_CommitHash]=size()-1;\r
118 \r
119                 //next=log.find(0,next);\r
120         }\r
121 \r
122         return 0;\r
123 \r
124 }\r
125 int CLogDataVector::FetchShortLog(CTGitPath *path ,CString &hash,int count ,int mask, int ShowWC )\r
126 {\r
127         //BYTE_VECTOR log;\r
128         m_RawlogData.clear();\r
129         m_RawLogStart.clear();\r
130 \r
131         GitRev rev;\r
132         \r
133         if(g_Git.IsInitRepos())\r
134                 return 0;\r
135 \r
136         CString begin;\r
137         begin.Format(_T("#<%c>"),LOG_REV_ITEM_BEGIN);\r
138 \r
139         //g_Git.GetShortLog(log,path,count);\r
140         ULONGLONG  t1,t2;\r
141         t1=GetTickCount();\r
142         g_Git.GetLog(m_RawlogData, hash,path,count,mask);\r
143         t2=GetTickCount();\r
144 \r
145         TRACE(_T("GetLog Time %ld\r\n"),t2-t1);\r
146 \r
147         if(m_RawlogData.size()==0)\r
148                 return 0;\r
149         \r
150         int start=4;\r
151         int length;\r
152         int next =0;\r
153         t1=GetTickCount();\r
154         int a1=0,b1=0;\r
155 \r
156         while( next>=0 && next<m_RawlogData.size())\r
157         {\r
158                 static const BYTE dataToFind[]={0,0};\r
159                 m_RawLogStart.push_back(next);\r
160                 //this->at(i).m_Subject=_T("parser...");\r
161                 next=m_RawlogData.findData(dataToFind,2,next+1);\r
162                 //next=log.find(0,next);\r
163         }\r
164 \r
165         resize(m_RawLogStart.size() + ShowWC);\r
166 \r
167         t2=GetTickCount();\r
168 \r
169         return 0;\r
170 }\r
171 int CLogDataVector::FetchFullInfo(int i)\r
172 {\r
173         return GetGitRevAt(i).SafeFetchFullInfo(&g_Git);\r
174 }\r
175 //CLogDataVector Class\r
176 int CLogDataVector::ParserFromLog(CTGitPath *path ,int count ,int infomask,CString *from,CString *to)\r
177 {\r
178         BYTE_VECTOR log;\r
179         GitRev rev;\r
180         CString emptyhash;\r
181         g_Git.GetLog(log,emptyhash,path,count,infomask,from,to);\r
182 \r
183         CString begin;\r
184         begin.Format(_T("#<%c>"),LOG_REV_ITEM_BEGIN);\r
185         \r
186         if(log.size()==0)\r
187                 return 0;\r
188         \r
189         int start=4;\r
190         int length;\r
191         int next =0;\r
192         while( next>=0 )\r
193         {\r
194                 next=rev.ParserFromLog(log,next);\r
195 \r
196                 if(this->m_pLogCache->m_HashMap.IsExist(rev.m_CommitHash))\r
197                 {\r
198                         if(!this->m_pLogCache->m_HashMap[rev.m_CommitHash].m_IsFull)\r
199                         {\r
200                                 this->m_pLogCache->m_HashMap[rev.m_CommitHash].CopyFrom(rev);\r
201                         }\r
202                 }else\r
203                         this->m_pLogCache->m_HashMap[rev.m_CommitHash].CopyFrom(rev);\r
204 \r
205                 this->m_pLogCache->m_HashMap[rev.m_CommitHash].m_IsFull=true;\r
206 \r
207                 this->push_back(rev.m_CommitHash);\r
208 \r
209                 m_HashMap[rev.m_CommitHash]=size()-1;           \r
210         }\r
211 \r
212         return 0;\r
213 }\r
214 \r
215 int CLogDataVector::ParserFromRefLog(CString ref)\r
216 {\r
217         CString cmd,out;\r
218         GitRev rev;\r
219         cmd.Format(_T("git.exe reflog show %s"),ref);\r
220         if(g_Git.Run(cmd,&out,CP_UTF8))\r
221                 return -1;\r
222         \r
223         int pos=0;\r
224         while(pos>=0)\r
225         {\r
226                 CString one=out.Tokenize(_T("\n"),pos);\r
227                 int ref=one.Find(_T(' '),0);\r
228                 if(ref<0)\r
229                         continue;\r
230 \r
231                 rev.Clear();\r
232 \r
233                 rev.m_CommitHash=g_Git.GetHash(one.Left(ref));\r
234                 int action=one.Find(_T(' '),ref+1);\r
235                 int message;\r
236                 if(action>0)\r
237                 {\r
238                         rev.m_Ref=one.Mid(ref+1,action-ref-2);\r
239                         message=one.Find(_T(":"),action);\r
240                         if(message>0)\r
241                         {\r
242                                 rev.m_RefAction=one.Mid(action+1,message-action-1);\r
243                                 rev.m_Subject=one.Right(one.GetLength()-message-1);\r
244                         }\r
245                 }\r
246 \r
247                 if(this->m_pLogCache->m_HashMap.IsExist(rev.m_CommitHash))\r
248                 {\r
249                         if(!this->m_pLogCache->m_HashMap[rev.m_CommitHash].m_IsFull)\r
250                                 this->m_pLogCache->m_HashMap[rev.m_CommitHash].CopyFrom(rev);\r
251                 }else\r
252                         this->m_pLogCache->m_HashMap[rev.m_CommitHash].CopyFrom(rev);\r
253 \r
254         }\r
255         return 0;\r
256 }\r
257 \r
258 void CLogDataVector::setLane(CGitHash& sha) \r
259 {\r
260         Lanes* l = &(this->m_Lns);\r
261         int i = m_FirstFreeLane;\r
262         \r
263 //      QVector<QByteArray> ba;\r
264 //      const ShaString& ss = toPersistentSha(sha, ba);\r
265 //      const ShaVect& shaVec(fh->revOrder);\r
266 \r
267         for (int cnt = size(); i < cnt; ++i) {\r
268 \r
269                 GitRev* r = & this->GetGitRevAt(i); \r
270                 CGitHash curSha=r->m_CommitHash;\r
271 \r
272                 if (r->m_Lanes.size() == 0)\r
273                         updateLanes(*r, *l, curSha);\r
274 \r
275                 if (curSha == sha)\r
276                         break;\r
277         }\r
278         m_FirstFreeLane = ++i;\r
279 \r
280 #if 0\r
281         Lanes* l = &(this->m_Lanes);\r
282         int i = m_FirstFreeLane;\r
283         \r
284         QVector<QByteArray> ba;\r
285         const ShaString& ss = toPersistentSha(sha, ba);\r
286         const ShaVect& shaVec(fh->revOrder);\r
287 \r
288         for (uint cnt = shaVec.count(); i < cnt; ++i) {\r
289 \r
290                 const ShaString& curSha = shaVec[i];\r
291                 Rev* r = m_HashMap[curSha]const_cast<Rev*>(revLookup(curSha, fh));\r
292                 if (r->lanes.count() == 0)\r
293                         updateLanes(*r, *l, curSha);\r
294 \r
295                 if (curSha == ss)\r
296                         break;\r
297         }\r
298         fh->firstFreeLane = ++i;\r
299 #endif\r
300 }\r
301 \r
302 \r
303 void CLogDataVector::updateLanes(GitRev& c, Lanes& lns, CGitHash &sha) \r
304 {\r
305 // we could get third argument from c.sha(), but we are in fast path here\r
306 // and c.sha() involves a deep copy, so we accept a little redundancy\r
307 \r
308         if (lns.isEmpty())\r
309                 lns.init(sha);\r
310 \r
311         bool isDiscontinuity;\r
312         bool isFork = lns.isFork(sha, isDiscontinuity);\r
313         bool isMerge = (c.ParentsCount() > 1);\r
314         bool isInitial = (c.ParentsCount() == 0);\r
315 \r
316         if (isDiscontinuity)\r
317                 lns.changeActiveLane(sha); // uses previous isBoundary state\r
318 \r
319         lns.setBoundary(c.IsBoundary() == TRUE); // update must be here\r
320         TRACE(_T("%s %d"),c.m_CommitHash.ToString(),c.IsBoundary());\r
321 \r
322         if (isFork)\r
323                 lns.setFork(sha);\r
324         if (isMerge)\r
325                 lns.setMerge(c.m_ParentHash);\r
326         //if (c.isApplied)\r
327         //      lns.setApplied();\r
328         if (isInitial)\r
329                 lns.setInitial();\r
330 \r
331         lns.getLanes(c.m_Lanes); // here lanes are snapshotted\r
332 \r
333         CGitHash nextSha;\r
334         if( !isInitial) \r
335                 nextSha = c.m_ParentHash[0];\r
336 \r
337         lns.nextParent(nextSha);\r
338 \r
339         //if (c.isApplied)\r
340         //      lns.afterApplied();\r
341         if (isMerge)\r
342                 lns.afterMerge();\r
343         if (isFork)\r
344                 lns.afterFork();\r
345         if (lns.isBranch())\r
346                 lns.afterBranch();\r
347 \r
348 //      QString tmp = "", tmp2;\r
349 //      for (uint i = 0; i < c.lanes.count(); i++) {\r
350 //              tmp2.setNum(c.lanes[i]);\r
351 //              tmp.append(tmp2 + "-");\r
352 //      }\r
353 //      qDebug("%s %s",tmp.latin1(), c.sha.latin1());\r
354 }