OSDN Git Service

fad928d79ee5e9f6b56cb213b97f27b9e491c463
[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         this->m_pLogCache->ClearAllParent();\r
182 \r
183         g_Git.GetLog(log,emptyhash,path,count,infomask,from,to);\r
184 \r
185         CString begin;\r
186         begin.Format(_T("#<%c>"),LOG_REV_ITEM_BEGIN);\r
187         \r
188         if(log.size()==0)\r
189                 return 0;\r
190         \r
191         int start=4;\r
192         int length;\r
193         int next =0;\r
194         while( next>=0 )\r
195         {\r
196                 next=rev.ParserFromLog(log,next);\r
197 \r
198                 if(this->m_pLogCache->m_HashMap.IsExist(rev.m_CommitHash))\r
199                 {\r
200                         if(!this->m_pLogCache->m_HashMap[rev.m_CommitHash].m_IsFull)\r
201                         {\r
202                                 this->m_pLogCache->m_HashMap[rev.m_CommitHash].CopyFrom(rev);\r
203                         }\r
204                 }else\r
205                         this->m_pLogCache->m_HashMap[rev.m_CommitHash].CopyFrom(rev);\r
206 \r
207                 this->m_pLogCache->m_HashMap[rev.m_CommitHash].m_IsFull=true;\r
208 \r
209                 this->push_back(rev.m_CommitHash);\r
210 \r
211                 m_HashMap[rev.m_CommitHash]=size()-1;           \r
212         }\r
213 \r
214         return 0;\r
215 }\r
216 \r
217 int CLogDataVector::ParserFromRefLog(CString ref)\r
218 {\r
219         CString cmd,out;\r
220         GitRev rev;\r
221         cmd.Format(_T("git.exe reflog show %s"),ref);\r
222         if(g_Git.Run(cmd,&out,CP_UTF8))\r
223                 return -1;\r
224         \r
225         int pos=0;\r
226         while(pos>=0)\r
227         {\r
228                 CString one=out.Tokenize(_T("\n"),pos);\r
229                 int ref=one.Find(_T(' '),0);\r
230                 if(ref<0)\r
231                         continue;\r
232 \r
233                 rev.Clear();\r
234 \r
235                 rev.m_CommitHash=g_Git.GetHash(one.Left(ref));\r
236                 int action=one.Find(_T(' '),ref+1);\r
237                 int message;\r
238                 if(action>0)\r
239                 {\r
240                         rev.m_Ref=one.Mid(ref+1,action-ref-2);\r
241                         message=one.Find(_T(":"),action);\r
242                         if(message>0)\r
243                         {\r
244                                 rev.m_RefAction=one.Mid(action+1,message-action-1);\r
245                                 rev.m_Subject=one.Right(one.GetLength()-message-1);\r
246                         }\r
247                 }\r
248 \r
249                 if(this->m_pLogCache->m_HashMap.IsExist(rev.m_CommitHash))\r
250                 {\r
251                         if(!this->m_pLogCache->m_HashMap[rev.m_CommitHash].m_IsFull)\r
252                                 this->m_pLogCache->m_HashMap[rev.m_CommitHash].CopyFrom(rev);\r
253                 }else\r
254                         this->m_pLogCache->m_HashMap[rev.m_CommitHash].CopyFrom(rev);\r
255 \r
256         }\r
257         return 0;\r
258 }\r
259 \r
260 void CLogDataVector::setLane(CGitHash& sha) \r
261 {\r
262         Lanes* l = &(this->m_Lns);\r
263         int i = m_FirstFreeLane;\r
264         \r
265 //      QVector<QByteArray> ba;\r
266 //      const ShaString& ss = toPersistentSha(sha, ba);\r
267 //      const ShaVect& shaVec(fh->revOrder);\r
268 \r
269         for (int cnt = size(); i < cnt; ++i) {\r
270 \r
271                 GitRev* r = & this->GetGitRevAt(i); \r
272                 CGitHash curSha=r->m_CommitHash;\r
273 \r
274                 if (r->m_Lanes.size() == 0)\r
275                         updateLanes(*r, *l, curSha);\r
276 \r
277                 if (curSha == sha)\r
278                         break;\r
279         }\r
280         m_FirstFreeLane = ++i;\r
281 \r
282 #if 0\r
283         Lanes* l = &(this->m_Lanes);\r
284         int i = m_FirstFreeLane;\r
285         \r
286         QVector<QByteArray> ba;\r
287         const ShaString& ss = toPersistentSha(sha, ba);\r
288         const ShaVect& shaVec(fh->revOrder);\r
289 \r
290         for (uint cnt = shaVec.count(); i < cnt; ++i) {\r
291 \r
292                 const ShaString& curSha = shaVec[i];\r
293                 Rev* r = m_HashMap[curSha]const_cast<Rev*>(revLookup(curSha, fh));\r
294                 if (r->lanes.count() == 0)\r
295                         updateLanes(*r, *l, curSha);\r
296 \r
297                 if (curSha == ss)\r
298                         break;\r
299         }\r
300         fh->firstFreeLane = ++i;\r
301 #endif\r
302 }\r
303 \r
304 \r
305 void CLogDataVector::updateLanes(GitRev& c, Lanes& lns, CGitHash &sha) \r
306 {\r
307 // we could get third argument from c.sha(), but we are in fast path here\r
308 // and c.sha() involves a deep copy, so we accept a little redundancy\r
309 \r
310         if (lns.isEmpty())\r
311                 lns.init(sha);\r
312 \r
313         bool isDiscontinuity;\r
314         bool isFork = lns.isFork(sha, isDiscontinuity);\r
315         bool isMerge = (c.ParentsCount() > 1);\r
316         bool isInitial = (c.ParentsCount() == 0);\r
317 \r
318         if (isDiscontinuity)\r
319                 lns.changeActiveLane(sha); // uses previous isBoundary state\r
320 \r
321         lns.setBoundary(c.IsBoundary() == TRUE); // update must be here\r
322         TRACE(_T("%s %d"),c.m_CommitHash.ToString(),c.IsBoundary());\r
323 \r
324         if (isFork)\r
325                 lns.setFork(sha);\r
326         if (isMerge)\r
327                 lns.setMerge(c.m_ParentHash);\r
328         //if (c.isApplied)\r
329         //      lns.setApplied();\r
330         if (isInitial)\r
331                 lns.setInitial();\r
332 \r
333         lns.getLanes(c.m_Lanes); // here lanes are snapshotted\r
334 \r
335         CGitHash nextSha;\r
336         if( !isInitial) \r
337                 nextSha = c.m_ParentHash[0];\r
338 \r
339         lns.nextParent(nextSha);\r
340 \r
341         //if (c.isApplied)\r
342         //      lns.afterApplied();\r
343         if (isMerge)\r
344                 lns.afterMerge();\r
345         if (isFork)\r
346                 lns.afterFork();\r
347         if (lns.isBranch())\r
348                 lns.afterBranch();\r
349 \r
350 //      QString tmp = "", tmp2;\r
351 //      for (uint i = 0; i < c.lanes.count(); i++) {\r
352 //              tmp2.setNum(c.lanes[i]);\r
353 //              tmp.append(tmp2 + "-");\r
354 //      }\r
355 //      qDebug("%s %s",tmp.latin1(), c.sha.latin1());\r
356 }