// Update our composite status and deal with things if it's changed void CCachedDirectory::UpdateCurrentStatus() { git_wc_status_kind newStatus = CalculateRecursiveStatus(); CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": UpdateCurrentStatus %s new:%d old: %d\n"), m_directoryPath.GetWinPath(), newStatus, m_currentFullStatus); if (newStatus != m_currentFullStatus && m_ownStatus.IsDirectory()) { m_currentFullStatus = newStatus; // Our status has changed - tell the shell CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": Dir %s, status change from %d to %d\n"), m_directoryPath.GetWinPath(), m_currentFullStatus, newStatus); CGitStatusCache::Instance().UpdateShell(m_directoryPath); } // And tell our parent, if we've got one... // we tell our parent *always* about our status, even if it hasn't // changed. This is to make sure that the parent has really our current // status - the parent can decide itself if our status has changed // or not. CTGitPath parentPath = m_directoryPath.GetContainingDirectory(); if(!parentPath.IsEmpty()) { // We have a parent // just version controled directory need to cache. CString root1, root2; if (parentPath.HasAdminDir(&root1) && (CGitStatusCache::Instance().IsRecurseSubmodules() || m_directoryPath.HasAdminDir(&root2) && root1 == root2)) { CCachedDirectory * cachedDir = CGitStatusCache::Instance().GetDirectoryCacheEntry(parentPath); if (cachedDir) cachedDir->UpdateChildDirectoryStatus(m_directoryPath, m_currentFullStatus); } } }
// Update our composite status and deal with things if it's changed void CCachedDirectory::UpdateCurrentStatus() { svn_wc_status_kind newStatus = CalculateRecursiveStatus(); if ((newStatus != m_currentFullStatus)&&(m_ownStatus.IsVersioned())) { if ((m_currentFullStatus != svn_wc_status_none)&&(m_ownStatus.GetEffectiveStatus() != svn_wc_status_ignored)) { // Our status has changed - tell the shell CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": Dir %s, status change from %d to %d\n"), m_directoryPath.GetWinPath(), m_currentFullStatus, newStatus); CSVNStatusCache::Instance().UpdateShell(m_directoryPath); } if (m_ownStatus.GetEffectiveStatus() != svn_wc_status_ignored) m_currentFullStatus = newStatus; else m_currentFullStatus = svn_wc_status_ignored; } // And tell our parent, if we've got one... // we tell our parent *always* about our status, even if it hasn't // changed. This is to make sure that the parent has really our current // status - the parent can decide itself if our status has changed // or not. CTSVNPath parentPath = m_directoryPath.GetContainingDirectory(); if(!parentPath.IsEmpty()) { CCachedDirectory * cachedDir = CSVNStatusCache::Instance().GetDirectoryCacheEntry(parentPath); if (cachedDir) cachedDir->UpdateChildDirectoryStatus(m_directoryPath, m_currentFullStatus); } }
// Update our composite status and deal with things if it's changed void CCachedDirectory::UpdateCurrentStatus() { git_wc_status_kind newStatus = CalculateRecursiveStatus(); ATLTRACE(_T("UpdateCurrentStatus %s new:%d old: %d\n"), m_directoryPath.GetWinPath(), newStatus, m_currentFullStatus); if ( this->m_ownStatus.GetEffectiveStatus() < git_wc_status_normal ) { if (::PathFileExists(this->m_directoryPath.GetWinPathString()+_T("\\.git"))) { //project root must be normal status at least. ATLTRACE(_T("force update project root directory as normal status\n")); this->m_ownStatus.ForceStatus(git_wc_status_normal); } } if ((newStatus != m_currentFullStatus) && m_ownStatus.IsVersioned()) { if ((m_currentFullStatus != git_wc_status_none)&&(m_ownStatus.GetEffectiveStatus() != git_wc_status_missing)) { // Our status has changed - tell the shell ATLTRACE(_T("Dir %s, status change from %d to %d, send shell notification\n"), m_directoryPath.GetWinPath(), m_currentFullStatus, newStatus); CGitStatusCache::Instance().UpdateShell(m_directoryPath); } if (m_ownStatus.GetEffectiveStatus() != git_wc_status_missing) m_currentFullStatus = newStatus; else m_currentFullStatus = git_wc_status_missing; } // And tell our parent, if we've got one... // we tell our parent *always* about our status, even if it hasn't // changed. This is to make sure that the parent has really our current // status - the parent can decide itself if our status has changed // or not. CTGitPath parentPath = m_directoryPath.GetContainingDirectory(); if(!parentPath.IsEmpty()) { // We have a parent // just version controled directory need to cache. CString root1, root2; if(parentPath.HasAdminDir(&root1) && m_directoryPath.HasAdminDir(&root2) && root1 == root2) { CCachedDirectory * cachedDir = CGitStatusCache::Instance().GetDirectoryCacheEntry(parentPath); if (cachedDir) cachedDir->UpdateChildDirectoryStatus(m_directoryPath, m_currentFullStatus); } } }
int CCachedDirectory::EnumFiles(const CTGitPath &path , bool IsFull) { CString sProjectRoot; path.HasAdminDir(&sProjectRoot); CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": EnumFiles %s\n"), path.GetWinPath()); ATLASSERT( !m_directoryPath.IsEmpty() ); CString sSubPath; CString s = path.GetWinPath(); if (s.GetLength() > sProjectRoot.GetLength()) { // skip initial slash if necessary if(s[sProjectRoot.GetLength()] == _T('\\')) sSubPath = s.Right(s.GetLength() - sProjectRoot.GetLength() -1); else sSubPath = s.Right(s.GetLength() - sProjectRoot.GetLength() ); } // strip "\" at the end, otherwise cache lookups for drives do not work correctly sProjectRoot.TrimRight(_T("\\")); GitStatus *pStatus = &CGitStatusCache::Instance().m_GitStatus; UNREFERENCED_PARAMETER(pStatus); git_wc_status_kind status = git_wc_status_none; if (!path.IsDirectory()) { bool assumeValid = false; bool skipWorktree = false; pStatus->GetFileStatus(sProjectRoot, sSubPath, &status, IsFull, false, true, GetStatusCallback, this, &assumeValid, &skipWorktree); if (status < m_mostImportantFileStatus) RefreshMostImportant(); } else { bool isSelf = path == m_directoryPath; if (isSelf) { AutoLocker lock(m_critSec); // clear subdirectory status cache m_childDirectories.clear(); // build new files status cache m_entryCache_tmp.clear(); } m_mostImportantFileStatus = git_wc_status_none; pStatus->EnumDirStatus(sProjectRoot, sSubPath, &status, IsFull, false, true, GetStatusCallback,this); m_mostImportantFileStatus = GitStatus::GetMoreImportant(m_mostImportantFileStatus, status); if (isSelf) { AutoLocker lock(m_critSec); // use a tmp files status cache so that we can still use the old cached values // for deciding whether we have to issue a shell notify m_entryCache = m_entryCache_tmp; m_entryCache_tmp.clear(); } // need to set/construct m_ownStatus (only unversioned and normal are valid values) m_ownStatus = git_wc_status_unversioned; m_ownStatus.SetKind(git_node_dir); if (m_mostImportantFileStatus > git_wc_status_unversioned) { git_wc_status2_t status2; status2.text_status = status2.prop_status = git_wc_status_normal; m_ownStatus.SetStatus(&status2); } else { if (::PathFileExists(m_directoryPath.GetWinPathString() + _T("\\.git"))) { git_wc_status2_t status2; status2.text_status = status2.prop_status = git_wc_status_normal; m_ownStatus.SetStatus(&status2); } else { git_wc_status2_t status2; status2.text_status = status2.prop_status = CalculateRecursiveStatus(); m_ownStatus.SetStatus(&status2); } } } return 0; }