some spaces-tabs code cleanup
[TortoiseGit.git] / src / TortoiseProc / LogDataVector.cpp
blob6e4c4570cb6283e4faa976f7bccb1baa137bc799
1 // TortoiseSVN - a Windows shell extension for easy version control
3 // Copyright (C) 2007-2008 - TortoiseSVN
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.
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.
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.
20 Description: start-up repository opening and reading
22 Author: Marco Costalba (C) 2005-2007
24 Copyright: See COPYING file that comes with this distribution
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 #include "GitHash.h"
66 CGitHashMap a;
68 void CLogDataVector::ClearAll()
71 clear();
72 m_HashMap.clear();
73 m_Lns.clear();
75 m_FirstFreeLane=0;
76 m_Lns.clear();
78 m_RawlogData.clear();
79 m_RawLogStart.clear();
82 //CLogDataVector Class
83 int CLogDataVector::ParserFromLog(CTGitPath *path ,int count ,int infomask,CString *from,CString *to)
85 CString hash;
86 CString cmd=g_Git.GetLogCmd(hash,path,count,infomask,from,to,true);
88 if(g_Git.IsInitRepos())
89 return 0;
91 git_init();
93 GIT_LOG handle;
94 if(git_open_log(&handle,CUnicodeUtils::GetMulti(cmd,CP_ACP).GetBuffer()))
96 return -1;
99 git_get_log_firstcommit(handle);
101 GIT_COMMIT commit;
103 GitRev rev;
105 while( git_get_log_nextcommit(handle,&commit) == 0)
108 CGitHash hash = (char*)commit.m_hash ;
109 rev.Clear();
111 GitRev *pRev = this->m_pLogCache->GetCacheData(hash);
113 char *note=NULL;
114 git_get_notes(commit.m_hash,&note);
115 if(note)
117 pRev->m_Notes.Empty();
118 g_Git.StringAppend(&pRev->m_Notes,(BYTE*)note);
121 if(pRev == NULL || !pRev->m_IsFull)
123 pRev->ParserFromCommit(&commit);
124 pRev->ParserParentFromCommit(&commit);
125 git_free_commit(&commit);
126 //Must call free commit before SafeFetchFullInfo, commit parent is rewrite by log.
127 //file list will wrong if parent rewrite.
128 pRev->SafeFetchFullInfo(&g_Git);
130 }else
132 ASSERT(pRev->m_CommitHash == hash);
133 pRev->ParserParentFromCommit(&commit);
134 git_free_commit(&commit);
137 this->push_back(pRev->m_CommitHash);
139 m_HashMap[rev.m_CommitHash]=size()-1;
143 git_close_log(handle);
145 return 0;
148 int AddTolist(unsigned char * /*osha1*/, unsigned char *nsha1, const char * /*name*/, unsigned long /*time*/, int /*sz*/, const char *msg, void *data)
150 CLogDataVector *vector = (CLogDataVector*)data;
151 GitRev rev;
152 rev.m_CommitHash=(char*)nsha1;
154 CString one;
155 g_Git.StringAppend(&one, (BYTE *)msg);
157 int message=one.Find(_T(":"),0);
158 if(message>0)
160 rev.m_RefAction=one.Left(message);
161 rev.GetSubject()=one.Mid(message+1);
164 vector->m_pLogCache->m_HashMap[rev.m_CommitHash]=rev;
165 vector->insert(vector->begin(),rev.m_CommitHash);
167 return 0;
170 int CLogDataVector::ParserFromRefLog(CString ref)
172 if(g_Git.m_IsUseGitDLL)
174 git_for_each_reflog_ent(CUnicodeUtils::GetUTF8(ref),AddTolist,this);
175 for(int i=0;i<size();i++)
177 m_pLogCache->m_HashMap[at(i)].m_Ref.Format(_T("%s{%d}"), ref,i);
180 }else
183 CString cmd,out;
184 GitRev rev;
185 cmd.Format(_T("git.exe reflog show %s"),ref);
186 if(g_Git.Run(cmd,&out,CP_UTF8))
187 return -1;
189 int pos=0;
190 while(pos>=0)
192 CString one=out.Tokenize(_T("\n"),pos);
193 int ref=one.Find(_T(' '),0);
194 if(ref<0)
195 continue;
197 rev.Clear();
199 rev.m_CommitHash=g_Git.GetHash(one.Left(ref));
200 int action=one.Find(_T(' '),ref+1);
201 int message;
202 if(action>0)
204 rev.m_Ref=one.Mid(ref+1,action-ref-2);
205 message=one.Find(_T(":"),action);
206 if(message>0)
208 rev.m_RefAction=one.Mid(action+1,message-action-1);
209 rev.GetSubject()=one.Right(one.GetLength()-message-1);
213 this->m_pLogCache->m_HashMap[rev.m_CommitHash]=rev;
215 this->push_back(rev.m_CommitHash);
219 return 0;
222 void CLogDataVector::setLane(CGitHash& sha)
224 Lanes* l = &(this->m_Lns);
225 int i = m_FirstFreeLane;
227 // QVector<QByteArray> ba;
228 // const ShaString& ss = toPersistentSha(sha, ba);
229 // const ShaVect& shaVec(fh->revOrder);
231 for (int cnt = size(); i < cnt; ++i) {
233 GitRev* r = & this->GetGitRevAt(i);
234 CGitHash curSha=r->m_CommitHash;
236 if (r->m_Lanes.size() == 0)
237 updateLanes(*r, *l, curSha);
239 if (curSha == sha)
240 break;
242 m_FirstFreeLane = ++i;
244 #if 0
245 Lanes* l = &(this->m_Lanes);
246 int i = m_FirstFreeLane;
248 QVector<QByteArray> ba;
249 const ShaString& ss = toPersistentSha(sha, ba);
250 const ShaVect& shaVec(fh->revOrder);
252 for (uint cnt = shaVec.count(); i < cnt; ++i) {
254 const ShaString& curSha = shaVec[i];
255 Rev* r = m_HashMap[curSha]const_cast<Rev*>(revLookup(curSha, fh));
256 if (r->lanes.count() == 0)
257 updateLanes(*r, *l, curSha);
259 if (curSha == ss)
260 break;
262 fh->firstFreeLane = ++i;
263 #endif
267 void CLogDataVector::updateLanes(GitRev& c, Lanes& lns, CGitHash &sha)
269 // we could get third argument from c.sha(), but we are in fast path here
270 // and c.sha() involves a deep copy, so we accept a little redundancy
272 if (lns.isEmpty())
273 lns.init(sha);
275 bool isDiscontinuity;
276 bool isFork = lns.isFork(sha, isDiscontinuity);
277 bool isMerge = (c.ParentsCount() > 1);
278 bool isInitial = (c.ParentsCount() == 0);
280 if (isDiscontinuity)
281 lns.changeActiveLane(sha); // uses previous isBoundary state
283 lns.setBoundary(c.IsBoundary() == TRUE); // update must be here
284 TRACE(_T("%s %d"),c.m_CommitHash.ToString(),c.IsBoundary());
286 if (isFork)
287 lns.setFork(sha);
288 if (isMerge)
289 lns.setMerge(c.m_ParentHash);
290 //if (c.isApplied)
291 // lns.setApplied();
292 if (isInitial)
293 lns.setInitial();
295 lns.getLanes(c.m_Lanes); // here lanes are snapshotted
297 CGitHash nextSha;
298 if( !isInitial)
299 nextSha = c.m_ParentHash[0];
301 lns.nextParent(nextSha);
303 //if (c.isApplied)
304 // lns.afterApplied();
305 if (isMerge)
306 lns.afterMerge();
307 if (isFork)
308 lns.afterFork();
309 if (lns.isBranch())
310 lns.afterBranch();
312 // QString tmp = "", tmp2;
313 // for (uint i = 0; i < c.lanes.count(); i++) {
314 // tmp2.setNum(c.lanes[i]);
315 // tmp.append(tmp2 + "-");
316 // }
317 // qDebug("%s %s",tmp.latin1(), c.sha.latin1());