Example #1
0
int CGit::GetDiffPath(CTGitPathList *PathList, CGitHash *hash1, CGitHash *hash2, char *arg)
{
	GIT_FILE file=0;
	int ret=0;
	GIT_DIFF diff=0;

	CAutoLocker lock(g_Git.m_critGitDllSec);

	if(arg == NULL)
		diff = GetGitDiff();
	else
		git_open_diff(&diff, arg);

	if(diff ==NULL)
		return -1;

	bool isStat = 0;
	if(arg == NULL)
		isStat = true;
	else
		isStat = !!strstr(arg, "stat");

	int count=0;

	if(hash2 == NULL)
		ret = git_root_diff(diff, hash1->m_hash, &file, &count,isStat);
	else
		ret = git_diff(diff,hash2->m_hash,hash1->m_hash,&file,&count,isStat);

	if(ret)
		return -1;

	CTGitPath path;
	CString strnewname;
	CString stroldname;

	for(int j=0;j<count;j++)
	{
		path.Reset();
		char *newname;
		char *oldname;

		strnewname.Empty();
		stroldname.Empty();

		int mode=0,IsBin=0,inc=0,dec=0;
		git_get_diff_file(diff,file,j,&newname,&oldname,
					&mode,&IsBin,&inc,&dec);

		StringAppend(&strnewname, (BYTE*)newname, CP_UTF8);
		StringAppend(&stroldname, (BYTE*)oldname, CP_UTF8);

		path.SetFromGit(strnewname,&stroldname);
		path.ParserAction((BYTE)mode);

		if(IsBin)
		{
			path.m_StatAdd=_T("-");
			path.m_StatDel=_T("-");
		}
		else
		{
			path.m_StatAdd.Format(_T("%d"),inc);
			path.m_StatDel.Format(_T("%d"),dec);
		}
		PathList->AddPath(path);
	}
	git_diff_flush(diff);

	if(arg)
		git_close_diff(diff);

	return 0;
}
Example #2
0
int GitRev::SafeFetchFullInfo(CGit *git)
{
	if(InterlockedExchange(&m_IsUpdateing,TRUE) == FALSE)
	{
		this->m_Files.Clear();
		git->CheckAndInitDll();
		GIT_COMMIT commit;
		GIT_COMMIT_LIST list;
		GIT_HASH   parent;
		memset(&commit,0,sizeof(GIT_COMMIT));

		CAutoLocker lock(g_Git.m_critGitDllSec);

		try
		{
			if (git_get_commit_from_hash(&commit, this->m_CommitHash.m_hash))
				return -1;
		}
		catch (char *)
		{
			return -1;
		}

		int i=0;

		git_get_commit_first_parent(&commit,&list);
		bool isRoot = (list==NULL);

		while(git_get_commit_next_parent(&list,parent) == 0 || isRoot)
		{
			GIT_FILE file=0;
			int count=0;

			try
			{
				if (isRoot)
					git_root_diff(git->GetGitDiff(), this->m_CommitHash.m_hash, &file, &count, 1);
				else
					git_diff(git->GetGitDiff(), parent, commit.m_hash, &file, &count, 1);
			}
			catch (char *)
			{
				git_free_commit(&commit);
				return -1;
			}
			isRoot = false;

			CTGitPath path;
			CString strnewname;
			CString stroldname;

			for (int j = 0; j < count; ++j)
			{
				path.Reset();
				char *newname;
				char *oldname;

				strnewname.Empty();
				stroldname.Empty();

				int mode,IsBin,inc,dec;
				git_get_diff_file(git->GetGitDiff(),file,j,&newname,&oldname,
						&mode,&IsBin,&inc,&dec);

				git->StringAppend(&strnewname, (BYTE*)newname, CP_UTF8);
				git->StringAppend(&stroldname, (BYTE*)oldname, CP_UTF8);

				path.SetFromGit(strnewname,&stroldname);
				path.ParserAction((BYTE)mode);
				path.m_ParentNo = i;

				this->m_Action|=path.m_Action;

				if(IsBin)
				{
					path.m_StatAdd=_T("-");
					path.m_StatDel=_T("-");
				}
				else
				{
					path.m_StatAdd.Format(_T("%d"),inc);
					path.m_StatDel.Format(_T("%d"),dec);
				}
				m_Files.AddPath(path);
			}
			git_diff_flush(git->GetGitDiff());
			++i;
		}


		InterlockedExchange(&m_IsUpdateing,FALSE);
		InterlockedExchange(&m_IsFull,TRUE);
		git_free_commit(&commit);
	}

	return 0;
}
Example #3
0
int CTGitPathList::ParserFromLog(BYTE_VECTOR &log, bool parseDeletes /*false*/)
{
	this->Clear();
	std::map<CString, size_t> duplicateMap;
	int pos=0;
	CTGitPath path;
	m_Action=0;
	int logend = (int)log.size();
	while (pos >= 0 && pos < logend)
	{
		path.Reset();
		if(log[pos]=='\n')
			++pos;

		if (pos >= logend)
			return -1;

		if(log[pos]==':')
		{
			bool merged=false;
			if (pos + 1 >= logend)
				return -1;
			if(log[pos+1] ==':')
			{
				merged=true;
			}
			int end=log.find(0,pos);
			int actionstart=-1;
			int file1=-1,file2=-1;
			if( end>0 )
			{
				actionstart=log.find(' ',end-6);
				pos=actionstart;
			}
			if( actionstart>0 )
			{
				++actionstart;
				if (actionstart >= logend)
					return -1;

				file1 = log.find(0,actionstart);
				if( file1>=0 )
				{
					++file1;
					pos=file1;
				}
				if( log[actionstart] == 'C' || log[actionstart] == 'R' )
				{
					file2=file1;
					file1 = log.find(0,file1);
					if(file1>=0 )
					{
						++file1;
						pos=file1;
					}

				}
			}

			CString pathname1;
			CString pathname2;

			if( file1>=0 )
				CGit::StringAppend(&pathname1, &log[file1], CP_UTF8);
			if( file2>=0 )
				CGit::StringAppend(&pathname2, &log[file2], CP_UTF8);

			if (actionstart < 0)
				return -1;

			auto existing = duplicateMap.find(pathname1);
			if (existing != duplicateMap.end())
			{
				CTGitPath& p = m_paths[existing->second];
				p.ParserAction(log[actionstart]);

				if(merged)
					p.m_Action |= CTGitPath::LOGACTIONS_MERGED;
				m_Action |= p.m_Action;

			}
			else
			{
				int ac=path.ParserAction(log[actionstart] );
				ac |= merged?CTGitPath::LOGACTIONS_MERGED:0;

				path.SetFromGit(pathname1,&pathname2);
				path.m_Action=ac;
					//action must be set after setfromgit. SetFromGit will clear all status.
				this->m_Action|=ac;

				AddPath(path);
				duplicateMap.insert(std::pair<CString, size_t>(path.GetGitPathString(), m_paths.size() - 1));
			}

		}
		else
		{
			int tabstart=0;
			path.Reset();
			CString StatAdd;
			CString StatDel;
			CString file1;
			CString file2;

			tabstart=log.find('\t',pos);
			if(tabstart >=0)
			{
				log[tabstart]=0;
				CGit::StringAppend(&StatAdd, &log[pos], CP_UTF8);
				pos=tabstart+1;
			}

			tabstart=log.find('\t',pos);
			if(tabstart >=0)
			{
				log[tabstart]=0;

				CGit::StringAppend(&StatDel, &log[pos], CP_UTF8);
				pos=tabstart+1;
			}

			if(log[pos] == 0) //rename
			{
				++pos;
				CGit::StringAppend(&file2, &log[pos], CP_UTF8);
				int sec=log.find(0,pos);
				if(sec>=0)
				{
					++sec;
					CGit::StringAppend(&file1, &log[sec], CP_UTF8);
				}
				pos=sec;

			}
			else
			{
				CGit::StringAppend(&file1, &log[pos], CP_UTF8);
			}
			path.SetFromGit(file1,&file2);

			auto existing = duplicateMap.find(path.GetGitPathString());
			if (existing != duplicateMap.end())
			{
				CTGitPath& p = m_paths[existing->second];
				p.m_StatAdd = StatAdd;
				p.m_StatDel = StatDel;
			}
			else
			{
				//path.SetFromGit(pathname);
				if (parseDeletes)
				{
					path.m_StatAdd=_T("0");
					path.m_StatDel=_T("0");
					path.m_Action |= CTGitPath::LOGACTIONS_DELETED | CTGitPath::LOGACTIONS_MISSING;
				}
				else
				{
					path.m_StatAdd=StatAdd;
					path.m_StatDel=StatDel;
				}
				AddPath(path);
				duplicateMap.insert(std::pair<CString, size_t>(path.GetGitPathString(), m_paths.size() - 1));
			}

		}
		pos=log.findNextString(pos);
	}
	return 0;
}