const FileStatusCacheEntry * GitFolderStatus::BuildCache(const CTGitPath& filepath, const CString& /*sProjectRoot*/, BOOL bIsFolder, BOOL bDirectFolder) { //dont' build the cache if an instance of TortoiseGitProc is running //since this could interfere with svn commands running (concurrent //access of the .git directory). if (g_ShellCache.BlockStatus()) { CAutoGeneralHandle TGitMutex = ::CreateMutex(NULL, FALSE, _T("TortoiseGitProc.exe")); if (TGitMutex != NULL) { if (::GetLastError() == ERROR_ALREADY_EXISTS) { return &invalidstatus; } } } ClearCache(); if (bIsFolder) { if (bDirectFolder) { // NOTE: see not in GetFullStatus about project inside another project, we should only get here when // that occurs, and this is not correctly handled yet // initialize record members dirstat.status = git_wc_status_none; dirstat.askedcounter = GITFOLDERSTATUS_CACHETIMES; dirstat.assumeValid = FALSE; dirstat.skipWorktree = FALSE; dirstatus = NULL; // rev.kind = git_opt_revision_unspecified; if (dirstatus) { /* if (dirstatus->entry) { dirstat.author = authors.GetString (dirstatus->entry->cmt_author); dirstat.url = authors.GetString (dirstatus->entry->url); dirstat.rev = dirstatus->entry->cmt_rev; }*/ dirstat.status = GitStatus::GetMoreImportant(dirstatus->text_status, dirstatus->prop_status); } m_cache[filepath.GetWinPath()] = dirstat; m_TimeStamp = GetTickCount(); return &dirstat; } } // if (bIsFolder) m_nCounter = 0; git_wc_status_kind status; bool assumeValid = false; bool skipWorktree = false; int t1,t2; t2=t1=0; try { git_depth_t depth = git_depth_infinity; if (g_ShellCache.GetCacheType() == ShellCache::dll) { depth = git_depth_empty; } t1 = ::GetCurrentTime(); status = m_GitStatus.GetAllStatus(filepath, depth, &assumeValid, &skipWorktree); t2 = ::GetCurrentTime(); } catch ( ... ) { status = git_wc_status_unknown; } CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": building cache for %s - time %d\n"), filepath.GetWinPath(), t2 - t1); m_TimeStamp = GetTickCount(); FileStatusCacheEntry * ret = NULL; if (_tcslen(filepath.GetWinPath())==3) ret = &m_cache[(LPCTSTR)filepath.GetWinPathString().Left(2)]; else ret = &m_cache[filepath.GetWinPath()]; if (ret) { ret->status = status; ret->assumeValid = assumeValid; ret->skipWorktree = skipWorktree; } m_mostRecentPath = filepath; m_mostRecentStatus = ret; if (ret) return ret; return &invalidstatus; }
const FileStatusCacheEntry * GitFolderStatus::BuildCache(const CTGitPath& filepath, const CString& sProjectRoot, BOOL bIsFolder, BOOL bDirectFolder) { // svn_client_ctx_t * localctx; // apr_hash_t * statushash; // apr_pool_t * pool; //git_error_t * err = NULL; // If svn_client_status comes out through catch(...), err would else be unassigned git_error_t err = 0; //dont' build the cache if an instance of TortoiseProc is running //since this could interfere with svn commands running (concurrent //access of the .git directory). if (g_ShellCache.BlockStatus()) { HANDLE TGitMutex = ::CreateMutex(NULL, FALSE, _T("TortoiseGitProc.exe")); if (TGitMutex != NULL) { if (::GetLastError() == ERROR_ALREADY_EXISTS) { ::CloseHandle(TGitMutex); return &invalidstatus; } } ::CloseHandle(TGitMutex); } // pool = svn_pool_create (rootpool); // create the memory pool ClearCache(); // svn_error_clear(svn_client_create_context(&localctx, pool)); // set up the configuration // Note: I know this is an 'expensive' call, but without this, ignores // done in the global ignore pattern won't show up. // if (g_ShellCache.ShowIgnoredOverlay()) //;// svn_error_clear(svn_config_get_config (&(localctx->config), g_pConfigDir, pool)); // strings pools are unused, now -> we may clear them authors.clear(); urls.clear(); owners.clear(); if (bIsFolder) { if (bDirectFolder) { // NOTE: see not in GetFullStatus about project inside another project, we should only get here when // that occurs, and this is not correctly handled yet // initialize record members // dirstat.rev = -1; dirstat.status = git_wc_status_none; dirstat.author = authors.GetString(NULL); dirstat.url = urls.GetString(NULL); dirstat.owner = owners.GetString(NULL); dirstat.askedcounter = GITFOLDERSTATUS_CACHETIMES; dirstat.needslock = false; dirstat.tree_conflict = false; dirstatus = NULL; // statushash = apr_hash_make(pool); // git_revnum_t youngest = GIT_INVALID_REVNUM; // git_opt_revision_t rev; // rev.kind = git_opt_revision_unspecified; try { folderpath = filepath; /*err = svn_client_status4 (&youngest, filepath.GetDirectory().GetSVNApiPath(pool), &rev, findfolderstatus, this, svn_depth_empty,//depth TRUE, //getall FALSE, //update TRUE, //noignore FALSE, //ignore externals NULL, localctx, pool);*/ } catch ( ... ) { dirstatus = NULL; } if (dirstatus) { /* if (dirstatus->entry) { dirstat.author = authors.GetString (dirstatus->entry->cmt_author); dirstat.url = authors.GetString (dirstatus->entry->url); dirstat.rev = dirstatus->entry->cmt_rev; dirstat.owner = owners.GetString(dirstatus->entry->lock_owner); }*/ dirstat.status = GitStatus::GetMoreImportant(dirstatus->text_status, dirstatus->prop_status); // dirstat.tree_conflict = dirstatus->tree_conflict != NULL; } m_cache[filepath.GetWinPath()] = dirstat; m_TimeStamp = GetTickCount(); // svn_error_clear(err); // svn_pool_destroy (pool); //free allocated memory return &dirstat; } } // if (bIsFolder) m_nCounter = 0; //Fill in the cache with //all files inside the same folder as the asked file/folder is //since subversion can do this in one step // localctx->auth_baton = NULL; // statushash = apr_hash_make(pool); // git_revnum_t youngest = GIT_INVALID_REVNUM; // git_opt_revision_t rev; // rev.kind = git_opt_revision_unspecified; git_wc_status_kind status; int t1,t2; t2=t1=0; try { git_depth_t depth = git_depth_infinity; if (g_ShellCache.GetCacheType() == ShellCache::dll) { depth = git_depth_empty; } t1 = ::GetCurrentTime(); status = m_GitStatus.GetAllStatus(filepath, depth); t2 = ::GetCurrentTime(); } catch ( ... ) { } ATLTRACE2(_T("building cache for %s - time %d\n"), filepath.GetWinPath(), t2 -t1); // Error present if function is not under version control if (err != NULL) { // svn_error_clear(err); // svn_pool_destroy (pool); //free allocated memory return &invalidstatus; } // svn_error_clear(err); // svn_pool_destroy (pool); //free allocated memory m_TimeStamp = GetTickCount(); FileStatusCacheEntry * ret = NULL; if (_tcslen(filepath.GetWinPath())==3) ret = &m_cache[(LPCTSTR)filepath.GetWinPathString().Left(2)]; else ret = &m_cache[filepath.GetWinPath()]; //memset(ret, 0, sizeof(FileStatusCacheEntry)); ret->status = status; m_mostRecentPath = filepath; m_mostRecentStatus = ret; #if 0 FileStatusMap::const_iterator iter; if ((iter = m_cache.find(filepath.GetWinPath())) != m_cache.end()) { ret = &iter->second; m_mostRecentPath = filepath; m_mostRecentStatus = ret; } else { // for SUBST'ed drives, Subversion doesn't return a path with a backslash // e.g. G:\ but only G: when fetching the status. So search for that // path too before giving up. // This is especially true when right-clicking directly on a SUBST'ed // drive to get the context menu if (_tcslen(filepath.GetWinPath())==3) { if ((iter = m_cache.find((LPCTSTR)filepath.GetWinPathString().Left(2))) != m_cache.end()) { ret = &iter->second; m_mostRecentPath = filepath; m_mostRecentStatus = ret; } } } #endif if (ret) return ret; return &invalidstatus; }