//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,&note);
		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;
}
Exemple #2
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;
}