//CLogDataVector Class int CLogDataVector::ParserFromLog(CTGitPath *path ,int count ,int infomask,CString *from,CString *to) { // only enable --follow on files if ((path == NULL || path->IsDirectory()) && (infomask & CGit::LOG_INFO_FOLLOW)) infomask = infomask ^ CGit::LOG_INFO_FOLLOW; CString hash; CString cmd=g_Git.GetLogCmd(hash,path,count,infomask,from,to,true); if(g_Git.IsInitRepos()) return 0; git_init(); GIT_LOG handle; if(git_open_log(&handle,CUnicodeUtils::GetMulti(cmd,CP_ACP).GetBuffer())) { return -1; } git_get_log_firstcommit(handle); GIT_COMMIT commit; GitRev rev; while (git_get_log_nextcommit(handle, &commit, infomask & CGit::LOG_INFO_FOLLOW) == 0) { if (commit.m_ignore == 1) { git_free_commit(&commit); continue; } CGitHash hash = (char*)commit.m_hash ; rev.Clear(); GitRev *pRev = this->m_pLogCache->GetCacheData(hash); char *note=NULL; git_get_notes(commit.m_hash,¬e); if(note) { pRev->m_Notes.Empty(); g_Git.StringAppend(&pRev->m_Notes,(BYTE*)note); } if(pRev == NULL || !pRev->m_IsFull) { pRev->ParserFromCommit(&commit); pRev->ParserParentFromCommit(&commit); git_free_commit(&commit); //Must call free commit before SafeFetchFullInfo, commit parent is rewrite by log. //file list will wrong if parent rewrite. pRev->SafeFetchFullInfo(&g_Git); } else { ASSERT(pRev->m_CommitHash == hash); pRev->ParserParentFromCommit(&commit); git_free_commit(&commit); } this->push_back(pRev->m_CommitHash); m_HashMap[rev.m_CommitHash]=size()-1; } git_close_log(handle); return 0; }
//CLogDataVector Class int CLogDataVector::ParserFromLog(CTGitPath *path, int count, int infomask, CString *range) { // only enable --follow on files if ((path == NULL || path->IsDirectory()) && (infomask & CGit::LOG_INFO_FOLLOW)) infomask = infomask ^ CGit::LOG_INFO_FOLLOW; CString gitrange = _T("HEAD"); if (range != nullptr) gitrange = *range; CString cmd = g_Git.GetLogCmd(gitrange, path, count, infomask, true); if (!g_Git.CanParseRev(gitrange)) return 0; try { [] { git_init(); } (); } catch (const char* msg) { MessageBox(NULL, _T("Could not initialize libgit.\nlibgit reports:\n") + CString(msg), _T("TortoiseGit"), MB_ICONERROR); return -1; } GIT_LOG handle; try { CAutoLocker lock(g_Git.m_critGitDllSec); if (git_open_log(&handle,CUnicodeUtils::GetMulti(cmd, CP_UTF8).GetBuffer())) { return -1; } } catch (char* msg) { MessageBox(NULL, _T("Could not open log.\nlibgit reports:\n") + CString(msg), _T("TortoiseGit"), MB_ICONERROR); return -1; } try { CAutoLocker lock(g_Git.m_critGitDllSec); [&]{ git_get_log_firstcommit(handle); }(); } catch (char* msg) { MessageBox(NULL, _T("Could not get first commit.\nlibgit reports:\n") + CString(msg), _T("TortoiseGit"), MB_ICONERROR); return -1; } int ret = 0; while (ret == 0) { GIT_COMMIT commit; try { CAutoLocker lock(g_Git.m_critGitDllSec); [&]{ ret = git_get_log_nextcommit(handle, &commit, infomask & CGit::LOG_INFO_FOLLOW); }(); } catch (char* msg) { MessageBox(NULL, _T("Could not get next commit.\nlibgit reports:\n") + CString(msg), _T("TortoiseGit"), MB_ICONERROR); break; } if (ret) break; if (commit.m_ignore == 1) { git_free_commit(&commit); continue; } CGitHash hash = (char*)commit.m_hash ; GitRev *pRev = this->m_pLogCache->GetCacheData(hash); char *pNote = nullptr; { CAutoLocker lock(g_Git.m_critGitDllSec); git_get_notes(commit.m_hash, &pNote); } if (pNote) { pRev->m_Notes.Empty(); g_Git.StringAppend(&pRev->m_Notes,(BYTE*)pNote); } ASSERT(pRev->m_CommitHash == hash); pRev->ParserFromCommit(&commit); pRev->ParserParentFromCommit(&commit); git_free_commit(&commit); // Must call free commit before SafeFetchFullInfo, commit parent is rewrite by log. // file list will wrong if parent rewrite. if (!pRev->m_IsFull && (infomask & CGit::LOG_INFO_FULL_DIFF)) { try { pRev->SafeFetchFullInfo(&g_Git); } catch (char * g_last_error) { MessageBox(NULL, _T("Could not fetch full info of a commit.\nlibgit reports:\n") + CString(g_last_error), _T("TortoiseGit"), MB_ICONERROR); return -1; } } this->push_back(pRev->m_CommitHash); m_HashMap[pRev->m_CommitHash] = (int)size() - 1; } { CAutoLocker lock(g_Git.m_critGitDllSec); git_close_log(handle); } return 0; }