/* * DoAutoSave - try to do autosave of current file */ void DoAutoSave( void ) { char path[FILENAME_MAX]; char path2[FILENAME_MAX]; char tmp[FILENAME_MAX]; bool quiet; FILE *f; vi_rc rc; status_type lastst; if( EditVars.AutoSaveInterval == 0 ) { return; } if( clock() < NextAutoSave ) { return; } if( CurrentFile == NULL ) { return; } if( CurrentFile->is_stdio || CurrentFile->viewonly || !CurrentFile->need_autosave ) { SetNextAutoSaveTime(); return; } MakeTmpPath( path, "" ); if( !CurrentFile->been_autosaved ) { getTmpName( path, CurrentFile->as_name ); } strcat( path, CurrentFile->as_name ); quiet = EditFlags.Quiet; EditFlags.Quiet = TRUE; lastst = UpdateCurrentStatus( CSTATUS_AUTOSAVE ); rc = SaveFile( path, -1, -1, TRUE ); EditFlags.Quiet = quiet; UpdateCurrentStatus( lastst ); if( rc != ERR_NO_ERR ) { SetNextAutoSaveTime(); return; } /* * update history file */ CurrentFile->need_autosave = FALSE; if( !CurrentFile->been_autosaved ) { GetCurrentFilePath( path2 ); CurrentFile->been_autosaved = TRUE; MakeTmpPath( tmp, checkFileName ); f = fopen( tmp, "a" ); if( f != NULL ) { MyFprintf( f, "%s %s\n", path, path2 ); fclose( f ); } } SetNextAutoSaveTime(); } /* DoAutoSave */
/* * UpdateEditStatus - update current editing status */ void UpdateEditStatus( void ) { if( overStrike ) { UpdateCurrentStatus( CSTATUS_OVERSTRIKE ); EditFlags.WasOverstrike = TRUE; NewCursor( CurrentWindow, EditVars.OverstrikeCursorType ); } else { UpdateCurrentStatus( CSTATUS_INSERT ); EditFlags.WasOverstrike = FALSE; NewCursor( CurrentWindow, EditVars.InsertCursorType ); } SetWindowCursor(); } /* UpdateEditStatus */
MI_Result UpdateServerURLsToDSCCache( _In_ RegistrationManager *self, _Outptr_result_maybenull_ MI_Instance **cimErrorDetails) { MI_Application miApp = MI_APPLICATION_NULL; MI_Result result = MI_RESULT_OK; MI_Char* serverURLs = NULL; result = DSC_MI_Application_Initialize(0, NULL, NULL, &miApp); if (result != MI_RESULT_OK) { EH_Fail_(GetCimMIError(result, cimErrorDetails, ID_MODMAN_APPINIT_FAILED)); } result = FormatServerURLsForDscCache(self, &serverURLs, cimErrorDetails); EH_CheckResult(result); result = UpdateCurrentStatus(NULL, NULL, NULL, serverURLs, cimErrorDetails); EH_CheckResult(result); EH_UNWIND: if (serverURLs) { DSC_free(serverURLs); } MI_Application_Close(&miApp); return result; }
/* * DoHideCmd - hide a line range */ int DoHideCmd( void ) { int wasline = TRUE; vi_rc rc; int scol, ecol; linenum s, e; UpdateCurrentStatus( CSTATUS_HIDE ); rc = GetRange( 'g', &wasline, &scol, &ecol, &s, &e ); if( rc != ERR_NO_ERR ) { if( rc == ERR_INVALID_RANGE ) { rc = ERR_INVALID_HIDE_CMD; } if( rc == RANGE_REQUEST_CANCELLED ) { rc = ERR_NO_ERR; } return( rc ); } if( wasline == 0 ) { e = s = CurrentLineNumber; } return( HideLineRange( s, e, FALSE ) ); } /* DoHideCmd */
CStatusCacheEntry CCachedDirectory::GetOwnStatus(bool bRecursive) { // Don't return recursive status if we're unversioned ourselves. if(bRecursive && m_ownStatus.IsDirectory() && m_ownStatus.GetEffectiveStatus() != git_wc_status_ignored) { CStatusCacheEntry recursiveStatus(m_ownStatus); UpdateCurrentStatus(); recursiveStatus.ForceStatus(m_currentFullStatus); return recursiveStatus; } else { return m_ownStatus; } }
// Receive a notification from a child that its status has changed void CCachedDirectory::UpdateChildDirectoryStatus(const CTGitPath& childDir, git_wc_status_kind childStatus) { git_wc_status_kind currentStatus = git_wc_status_none; { AutoLocker lock(m_critSec); currentStatus = m_childDirectories[childDir]; } if ((currentStatus != childStatus)||(!IsOwnStatusValid())) { { AutoLocker lock(m_critSec); m_childDirectories[childDir] = childStatus; } UpdateCurrentStatus(); } }
// Receive a notification from a child that its status has changed void CCachedDirectory::UpdateChildDirectoryStatus(const CTSVNPath& childDir, svn_wc_status_kind childStatus) { CStringA winPath = CUnicodeUtils::GetUTF8 (childDir.GetWinPathString()); svn_wc_status_kind currentStatus = svn_wc_status_none; { AutoLocker lock(m_critSec); auto it = m_childDirectories.find(winPath); if (it == m_childDirectories.end()) return; // this is not a child, or at least not a child connected to the parent currentStatus = it->second; } if ((currentStatus != childStatus)||(!IsOwnStatusValid())) { SetChildStatus(winPath, childStatus); UpdateCurrentStatus(); } }
LRESULT CRebaseDlg::OnRebaseUpdateUI(WPARAM,LPARAM) { UpdateCurrentStatus(); if(m_CurrentRebaseIndex <0) return 0; if(m_CurrentRebaseIndex >= m_CommitList.GetItemCount() ) return 0; GitRev *curRev=(GitRev*)m_CommitList.m_arShownList[m_CurrentRebaseIndex]; switch(m_RebaseStage) { case REBASE_CONFLICT: case REBASE_SQUASH_CONFLICT: ListConflictFile(); this->m_ctrlTabCtrl.SetActiveTab(REBASE_TAB_CONFLICT); if (m_pTaskbarList) m_pTaskbarList->SetProgressState(m_hWnd, TBPF_ERROR); this->m_LogMessageCtrl.Call(SCI_SETREADONLY, FALSE); this->m_LogMessageCtrl.SetText(curRev->GetSubject()+_T("\n")+curRev->GetBody()); break; case REBASE_EDIT: this->m_ctrlTabCtrl.SetActiveTab(REBASE_TAB_MESSAGE); if (m_pTaskbarList) m_pTaskbarList->SetProgressState(m_hWnd, TBPF_PAUSED); this->m_LogMessageCtrl.Call(SCI_SETREADONLY, FALSE); this->m_LogMessageCtrl.SetText(curRev->GetSubject()+_T("\n")+curRev->GetBody()); break; case REBASE_SQUASH_EDIT: this->m_ctrlTabCtrl.SetActiveTab(REBASE_TAB_MESSAGE); this->m_LogMessageCtrl.Call(SCI_SETREADONLY, FALSE); this->m_LogMessageCtrl.SetText(this->m_SquashMessage); if (m_pTaskbarList) m_pTaskbarList->SetProgressState(m_hWnd, TBPF_PAUSED); break; default: this->m_ctrlTabCtrl.SetActiveTab(REBASE_TAB_LOG); } return 0; }
/* * SaveFile - save data from current file */ vi_rc SaveFile( char *name, linenum start, linenum end, int dammit ) { int i; bool existflag = FALSE, restpath = FALSE, makerw = FALSE; char *fn; fcb *cfcb, *sfcb, *efcb; linenum s, e, lc; long bc = 0; status_type lastst; vi_rc rc; int write_crlf; if( CurrentFile == NULL ) { return( ERR_NO_FILE ); } /* * get file name */ if( name == NULL ) { if( CurrentFile->viewonly ) { return( ERR_FILE_VIEW_ONLY ); } if( CFileReadOnly() ) { rc = readOnlyCheck(); if( rc != ERR_NO_ERR ) { return( ERR_READ_ONLY_FILE ); } makerw = TRUE; } fn = CurrentFile->name; restpath = TRUE; } else { existflag = TRUE; fn = name; } if( fn[0] == 0 ) { return( ERR_NO_FILE_NAME ); } if( SameFile( fn, CurrentFile->name ) ) { if( CurrentFile->viewonly ) { return( ERR_FILE_VIEW_ONLY ); } } if( dammit ) { existflag = FALSE; } /* * get range and fcbs */ if( start == -1L && end == -1L ) { s = 1L; rc = CFindLastLine( &e ); if( rc != ERR_NO_ERR ) { return( rc ); } } else { s = start; e = end; } lc = e - s + 1; rc = FindFcbWithLine( s, CurrentFile, &sfcb ); if( rc != ERR_NO_ERR ) { return( rc ); } rc = FindFcbWithLine( e, CurrentFile, &efcb ); if( rc != ERR_NO_ERR ) { return( rc ); } if( restpath ) { rc = ChangeDirectory( CurrentFile->home ); if( rc != ERR_NO_ERR ) { return( rc ); } } if( !CurrentFile->is_stdio ) { if( makerw ) { chmod( fn, PMODE_RW ); } rc = FileOpen( fn, existflag, O_TRUNC | O_WRONLY | O_BINARY | O_CREAT, WRITEATTRS, &fileHandle); if( rc != ERR_NO_ERR ) { Message1( strerror( errno ) ); return( rc ); } } else { fileHandle = 0; #ifdef __WATCOMC__ setmode( fileno( stdout ), O_BINARY ); #endif } /* * start writing fcbs */ #ifdef __WIN__ ToggleHourglass( TRUE ); #endif if( EditFlags.CRLFAutoDetect ) { write_crlf = CurrentFile->write_crlf; } else { write_crlf = EditFlags.WriteCRLF; } lastst = UpdateCurrentStatus( CSTATUS_WRITING ); for( cfcb = sfcb; cfcb != efcb; cfcb = cfcb->next ) { rc = writeRange( s, cfcb->end_line, cfcb, &bc, write_crlf, TRUE ); if( rc != ERR_NO_ERR ) { #ifdef __WIN__ ToggleHourglass( FALSE ); #endif UpdateCurrentStatus( lastst ); return( rc ); } s = cfcb->end_line + 1; } /* * last bit */ rc = writeRange( s, e, efcb, &bc, write_crlf, EditFlags.LastEOL ); #ifdef __WIN__ ToggleHourglass( FALSE ); #endif UpdateCurrentStatus( lastst ); if( rc != ERR_NO_ERR ) { return( rc ); } if( !CurrentFile->is_stdio ) { i = close( fileHandle ); if( makerw ) { chmod( fn, PMODE_R ); } if( i == -1 ) { Message1( strerror( errno ) ); return( ERR_FILE_CLOSE ); } } if( restpath ) { rc = ChangeDirectory( CurrentDirectory ); if( rc != ERR_NO_ERR ) { return( rc ); } } FileIOMessage( fn, lc, bc ); return( ERR_NO_ERR ); } /* SaveFile */
void CRebaseDlg::OnBnClickedContinue() { if( m_RebaseStage == REBASE_DONE) { OnOK(); return; } if( this->m_IsFastForward ) { CString cmd,out; CString oldbranch = g_Git.GetCurrentBranch(); if( oldbranch != m_BranchCtrl.GetString() ) { cmd.Format(_T("git.exe checkout %s"),m_BranchCtrl.GetString()); AddLogString(cmd); if( g_Git.Run(cmd,&out,CP_ACP) ) { this->m_ctrlTabCtrl.SetActiveTab(REBASE_TAB_LOG); AddLogString(out); return; } } AddLogString(out); out.Empty(); m_OrigBranchHash = g_Git.GetHash(m_BranchCtrl.GetString()); m_OrigUpstreamHash = g_Git.GetHash(this->m_UpstreamCtrl.GetString()); if(!g_Git.IsFastForward(this->m_BranchCtrl.GetString(),this->m_UpstreamCtrl.GetString())) { this->m_ctrlTabCtrl.SetActiveTab(REBASE_TAB_LOG); AddLogString(_T("No fast forward\r\nMaybe repository changed")); return; } cmd.Format(_T("git.exe reset --hard %s"),g_Git.FixBranchName(this->m_UpstreamCtrl.GetString())); this->AddLogString(CString(_T("Fast forward to "))+m_UpstreamCtrl.GetString()); AddLogString(cmd); this->m_ctrlTabCtrl.SetActiveTab(REBASE_TAB_LOG); if(g_Git.Run(cmd,&out,CP_ACP)) { AddLogString(_T("Fail")); AddLogString(out); return; } AddLogString(out); AddLogString(_T("Done")); m_RebaseStage = REBASE_DONE; UpdateCurrentStatus(); return; } if( m_RebaseStage == CHOOSE_BRANCH|| m_RebaseStage == CHOOSE_COMMIT_PICK_MODE ) { if(CheckRebaseCondition()) return ; m_RebaseStage = REBASE_START; m_FileListCtrl.Clear(); m_FileListCtrl.m_CurrentVersion = L""; m_ctrlTabCtrl.SetTabLabel(REBASE_TAB_CONFLICT, _T("Conflict Files")); m_ctrlTabCtrl.AddTab(&m_wndOutputRebase,_T("Log"),2); } if( m_RebaseStage == REBASE_FINISH ) { if(FinishRebase()) return ; OnOK(); } if( m_RebaseStage == REBASE_SQUASH_CONFLICT) { if(VerifyNoConflict()) return; GitRev *curRev=(GitRev*)m_CommitList.m_arShownList[m_CurrentRebaseIndex]; if(this->CheckNextCommitIsSquash()) {//next commit is not squash; m_RebaseStage = REBASE_SQUASH_EDIT; this->OnRebaseUpdateUI(0,0); this->UpdateCurrentStatus(); return ; } m_RebaseStage=REBASE_CONTINUE; curRev->GetAction(&m_CommitList)|=CTGitPath::LOGACTIONS_REBASE_DONE; this->UpdateCurrentStatus(); } if( m_RebaseStage == REBASE_CONFLICT ) { if(VerifyNoConflict()) return; GitRev *curRev=(GitRev*)m_CommitList.m_arShownList[m_CurrentRebaseIndex]; CString out =_T(""); CString cmd; cmd.Format(_T("git.exe commit -a -C %s"), curRev->m_CommitHash.ToString()); AddLogString(cmd); if(g_Git.Run(cmd,&out,CP_UTF8)) { AddLogString(out); if(!g_Git.CheckCleanWorkTree()) { CMessageBox::Show(NULL,out,_T("TortoiseGit"),MB_OK|MB_ICONERROR); return; } } AddLogString(out); this->m_ctrlTabCtrl.SetActiveTab(REBASE_TAB_LOG); if( curRev->GetAction(&m_CommitList) & CTGitPath::LOGACTIONS_REBASE_EDIT) { m_RebaseStage=REBASE_EDIT; this->m_ctrlTabCtrl.SetActiveTab(REBASE_TAB_MESSAGE); this->UpdateCurrentStatus(); return; } else { m_RebaseStage=REBASE_CONTINUE; curRev->GetAction(&m_CommitList)|=CTGitPath::LOGACTIONS_REBASE_DONE; this->UpdateCurrentStatus(); } } if( m_RebaseStage == REBASE_EDIT || m_RebaseStage == REBASE_SQUASH_EDIT ) { CString str; GitRev *curRev=(GitRev*)m_CommitList.m_arShownList[m_CurrentRebaseIndex]; str=this->m_LogMessageCtrl.GetText(); if(str.Trim().IsEmpty()) { CMessageBox::Show(NULL,_T("Commit Message Is Empty"),_T("TortoiseGit"),MB_OK|MB_ICONERROR); return; } CString tempfile=::GetTempFile(); CFile file(tempfile,CFile::modeReadWrite|CFile::modeCreate ); CStringA log=CUnicodeUtils::GetUTF8( str); file.Write(log,log.GetLength()); //file.WriteString(m_sLogMessage); file.Close(); CString out,cmd; if( m_RebaseStage == REBASE_SQUASH_EDIT ) cmd.Format(_T("git.exe commit -F \"%s\""), tempfile); else cmd.Format(_T("git.exe commit --amend -F \"%s\""), tempfile); if(g_Git.Run(cmd,&out,CP_UTF8)) { if(!g_Git.CheckCleanWorkTree()) { CMessageBox::Show(NULL,out,_T("TortoiseGit"),MB_OK|MB_ICONERROR); return; } } CFile::Remove(tempfile); AddLogString(out); this->m_ctrlTabCtrl.SetActiveTab(REBASE_TAB_LOG); m_RebaseStage=REBASE_CONTINUE; curRev->GetAction(&m_CommitList)|=CTGitPath::LOGACTIONS_REBASE_DONE; this->UpdateCurrentStatus(); } InterlockedExchange(&m_bThreadRunning, TRUE); SetControlEnable(); if (AfxBeginThread(RebaseThreadEntry, this)==NULL) { InterlockedExchange(&m_bThreadRunning, FALSE); CMessageBox::Show(NULL, _T("Create Rebase Thread Fail"), _T("TortoiseGit"), MB_OK | MB_ICONERROR); SetControlEnable(); } }
int CRebaseDlg::RebaseThread() { CBlockCacheForPath cacheBlock(g_Git.m_CurrentDir); int ret=0; while(1) { if( m_RebaseStage == REBASE_START ) { if( this->StartRebase() ) { InterlockedExchange(&m_bThreadRunning, FALSE); ret = -1; this->m_ctrlTabCtrl.SetActiveTab(REBASE_TAB_LOG); break; } m_RebaseStage = REBASE_CONTINUE; } else if( m_RebaseStage == REBASE_CONTINUE ) { this->GoNext(); UpdateCurrentStatus(); if(IsEnd()) { ret = 0; m_RebaseStage = REBASE_FINISH; } else { ret = DoRebase(); if( ret ) { break; } } } else if( m_RebaseStage == REBASE_FINISH ) { FinishRebase(); m_RebaseStage = REBASE_DONE; if (m_pTaskbarList) m_pTaskbarList->SetProgressState(m_hWnd, TBPF_NOPROGRESS); break; } else { break; } this->PostMessage(MSG_REBASE_UPDATE_UI); //this->UpdateCurrentStatus(); } InterlockedExchange(&m_bThreadRunning, FALSE); this->PostMessage(MSG_REBASE_UPDATE_UI); return ret; }
/* * EditMain - main driver for editor (command mode) */ void EditMain( void ) { vi_rc rc; char *msg = NULL; bool doclear; /* * loop forever, or at least until all done */ for( ;; ) { #if 0 #ifdef __WIN__ PushMode(); UpdateFiles(); PopMode(); #endif #endif if( !EditFlags.InsertModeActive || EditFlags.Modeless ) { if( EditFlags.Modeless ) { UpdateEditStatus(); EditFlags.NoCapsLock = false; } else { UpdateCurrentStatus( CSTATUS_COMMAND ); EditFlags.NoCapsLock = true; } if( !EditFlags.Modeless && EditFlags.ReturnToInsertMode && !NonKeyboardEventsPending() ) { EditFlags.ReturnToInsertMode = false; if( EditFlags.WasOverstrike ) { LastEvent = 'R'; } else { LastEvent = 'i'; } } else { DCUpdateAll(); #ifdef __WIN__ SetWindowCursorForReal(); #endif LastEvent = GetNextEvent( true ); } EditFlags.NoCapsLock = false; doclear = true; if( LastEvent == VI_KEY( MOUSEEVENT ) ) { if( LastMouseEvent == MOUSE_MOVE ) { doclear = false; } } if( doclear ) { if( EditFlags.AutoMessageClear ) { ClearWindow( MessageWindow ); } #ifndef __WIN__ ResetDisplayLine(); #endif } } else { // Cannot do a RestoreInfo while we are in insert mode // because it will call ValidateCurrentColumn which will // do something stupid on us... PushMode/PopMode solution // not working yet... this needs a little work DCUpdate(); #ifdef __WIN__ SetWindowCursorForReal(); #endif LastEvent = GetNextEvent( true ); } rc = DoLastEvent(); if( EditFlags.ReadOnlyError && rc <= ERR_NO_ERR ) { EditFlags.ReadOnlyError = false; rc = ERR_READ_ONLY_FILE_MODIFIED; } if( rc > ERR_NO_ERR ) { msg = GetErrorMsg( rc ); } DoneLastEvent( rc, false ); if( rc > ERR_NO_ERR ) { Error( msg ); } } } /* EditMain */
CStatusCacheEntry CCachedDirectory::GetStatusFromGit(const CTGitPath &path, CString sProjectRoot) { CString subpaths = path.GetGitPathString(); if(subpaths.GetLength() >= sProjectRoot.GetLength()) { if(subpaths[sProjectRoot.GetLength()] == _T('/')) subpaths=subpaths.Right(subpaths.GetLength() - sProjectRoot.GetLength()-1); else subpaths=subpaths.Right(subpaths.GetLength() - sProjectRoot.GetLength()); } GitStatus *pGitStatus = &CGitStatusCache::Instance().m_GitStatus; UNREFERENCED_PARAMETER(pGitStatus); bool isVersion =true; pGitStatus->IsUnderVersionControl(sProjectRoot, subpaths, path.IsDirectory(), &isVersion); if(!isVersion) { //untracked file bool isDir = path.IsDirectory(); bool isIgnoreFileChanged = pGitStatus->HasIgnoreFilesChanged(sProjectRoot, subpaths, isDir); if( isIgnoreFileChanged) { pGitStatus->LoadIgnoreFile(sProjectRoot, subpaths, isDir); } if (isDir) { CCachedDirectory * dirEntry = CGitStatusCache::Instance().GetDirectoryCacheEntry(path, false); /* we needn't watch untracked directory*/ if(dirEntry) { AutoLocker lock(dirEntry->m_critSec); git_wc_status_kind dirstatus = dirEntry->GetCurrentFullStatus() ; if (CGitStatusCache::Instance().IsUnversionedAsModified() || dirstatus == git_wc_status_none || dirstatus >= git_wc_status_normal || isIgnoreFileChanged) {/* status have not initialized*/ bool isignore = false; pGitStatus->IsIgnore(sProjectRoot, subpaths, &isignore, isDir); if (!isignore && CGitStatusCache::Instance().IsUnversionedAsModified()) { dirEntry->EnumFiles(path, TRUE); dirEntry->UpdateCurrentStatus(); return CStatusCacheEntry(dirEntry->GetCurrentFullStatus()); } git_wc_status2_t status2; status2.text_status = status2.prop_status = (isignore? git_wc_status_ignored:git_wc_status_unversioned); // we do not know anything about files here, all we know is that there are not versioned files in this dir dirEntry->m_mostImportantFileStatus = git_wc_status_none; dirEntry->m_ownStatus.SetKind(git_node_dir); dirEntry->m_ownStatus.SetStatus(&status2); dirEntry->m_currentFullStatus = status2.text_status; } return dirEntry->m_ownStatus; } } else /* path is file */ { AutoLocker lock(m_critSec); CString strCacheKey = GetCacheKey(path); if (strCacheKey.IsEmpty()) return CStatusCacheEntry(); CacheEntryMap::iterator itMap = m_entryCache.find(strCacheKey); if(itMap == m_entryCache.end() || isIgnoreFileChanged) { git_wc_status2_t status2; bool isignore = false; pGitStatus->IsIgnore(sProjectRoot, subpaths, &isignore, isDir); status2.text_status = status2.prop_status = (isignore? git_wc_status_ignored:git_wc_status_unversioned); AddEntry(path, &status2); return m_entryCache[strCacheKey]; } else { return itMap->second; } } return CStatusCacheEntry(); } else { EnumFiles(path, TRUE); UpdateCurrentStatus(); if (!path.IsDirectory()) return GetCacheStatusForMember(path); return CStatusCacheEntry(m_ownStatus); } }
CStatusCacheEntry CCachedDirectory::GetStatusFromGit(const CTGitPath &path, CString sProjectRoot) { CString subpaths = path.GetGitPathString(); if(subpaths.GetLength() >= sProjectRoot.GetLength()) { if(subpaths[sProjectRoot.GetLength()] == _T('/')) subpaths=subpaths.Right(subpaths.GetLength() - sProjectRoot.GetLength()-1); else subpaths=subpaths.Right(subpaths.GetLength() - sProjectRoot.GetLength()); } GitStatus *pGitStatus = &CGitStatusCache::Instance().m_GitStatus; CGitHash head; pGitStatus->GetHeadHash(sProjectRoot,head); bool isVersion =true; pGitStatus->IsUnderVersionControl(sProjectRoot, subpaths, path.IsDirectory(), &isVersion); if(!isVersion) { //untracked file bool isIgnoreFileChanged=false; isIgnoreFileChanged = pGitStatus->IsGitReposChanged(sProjectRoot, subpaths, GIT_MODE_IGNORE); if( isIgnoreFileChanged) { pGitStatus->LoadIgnoreFile(sProjectRoot, subpaths); } if(path.IsDirectory()) { CCachedDirectory * dirEntry = CGitStatusCache::Instance().GetDirectoryCacheEntry(path, false); /* we needn't watch untracked directory*/ if(dirEntry) { AutoLocker lock(dirEntry->m_critSec); git_wc_status_kind dirstatus = dirEntry->GetCurrentFullStatus() ; if( dirstatus == git_wc_status_none || dirstatus >= git_wc_status_normal || isIgnoreFileChanged ) {/* status have not initialized*/ git_wc_status2_t status2; bool isignore = false; pGitStatus->IsIgnore(sProjectRoot,subpaths,&isignore); status2.text_status = status2.prop_status = (isignore? git_wc_status_ignored:git_wc_status_unversioned); dirEntry->m_ownStatus.SetStatus(&status2); dirEntry->m_ownStatus.SetKind(git_node_dir); } return dirEntry->m_ownStatus; } } else /* path is file */ { AutoLocker lock(m_critSec); CString strCacheKey = GetCacheKey(path); CacheEntryMap::iterator itMap = m_entryCache.find(strCacheKey); if(itMap == m_entryCache.end() || isIgnoreFileChanged) { git_wc_status2_t status2; bool isignore = false; pGitStatus->IsIgnore(sProjectRoot,subpaths,&isignore); status2.text_status = status2.prop_status = (isignore? git_wc_status_ignored:git_wc_status_unversioned); AddEntry(path, &status2); return m_entryCache[strCacheKey]; } else { return itMap->second; } } return CStatusCacheEntry(); } else { EnumFiles((CTGitPath*)&path, TRUE); UpdateCurrentStatus(); return CStatusCacheEntry(m_ownStatus); } }
/* * NewFile - load up a new file */ vi_rc NewFile( char *name, bool same_file ) { vi_rc rc; bool dup; status_type oldstatus; dup = EditFlags.DuplicateFile; EditFlags.DuplicateFile = false; oldstatus = UpdateCurrentStatus( CSTATUS_READING ); ScreenPage( 1 ); #ifdef __WIN__ EditFlags.ResizeableWindow = true; #endif rc = createNewFile( name, same_file ); if( rc != ERR_NO_ERR && rc != NEW_FILE ) { ScreenPage( -1 ); if( !EditFlags.Starting ) { MoveWindowToFrontDammit( MessageWindow, true ); MoveWindowToFrontDammit( CurrentWindow, true ); } UpdateCurrentStatus( oldstatus ); return( rc ); } GoToLineNoRelCurs( 1 ); GoToColumnOnCurrentLine( 1 ); FileSPVAR(); SaveCurrentInfo(); if( !same_file ) { inReadHook++; rc = SourceHook( SRC_HOOK_READ, rc ); inReadHook--; } /* * back from hook, so all loadings are done * (who should have priority - hook or fts commands?) */ #if 0 rc = FTSRunCmds( CurrentFile->name ); FTSRunCmds( CurrentFile->name ); #endif /* * reset the screen to the display page, display everything */ ScreenPage( -1 ); MoveWindowToFrontDammit( CurrentWindow, true ); UpdateStatusWindow(); SetWindowCursor(); DCDisplayAllLines(); EditFlags.DuplicateFile = dup; DisplayFileStatus(); SaveCurrentInfo(); ActiveWindow( CurrentWindow ); VarAddRandC(); SetModifiedVar( false ); UpdateCurrentStatus( oldstatus ); if( !same_file && !inReadHook ) { UpdateLastFileList( CurrentFile->name ); } #ifdef __WIN__ DCUpdateAll(); ResetEditWindowCursor( CurrentWindow ); SetWindowCursorForReal(); GotoFile( CurrentWindow ); #endif return( rc ); } /* NewFile */
/* * processSetToken - set value for set token */ static vi_rc processSetToken( int j, char *value, int *winflag, bool isnonbool ) { char fn[MAX_STR], str[MAX_STR]; #ifndef VICOMP char tmp[3]; char settokstr[TOK_MAX_LEN + 1]; char save[MAX_STR]; vi_rc rc = ERR_NO_ERR; int i, clr, k; bool newset; bool set1, toggle, *ptr; jmp_buf jmpaddr; cursor_type ct; char *name; command_rtn fptr; event_bits eb; bool redisplay = FALSE; #endif bool bvalue; #ifdef VICOMP winflag = winflag; isnonbool = isnonbool; #endif /* * set up value for boolean set commands */ if( j < 0 ) { j *= -1; bvalue = FALSE; } else { bvalue = TRUE; } #ifndef VICOMP if( !(*winflag) ) { toggle = TRUE; set1 = isnonbool; } else { toggle = FALSE; #endif if( j >= SET1_T_ ) { #ifndef VICOMP if( EditFlags.CompileScript ) { #endif if( !bvalue ) { j *= -1; } itoa( j, str, 10 ); StrMerge( 2, WorkLine->data, str, SingleBlank ); return( ERR_NO_ERR ); #ifndef VICOMP } set1 = FALSE; j -= SET1_T_; } else { set1 = TRUE; #endif } #ifndef VICOMP } *winflag = FALSE; /* * process boolean settings */ if( !set1 ) { if( j >= SET2_T_ ) { return( ERR_INVALID_SET_COMMAND ); } ptr = &(((bool *)&EditFlags)[j]); newset = bvalue; if( toggle ) { newset = !(*ptr); } switch( j ) { case SET2_T_MODELESS: if( (newset && !EditFlags.Modeless) || (!newset && EditFlags.Modeless) ) { for( k = 0; k < MAX_EVENTS; k++ ) { fptr = EventList[k].rtn; eb = EventList[k].b; EventList[k].rtn = EventList[k].alt_rtn; EventList[k].alt_rtn = fptr; EventList[k].b = EventList[k].alt_b; EventList[k].alt_b = eb; } if( !EditFlags.Modeless ) { if( MenuWindow != NO_WINDOW ) { UpdateCurrentStatus( CSTATUS_INSERT ); } EditFlags.WasOverstrike = FALSE; NewCursor( CurrentWindow, EditVars.InsertCursorType ); } else { if( MenuWindow != NO_WINDOW ) { UpdateCurrentStatus( CSTATUS_COMMAND ); } NewCursor( CurrentWindow, EditVars.NormalCursorType ); // nomodeless must be line based or it dies! EditFlags.LineBased = TRUE; } /* re-position cursor in window */ SetWindowCursor(); } EditFlags.Modeless = newset; break; case SET2_T_UNDO: if( EditFlags.Undo && !newset ) { FreeAllUndos(); } EditFlags.Undo = newset; break; case SET2_T_STATUSINFO: EditFlags.StatusInfo = newset; #ifdef __WIN__ ResizeRoot(); #endif rc = NewStatusWindow(); break; case SET2_T_WINDOWGADGETS: EditFlags.WindowGadgets = newset; ResetAllWindows(); *winflag = TRUE; redisplay = TRUE; break; case SET2_T_REALTABS: EditFlags.RealTabs = newset; redisplay = TRUE; break; case SET2_T_CLOCK: EditFlags.Clock = newset; redisplay = TRUE; break; case SET2_T_TOOLBAR: EditFlags.Toolbar = newset; #ifdef __WIN__ ResizeRoot(); #endif break; case SET2_T_COLORBAR: EditFlags.Colorbar = newset; #ifdef __WIN__ if( Root == NULL ) { EditFlags.Colorbar = FALSE; } else { RefreshColorbar(); } #endif break; case SET2_T_SSBAR: EditFlags.SSbar = newset; #ifdef __WIN__ if( Root == NULL ) { EditFlags.SSbar = FALSE; } else { RefreshSSbar(); } #endif break; case SET2_T_FONTBAR: EditFlags.Fontbar = newset; #ifdef __WIN__ if( Root == NULL ) { EditFlags.Fontbar = FALSE; } else { RefreshFontbar(); } #endif break; case SET2_T_MARKLONGLINES: EditFlags.MarkLongLines = newset; break; case SET2_T_MENUS: EditFlags.Menus = newset; InitMenu(); break; case SET2_T_LINENUMBERS: if( toggle ) { newset = !EditFlags.LineNumbers; } if( newset != EditFlags.LineNumbers ) { EditFlags.LineNumbers = newset; rc = LineNumbersSetup(); *winflag = TRUE; } break; case SET2_T_CURRENTSTATUS: EditFlags.CurrentStatus = newset; InitMenu(); break; case SET2_T_DISPLAYSECONDS: EditFlags.DisplaySeconds = newset; redisplay = TRUE; break; case SET2_T_PPKEYWORDONLY: EditFlags.PPKeywordOnly = newset; redisplay = TRUE; break; case SET2_T_LASTEOL: #ifndef __WIN__ *ptr = TRUE; toggle = FALSE; break; #endif default: *ptr = newset; break; } if( msgFlag ) { if( !newset ) { tmp[0] = 'n'; tmp[1] = 'o'; tmp[2] = 0; } else { tmp[0] = 0; } MySprintf( fn, "%s%s set", tmp, GetTokenStringCVT( SetTokens2, j, settokstr, TRUE ) ); } if( toggle ) { strcpy( save, BoolStr[(int) newset] ); (*winflag) += 1; } /* * process value settings */ } else { if( toggle ) { rc = GetNewValueDialog( value ); if( rc != ERR_NO_ERR ) { return( rc ); } strcpy( save, value ); } #endif /* VICOMP */ RemoveLeadingSpaces( value ); if( value[0] == '"' ) { NextWord( value, fn, "\"" ); EliminateFirstN( value, 1 ); } else { NextWord1( value, fn ); } #ifndef VICOMP if( EditFlags.CompileScript ) { #endif itoa( j, str, 10 ); strcat( WorkLine->data, str ); if( fn[0] == '\0' ) return( ERR_NO_ERR ); switch( j ) { case SET1_T_STATUSSTRING: case SET1_T_FILEENDSTRING: case SET1_T_HISTORYFILE: case SET1_T_TMPDIR: case SET1_T_TAGFILENAME: StrMerge( 4, WorkLine->data, SingleBlank, SingleQuote, fn, SingleQuote ); break; case SET1_T_COMMANDCURSORTYPE: case SET1_T_OVERSTRIKECURSORTYPE: case SET1_T_INSERTCURSORTYPE: StrMerge( 2, WorkLine->data, SingleBlank, fn ); if( NextWord1( value, fn ) <= 0 ) { break; } StrMerge( 2, WorkLine->data, SingleBlank, fn ); break; case SET1_T_TILECOLOR: StrMerge( 2, WorkLine->data, SingleBlank, fn ); if( NextWord1( value, fn ) <= 0 ) { return( ERR_INVALID_SET_COMMAND ); } if( NextWord1( value, str ) <= 0 ) { return( ERR_INVALID_SET_COMMAND ); } StrMerge( 4, WorkLine->data, fn, SingleBlank, str, SingleBlank ); break; case SET1_T_STATUSSECTIONS: StrMerge( 2, WorkLine->data, SingleBlank, fn ); while( NextWord1( value, fn ) > 0 ) { #ifdef VICOMP int k; #endif k = atoi( fn ); if( k <= 0 ) { break; } StrMerge( 2, WorkLine->data, SingleBlank, fn ); } break; default: StrMerge( 2, WorkLine->data, SingleBlank, fn ); break; } return( ERR_NO_ERR ); #ifndef VICOMP } switch( j ) { case SET1_T_STATUSSECTIONS: if( EditVars.StatusSections != NULL ) { MemFree( EditVars.StatusSections ); EditVars.StatusSections = NULL; EditVars.NumStatusSections = 0; } for( ;; ) { k = atoi( fn ); if( k <= 0 ) { break; } EditVars.StatusSections = MemReAlloc( EditVars.StatusSections, sizeof( short ) * (EditVars.NumStatusSections + 1) ); EditVars.StatusSections[EditVars.NumStatusSections] = k; EditVars.NumStatusSections++; if( NextWord1( value, fn ) <= 0 ) { break; } } if( EditVars.StatusSections == NULL ) { MySprintf( fn, "statussections turned off" ); } else { MySprintf( fn, "statussections set" ); } break; case SET1_T_FILEENDSTRING: AddString2( &EditVars.FileEndString, fn ); ResetAllWindows(); redisplay = TRUE; break; case SET1_T_STATUSSTRING: AddString2( &EditVars.StatusString, fn ); if( StatusWindow != NO_WINDOW ) { ClearWindow( StatusWindow ); UpdateStatusWindow(); } if( msgFlag ) { MySprintf( fn, "statusstring set to %s", EditVars.StatusString ); } break; case SET1_T_GREPDEFAULT: AddString2( &EditVars.GrepDefault, fn ); break; case SET1_T_TILECOLOR: if( EditVars.TileColors == NULL ) { EditVars.TileColors = (type_style *) MemAlloc( sizeof( type_style ) * ( EditVars.MaxTileColors + 1 ) ); for( i = 0; i <= EditVars.MaxTileColors; ++i ) { EditVars.TileColors[i].foreground = -1; EditVars.TileColors[i].background = -1; EditVars.TileColors[i].font = -1; } } clr = atoi( fn ); if( clr > EditVars.MaxTileColors ) { return( ERR_INVALID_SET_COMMAND ); } if( NextWord1( value, fn ) <= 0 ) { return( ERR_INVALID_SET_COMMAND ); } EditVars.TileColors[clr].foreground = atoi( fn ); if( NextWord1( value, fn ) <= 0 ) { return( ERR_INVALID_SET_COMMAND ); } EditVars.TileColors[clr].background = atoi( fn ); EditVars.TileColors[clr].font = FONT_DEFAULT; if( msgFlag ) { MySprintf( fn, "tilecolor %d set", clr ); } break; case SET1_T_GADGETSTRING: SetGadgetString( fn ); if( msgFlag ) { MySprintf( fn, "gadget string set to %s", EditVars.GadgetString ); } ResetAllWindows(); break; case SET1_T_SHELLPROMPT: AddString2( &EditVars.SpawnPrompt, fn ); if( msgFlag ) { MySprintf( fn, "prompt string set to %s", EditVars.SpawnPrompt ); } break; case SET1_T_FIGNORE: if( fn[0] == 0 ) { MemFreePtr( (void **)&EditVars.FIgnore ); EditVars.CurrFIgnore = 0; if( msgFlag ) { MySprintf( fn, "fignore reset" ); } } else { EditVars.FIgnore = MemReAlloc( EditVars.FIgnore, EXTENSION_LENGTH * (EditVars.CurrFIgnore + 1) ); str[0] = '.'; str[1] = 0; strcat( str, fn ); str[EXTENSION_LENGTH - 1] = 0; strcpy( &EditVars.FIgnore[EXTENSION_LENGTH * EditVars.CurrFIgnore], str ); EditVars.CurrFIgnore++; if( msgFlag ) { MySprintf( fn, "%s added to fignore", str ); } } break; case SET1_T_HISTORYFILE: AddString2( &EditVars.HistoryFile, fn ); if( msgFlag ) { MySprintf( fn, "history file set to %s", EditVars.HistoryFile ); } break; case SET1_T_TAGFILENAME: AddString2( &EditVars.TagFileName, fn ); if( msgFlag ) { MySprintf( fn, "tag file name set to %s", EditVars.TagFileName ); } break; case SET1_T_FILENAME: if( CurrentFile != NULL ) { AddString2( &(CurrentFile->name), fn ); SetFileWindowTitle( CurrentWindow, CurrentInfo, TRUE ); if( msgFlag ) { MySprintf( fn, "filename set to %s", CurrentFile->name ); } FileSPVAR(); } break; case SET1_T_TMPDIR: AddString2( &EditVars.TmpDir, fn ); VerifyTmpDir(); if( msgFlag ) { MySprintf( fn, "tmpdir set to %s", EditVars.TmpDir ); } break; case SET1_T_WORD: AddString2( &EditVars.WordDefn, fn ); InitWordSearch( EditVars.WordDefn ); if( msgFlag ) { MySprintf( fn, "word set to %s", EditVars.WordDefn ); } break; case SET1_T_WORDALT: AddString2( &EditVars.WordAltDefn, fn ); if( msgFlag ) { MySprintf( fn, "wordalt set to %s", EditVars.WordAltDefn ); } break; case SET1_T_MAGICSTRING: AddString2( &EditVars.Majick, fn ); if( msgFlag ) { MySprintf( fn, "magicstring set to %s", EditVars.Majick ); } break; case SET1_T_COMMANDCURSORTYPE: case SET1_T_OVERSTRIKECURSORTYPE: case SET1_T_INSERTCURSORTYPE: i = setjmp( jmpaddr ); if( i != 0 ) { return( ERR_INVALID_SET_COMMAND ); } StartExprParse( fn, jmpaddr ); ct.height = GetConstExpr(); if( NextWord1( value, fn ) <= 0 ) { ct.width = 100; } else { i = setjmp( jmpaddr ); if( i != 0 ) { return( ERR_INVALID_SET_COMMAND ); } StartExprParse( fn, jmpaddr ); ct.width = GetConstExpr(); } if( j == SET1_T_COMMANDCURSORTYPE ) { EditVars.NormalCursorType = ct; name = "command"; } else if( j == SET1_T_OVERSTRIKECURSORTYPE ) { EditVars.OverstrikeCursorType = ct; name = "overstrike"; } else { EditVars.InsertCursorType = ct; name = "insert"; } if( msgFlag ) { MySprintf( fn, "%s cursor type set to %d,%d", name, ct.height, ct.width ); } break; default: i = setjmp( jmpaddr ); if( i != 0 ) { return( ERR_INVALID_SET_COMMAND ); } StartExprParse( fn, jmpaddr ); i = GetConstExpr(); if( i < 0 ) { i = 0; } switch( j ) { case SET1_T_WRAPMARGIN: EditVars.WrapMargin = i; break; case SET1_T_CURSORBLINKRATE: SetCursorBlinkRate( i ); break; case SET1_T_MAXPUSH: EditVars.MaxPush = i; if( EditVars.MaxPush < 1 ) { EditVars.MaxPush = 1; } InitFileStack(); break; case SET1_T_RADIX: EditVars.Radix = i; break; case SET1_T_AUTOSAVEINTERVAL: EditVars.AutoSaveInterval = i; SetNextAutoSaveTime(); break; case SET1_T_LANGUAGE: if( i < LANG_NONE || i >= LANG_MAX ) { return( ERR_INVALID_SET_COMMAND ); } if( CurrentInfo != NULL ) { LangFini( CurrentInfo->fsi.Language ); LangInit( i ); redisplay = TRUE; } break; case SET1_T_MOVECOLOR: EditVars.MoveColor = i; break; case SET1_T_RESIZECOLOR: EditVars.ResizeColor = i; break; case SET1_T_MOUSEDCLICKSPEED: EditVars.MouseDoubleClickSpeed = i; break; case SET1_T_MOUSESPEED: SetMouseSpeed( i ); break; case SET1_T_MOUSEREPEATDELAY: EditVars.MouseRepeatDelay = i; break; case SET1_T_CURRENTSTATUSCOLUMN: EditVars.CurrentStatusColumn = i; InitMenu(); break; case SET1_T_ENDOFLINECHAR: EditVars.EndOfLineChar = i; break; case SET1_T_EXITATTR: EditVars.ExitAttr = (char) i; break; case SET1_T_INACTIVEWINDOWCOLOR: EditVars.InactiveWindowColor = i; break; case SET1_T_TABAMOUNT: EditVars.TabAmount = i; break; case SET1_T_SHIFTWIDTH: EditVars.ShiftWidth = i; break; case SET1_T_PAGELINESEXPOSED: EditVars.PageLinesExposed = i; break; case SET1_T_HARDTAB: EditVars.HardTab = i; redisplay = TRUE; break; case SET1_T_STACKK: if( EditFlags.Starting ) { EditVars.StackK = i; } break; case SET1_T_LINENUMWINWIDTH: EditVars.LineNumWinWidth = i; break; case SET1_T_MAXWINDOWTILEX: EditVars.MaxWindowTileX = i; break; case SET1_T_MAXWINDOWTILEY: EditVars.MaxWindowTileY = i; break; case SET1_T_MAXSWAPK: SwapBlockInit( i ); break; case SET1_T_MAXEMSK: #ifndef NOEMS EMSBlockInit( i ); #endif break; case SET1_T_MAXXMSK: #ifndef NOXMS XMSBlockInit( i ); #endif break; case SET1_T_MAXFILTERHISTORY: FilterHistInit( i ); break; case SET1_T_MAXCLHISTORY: CLHistInit( i ); break; case SET1_T_MAXFINDHISTORY: FindHistInit( i ); break; case SET1_T_MAXLASTFILESHISTORY: LastFilesHistInit( i ); break; case SET1_T_MAXTILECOLORS: k = (EditVars.TileColors == NULL) ? 0 : EditVars.MaxTileColors + 1; EditVars.MaxTileColors = i; EditVars.TileColors = MemReAlloc( EditVars.TileColors, sizeof( type_style ) * ( EditVars.MaxTileColors + 1 ) ); for( ; k <= EditVars.MaxTileColors; ++k ) { EditVars.TileColors[k].foreground = -1; EditVars.TileColors[k].background = -1; EditVars.TileColors[k].font = -1; } break; case SET1_T_CLOCKX: EditVars.ClockX = i; GetClockStart(); break; case SET1_T_CLOCKY: EditVars.ClockY = i; GetClockStart(); break; case SET1_T_SPINX: EditVars.SpinX = i; GetSpinStart(); break; case SET1_T_SPINY: EditVars.SpinY = i; GetSpinStart(); break; case SET1_T_MAXLINELEN: /* file save fails if 1 line is > MAX_IO_BUFFER */ i = __min( i, MAX_IO_BUFFER ); EditVars.MaxLine = i; StaticStart(); WorkLine = MemReAlloc( WorkLine, sizeof( line ) + EditVars.MaxLine + 2 ); break; case SET1_T_TOOLBARBUTTONHEIGHT: EditVars.ToolBarButtonHeight = i; #ifdef __WIN__ ResizeRoot(); #endif break; case SET1_T_TOOLBARBUTTONWIDTH: EditVars.ToolBarButtonWidth = i; #ifdef __WIN__ ResizeRoot(); #endif break; case SET1_T_TOOLBARCOLOR: EditVars.ToolBarColor = i; #ifdef __WIN__ if( GetToolbarWindow() != NULL ) { InvalidateRect( GetToolbarWindow(), NULL, TRUE ); UpdateWindow( GetToolbarWindow() ); } #endif break; default: return( ERR_INVALID_SET_COMMAND ); } if( msgFlag ) { MySprintf( fn, "%s set to %d", GetTokenStringCVT( SetTokens1, j, settokstr, TRUE ), i ); } break; } } if( msgFlag && rc == ERR_NO_ERR && !EditFlags.Quiet ) { setMessage( fn, redisplay ); rc = DO_NOT_CLEAR_MESSAGE_WINDOW; } if( rc == ERR_NO_ERR && toggle ) { strcpy( value, save ); } return( rc ); #endif /* VICOMP */ } /* processSetToken */
CStatusCacheEntry CCachedDirectory::GetStatusForMember(const CTSVNPath& path, bool bRecursive, bool bFetch /* = true */) { CStringA strCacheKey; bool bThisDirectoryIsUnversioned = false; bool bRequestForSelf = false; if(path.IsEquivalentToWithoutCase(m_directoryPath)) { bRequestForSelf = true; } // In all most circumstances, we ask for the status of a member of this directory. ATLASSERT(m_directoryPath.IsEquivalentToWithoutCase(path.GetContainingDirectory()) || bRequestForSelf); long long dbFileTime = CSVNStatusCache::Instance().WCRoots()->GetDBFileTime(m_directoryPath); bool wcDbFileTimeChanged = (m_wcDbFileTime != dbFileTime); if ( !wcDbFileTimeChanged ) { if(m_wcDbFileTime == 0) { // We are a folder which is not in a working copy bThisDirectoryIsUnversioned = true; m_ownStatus.SetStatus(NULL, false, false); // If a user removes the .svn directory, we get here with m_entryCache // not being empty, but still us being unversioned if (!m_entryCache.empty()) { m_entryCache.clear(); } ATLASSERT(m_entryCache.empty()); // However, a member *DIRECTORY* might be the top of WC // so we need to ask them to get their own status if(!path.IsDirectory()) { if ((PathFileExists(path.GetWinPath()))||(bRequestForSelf)) return CStatusCacheEntry(); // the entry doesn't exist anymore! // but we can't remove it from the cache here: // the GetStatusForMember() method is called only with a read // lock and not a write lock! // So mark it for crawling, and let the crawler remove it // later CSVNStatusCache::Instance().AddFolderForCrawling(path.GetContainingDirectory()); return CStatusCacheEntry(); } else { // If we're in the special case of a directory being asked for its own status // and this directory is unversioned, then we should just return that here if(bRequestForSelf) { return CStatusCacheEntry(); } } } if (CSVNStatusCache::Instance().GetDirectoryCacheEntryNoCreate(path) != NULL) { // We don't have directory status in our cache // Ask the directory if it knows its own status CCachedDirectory * dirEntry = CSVNStatusCache::Instance().GetDirectoryCacheEntry(path); if ((dirEntry)&&(dirEntry->IsOwnStatusValid())) { // To keep recursive status up to date, we'll request that children are all crawled again // We have to do this because the directory watcher isn't very reliable (especially under heavy load) // and also has problems with SUBSTed drives. // If nothing has changed in those directories, this crawling is fast and only // accesses two files for each directory. if (bRecursive) { AutoLocker lock(dirEntry->m_critSec); ChildDirStatus::const_iterator it; for(it = dirEntry->m_childDirectories.begin(); it != dirEntry->m_childDirectories.end(); ++it) { CTSVNPath newpath; CString winPath = CUnicodeUtils::GetUnicode (it->first); newpath.SetFromWin(winPath, true); CSVNStatusCache::Instance().AddFolderForCrawling(newpath); } } return dirEntry->GetOwnStatus(bRecursive); } } else { { // if we currently are fetching the status of the directory // we want the status for, we just return an empty entry here // and don't wait for that fetching to finish. // That's because fetching the status can take a *really* long // time (e.g. if a commit is also in progress on that same // directory), and we don't want to make the explorer appear // to hang. if ((!bFetch)&&(m_FetchingStatus)) { if (m_directoryPath.IsAncestorOf(path)) { m_currentFullStatus = m_mostImportantFileStatus = svn_wc_status_none; return GetCacheStatusForMember(path); } } } // Look up a file in our own cache AutoLocker lock(m_critSec); strCacheKey = GetCacheKey(path); CacheEntryMap::iterator itMap = m_entryCache.find(strCacheKey); if(itMap != m_entryCache.end()) { // We've hit the cache - check for timeout if(!itMap->second.HasExpired((long)GetTickCount())) { if(itMap->second.DoesFileTimeMatch(path.GetLastWriteTime())) { if ((itMap->second.GetEffectiveStatus()!=svn_wc_status_missing)||(!PathFileExists(path.GetWinPath()))) { // Note: the filetime matches after a modified has been committed too. // So in that case, we would return a wrong status (e.g. 'modified' instead // of 'normal') here. return itMap->second; } } } } } } else { if ((!bFetch)&&(m_FetchingStatus)) { if (m_directoryPath.IsAncestorOf(path)) { // returning empty status (status fetch in progress) // also set the status to 'none' to have the status change and // the shell updater invoked in the crawler m_currentFullStatus = m_mostImportantFileStatus = svn_wc_status_none; CSVNStatusCache::Instance().AddFolderForCrawling(m_directoryPath.GetDirectory()); return GetCacheStatusForMember(path); } } // if we're fetching the status for the explorer, // we don't refresh the status but use the one // we already have (to save time and make the explorer // more responsive in stress conditions). // We leave the refreshing to the crawler. if ((!bFetch)&&(m_wcDbFileTime)) { CSVNStatusCache::Instance().AddFolderForCrawling(m_directoryPath.GetDirectory()); return GetCacheStatusForMember(path); } AutoLocker lock(m_critSec); m_entryCache.clear(); strCacheKey = GetCacheKey(path); } // We've not got this item in the cache - let's add it // We never bother asking SVN for the status of just one file, always for its containing directory if (g_SVNAdminDir.IsAdminDirPath(path.GetWinPathString())) { // We're being asked for the status of an .SVN directory // It's not worth asking for this return CStatusCacheEntry(); } { if ((!bFetch)&&(m_FetchingStatus)) { if (m_directoryPath.IsAncestorOf(path)) { m_currentFullStatus = m_mostImportantFileStatus = svn_wc_status_none; return GetCacheStatusForMember(path); } } } { AutoLocker lock(m_critSec); m_mostImportantFileStatus = svn_wc_status_none; m_childDirectories.clear(); m_entryCache.clear(); m_ownStatus.SetStatus(NULL, false, false); } if(!bThisDirectoryIsUnversioned) { if (!SvnUpdateMembersStatus()) { m_wcDbFileTime = 0; return CStatusCacheEntry(); } } // Now that we've refreshed our SVN status, we can see if it's // changed the 'most important' status value for this directory. // If it has, then we should tell our parent UpdateCurrentStatus(); m_wcDbFileTime = dbFileTime; if (path.IsDirectory()) { CCachedDirectory * dirEntry = CSVNStatusCache::Instance().GetDirectoryCacheEntry(path); if ((dirEntry)&&(dirEntry->IsOwnStatusValid())) { //CSVNStatusCache::Instance().AddFolderForCrawling(path); return dirEntry->GetOwnStatus(bRecursive); } // If the status *still* isn't valid here, it means that // the current directory is unversioned, and we shall need to ask its children for info about themselves if ((dirEntry)&&(dirEntry != this)) return dirEntry->GetStatusForMember(path,bRecursive); // add the path for crawling: if it's really unversioned, the crawler will // only check for the admin dir and do nothing more. But if it is // versioned (could happen in a nested layout) the crawler will update its // status correctly CSVNStatusCache::Instance().AddFolderForCrawling(path); return CStatusCacheEntry(); } else { CacheEntryMap::iterator itMap = m_entryCache.find(strCacheKey); if(itMap != m_entryCache.end()) { return itMap->second; } } AddEntry(path, NULL, false, false); return CStatusCacheEntry(); }
vi_rc StartSuck( range *r ) { UpdateCurrentStatus( CSTATUS_SHIFT_LEFT ); return( doPush( r, false ) ); } /* StartSuck */
vi_rc StartShove( range *r ) { UpdateCurrentStatus( CSTATUS_SHIFT_RIGHT ); return( doPush( r, true ) ); } /* StartShove */