Dropped unused variables
[TortoiseGit.git] / src / TortoiseProc / LogDataVector.cpp
blobad088a3d622d01da98704e07ed51db3d035a0632
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2009-2013 - TortoiseGit
4 // Copyright (C) 2007-2008 - TortoiseSVN
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software Foundation,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 Description: start-up repository opening and reading
23 Author: Marco Costalba (C) 2005-2007
25 Copyright: See COPYING file that comes with this distribution
29 #include "stdafx.h"
30 #include "TortoiseProc.h"
31 #include "GitLogListBase.h"
32 #include "GitRev.h"
33 #include "IconMenu.h"
34 // CGitLogList
35 #include "cursor.h"
36 #include "InputDlg.h"
37 #include "GITProgressDlg.h"
38 #include "ProgressDlg.h"
39 #include "Logdlg.h"
40 #include "MessageBox.h"
41 #include "registry.h"
42 #include "AppUtils.h"
43 #include "PathUtils.h"
44 #include "StringUtils.h"
45 #include "UnicodeUtils.h"
46 #include "TempFile.h"
47 #include "IconMenu.h"
48 #include "GitStatus.h"
49 #include "FileDiffDlg.h"
50 #include "GitHash.h"
51 CGitHashMap a;
53 void CLogDataVector::ClearAll()
56 clear();
57 m_HashMap.clear();
58 m_Lns.clear();
60 m_FirstFreeLane=0;
61 m_Lns.clear();
63 m_RawlogData.clear();
64 m_RawLogStart.clear();
67 //CLogDataVector Class
68 int CLogDataVector::ParserFromLog(CTGitPath *path, int count, int infomask, CString *range)
70 // only enable --follow on files
71 if ((path == NULL || path->IsDirectory()) && (infomask & CGit::LOG_INFO_FOLLOW))
72 infomask = infomask ^ CGit::LOG_INFO_FOLLOW;
74 CString gitrange = _T("HEAD");
75 if (range != nullptr)
76 gitrange = *range;
77 CString cmd = g_Git.GetLogCmd(gitrange, path, count, infomask, true);
79 if (!g_Git.CanParseRev(gitrange))
80 return 0;
82 try
84 [] { git_init(); } ();
86 catch (const char* msg)
88 MessageBox(NULL, _T("Could not initialize libgit.\nlibgit reports:\n") + CString(msg), _T("TortoiseGit"), MB_ICONERROR);
89 return -1;
92 GIT_LOG handle;
93 g_Git.m_critGitDllSec.Lock();
94 try
96 if (git_open_log(&handle,CUnicodeUtils::GetMulti(cmd, CP_UTF8).GetBuffer()))
98 return -1;
101 catch (char* msg)
103 g_Git.m_critGitDllSec.Unlock();
104 MessageBox(NULL, _T("Could not open log.\nlibgit reports:\n") + CString(msg), _T("TortoiseGit"), MB_ICONERROR);
105 return -1;
107 g_Git.m_critGitDllSec.Unlock();
109 g_Git.m_critGitDllSec.Lock();
112 [&]{ git_get_log_firstcommit(handle); }();
114 catch (char* msg)
116 g_Git.m_critGitDllSec.Unlock();
117 MessageBox(NULL, _T("Could not get first commit.\nlibgit reports:\n") + CString(msg), _T("TortoiseGit"), MB_ICONERROR);
118 return -1;
120 g_Git.m_critGitDllSec.Unlock();
122 int ret = 0;
123 while (ret == 0)
125 GIT_COMMIT commit;
126 g_Git.m_critGitDllSec.Lock();
129 [&]{ ret = git_get_log_nextcommit(handle, &commit, infomask & CGit::LOG_INFO_FOLLOW); }();
131 catch (char* msg)
133 g_Git.m_critGitDllSec.Unlock();
134 MessageBox(NULL, _T("Could not get next commit.\nlibgit reports:\n") + CString(msg), _T("TortoiseGit"), MB_ICONERROR);
135 break;
137 g_Git.m_critGitDllSec.Unlock();
139 if (ret)
140 break;
142 if (commit.m_ignore == 1)
144 git_free_commit(&commit);
145 continue;
148 CGitHash hash = (char*)commit.m_hash ;
150 GitRev *pRev = this->m_pLogCache->GetCacheData(hash);
152 char *note=NULL;
153 g_Git.m_critGitDllSec.Lock();
154 git_get_notes(commit.m_hash,&note);
155 g_Git.m_critGitDllSec.Unlock();
156 if(note)
158 pRev->m_Notes.Empty();
159 g_Git.StringAppend(&pRev->m_Notes,(BYTE*)note);
162 if((pRev == NULL || !pRev->m_IsFull) && infomask& CGit::LOG_INFO_FULL_DIFF)
164 pRev->ParserFromCommit(&commit);
165 pRev->ParserParentFromCommit(&commit);
166 git_free_commit(&commit);
167 //Must call free commit before SafeFetchFullInfo, commit parent is rewrite by log.
168 //file list will wrong if parent rewrite.
171 pRev->SafeFetchFullInfo(&g_Git);
173 catch (char * g_last_error)
175 MessageBox(NULL, _T("Could not fetch full info of a commit.\nlibgit reports:\n") + CString(g_last_error), _T("TortoiseGit"), MB_ICONERROR);
176 return -1;
179 else
181 ASSERT(pRev->m_CommitHash == hash);
182 pRev->ParserFromCommit(&commit);
183 pRev->ParserParentFromCommit(&commit);
184 git_free_commit(&commit);
187 this->push_back(pRev->m_CommitHash);
189 m_HashMap[pRev->m_CommitHash] = (int)size() - 1;
193 g_Git.m_critGitDllSec.Lock();
194 git_close_log(handle);
195 g_Git.m_critGitDllSec.Unlock();
197 return 0;
200 int AddTolist(unsigned char * /*osha1*/, unsigned char *nsha1, const char * /*name*/, unsigned long /*time*/, int /*sz*/, const char *msg, void *data)
202 CLogDataVector *vector = (CLogDataVector*)data;
203 GitRev rev;
204 rev.m_CommitHash=(char*)nsha1;
206 CString one;
207 g_Git.StringAppend(&one, (BYTE *)msg);
209 int message=one.Find(_T(":"),0);
210 if(message>0)
212 rev.m_RefAction=one.Left(message);
213 rev.GetSubject()=one.Mid(message+1);
216 vector->m_pLogCache->m_HashMap[rev.m_CommitHash]=rev;
217 vector->insert(vector->begin(),rev.m_CommitHash);
219 return 0;
222 int CLogDataVector::ParserFromRefLog(CString ref)
224 if(g_Git.m_IsUseGitDLL)
226 git_for_each_reflog_ent(CUnicodeUtils::GetUTF8(ref),AddTolist,this);
227 for (size_t i = 0; i < size(); ++i)
229 m_pLogCache->m_HashMap[at(i)].m_Ref.Format(_T("%s{%d}"), ref,i);
233 else
236 CString cmd, out;
237 GitRev rev;
238 cmd.Format(_T("git.exe reflog show %s"),ref);
239 if (g_Git.Run(cmd, &out, NULL, CP_UTF8))
240 return -1;
242 int pos=0;
243 while(pos>=0)
245 CString one=out.Tokenize(_T("\n"),pos);
246 int ref=one.Find(_T(' '),0);
247 if(ref<0)
248 continue;
250 rev.Clear();
252 if (g_Git.GetHash(rev.m_CommitHash, one.Left(ref)))
254 MessageBox(NULL, g_Git.GetGitLastErr(_T("Could not get hash of ") + one.Left(ref) + _T(".")), _T("TortoiseGit"), MB_ICONERROR);
255 return -1;
257 int action=one.Find(_T(' '),ref+1);
258 int message;
259 if(action>0)
261 rev.m_Ref=one.Mid(ref+1,action-ref-2);
262 message=one.Find(_T(":"),action);
263 if(message>0)
265 rev.m_RefAction=one.Mid(action+1,message-action-1);
266 rev.GetSubject()=one.Right(one.GetLength()-message-1);
270 this->m_pLogCache->m_HashMap[rev.m_CommitHash]=rev;
272 this->push_back(rev.m_CommitHash);
276 return 0;
279 void CLogDataVector::setLane(CGitHash& sha)
281 Lanes* l = &(this->m_Lns);
282 int i = m_FirstFreeLane;
284 // QVector<QByteArray> ba;
285 // const ShaString& ss = toPersistentSha(sha, ba);
286 // const ShaVect& shaVec(fh->revOrder);
288 for (int cnt = (int)size(); i < cnt; ++i) {
290 GitRev* r = & this->GetGitRevAt(i);
291 CGitHash curSha=r->m_CommitHash;
293 if (r->m_Lanes.empty())
294 updateLanes(*r, *l, curSha);
296 if (curSha == sha)
297 break;
299 m_FirstFreeLane = ++i;
301 #if 0
302 Lanes* l = &(this->m_Lanes);
303 int i = m_FirstFreeLane;
305 QVector<QByteArray> ba;
306 const ShaString& ss = toPersistentSha(sha, ba);
307 const ShaVect& shaVec(fh->revOrder);
309 for (uint cnt = shaVec.count(); i < cnt; ++i) {
311 const ShaString& curSha = shaVec[i];
312 Rev* r = m_HashMap[curSha]const_cast<Rev*>(revLookup(curSha, fh));
313 if (r->lanes.count() == 0)
314 updateLanes(*r, *l, curSha);
316 if (curSha == ss)
317 break;
319 fh->firstFreeLane = ++i;
320 #endif
324 void CLogDataVector::updateLanes(GitRev& c, Lanes& lns, CGitHash &sha)
326 // we could get third argument from c.sha(), but we are in fast path here
327 // and c.sha() involves a deep copy, so we accept a little redundancy
329 if (lns.isEmpty())
330 lns.init(sha);
332 bool isDiscontinuity;
333 bool isFork = lns.isFork(sha, isDiscontinuity);
334 bool isMerge = (c.ParentsCount() > 1);
335 bool isInitial = (c.ParentsCount() == 0);
337 if (isDiscontinuity)
338 lns.changeActiveLane(sha); // uses previous isBoundary state
340 lns.setBoundary(c.IsBoundary() == TRUE); // update must be here
341 TRACE(_T("%s %d"),c.m_CommitHash.ToString(),c.IsBoundary());
343 if (isFork)
344 lns.setFork(sha);
345 if (isMerge)
346 lns.setMerge(c.m_ParentHash);
347 //if (c.isApplied)
348 // lns.setApplied();
349 if (isInitial)
350 lns.setInitial();
352 lns.getLanes(c.m_Lanes); // here lanes are snapshotted
354 CGitHash nextSha;
355 if( !isInitial)
356 nextSha = c.m_ParentHash[0];
358 lns.nextParent(nextSha);
360 //if (c.isApplied)
361 // lns.afterApplied();
362 if (isMerge)
363 lns.afterMerge();
364 if (isFork)
365 lns.afterFork();
366 if (lns.isBranch())
367 lns.afterBranch();