OSDN Git Service

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