bool GitStatus::IsExistIndexLockFile(const CString &gitdir)
{
	CString sDirName= gitdir;

	if (!PathIsDirectory(sDirName))
	{
		int x = sDirName.ReverseFind(_T('\\'));
		if (x < 2)
			return false;

		sDirName = sDirName.Left(x);
	}

	for (;;)
	{
		if(PathFileExists(sDirName + _T("\\.git")))
		{
			if(PathFileExists(g_AdminDirMap.GetAdminDir(sDirName) + _T("index.lock")))
				return true;
			else
				return false;
		}

		int x = sDirName.ReverseFind(_T('\\'));
		if (x < 2)
			return false;

		sDirName = sDirName.Left(x);
	}
}
Exemple #2
0
int CGitIndexFileMap::Check(const CString &gitdir, bool *isChanged)
{
    __int64 time;
    int result;

    CString IndexFile = g_AdminDirMap.GetAdminDir(gitdir) + _T("index");

    /* Get data associated with "crt_stat.c": */
    result = g_Git.GetFileModifyTime(IndexFile, &time);

    if (result)
        return result;

    SHARED_INDEX_PTR pIndex;
    pIndex = this->SafeGet(gitdir);

    if (pIndex.get() == NULL)
    {
        if(isChanged)
            *isChanged = true;
        return 0;
    }

    if (pIndex->m_LastModifyTime == time)
    {
        if (isChanged)
            *isChanged = false;
    }
    else
    {
        if (isChanged)
            *isChanged = true;
    }
    return 0;
}
Exemple #3
0
bool CGitIgnoreList::CheckIgnoreChanged(const CString &gitdir, const CString &path, bool isDir)
{
	CString temp;
	temp = gitdir;
	temp += _T("\\");
	temp += path;

	temp.Replace(_T('/'), _T('\\'));

	if (!isDir)
	{
		int x = temp.ReverseFind(_T('\\'));
		if (x >= 2)
			temp = temp.Left(x);
	}

	while(!temp.IsEmpty())
	{
		CString tempOrig = temp;
		temp += _T("\\.git");

		if (CGit::GitPathFileExists(temp))
		{
			CString gitignore=temp;
			gitignore += _T("ignore");
			if (CheckFileChanged(gitignore))
				return true;

			CString adminDir = g_AdminDirMap.GetAdminDir(tempOrig);
			CString wcglobalgitignore = adminDir + _T("info\\exclude");
			if (CheckFileChanged(wcglobalgitignore))
				return true;

			if (CheckAndUpdateCoreExcludefile(adminDir))
				return true;

			return false;
		}
		else
		{
			temp += _T("ignore");
			if (CheckFileChanged(temp))
				return true;
		}

		int found=0;
		int i;
		for (i = temp.GetLength() - 1; i >= 0; i--)
		{
			if(temp[i] == _T('\\'))
				++found;

			if(found == 2)
				break;
		}

		temp = temp.Left(i);
	}
	return true;
}
int CGitIndexFileMap::LoadIndex(const CString &gitdir)
{
	SHARED_INDEX_PTR pIndex(new CGitIndexList);

	if (pIndex->ReadIndex(g_AdminDirMap.GetAdminDir(gitdir)))
		return -1;

	this->SafeSet(gitdir, pIndex);

	return 0;
}
int CGitIgnoreList::LoadAllIgnoreFile(const CString &gitdir, const CString &path, bool isDir)
{
	CString temp(gitdir);
	temp += _T('\\');
	temp += path;

	temp.Replace(_T('/'), _T('\\'));

	if (!isDir)
	{
		int x = temp.ReverseFind(_T('\\'));
		if (x >= 2)
			temp.Truncate(x);
	}

	while (!temp.IsEmpty())
	{
		CString tempOrig = temp;
		temp += _T("\\.git");

		if (CGit::GitPathFileExists(temp))
		{
			CString gitignore = temp;
			gitignore += _T("ignore");
			if (CheckFileChanged(gitignore))
				FetchIgnoreFile(gitdir, gitignore, false);

			CString adminDir = g_AdminDirMap.GetAdminDir(tempOrig);
			CString wcglobalgitignore = adminDir;
			wcglobalgitignore += _T("info\\exclude");
			if (CheckFileChanged(wcglobalgitignore))
			{
				FetchIgnoreFile(gitdir, wcglobalgitignore, true);
			}

			if (CheckAndUpdateCoreExcludefile(adminDir))
			{
				CString excludesFile;
				{
					CAutoReadLock lock(m_SharedMutex);
					excludesFile = m_CoreExcludesfiles[adminDir];
				}
				if (!excludesFile.IsEmpty())
					FetchIgnoreFile(gitdir, excludesFile, true);
			}

			return 0;
		}

		temp += _T("ignore");
		if (CheckFileChanged(temp))
			FetchIgnoreFile(gitdir, temp, false);

		int found = 0;
		int i;
		for (i = temp.GetLength() - 1; i >= 0; --i)
		{
			if(temp[i] == _T('\\'))
				++found;

			if(found == 2)
				break;
		}

		temp.Truncate(i);
	}
	return 0;
}
int CGitHeadFileList::ReadHeadHash(const CString& gitdir)
{
	CAutoWriteLock lock(m_SharedMutex);
	m_Gitdir = g_AdminDirMap.GetAdminDir(gitdir);

	m_HeadFile = m_Gitdir;
	m_HeadFile += _T("HEAD");

	if( CGit::GetFileModifyTime(m_HeadFile, &m_LastModifyTimeHead))
		return -1;

	CAutoFile hfile = CreateFile(m_HeadFile,
		GENERIC_READ,
		FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE,
		nullptr,
		OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL,
		nullptr);

	if (!hfile)
		return -1;

	DWORD size = 0;
	unsigned char buffer[40];
	ReadFile(hfile, buffer, 4, &size, nullptr);
	if (size != 4)
		return -1;
	buffer[4] = 0;
	if (strcmp((const char*)buffer, "ref:") == 0)
	{
		m_HeadRefFile.Empty();
		DWORD filesize = GetFileSize(hfile, nullptr);
		if (filesize < 5)
			return -1;

		unsigned char *p = (unsigned char*)malloc(filesize - 4);
		if (!p)
			return -1;

		ReadFile(hfile, p, filesize - 4, &size, nullptr);
		CGit::StringAppend(&m_HeadRefFile, p, CP_UTF8, filesize - 4);
		free(p);

		CString ref = m_HeadRefFile.Trim();
		int start = 0;
		ref = ref.Tokenize(_T("\n"), start);
		m_HeadRefFile = m_Gitdir + m_HeadRefFile;
		m_HeadRefFile.Replace(_T('/'), _T('\\'));

		__int64 time;
		if (CGit::GetFileModifyTime(m_HeadRefFile, &time, nullptr))
		{
			m_HeadRefFile.Empty();
			if (GetPackRef(gitdir))
				return -1;
			if (m_PackRefMap.find(ref) == m_PackRefMap.end())
				return -1;

			m_Head = m_PackRefMap[ref];
			return 0;
		}

		CAutoFile href = CreateFile(m_HeadRefFile,
			GENERIC_READ,
			FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE,
			nullptr,
			OPEN_EXISTING,
			FILE_ATTRIBUTE_NORMAL,
			nullptr);

		if (!href)
		{
			m_HeadRefFile.Empty();

			if (GetPackRef(gitdir))
				return -1;

			if (m_PackRefMap.find(ref) == m_PackRefMap.end())
				return -1;

			m_Head = m_PackRefMap[ref];
			return 0;
		}

		ReadFile(href, buffer, 40, &size, nullptr);
		if (size != 40)
			return -1;

		m_Head.ConvertFromStrA((char*)buffer);

		m_LastModifyTimeRef = time;

		return 0;
	}

	ReadFile(hfile, buffer + 4, 40 - 4, &size, nullptr);
	if (size != 36)
		return -1;

	m_HeadRefFile.Empty();

	m_Head.ConvertFromStrA((char*)buffer);

	return 0;
}
int CGitIgnoreList::CheckIgnore(const CString &path, const CString &projectroot, bool isDir)
{
	CString temp = CombinePath(projectroot, path);
	temp.Replace(_T('/'), _T('\\'));

	CStringA patha = CUnicodeUtils::GetMulti(path, CP_UTF8);
	patha.Replace('\\', '/');

	int type = 0;
	if (isDir)
	{
		type = DT_DIR;

		// strip directory name
		// we do not need to check for a .ignore file inside a directory we might ignore
		int i = temp.ReverseFind(_T('\\'));
		if (i >= 0)
			temp.Truncate(i);
	}
	else
	{
		type = DT_REG;

		int x = temp.ReverseFind(_T('\\'));
		if (x >= 2)
			temp.Truncate(x);
	}

	int pos = patha.ReverseFind('/');
	const char * base = (pos >= 0) ? ((const char*)patha + pos + 1) : patha;

	int ret = -1;

	CAutoReadLock lock(m_SharedMutex);
	while (!temp.IsEmpty())
	{
		CString tempOrig = temp;
		temp += _T("\\.git");

		if (CGit::GitPathFileExists(temp))
		{
			CString gitignore = temp;
			gitignore += _T("ignore");
			if ((ret = CheckFileAgainstIgnoreList(gitignore, patha, base, type)) != -1)
				break;

			CString adminDir = g_AdminDirMap.GetAdminDir(tempOrig);
			CString wcglobalgitignore = adminDir;
			wcglobalgitignore += _T("info\\exclude");
			if ((ret = CheckFileAgainstIgnoreList(wcglobalgitignore, patha, base, type)) != -1)
				break;

			CString excludesFile = m_CoreExcludesfiles[adminDir];
			if (!excludesFile.IsEmpty())
				ret = CheckFileAgainstIgnoreList(excludesFile, patha, base, type);

			break;
		}

		temp += _T("ignore");
		if ((ret = CheckFileAgainstIgnoreList(temp, patha, base, type)) != -1)
			break;

		int found = 0;
		int i;
		for (i = temp.GetLength() - 1; i >= 0; i--)
		{
			if (temp[i] == _T('\\'))
				++found;

			if (found == 2)
				break;
		}

		temp.Truncate(i);
	}

	return ret;
}
Exemple #8
0
int CGitHeadFileList::ReadHeadHash(CString gitdir)
{
    int ret = 0;
    CAutoWriteLock lock(&this->m_SharedMutex);
    m_Gitdir = g_AdminDirMap.GetAdminDir(gitdir);

    m_HeadFile = m_Gitdir + _T("HEAD");

    if( g_Git.GetFileModifyTime(m_HeadFile, &m_LastModifyTimeHead))
        return -1;

    try
    {
        do
        {
            CAutoFile hfile = CreateFile(m_HeadFile,
                                         GENERIC_READ,
                                         FILE_SHARE_READ|FILE_SHARE_DELETE|FILE_SHARE_WRITE,
                                         NULL,
                                         OPEN_EXISTING,
                                         FILE_ATTRIBUTE_NORMAL,
                                         NULL);

            if (!hfile)
            {
                ret = -1;
                break;
            }

            DWORD size = 0;
            unsigned char buffer[40] ;
            ReadFile(hfile, buffer, 4, &size, NULL);
            if (size != 4)
            {
                ret = -1;
                break;
            }
            buffer[4]=0;
            if (strcmp((const char*)buffer,"ref:") == 0)
            {
                DWORD filesize = GetFileSize(hfile, NULL);
                if (filesize < 5)
                {
                    m_HeadRefFile.Empty();
                    ret = -1;
                    break;
                }

                unsigned char *p = (unsigned char*)malloc(filesize -4);

                ReadFile(hfile, p, filesize - 4, &size, NULL);

                m_HeadRefFile.Empty();
                g_Git.StringAppend(&this->m_HeadRefFile, p, CP_UTF8, filesize - 4);
                CString ref = this->m_HeadRefFile;
                ref = ref.Trim();
                int start = 0;
                ref = ref.Tokenize(_T("\n"), start);
                free(p);
                m_HeadRefFile = m_Gitdir + m_HeadRefFile.Trim();
                m_HeadRefFile.Replace(_T('/'),_T('\\'));

                __int64 time;
                if (g_Git.GetFileModifyTime(m_HeadRefFile, &time, NULL))
                {
                    m_HeadRefFile.Empty();
                    if (GetPackRef(gitdir))
                    {
                        ret = -1;
                        break;
                    }
                    if (this->m_PackRefMap.find(ref) == m_PackRefMap.end())
                    {
                        ret = -1;
                        break;
                    }
                    this ->m_Head = m_PackRefMap[ref];
                    ret = 0;
                    break;
                }

                CAutoFile href = CreateFile(m_HeadRefFile,
                                            GENERIC_READ,
                                            FILE_SHARE_READ|FILE_SHARE_DELETE|FILE_SHARE_WRITE,
                                            NULL,
                                            OPEN_EXISTING,
                                            FILE_ATTRIBUTE_NORMAL,
                                            NULL);

                if (!href)
                {
                    m_HeadRefFile.Empty();

                    if (GetPackRef(gitdir))
                    {
                        ret = -1;
                        break;
                    }

                    if (this->m_PackRefMap.find(ref) == m_PackRefMap.end())
                    {
                        ret = -1;
                        break;
                    }
                    this ->m_Head = m_PackRefMap[ref];
                    ret = 0;
                    break;
                }
                ReadFile(href, buffer, 40, &size, NULL);
                if (size != 40)
                {
                    ret = -1;
                    break;
                }
                this->m_Head.ConvertFromStrA((char*)buffer);

                this->m_LastModifyTimeRef = time;

            }
            else
            {
                ReadFile(hfile, buffer + 4, 40 - 4, &size, NULL);
                if(size != 36)
                {
                    ret = -1;
                    break;
                }
                m_HeadRefFile.Empty();

                this->m_Head.ConvertFromStrA((char*)buffer);
            }
        } while(0);
    }
    catch(...)
    {
        ret = -1;
    }

    return ret;
}
Exemple #9
0
// This method is assumed to be called with m_SharedMutex locked.
int CGitHeadFileList::GetPackRef(const CString &gitdir)
{
    CString PackRef = g_AdminDirMap.GetAdminDir(gitdir) + _T("packed-refs");

    __int64 mtime;
    if (g_Git.GetFileModifyTime(PackRef, &mtime))
    {
        //packed refs is not existed
        this->m_PackRefFile.Empty();
        this->m_PackRefMap.clear();
        return 0;
    }
    else if(mtime == m_LastModifyTimePackRef)
    {
        return 0;
    }
    else
    {
        this->m_PackRefFile = PackRef;
        this->m_LastModifyTimePackRef = mtime;
    }

    int ret = 0;
    {
        this->m_PackRefMap.clear();

        CAutoFile hfile = CreateFile(PackRef,
                                     GENERIC_READ,
                                     FILE_SHARE_READ|FILE_SHARE_DELETE|FILE_SHARE_WRITE,
                                     NULL,
                                     OPEN_EXISTING,
                                     FILE_ATTRIBUTE_NORMAL,
                                     NULL);
        do
        {
            if (!hfile)
            {
                ret = -1;
                break;
            }

            DWORD filesize = GetFileSize(hfile, NULL);
            if (filesize == 0)
            {
                ret = -1;
                break;
            }
            DWORD size =0;
            char *buff;
            buff = new char[filesize];

            ReadFile(hfile, buff, filesize, &size, NULL);

            if (size != filesize)
            {
                delete[] buff;
                ret = -1;
                break;
            }

            CString hash;
            CString ref;

            for(DWORD i=0; i<filesize;)
            {
                hash.Empty();
                ref.Empty();
                if (buff[i] == '#' || buff[i] == '^')
                {
                    while (buff[i] != '\n')
                    {
                        ++i;
                        if (i == filesize)
                            break;
                    }
                    ++i;
                }

                if (i >= filesize)
                    break;

                while (buff[i] != ' ')
                {
                    hash.AppendChar(buff[i]);
                    ++i;
                    if (i == filesize)
                        break;
                }

                ++i;
                if (i >= filesize)
                    break;

                while (buff[i] != '\n')
                {
                    ref.AppendChar(buff[i]);
                    ++i;
                    if (i == filesize)
                        break;
                }

                if (!ref.IsEmpty() )
                {
                    this->m_PackRefMap[ref] = hash;
                }

                while (buff[i] == '\n')
                {
                    ++i;
                    if (i == filesize)
                        break;
                }
            }

            delete[] buff;

        } while(0);
    }
    return ret;

}
Exemple #10
0
int CGitIgnoreList::CheckIgnore(const CString &path,const CString &projectroot)
{
    __int64 time = 0;
    bool dir = 0;
    CString temp = projectroot + _T("\\") + path;
    temp.Replace(_T('/'), _T('\\'));

    CStringA patha = CUnicodeUtils::GetMulti(path, CP_UTF8);
    patha.Replace('\\', '/');

    if(g_Git.GetFileModifyTime(temp, &time, &dir))
        return -1;

    int type = 0;
    if (dir)
    {
        type = DT_DIR;

        // strip directory name
        // we do not need to check for a .ignore file inside a directory we might ignore
        int i = temp.ReverseFind(_T('\\'));
        if (i >= 0)
            temp = temp.Left(i);
    }
    else
        type = DT_REG;

    char * base = NULL;
    int pos = patha.ReverseFind('/');
    base = pos >= 0 ? patha.GetBuffer() + pos + 1 : patha.GetBuffer();

    int ret = -1;

    CAutoReadLock lock(&this->m_SharedMutex);
    while (!temp.IsEmpty())
    {
        CString tempOrig = temp;
        temp += _T("\\.git");

        if (CGit::GitPathFileExists(temp))
        {
            CString gitignore = temp;
            gitignore += _T("ignore");
            if ((ret = CheckFileAgainstIgnoreList(gitignore, patha, base, type)) != -1)
                break;

            CString adminDir = g_AdminDirMap.GetAdminDir(tempOrig);
            CString wcglobalgitignore = adminDir + _T("info\\exclude");
            if ((ret = CheckFileAgainstIgnoreList(wcglobalgitignore, patha, base, type)) != -1)
                break;

            m_SharedMutex.AcquireShared();
            CString excludesFile = m_CoreExcludesfiles[adminDir];
            m_SharedMutex.ReleaseShared();
            if (!excludesFile.IsEmpty())
                ret = CheckFileAgainstIgnoreList(excludesFile, patha, base, type);

            break;
        }
        else
        {
            temp += _T("ignore");
            if ((ret = CheckFileAgainstIgnoreList(temp, patha, base, type)) != -1)
                break;
        }

        int found = 0;
        int i;
        for (i = temp.GetLength() - 1; i >= 0; i--)
        {
            if (temp[i] == _T('\\'))
                ++found;

            if (found == 2)
                break;
        }

        temp = temp.Left(i);
    }

    patha.ReleaseBuffer();

    return ret;
}
Exemple #11
0
int CGitIgnoreList::LoadAllIgnoreFile(const CString &gitdir,const CString &path)
{
    CString temp;

    temp = gitdir;
    temp += _T("\\");
    temp += path;

    temp.Replace(_T('/'), _T('\\'));

    while (!temp.IsEmpty())
    {
        CString tempOrig = temp;
        temp += _T("\\.git");

        if (CGit::GitPathFileExists(temp))
        {
            CString gitignore = temp;
            gitignore += _T("ignore");
            if (CheckFileChanged(gitignore))
            {
                FetchIgnoreFile(gitdir, gitignore, false);
            }

            CString adminDir = g_AdminDirMap.GetAdminDir(tempOrig);
            CString wcglobalgitignore = adminDir + _T("info\\exclude");
            if (CheckFileChanged(wcglobalgitignore))
            {
                FetchIgnoreFile(gitdir, wcglobalgitignore, true);
            }

            if (CheckAndUpdateCoreExcludefile(adminDir))
            {
                m_SharedMutex.AcquireShared();
                CString excludesFile = m_CoreExcludesfiles[adminDir];
                m_SharedMutex.ReleaseShared();
                if (!excludesFile.IsEmpty())
                    FetchIgnoreFile(gitdir, excludesFile, true);
            }

            return 0;
        }
        else
        {
            temp += _T("ignore");
            if (CheckFileChanged(temp))
            {
                FetchIgnoreFile(gitdir, temp, false);
            }
        }

        int found = 0;
        int i;
        for (i = temp.GetLength() - 1; i >= 0; i--)
        {
            if(temp[i] == _T('\\'))
                ++found;

            if(found == 2)
                break;
        }

        temp = temp.Left(i);
    }
    return 0;
}
Exemple #12
0
// This method is assumed to be called with m_SharedMutex locked.
int CGitHeadFileList::GetPackRef(const CString &gitdir)
{
	CString PackRef = g_AdminDirMap.GetAdminDir(gitdir) + _T("packed-refs");

	__int64 mtime;
	if (g_Git.GetFileModifyTime(PackRef, &mtime))
	{
		//packed refs is not existed
		this->m_PackRefFile.Empty();
		this->m_PackRefMap.clear();
		return 0;
	}
	else if(mtime == m_LastModifyTimePackRef)
	{
		return 0;
	}
	else
	{
		this->m_PackRefFile = PackRef;
		this->m_LastModifyTimePackRef = mtime;
	}

	m_PackRefMap.clear();

	CAutoFile hfile = CreateFile(PackRef,
		GENERIC_READ,
		FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE,
		nullptr,
		OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL,
		nullptr);

	if (!hfile)
		return -1;

	DWORD filesize = GetFileSize(hfile, nullptr);
	if (filesize == 0)
		return -1;

	DWORD size = 0;
	std::unique_ptr<char[]> buff(new char[filesize]);
	ReadFile(hfile, buff.get(), filesize, &size, nullptr);

	if (size != filesize)
		return -1;

	CString hash;
	CString ref;
	for (DWORD i = 0; i < filesize;)
	{
		hash.Empty();
		ref.Empty();
		if (buff[i] == '#' || buff[i] == '^')
		{
			while (buff[i] != '\n')
			{
				++i;
				if (i == filesize)
					break;
			}
			++i;
		}

		if (i >= filesize)
			break;

		while (buff[i] != ' ')
		{
			hash.AppendChar(buff[i]);
			++i;
			if (i == filesize)
				break;
		}

		++i;
		if (i >= filesize)
			break;

		while (buff[i] != '\n')
		{
			ref.AppendChar(buff[i]);
			++i;
			if (i == filesize)
				break;
		}

		if (!ref.IsEmpty())
			m_PackRefMap[ref] = hash;

		while (buff[i] == '\n')
		{
			++i;
			if (i == filesize)
				break;
		}
	}
	return 0;
}