Example #1
0
	ulong Board::GetAttackMask(int square, int attackerType) const
	{
		switch (attackerType)
		{
		case PieceTypes::Pawn:
			return 0;

		case PieceTypes::Knight:
			return MoveGenerator::knightAttacks[square];

		case PieceTypes::Bishop:
				return MoveGenerator::diagA1H8Attacks[square][GetDiagA1H8Status(square)] | 
					MoveGenerator::diagA8H1Attacks[square][GetDiagA8H1Status(square)];
				
		case PieceTypes::Rook:
				return MoveGenerator::rankAttacks[square][GetRankStatus(square)] | 
					MoveGenerator::fileAttacks[square][GetFileStatus(square)];

		case PieceTypes::Queen:
				return MoveGenerator::rankAttacks[square][GetRankStatus(square)] | 
					MoveGenerator::fileAttacks[square][GetFileStatus(square)] |
					MoveGenerator::diagA1H8Attacks[square][GetDiagA1H8Status(square)] | 
					MoveGenerator::diagA8H1Attacks[square][GetDiagA8H1Status(square)];

		case PieceTypes::King:
				return MoveGenerator::kingAttacks[square];

			default:
				return 0;
		}
	}
Example #2
0
bool UniStdioFile::DoOpen(LPCTSTR filename, LPCTSTR mode)
{
	Close();

	m_filepath = filename;
	m_filename = filename; // TODO: Make canonical ?

	// Fails if file doesn't exist (when we are creating new file)
	// But we don't care since size is set to 0 anyway.
	GetFileStatus();

	m_fp = _tfopen(m_filepath.c_str(), mode);
	if (!m_fp)
		return false;

	DWORD sizehi = (DWORD)(m_filesize >> 32);

	if (sizehi)
	{
		// TODO: We could do this in MSC_VER 7+ I think

		LastErrorCustom(_T("UniStdioFile cannot handle files over 4 gigabytes"));
		return false;
	}

	m_lineno = 0;
	return true;
}
bool FProvider::UpdateFileStateCache(const TArray<FFileState>& InStates)
{
	for (auto StateIt(InStates.CreateConstIterator()); StateIt; StateIt++)
	{
		FFileStateRef FileState = GetFileStateFromCache(StateIt->GetFilename());
		FileState->SetFileStatus(StateIt->GetFileStatus());
		FileState->SetTimeStamp(StateIt->GetTimeStamp());
	}
	return InStates.Num() > 0;
}
Example #4
0
void GitStatus::GetStatus(const CTGitPath& path, bool /*update*/ /* = false */, bool noignore /* = false */, bool /*noexternals*/ /* = false */)
{
	// NOTE: unlike the SVN version this one does not cache the enumerated files, because in practice no code in all of
	//       Tortoise uses this, all places that call GetStatus create a temp GitStatus object which gets destroyed right
	//       after the call again

	CString sProjectRoot;
	if ( !path.HasAdminDir(&sProjectRoot) )
		return;

	bool isfull = ((DWORD)CRegStdDWORD(_T("Software\\TortoiseGit\\CacheType"),
				GetSystemMetrics(SM_REMOTESESSION) ? ShellCache::dll : ShellCache::exe) == ShellCache::dllFull);

	int err = 0;

	{
		LPCTSTR lpszSubPath = NULL;
		CString sSubPath;
		CString s = path.GetWinPathString();
		if (s.GetLength() > sProjectRoot.GetLength())
		{
			sSubPath = s.Right(s.GetLength() - sProjectRoot.GetLength());
			lpszSubPath = sSubPath;
			// skip initial slash if necessary
			if (*lpszSubPath == _T('\\'))
				++lpszSubPath;
		}

		m_status.prop_status = m_status.text_status = git_wc_status_none;
		m_status.assumeValid = false;
		m_status.skipWorktree = false;

		if(path.IsDirectory())
		{
			err = GetDirStatus(sProjectRoot,lpszSubPath,&m_status.text_status , isfull, false,!noignore, NULL, NULL);
			if (m_status.text_status == git_wc_status_added || m_status.text_status == git_wc_status_deleted) // fix for issue #1769; a folder is either modified, conflicted or normal
				m_status.text_status = git_wc_status_modified;
		}
		else
		{
			err = GetFileStatus(sProjectRoot, lpszSubPath, &m_status.text_status ,isfull, false,!noignore, NULL,NULL, &m_status.assumeValid, &m_status.skipWorktree);
		}
	}

	// Error present if function is not under version control
	if (err)
	{
		status = NULL;
		return;
	}

	status = &m_status;
}
Example #5
0
// static method
git_wc_status_kind GitStatus::GetAllStatus(const CTGitPath& path, git_depth_t depth)
{
	git_wc_status_kind			statuskind;
//	git_client_ctx_t * 			ctx;

//	apr_pool_t *				pool;
//	git_error_t *				err;
	BOOL						err;
	BOOL						isDir;
	CString						sProjectRoot;

	isDir = path.IsDirectory();
	if (!path.HasAdminDir(&sProjectRoot))
		return git_wc_status_none;

//	pool = git_pool_create (NULL);				// create the memory pool

//	git_error_clear(git_client_create_context(&ctx, pool));

//	git_revnum_t youngest = Git_INVALID_REVNUM;
//	git_opt_revision_t rev;
//	rev.kind = git_opt_revision_unspecified;
	statuskind = git_wc_status_none;

	const BOOL bIsRecursive = (depth == git_depth_infinity || depth == git_depth_unknown); // taken from SVN source

	CString sSubPath;
	CString s = path.GetWinPathString();
	if (s.GetLength() > sProjectRoot.GetLength())
	{
		if (sProjectRoot.GetLength() == 3 && sProjectRoot[1] == _T(':'))
			sSubPath = s.Right(s.GetLength() - sProjectRoot.GetLength());
		else
			sSubPath = s.Right(s.GetLength() - sProjectRoot.GetLength() - 1/*otherwise it gets initial slash*/);
	}

	bool isfull = ((DWORD)CRegStdDWORD(_T("Software\\TortoiseGit\\CacheType"),
				GetSystemMetrics(SM_REMOTESESSION) ? ShellCache::dll : ShellCache::exe) == ShellCache::dllFull);

	if(isDir)
	{
		err = GetDirStatus(sProjectRoot,sSubPath,&statuskind, isfull,bIsRecursive,isfull,NULL, NULL);

	}
	else
	{
		err = GetFileStatus(sProjectRoot,sSubPath,&statuskind,isfull, false,isfull, NULL,NULL);
	}

	return statuskind;
}
Example #6
0
	bool Board::IsSquareAttacked(int square, int attackerColor) const
	{
		ulong colorMask = colorBitBoards[attackerColor];

		ulong attackMask = MoveGenerator::rankAttacks[square][GetRankStatus(square)];
		ulong attackers = (pieceBitBoards[PieceTypes::Queen] | pieceBitBoards[PieceTypes::Rook]) & colorMask;
		if ((attackers & attackMask) != 0)
		{
			return true;
		}

		attackMask = MoveGenerator::fileAttacks[square][GetFileStatus(square)];
		if ((attackers & attackMask) != 0)
		{
			return true;
		}

		attackMask = MoveGenerator::diagA1H8Attacks[square][GetDiagA1H8Status(square)];
		attackers = (pieceBitBoards[PieceTypes::Queen] | pieceBitBoards[PieceTypes::Bishop]) & colorMask;
		if ((attackers & attackMask) != 0)
		{
			return true;
		}

		attackMask = MoveGenerator::diagA8H1Attacks[square][GetDiagA8H1Status(square)];
		if ((attackers & attackMask) != 0)
		{
			return true;
		}

		if ((MoveGenerator::knightAttacks[square] & pieceBitBoards[PieceTypes::Knight] & colorMask) != 0)
		{
			return true;
		}

		if ((MoveGenerator::kingAttacks[square] & pieceBitBoards[PieceTypes::King] & colorMask) != 0)
		{
			return true;
		}

		if ((MoveGenerator::pawnAttacks[square][attackerColor] & pieceBitBoards[PieceTypes::Pawn] & colorMask) != 0)
		{
			return true;
		}
		return false;
	}
Example #7
0
// static method
git_wc_status_kind GitStatus::GetAllStatus(const CTGitPath& path, git_depth_t depth, bool * assumeValid, bool * skipWorktree)
{
	git_wc_status_kind			statuskind;
	BOOL						err;
	BOOL						isDir;
	CString						sProjectRoot;

	isDir = path.IsDirectory();
	if (!path.HasAdminDir(&sProjectRoot))
		return git_wc_status_none;

//	rev.kind = git_opt_revision_unspecified;
	statuskind = git_wc_status_none;

	const BOOL bIsRecursive = (depth == git_depth_infinity || depth == git_depth_unknown); // taken from SVN source

	CString sSubPath;
	CString s = path.GetWinPathString();
	if (s.GetLength() > sProjectRoot.GetLength())
	{
		if (sProjectRoot.GetLength() == 3 && sProjectRoot[1] == _T(':'))
			sSubPath = s.Right(s.GetLength() - sProjectRoot.GetLength());
		else
			sSubPath = s.Right(s.GetLength() - sProjectRoot.GetLength() - 1/*otherwise it gets initial slash*/);
	}

	bool isfull = ((DWORD)CRegStdDWORD(_T("Software\\TortoiseGit\\CacheType"),
				GetSystemMetrics(SM_REMOTESESSION) ? ShellCache::dll : ShellCache::exe) == ShellCache::dllFull);

	if(isDir)
	{
		err = GetDirStatus(sProjectRoot,sSubPath,&statuskind, isfull,bIsRecursive,isfull,NULL, NULL);
		// folders must not be displayed as added or deleted only as modified (this is for Shell Overlay-Modes)
		if (statuskind == git_wc_status_unversioned && sSubPath.IsEmpty())
			statuskind = git_wc_status_normal;
		else if (statuskind == git_wc_status_deleted || statuskind == git_wc_status_added)
			statuskind = git_wc_status_modified;
	}
	else
	{
		err = GetFileStatus(sProjectRoot, sSubPath, &statuskind, isfull, false, isfull, NULL, NULL, assumeValid, skipWorktree);
	}

	return statuskind;
}
Example #8
0
	ulong Board::GetPinRestrictionMask(int square, int color)
	{
		int attackerColor = OtherColor(color);
		int kingSquare = GetKingSquare(color);
		int kingRow = GetRow(kingSquare);
		int kingCol = GetCol(kingSquare);
		int pieceRow = GetRow(square);
		int pieceCol = GetCol(square);
		int dr = pieceRow - kingRow;
		int dc = pieceCol - kingCol;
		ulong defenderKing = 1ULL << kingSquare;
			
		if(dr == 0)
		{
			ulong rankAttacks = MoveGenerator::rankAttacks[square][GetRankStatus(square)];
			ulong defenderKing = 1ULL << kingSquare;
			if((defenderKing & rankAttacks) != 0)
			{
				ulong attackers = GetPieceBitBoard(Pieces::GetPiece(PieceTypes::Rook, attackerColor)) |
					GetPieceBitBoard(Pieces::GetPiece(PieceTypes::Queen, attackerColor));
				if((rankAttacks & attackers) != 0)
				{
					return rankAttacks;
				}
			}
		}
		else if(dc == 0)
		{
			ulong fileAttacks = MoveGenerator::fileAttacks[square][GetFileStatus(square)];
			if((defenderKing & fileAttacks) != 0)
			{
				ulong attackers = GetPieceBitBoard(Pieces::GetPiece(PieceTypes::Rook, attackerColor)) |
					GetPieceBitBoard(Pieces::GetPiece(PieceTypes::Queen, attackerColor));
				if((fileAttacks & attackers) != 0)
				{
					return fileAttacks;
				}
			}
		}
		else if(dr == dc || dr == -dc)
		{
			ulong diagAttacks = 0;
			if(dr == dc)
			{
				diagAttacks = MoveGenerator::diagA1H8Attacks[square][GetDiagA1H8Status(square)];
			}
			else
			{
				diagAttacks = MoveGenerator::diagA8H1Attacks[square][GetDiagA8H1Status(square)];
			}
			if((defenderKing & diagAttacks) != 0)
			{
				ulong attackers = GetPieceBitBoard(Pieces::GetPiece(PieceTypes::Bishop, attackerColor)) |
					GetPieceBitBoard(Pieces::GetPiece(PieceTypes::Queen, attackerColor));
				if((diagAttacks & attackers) != 0)
				{
					return diagAttacks;
				}
			}
		}
		return ~(0ULL);
	}
Example #9
0
	ulong Board::GetSquareAttackers(int square, int attackerColor) const
	{
		ulong attackPieces = 0;

		ulong attackMask = MoveGenerator::rankAttacks[square][GetRankStatus(square)] | MoveGenerator::fileAttacks[square][GetFileStatus(square)];
		ulong attackers = pieceBitBoards[PieceTypes::Queen] | pieceBitBoards[PieceTypes::Rook];
		attackPieces |= attackers & attackMask;

		attackMask = MoveGenerator::diagA1H8Attacks[square][GetDiagA1H8Status(square)] | MoveGenerator::diagA8H1Attacks[square][GetDiagA8H1Status(square)];
		attackers = pieceBitBoards[PieceTypes::Queen] | pieceBitBoards[PieceTypes::Bishop];
		attackPieces |= attackers & attackMask;

		attackPieces |= MoveGenerator::knightAttacks[square] & pieceBitBoards[PieceTypes::Knight];
		attackPieces |= MoveGenerator::kingAttacks[square] & pieceBitBoards[PieceTypes::King];
		attackPieces |= MoveGenerator::pawnAttacks[square][attackerColor] & pieceBitBoards[PieceTypes::Pawn];
		return attackPieces & colorBitBoards[attackerColor];
	}
Example #10
0
	int Board::GetFileStatus(int square) const
	{
		return GetFileStatus(square, occupiedSquares);
	}
Example #11
0
int CGitIndexList::GetStatus(const CString& gitdir, CString path, git_wc_status_kind* status,
							 BOOL IsFull, BOOL /*IsRecursive*/,
							 FILL_STATUS_CALLBACK callback, void *pData,
							 CGitHash *pHash, bool * assumeValid, bool * skipWorktree)
{
	__int64 time, filesize = 0;
	bool isDir = false;

	if (!status)
		return 0;

	git_wc_status_kind dirstatus = git_wc_status_none;
	int result;
	if (path.IsEmpty())
		result = CGit::GetFileModifyTime(gitdir, &time, &isDir);
	else
		result = CGit::GetFileModifyTime(CombinePath(gitdir, path), &time, &isDir, &filesize);

	if (result)
	{
		*status = git_wc_status_deleted;
		if (callback && assumeValid && skipWorktree)
			callback(CombinePath(gitdir, path), git_wc_status_deleted, false, pData, *assumeValid, *skipWorktree);

		return 0;
	}

	if (!isDir)
	{
		GetFileStatus(gitdir, path, status, time, filesize, callback, pData, pHash, assumeValid, skipWorktree);
		return 0;
	}

	if (!path.IsEmpty() && path.Right(1) != _T('\\'))
		path += _T('\\');

	int len = path.GetLength();

	for (auto it = cbegin(), itend = cend(); it != itend; ++it)
	{
		if (!((*it).m_FileName.GetLength() > len && wcsncmp((*it).m_FileName, path, len) == 0))
			continue;

		if (!IsFull)
		{
			*status = git_wc_status_normal;
			if (callback)
				callback(CombinePath(gitdir, path), *status, false, pData, ((*it).m_Flags & GIT_IDXENTRY_VALID) && !((*it).m_FlagsExtended & GIT_IDXENTRY_SKIP_WORKTREE), ((*it).m_FlagsExtended & GIT_IDXENTRY_SKIP_WORKTREE) != 0);

			return 0;
		}

		result = CGit::GetFileModifyTime(CombinePath(gitdir, (*it).m_FileName), &time, nullptr, &filesize);
		if (result)
			continue;

		*status = git_wc_status_none;
		if (assumeValid)
			*assumeValid = false;
		if (skipWorktree)
			*skipWorktree = false;

		GetFileStatus(gitdir, (*it).m_FileName, status, time, filesize, callback, pData, nullptr, assumeValid, skipWorktree);

		// if a file is assumed valid, we need to inform the caller, otherwise the assumevalid flag might not get to the explorer on first open of a repository
		if (callback && assumeValid && skipWorktree && (*assumeValid || *skipWorktree))
			callback(CombinePath(gitdir, path), *status, false, pData, *assumeValid, *skipWorktree);
		if (*status != git_wc_status_none)
		{
			if (dirstatus == git_wc_status_none)
				dirstatus = git_wc_status_normal;
			if (*status != git_wc_status_normal)
				dirstatus = git_wc_status_modified;
		}
	} /* End For */

	if (dirstatus != git_wc_status_none)
		*status = dirstatus;
	else
		*status = git_wc_status_unversioned;

	if (callback)
		callback(CombinePath(gitdir, path), *status, false, pData, false, false);

	return 0;
}
Example #12
0
/** @brief Internal implementation of Open */
bool UniMemFile::DoOpen(LPCTSTR filename, DWORD dwOpenAccess, DWORD dwOpenShareMode, DWORD dwOpenCreationDispostion, DWORD dwMappingProtect, DWORD dwMapViewAccess)
{
	Close();

	m_filename = filename;
	m_filepath = m_filename; // TODO: Make canonical ?

	m_handle = CreateFile(m_filename.c_str(), dwOpenAccess, dwOpenShareMode, NULL, dwOpenCreationDispostion, 0, 0);
	if (m_handle == INVALID_HANDLE_VALUE)
	{
		LastError(_T("CreateFile"), GetLastError());
		return false;
	}
	m_lineno = 0; // GetFileStatus requires file be "open", which means nonnegative line number
	if (!GetFileStatus())
		return false;
	m_lineno = -1;

	DWORD sizehi = (DWORD)(m_filesize >> 32);
	DWORD sizelo = (DWORD)(m_filesize & 0xFFFFFFFF);

	if (sizehi || sizelo > 0x7FFFFFFF)
	{
		LastErrorCustom(_T("UniMemFile cannot handle files over 2 gigabytes"));
		return false;
	}

	if (sizelo == 0)
	{
		// Allow opening empty file, but memory mapping doesn't work on such
		// m_base and m_current are 0 from the Close call above
		// so ReadString will correctly return empty EOF immediately
		m_lineno = 0;
		return true;
	}

	LPSECURITY_ATTRIBUTES lpAttributes = NULL; // default security
	LPCTSTR lpName = NULL; // nameless mapping
	m_hMapping = CreateFileMapping(m_handle, lpAttributes, dwMappingProtect, sizehi, sizelo, lpName);
	if (!m_hMapping)
	{
		LastError(_T("CreateFileMapping"), GetLastError());
		return false;
	}


	DWORD dwFileOffsetHigh = 0;
	DWORD dwFileOffsetLow = 0;
	SIZE_T dwNumberOfBytesToMap = sizelo;
	m_base = (LPBYTE)MapViewOfFile(m_hMapping, dwMapViewAccess, dwFileOffsetHigh, dwFileOffsetLow, dwNumberOfBytesToMap);
	if (!m_base)
	{
		LastError(_T("MapViewOfFile"), GetLastError());
		return false;
	}
	m_data = m_base;
	m_current = m_base;
	m_lineno = 0;

	return true;
}
Example #13
0
int CGitIndexList::GetStatus(const CString &gitdir,const CString &pathParam, git_wc_status_kind *status,
                             BOOL IsFull, BOOL /*IsRecursive*/,
                             FILL_STATUS_CALLBACK callback, void *pData,
                             CGitHash *pHash, bool * assumeValid, bool * skipWorktree)
{
    __int64 time;
    bool isDir = false;
    CString path = pathParam;

    if (status)
    {
        git_wc_status_kind dirstatus = git_wc_status_none;
        int result;
        if (path.IsEmpty())
            result = g_Git.GetFileModifyTime(gitdir, &time, &isDir);
        else
            result = g_Git.GetFileModifyTime(gitdir + _T("\\") + path, &time, &isDir);

        if (result)
        {
            *status = git_wc_status_deleted;
            if (callback && assumeValid && skipWorktree)
                callback(gitdir + _T("\\") + path, git_wc_status_deleted, false, pData, *assumeValid, *skipWorktree);

            return 0;
        }
        if (isDir)
        {
            if (!path.IsEmpty())
            {
                if (path.Right(1) != _T("\\"))
                    path += _T("\\");
            }
            int len = path.GetLength();

            for (size_t i = 0; i < size(); ++i)
            {
                if (at(i).m_FileName.GetLength() > len)
                {
                    if (at(i).m_FileName.Left(len) == path)
                    {
                        if (!IsFull)
                        {
                            *status = git_wc_status_normal;
                            if (callback)
                                callback(gitdir + _T("\\") + path, *status, false, pData, (at(i).m_Flags & GIT_IDXENTRY_VALID) && !(at(i).m_Flags & GIT_IDXENTRY_SKIP_WORKTREE), (at(i).m_Flags & GIT_IDXENTRY_SKIP_WORKTREE) != 0);
                            return 0;

                        }
                        else
                        {
                            result = g_Git.GetFileModifyTime(gitdir+_T("\\") + at(i).m_FileName, &time);
                            if (result)
                                continue;

                            *status = git_wc_status_none;
                            if (assumeValid)
                                *assumeValid = false;
                            if (skipWorktree)
                                *skipWorktree = false;
                            GetFileStatus(gitdir, at(i).m_FileName, status, time, callback, pData, NULL, assumeValid, skipWorktree);
                            // if a file is assumed valid, we need to inform the caller, otherwise the assumevalid flag might not get to the explorer on first open of a repository
                            if (callback && assumeValid && skipWorktree && (*assumeValid || *skipWorktree))
                                callback(gitdir + _T("\\") + path, *status, false, pData, *assumeValid, *skipWorktree);
                            if (*status != git_wc_status_none)
                            {
                                if (dirstatus == git_wc_status_none)
                                {
                                    dirstatus = git_wc_status_normal;
                                }
                                if (*status != git_wc_status_normal)
                                {
                                    dirstatus = git_wc_status_modified;
                                }
                            }

                        }
                    }
                }
            } /* End For */

            if (dirstatus != git_wc_status_none)
            {
                *status = dirstatus;
            }
            else
            {
                *status = git_wc_status_unversioned;
            }
            if(callback)
                callback(gitdir + _T("\\") + path, *status, false, pData, false, false);

            return 0;

        }
        else
        {
            GetFileStatus(gitdir, path, status, time, callback, pData, pHash, assumeValid, skipWorktree);
        }
    }
    return 0;
}
Example #14
0
git_revnum_t GitStatus::GetStatus(const CTGitPath& path, bool update /* = false */, bool noignore /* = false */, bool /*noexternals*/ /* = false */)
{
	// NOTE: unlike the SVN version this one does not cache the enumerated files, because in practice no code in all of
	//       Tortoise uses this, all places that call GetStatus create a temp GitStatus object which gets destroyed right
	//       after the call again

//	apr_hash_t *				statushash;
//	apr_hash_t *				exthash;
//	apr_array_header_t *		statusarray;
//	const sort_item*			item;

//	git_error_clear(m_err);
//	statushash = apr_hash_make(m_pool);
//	exthash = apr_hash_make(m_pool);
	git_revnum_t youngest = GIT_INVALID_REVNUM;
//	git_opt_revision_t rev;
//	rev.kind = git_opt_revision_unspecified;

	CString sProjectRoot;
	if ( !path.HasAdminDir(&sProjectRoot) )
		return youngest;

	struct hashbaton_t hashbaton;
//	hashbaton.hash = statushash;
//	hashbaton.exthash = exthash;
	hashbaton.pThis = this;

	bool isfull = ((DWORD)CRegStdDWORD(_T("Software\\TortoiseGit\\CacheType"),
				GetSystemMetrics(SM_REMOTESESSION) ? ShellCache::dll : ShellCache::exe) == ShellCache::dllFull);

	{
		LPCTSTR lpszSubPath = NULL;
		CString sSubPath;
		CString s = path.GetWinPathString();
		if (s.GetLength() > sProjectRoot.GetLength())
		{
			sSubPath = s.Right(s.GetLength() - sProjectRoot.GetLength());
			lpszSubPath = sSubPath;
			// skip initial slash if necessary
			if (*lpszSubPath == _T('\\'))
				lpszSubPath++;
		}

		m_status.prop_status = m_status.text_status = git_wc_status_none;

		if(path.IsDirectory())
		{
			m_err = GetDirStatus(sProjectRoot,CString(lpszSubPath),&m_status.text_status , isfull, false,!noignore, NULL, NULL);

		}
		else
		{
			m_err = GetFileStatus(sProjectRoot,CString(lpszSubPath),&m_status.text_status ,isfull, false,!noignore, NULL,NULL);
		}
	}

	// Error present if function is not under version control
	if (m_err) /*|| (apr_hash_count(statushash) == 0)*/
	{
		status = NULL;
		return GIT_INVALID_REVNUM;
	}

	// Convert the unordered hash to an ordered, sorted array
	/*statusarray = sort_hash (statushash,
							  sort_compare_items_as_paths,
							  m_pool);*/

	// only the first entry is needed (no recurse)
//	item = &APR_ARRAY_IDX (statusarray, 0, const sort_item);

//	status = (git_wc_status2_t *) item->value;
	status = &m_status;

	if (update)
	{
		// done to match TSVN functionality of this function (not sure if any code uses the reutrn val)
		// if TGit does not need this, then change the return type of function
		youngest = g_Git.GetHash(_T("HEAD"));
	}

	return youngest;
}
Example #15
0
int CGitStatus::GetStatus(const CString &gitdir, const CString &path, git_wc_status_kind *status, BOOL IsFull, BOOL IsRecursive , FIll_STATUS_CALLBACK callback , void *pData)
{
	int result;
	__int64 time;
	bool dir;

	git_wc_status_kind dirstatus = git_wc_status_none;
	if (status)
	{
		g_Git.GetFileModifyTime(path, &time, &dir);
		if(path.IsEmpty())
			result = _tstat64( gitdir, &buf );
		else
			result = _tstat64( gitdir+_T("\\")+path, &buf );

		if(result)
			return -1;

		if(buf.st_mode & _S_IFDIR)
		{
			if(!path.IsEmpty())
			{
				if( path.Right(1) != _T("\\"))
					path += _T("\\");
			}
			int len = path.GetLength();

			for (int i = 0; i < size(); i++)
			{
				if (at(i).m_FileName.GetLength() > len)
				{
					if (at(i).m_FileName.Left(len) == path)
					{
						if(!IsFull)
						{
							*status = git_wc_status_normal;
							if(callback)
								callback(gitdir + _T("\\") + path, *status, pData);
							return 0;

						}
						else
						{
							result = _tstat64(gitdir + _T("\\") + at(i).m_FileName, &buf);
							if (result)
								continue;

							*status = git_wc_status_none;
							GetFileStatus(gitdir, at(i).m_FileName, status, buf, callback, pData);
							if (*status != git_wc_status_none)
							{
								if (dirstatus == git_wc_status_none)
								{
									dirstatus = git_wc_status_normal;
								}
								if (*status != git_wc_status_normal)
								{
									dirstatus = git_wc_status_modified;
								}
							}

						}
					}
				}
			}

			if (dirstatus != git_wc_status_none)
			{
				*status = dirstatus;
			}
			else
			{
				*status = git_wc_status_unversioned;
			}
			if(callback)
				callback(gitdir + _T("\\") + path, *status, pData);

			return 0;

		}
		else
		{
			GetFileStatus(gitdir, path, status, buf, callback, pData);
		}
	}
	return 0;

}
Example #16
0
int GitStatus::EnumDirStatus(const CString &gitdir, const CString &subpath, git_wc_status_kind * status,BOOL IsFul, BOOL IsRecursive, BOOL IsIgnore, FILL_STATUS_CALLBACK callback, void *pData)
{
	try
	{
		CString path =subpath;

		path.Replace(_T('\\'),_T('/'));
		if(!path.IsEmpty())
			if(path[path.GetLength()-1] !=  _T('/'))
				path += _T('/'); //Add trail / to show it is directory, not file name.

		CString lowcasepath = path;
		lowcasepath.MakeLower();

		std::vector<CGitFileName> filelist;
		GetFileList(gitdir, subpath, filelist);

		if(status)
		{
			g_IndexFileMap.CheckAndUpdate(gitdir,true);

			g_HeadFileMap.CheckHeadAndUpdate(gitdir);

			SHARED_INDEX_PTR indexptr = g_IndexFileMap.SafeGet(gitdir);
			SHARED_TREE_PTR treeptr = g_HeadFileMap.SafeGet(gitdir);

			std::vector<CGitFileName>::iterator it;

			// new git working tree has no index file
			if (indexptr.get() == NULL)
			{
				for (it = filelist.begin(); it < filelist.end(); ++it)
				{
					CString casepath = path + it->m_CaseFileName;

					bool bIsDir = false;
					if (it->m_FileName.GetLength() > 0 && it->m_FileName[it->m_FileName.GetLength() - 1] == _T('/'))
						bIsDir = true;

					if (IsIgnore)
					{
						if (g_IgnoreList.CheckIgnoreChanged(gitdir, casepath, bIsDir))
							g_IgnoreList.LoadAllIgnoreFile(gitdir, casepath, bIsDir);

						if (g_IgnoreList.IsIgnore(casepath, gitdir, bIsDir))
							*status = git_wc_status_ignored;
						else if (bIsDir)
							continue;
						else
							*status = git_wc_status_unversioned;
					}
					else if (bIsDir)
						continue;
					else
						*status = git_wc_status_unversioned;

					if(callback)
						callback(gitdir + _T("/") + casepath, *status, bIsDir, pData, false, false);
				}
				return 0;
			}

			CString onepath;
			CString casepath;
			for (it = filelist.begin(); it < filelist.end(); ++it)
			{
				casepath=onepath = path;
				onepath.MakeLower();
				onepath += it->m_FileName;
				casepath += it->m_CaseFileName;

				bool bIsDir = false;
				if (!onepath.IsEmpty() && onepath[onepath.GetLength() - 1] == _T('/'))
					bIsDir = true;

				int matchLength = -1;
				if (bIsDir)
					matchLength = onepath.GetLength();
				int pos = SearchInSortVector(*indexptr, onepath, matchLength);
				int posintree = SearchInSortVector(*treeptr, onepath, matchLength);

				if(pos <0 && posintree<0)
				{
					if (onepath.IsEmpty())
						continue;

					if(!IsIgnore)
					{
						*status = git_wc_status_unversioned;
						if(callback)
							callback(gitdir + _T("/") + casepath, *status, bIsDir, pData, false, false);
						continue;
					}

					if (g_IgnoreList.CheckIgnoreChanged(gitdir, casepath, bIsDir))
						g_IgnoreList.LoadAllIgnoreFile(gitdir, casepath, bIsDir);

					if (g_IgnoreList.IsIgnore(casepath, gitdir, bIsDir))
						*status = git_wc_status_ignored;
					else
						*status = git_wc_status_unversioned;

					if(callback)
						callback(gitdir + _T("/") + casepath, *status, bIsDir, pData, false, false);

				}
				else if(pos <0 && posintree>=0) /* check if file delete in index */
				{
					*status = git_wc_status_deleted;
					if(callback)
						callback(gitdir + _T("/") + casepath, *status, bIsDir, pData, false, false);

				}
				else if(pos >=0 && posintree <0) /* Check if file added */
				{
					*status = git_wc_status_added;
					if(callback)
						callback(gitdir + _T("/") + casepath, *status, bIsDir, pData, false, false);
				}
				else
				{
					if (onepath.IsEmpty())
						continue;

					if (bIsDir)
					{
						*status = git_wc_status_normal;
						if(callback)
							callback(gitdir + _T("/") + casepath, *status, bIsDir, pData, false, false);
					}
					else
					{
						bool assumeValid = false;
						bool skipWorktree = false;
						git_wc_status_kind filestatus;
						GetFileStatus(gitdir, casepath, &filestatus, IsFul, IsRecursive, IsIgnore, callback, pData, &assumeValid, &skipWorktree);
					}
				}

			}/*End of For*/

			/* Check deleted file in system */
			int start=0, end=0;
			int pos = SearchInSortVector(*indexptr, lowcasepath, lowcasepath.GetLength()); // match path prefix, (sub)folders end with slash
			std::map<CString, bool> skipWorktreeMap;

			if (GetRangeInSortVector(*indexptr, lowcasepath, lowcasepath.GetLength(), &start, &end, pos) == 0)
			{
				CGitIndexList::iterator it;
				CString oldstring;

				for (it = indexptr->begin() + start; it <= indexptr->begin() + end; ++it)
				{
					int commonPrefixLength = lowcasepath.GetLength();
					int index = (*it).m_FileName.Find(_T('/'), commonPrefixLength);
					if(index<0)
						index = (*it).m_FileName.GetLength();
					else
						++index; // include slash at the end for subfolders, so that we do not match files by mistake

					CString filename = (*it).m_FileName.Mid(commonPrefixLength, index - commonPrefixLength);
					if(oldstring != filename)
					{
						oldstring = filename;
						if (SearchInSortVector(filelist, filename, filename.GetLength()) < 0)
						{
							bool skipWorktree = false;
							*status = git_wc_status_deleted;
							if (((*it).m_Flags & GIT_IDXENTRY_SKIP_WORKTREE) != 0)
							{
								skipWorktreeMap[filename] = true;
								skipWorktree = true;
								*status = git_wc_status_normal;
							}
							if(callback)
								callback(gitdir + _T("/") + (*it).m_FileName, *status, false, pData, false, skipWorktree);
						}
					}
				}
			}

			start = end =0;
			pos = SearchInSortVector(*treeptr, lowcasepath, lowcasepath.GetLength()); // match path prefix, (sub)folders end with slash
			if (GetRangeInSortVector(*treeptr, lowcasepath, lowcasepath.GetLength(), &start, &end, pos) == 0)
			{
				CGitHeadFileList::iterator it;
				CString oldstring;

				for (it = treeptr->begin() + start; it <= treeptr->begin() + end; ++it)
				{
					int commonPrefixLength = lowcasepath.GetLength();
					int index = (*it).m_FileName.Find(_T('/'), commonPrefixLength);
					if(index<0)
						index = (*it).m_FileName.GetLength();
					else
						++index; // include slash at the end for subfolders, so that we do not match files by mistake

					CString filename = (*it).m_FileName.Mid(commonPrefixLength, index - commonPrefixLength);
					if (oldstring != filename && skipWorktreeMap[filename] != true)
					{
						oldstring = filename;
						if (SearchInSortVector(filelist, filename, filename.GetLength()) < 0)
						{
							*status = git_wc_status_deleted;
							if(callback)
								callback(gitdir + _T("/") + (*it).m_FileName, *status, false, pData, false, false);
						}
					}
				}
			}

		}/*End of if status*/
	}catch(...)
	{
		return -1;
	}
	return 0;

}
Example #17
0
int CGitIndexList::GetStatus(const CString &gitdir,const CString &pathParam, git_wc_status_kind *status,
							 BOOL IsFull, BOOL IsRecursive,
							 FIll_STATUS_CALLBACK callback,void *pData,
							 CGitHash *pHash)
{
	int result;
	git_wc_status_kind dirstatus = git_wc_status_none;
	__int64 time;
	bool isDir = false;
	CString path = pathParam;

	if (status)
	{
		if (path.IsEmpty())
			result = g_Git.GetFileModifyTime(gitdir, &time, &isDir);
		else
			result = g_Git.GetFileModifyTime(gitdir + _T("\\") + path, &time, &isDir);

		if (result)
		{
			*status = git_wc_status_deleted;
			if (callback)
				callback(gitdir + _T("\\") + path, git_wc_status_deleted, false, pData);

			return 0;
		}
		if (isDir)
		{
			if (!path.IsEmpty())
			{
				if (path.Right(1) != _T("\\"))
					path += _T("\\");
			}
			int len = path.GetLength();

				for (int i = 0; i < size(); i++)
				{
					if (at(i).m_FileName.GetLength() > len)
					{
						if (at(i).m_FileName.Left(len) == path)
						{
							if (!IsFull)
							{
								*status = git_wc_status_normal;
								if (callback)
									callback(gitdir + _T("\\") + path, *status, false, pData);
								return 0;

							}
							else
							{
								result = g_Git.GetFileModifyTime(gitdir+_T("\\") + at(i).m_FileName, &time);
								if (result)
									continue;

								*status = git_wc_status_none;
								GetFileStatus(gitdir, at(i).m_FileName, status, time, callback, pData);
								if (*status != git_wc_status_none)
								{
									if (dirstatus == git_wc_status_none)
									{
										dirstatus = git_wc_status_normal;
									}
									if (*status != git_wc_status_normal)
									{
										dirstatus = git_wc_status_modified;
									}
								}

							}
						}
					}
				} /* End For */

			if (dirstatus != git_wc_status_none)
			{
				*status = dirstatus;
			}
			else
			{
				*status = git_wc_status_unversioned;
			}
			if(callback)
				callback(gitdir + _T("\\") + path, *status, false, pData);

			return 0;

		}
		else
		{
			GetFileStatus(gitdir, path, status, time, callback, pData, pHash);
		}
	}
	return 0;
}
Example #18
0
int GitStatus::GetDirStatus(const CString &gitdir, const CString &subpath, git_wc_status_kind * status, BOOL IsFul, BOOL IsRecursive, BOOL IsIgnore, FILL_STATUS_CALLBACK callback, void *pData)
{
	try
	{
		CString path =subpath;

		path.Replace(_T('\\'),_T('/'));
		if(!path.IsEmpty())
			if(path[path.GetLength()-1] !=  _T('/'))
				path += _T('/'); //Add trail / to show it is directory, not file name.

		CString lowcasepath = path;
		lowcasepath.MakeLower();

		if(status)
		{
			g_IndexFileMap.CheckAndUpdate(gitdir, true);

			SHARED_INDEX_PTR indexptr = g_IndexFileMap.SafeGet(gitdir);

			if (indexptr == NULL)
			{
				*status = git_wc_status_unversioned;
				return 0;
			}

			int pos = SearchInSortVector(*indexptr, lowcasepath, lowcasepath.GetLength());

			//Not In Version Contorl
			if(pos<0)
			{
				if(!IsIgnore)
				{
					*status = git_wc_status_unversioned;
					if(callback)
						callback(gitdir + _T("/") + path, *status, false, pData, false, false);
					return 0;
				}
				//Check ignore always.
				{
					if (g_IgnoreList.CheckIgnoreChanged(gitdir, path, true))
						g_IgnoreList.LoadAllIgnoreFile(gitdir, path, true);

					if (g_IgnoreList.IsIgnore(path, gitdir, true))
						*status = git_wc_status_ignored;
					else
						*status = git_wc_status_unversioned;

					g_HeadFileMap.CheckHeadAndUpdate(gitdir, false);

					SHARED_TREE_PTR treeptr = g_HeadFileMap.SafeGet(gitdir);
					//Check init repository
					if (treeptr->HeadIsEmpty() && path.IsEmpty())
						*status = git_wc_status_normal;
				}

			}
			else  // In version control
			{
				*status = git_wc_status_normal;

				int start=0;
				int end=0;
				if(path.IsEmpty())
				{
					start=0;
					end = (int)indexptr->size() - 1;
				}
				GetRangeInSortVector(*indexptr, lowcasepath, lowcasepath.GetLength(), &start, &end, pos);
				CGitIndexList::iterator it;

				it = indexptr->begin()+start;

				// Check Conflict;
				for (int i = start; i <= end; ++i)
				{
					if (((*it).m_Flags & GIT_IDXENTRY_STAGEMASK) !=0)
					{
						*status = git_wc_status_conflicted;
						if(callback)
						{
							int dirpos = (*it).m_FileName.Find(_T('/'), path.GetLength());
							if(dirpos<0 || IsRecursive)
								callback(gitdir + _T("\\") + it->m_FileName, git_wc_status_conflicted, false, pData, false, false);
						}
						else
							break;
					}
					++it;
				}

				if( IsFul && (*status != git_wc_status_conflicted))
				{
					*status = git_wc_status_normal;

					g_HeadFileMap.CheckHeadAndUpdate(gitdir);

					//Check Add
					it = indexptr->begin()+start;


					{
						//Check if new init repository
						SHARED_TREE_PTR treeptr = g_HeadFileMap.SafeGet(gitdir);

						if (!treeptr->empty() || treeptr->HeadIsEmpty())
						{
							for (int i = start; i<= end; ++i)
							{
								pos = SearchInSortVector(*treeptr, (*it).m_FileName, -1);

								if(pos < 0)
								{
									*status = max(git_wc_status_added, *status); // added file found
									if(callback)
									{
										int dirpos = (*it).m_FileName.Find(_T('/'), path.GetLength());
										if(dirpos<0 || IsRecursive)
											callback(gitdir + _T("\\") + it->m_FileName, git_wc_status_added, false, pData, false, false);

									}
									else
										break;
								}

								if( pos>=0 && treeptr->at(pos).m_Hash != (*it).m_IndexHash)
								{
									*status = max(git_wc_status_modified, *status); // modified file found
									if(callback)
									{
										int dirpos = (*it).m_FileName.Find(_T('/'), path.GetLength());
										if(dirpos<0 || IsRecursive)
											callback(gitdir + _T("\\") + it->m_FileName, git_wc_status_modified, false, pData, ((*it).m_Flags & GIT_IDXENTRY_VALID) && !((*it).m_Flags & GIT_IDXENTRY_SKIP_WORKTREE), ((*it).m_Flags & GIT_IDXENTRY_SKIP_WORKTREE) != 0);

									}
									else
										break;
								}

								++it;
							}

							//Check Delete
							if( *status == git_wc_status_normal )
							{
								pos = SearchInSortVector(*treeptr, lowcasepath, lowcasepath.GetLength());
								if(pos <0)
								{
									*status = max(git_wc_status_added, *status); // added file found

								}
								else
								{
									int hstart,hend;
									GetRangeInSortVector(*treeptr, lowcasepath, lowcasepath.GetLength(), &hstart, &hend, pos);
									CGitHeadFileList::iterator hit;
									hit = treeptr->begin() + hstart;
									CGitHeadFileList::iterator lastElement = treeptr->end();
									for (int i = hstart; i <= hend && hit != lastElement; ++i)
									{
										if (SearchInSortVector(*indexptr, (*hit).m_FileName, -1) < 0)
										{
											*status = max(git_wc_status_deleted, *status); // deleted file found
											break;
										}
										++hit;
									}
								}
							}
						}
					}/* End lock*/
				}
				// If define callback, it need update each file status.
				// If not define callback, status == git_wc_status_conflicted, needn't check each file status
				// because git_wc_status_conflicted is highest.s
				if(callback || (*status != git_wc_status_conflicted))
				{
					//Check File Time;
					//if(IsRecursive)
					{
						CString sub, currentPath;
						it = indexptr->begin()+start;
						for (int i = start; i <= end; ++i, ++it)
						{
							if( !IsRecursive )
							{
								//skip child directory
								int pos = (*it).m_FileName.Find(_T('/'), path.GetLength());

								if( pos > 0)
								{
									currentPath = (*it).m_FileName.Left(pos);
									if( callback && (sub != currentPath) )
									{
										sub = currentPath;
										CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": index subdir %s\n"),sub);
										if(callback) callback(gitdir + _T("\\") + sub,
											git_wc_status_normal, true, pData, false, false);
									}
									continue;
								}
							}

							git_wc_status_kind filestatus = git_wc_status_none;
							bool assumeValid = false;
							bool skipWorktree = false;
							GetFileStatus(gitdir, (*it).m_FileName, &filestatus, IsFul, IsRecursive, IsIgnore, callback, pData, &assumeValid, &skipWorktree);
						}
					}
				}
			}

			if(callback) callback(gitdir + _T("/") + subpath, *status, true, pData, false, false);
		}

	}catch(...)
	{
		if(status)
			*status = git_wc_status_none;
		return -1;
	}

	return 0;
}
Example #19
0
int GitStatus::GetDirStatus(const CString& gitdir, const CString& subpath, git_wc_status_kind* status, BOOL IsFul, BOOL IsRecursive, BOOL IsIgnore)
{
	if (!status)
		return 0;

	CString path = subpath;

	path.Replace(_T('\\'), _T('/'));
	if (!path.IsEmpty() && path[path.GetLength() - 1] != _T('/'))
		path += _T('/'); //Add trail / to show it is directory, not file name.

	g_IndexFileMap.CheckAndUpdate(gitdir, true);

	SHARED_INDEX_PTR indexptr = g_IndexFileMap.SafeGet(gitdir);

	if (!indexptr)
	{
		*status = git_wc_status_unversioned;
		return 0;
	}

	CString lowcasepath = path;
	lowcasepath.MakeLower();

	int pos = SearchInSortVector(*indexptr, lowcasepath, lowcasepath.GetLength());

	// Not In Version Contorl
	if (pos < 0)
	{
		if (!IsIgnore)
		{
			*status = git_wc_status_unversioned;
			return 0;
		}

		// Check ignore always.
		if (g_IgnoreList.CheckIgnoreChanged(gitdir, path, true))
			g_IgnoreList.LoadAllIgnoreFile(gitdir, path, true);

		if (g_IgnoreList.IsIgnore(path, gitdir, true))
			*status = git_wc_status_ignored;
		else
			*status = git_wc_status_unversioned;

		g_HeadFileMap.CheckHeadAndUpdate(gitdir);

		SHARED_TREE_PTR treeptr = g_HeadFileMap.SafeGet(gitdir);
		// Check init repository
		if (treeptr->HeadIsEmpty() && path.IsEmpty())
			*status = git_wc_status_normal;
		// check if only one file in repository is deleted in index
		else if (path.IsEmpty() && !treeptr->empty())
			*status = git_wc_status_deleted;

		return 0;
	}

	// In version control
	*status = git_wc_status_normal;

	int start = 0;
	int end = 0;

	GetRangeInSortVector(*indexptr, lowcasepath, lowcasepath.GetLength(), &start, &end, pos);

	// Check Conflict;
	for (auto it = indexptr->cbegin() + start, itlast = indexptr->cbegin() + end; indexptr->m_bHasConflicts && it <= itlast; ++it)
	{
		if (((*it).m_Flags & GIT_IDXENTRY_STAGEMASK) != 0)
		{
			*status = git_wc_status_conflicted;
			break;
		}
	}

	if (IsFul && (*status != git_wc_status_conflicted))
	{
		*status = git_wc_status_normal;

		g_HeadFileMap.CheckHeadAndUpdate(gitdir);

		// Check Add
		{
			// Check if new init repository
			SHARED_TREE_PTR treeptr = g_HeadFileMap.SafeGet(gitdir);

			if (!treeptr->empty() || treeptr->HeadIsEmpty())
			{
				for (auto it = indexptr->cbegin() + start, itlast = indexptr->cbegin() + end; it <= itlast; ++it)
				{
					pos = SearchInSortVector(*treeptr, (*it).m_FileName, -1);

					if (pos < 0)
					{
						*status = max(git_wc_status_added, *status); // added file found
						break;
					}

					if (pos >= 0 && treeptr->at(pos).m_Hash != (*it).m_IndexHash)
					{
						*status = max(git_wc_status_modified, *status); // modified file found
						break;
					}
				}

				// Check Delete
				if (*status == git_wc_status_normal)
				{
					pos = SearchInSortVector(*treeptr, lowcasepath, lowcasepath.GetLength());
					if (pos < 0)
						*status = max(git_wc_status_added, *status); // added file found
					else
					{
						int hstart, hend;
						GetRangeInSortVector(*treeptr, lowcasepath, lowcasepath.GetLength(), &hstart, &hend, pos);
						for (auto hit = treeptr->cbegin() + hstart, lastElement = treeptr->cbegin() + hend; hit <= lastElement; ++hit)
						{
							if (SearchInSortVector(*indexptr, (*hit).m_FileName, -1) < 0)
							{
								*status = max(git_wc_status_deleted, *status); // deleted file found
								break;
							}
						}
					}
				}
			}
		} /* End lock*/
	}

	// When status == git_wc_status_conflicted, needn't check each file status
	// because git_wc_status_conflicted is highest.s
	if (*status == git_wc_status_conflicted)
		return 0;

	for (auto it = indexptr->cbegin() + start, itlast = indexptr->cbegin() + end; it <= itlast; ++it)
	{
		//skip child directory
		if (!IsRecursive && (*it).m_FileName.Find(_T('/'), path.GetLength()) > 0)
			continue;

		git_wc_status_kind filestatus = git_wc_status_none;
		bool assumeValid = false;
		bool skipWorktree = false;
		GetFileStatus(gitdir, (*it).m_FileName, &filestatus, IsFul, IsRecursive, IsIgnore, nullptr, nullptr, &assumeValid, &skipWorktree);
		switch (filestatus)
		{
		case git_wc_status_added:
		case git_wc_status_modified:
		case git_wc_status_deleted:
		case git_wc_status_conflicted:
			*status = GetMoreImportant(filestatus, *status);
		}
	}

	return 0;
}