void CZLibReadBuffer::seek2CurBlock() { int curBlockIndex; for(int i = 0 ; i < m_FileHeader.m_nBlock ; i++ ) { if( m_DataNowPos < m_FileHeader.m_pEntris[i].m_dataBegPos) { curBlockIndex = i - 1; m_curBlockReadPos = m_DataNowPos - m_FileHeader.m_pEntris[i - 1].m_dataBegPos; if(m_curBlockIndex != curBlockIndex) { m_FileHeader.m_pEntris[m_curBlockIndex].Release(); cacheBlock(curBlockIndex); } m_curBlockIndex=curBlockIndex; return ; } } curBlockIndex = m_FileHeader.m_nBlock - 1 ; m_curBlockReadPos = m_DataNowPos - m_FileHeader.m_pEntris[m_FileHeader.m_nBlock - 1].m_dataBegPos; if(m_curBlockIndex != curBlockIndex) { m_FileHeader.m_pEntris[m_curBlockIndex].Release(); cacheBlock(curBlockIndex); } m_curBlockIndex=curBlockIndex; }
int CZLibReadBuffer::read(_xcd_int8* buf, int byte_read) { int byte_need_read = byte_read; if( size_t(m_DataNowPos + byte_read) > size_t(m_DataLen) ) { byte_need_read = m_DataLen - m_DataNowPos ; } if(byte_need_read == 0) return 0; CCDCompressedDataPackBuffer& readBlock = m_FileHeader.m_pEntris[m_curBlockIndex]; int byteInThisBlock = readBlock.m_Info.m_DataSize - m_curBlockReadPos; if(readBlock.buffer == NULL) cacheBlock(m_curBlockIndex); if(byteInThisBlock >= byte_need_read) { memcpy(buf,readBlock.buffer + m_curBlockReadPos , byte_need_read) ; m_curBlockReadPos += byte_need_read; m_DataNowPos += byte_need_read; return byte_need_read; } else { memcpy(buf,readBlock.buffer + m_curBlockReadPos , byteInThisBlock) ; m_DataNowPos += byteInThisBlock; m_curBlockIndex ++; readBlock.Release(); cacheBlock(m_curBlockIndex); m_curBlockReadPos = 0; return byteInThisBlock + read(buf + byteInThisBlock , byte_need_read - byteInThisBlock); } }
void initComplexSyncCache(uint32_t s_idx, uint32_t e_idx) { sbdi_block_t blk; cacheBlock(&blk, s_idx, SBDI_BC_BT_MNGT); for (uint32_t i = s_idx + 1; i < e_idx; ++i) { cacheBlock(&blk, i, SBDI_BC_BT_DATA); } }
void testComplexSync() { sbdi_block_t blk; initComplexSyncCache(0x00, (SBDI_CACHE_MAX_SIZE / 2)); initComplexSyncCache(0x80, 0x80 + (SBDI_CACHE_MAX_SIZE / 2)); complexSyncDirtyBlocks(0x00, (SBDI_CACHE_MAX_SIZE / 2)); complexSyncDirtyBlocks(0x80, 0x80 + (SBDI_CACHE_MAX_SIZE / 2)); cacheBlock(&blk, 0x200, SBDI_BC_BT_DATA); exp_sync.insert(exp_sync.begin(), 0x02); cacheBlock(&blk, 0x201, SBDI_BC_BT_DATA); CPPUNIT_ASSERT(exp_sync.size() == 0); exp_sync.clear(); }
int CGitLogList::CherryPickFrom(CString from, CString to) { CLogDataVector logs(&m_LogCache); if(logs.ParserFromLog(NULL,-1,0,&from,&to)) return -1; if(logs.size() == 0) return 0; CSysProgressDlg progress; if (progress.IsValid()) { progress.SetTitle(_T("Cherry Pick")); progress.SetAnimation(IDR_MOVEANI); progress.SetTime(true); progress.ShowModeless(this); } CBlockCacheForPath cacheBlock(g_Git.m_CurrentDir); for(int i=logs.size()-1;i>=0;i--) { if (progress.IsValid()) { progress.FormatPathLine(1, _T("Pick up %s"), logs.GetGitRevAt(i).m_CommitHash.ToString()); progress.FormatPathLine(2, _T("%s"), logs.GetGitRevAt(i).GetSubject()); progress.SetProgress(logs.size()-i, logs.size()); } if ((progress.IsValid())&&(progress.HasUserCancelled())) { //CMessageBox::Show(hwndExplorer, IDS_SVN_USERCANCELLED, IDS_APPNAME, MB_ICONINFORMATION); throw std::exception(CUnicodeUtils::GetUTF8(CString(_T("User canceled\r\n\r\n")))); return -1; } CString cmd,out; cmd.Format(_T("git.exe cherry-pick %s"),logs.GetGitRevAt(i).m_CommitHash.ToString()); out.Empty(); if(g_Git.Run(cmd,&out,CP_UTF8)) { throw std::exception(CUnicodeUtils::GetUTF8(CString(_T("Cherry Pick Failure\r\n\r\n"))+out)); return -1; } } return 0; }
int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){ i64 offset; /* The current offset from the start of the file */ i64 end; /* The byte just past the last byte written */ int blk; /* Block number the write starts on */ int i; const u8 *zCsr; int rc = SQLITE_OK; OsTestFile *pFile = *id; offset = osTell(pFile); end = offset+amt; blk = (offset/BLOCKSIZE); zCsr = (u8 *)pBuf; for(i=blk; i*BLOCKSIZE<end; i++){ u8 *pBlk; int off = 0; int len = 0; /* Make sure the block is in the cache */ rc = cacheBlock(pFile, i); if( rc!=SQLITE_OK ) return rc; /* Write into the cache */ pBlk = pFile->apBlk[i]; assert( pBlk ); if( BLOCK_OFFSET(i) < offset ){ off = offset-BLOCK_OFFSET(i); } len = BLOCKSIZE - off; if( BLOCK_OFFSET(i+1) > end ){ len = len - (BLOCK_OFFSET(i+1)-end); } memcpy(&pBlk[off], zCsr, len); zCsr += len; } if( pFile->nMaxWrite<end ){ pFile->nMaxWrite = end; } assert( zCsr==&((u8 *)pBuf)[amt] ); rc = sqlite3RealSeek(&pFile->fd, end); return rc; }
int CGitLogList::CherryPickFrom(CString from, CString to) { CLogDataVector logs(&m_LogCache); CString range; range.Format(_T("%s..%s"), (LPCTSTR)from, (LPCTSTR)to); if (logs.ParserFromLog(nullptr, 0, 0, &range)) return -1; if (logs.empty()) return 0; CSysProgressDlg progress; progress.SetTitle(CString(MAKEINTRESOURCE(IDS_PROGS_TITLE_CHERRYPICK))); progress.SetAnimation(IDR_MOVEANI); progress.SetTime(true); progress.ShowModeless(this); CBlockCacheForPath cacheBlock(g_Git.m_CurrentDir); for (int i = (int)logs.size() - 1; i >= 0; i--) { if (progress.IsVisible()) { progress.FormatNonPathLine(1, IDS_PROC_PICK, logs.GetGitRevAt(i).m_CommitHash.ToString()); progress.FormatNonPathLine(2, _T("%s"), (LPCTSTR)logs.GetGitRevAt(i).GetSubject()); progress.SetProgress64(logs.size() - i, logs.size()); } if (progress.HasUserCancelled()) { throw std::exception(CUnicodeUtils::GetUTF8(CString(MAKEINTRESOURCE(IDS_USERCANCELLED)))); } CString cmd,out; cmd.Format(_T("git.exe cherry-pick %s"), (LPCTSTR)logs.GetGitRevAt(i).m_CommitHash.ToString()); out.Empty(); if(g_Git.Run(cmd,&out,CP_UTF8)) { throw std::exception(CUnicodeUtils::GetUTF8(CString(MAKEINTRESOURCE(IDS_PROC_CHERRYPICKFAILED)) + _T(":\r\n\r\n") + out)); } } return 0; }
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; }
bool DiffCommand::Execute() { bool bRet = false; CString path2 = CPathUtils::GetLongPathname(parser.GetVal(_T("path2"))); bool bAlternativeTool = !!parser.HasKey(_T("alternative")); // bool bBlame = !!parser.HasKey(_T("blame")); if (path2.IsEmpty()) { if (this->orgCmdLinePath.IsDirectory()) { CChangedDlg dlg; dlg.m_pathList = CTGitPathList(cmdLinePath); dlg.DoModal(); bRet = true; } else { if (cmdLinePath.IsEmpty()) return false; CGitDiff diff; //diff.SetAlternativeTool(bAlternativeTool); if ( parser.HasKey(_T("startrev")) && parser.HasKey(_T("endrev")) ) { if (parser.HasKey(_T("unified"))) bRet = !!CAppUtils::StartShowUnifiedDiff(nullptr, cmdLinePath, git_revnum_t(parser.GetVal(_T("endrev"))), cmdLinePath, git_revnum_t(parser.GetVal(_T("startrev"))), bAlternativeTool); else bRet = !!diff.Diff(&cmdLinePath, &cmdLinePath, git_revnum_t(parser.GetVal(_T("startrev"))), git_revnum_t(parser.GetVal(_T("endrev"))), false, parser.HasKey(_T("unified")) == TRUE, parser.GetLongVal(_T("line")), bAlternativeTool); } else { // check if it is a newly added (but uncommitted) file git_wc_status_kind status = git_wc_status_none; CString topDir; if (orgCmdLinePath.HasAdminDir(&topDir)) { CBlockCacheForPath cacheBlock(topDir); CAutoIndex index; CString adminDir; GitAdminDir::GetAdminDirPath(topDir, adminDir); if (!git_index_open(index.GetPointer(), CUnicodeUtils::GetUTF8(adminDir + _T("index")))) g_Git.Run(_T("git.exe update-index -- \"") + cmdLinePath.GetGitPathString() + _T("\""), nullptr); // make sure we get the right status GitStatus::GetFileStatus(topDir, cmdLinePath.GetWinPathString(), &status, true); if (index) git_index_write(index); } if (status == git_wc_status_added) { if (!g_Git.IsInitRepos()) { // this might be a rename, try to find original name BYTE_VECTOR cmdout; g_Git.Run(_T("git.exe diff-index --raw HEAD -M -C -z --"), &cmdout); CTGitPathList changedFiles; changedFiles.ParserFromLog(cmdout); for (int i = 0; i < changedFiles.GetCount(); ++i) { if (changedFiles[i].GetGitPathString() == cmdLinePath.GetGitPathString()) { if (!changedFiles[i].GetGitOldPathString().IsEmpty()) { CTGitPath oldPath(changedFiles[i].GetGitOldPathString()); if (parser.HasKey(_T("unified"))) return !!CAppUtils::StartShowUnifiedDiff(nullptr, cmdLinePath, git_revnum_t(_T("HEAD")), cmdLinePath, git_revnum_t(GIT_REV_ZERO), bAlternativeTool); return !!diff.Diff(&cmdLinePath, &oldPath, git_revnum_t(GIT_REV_ZERO), git_revnum_t(_T("HEAD")), false, parser.HasKey(_T("unified")) == TRUE, parser.GetLongVal(_T("line")), bAlternativeTool); } break; } } } cmdLinePath.m_Action = cmdLinePath.LOGACTIONS_ADDED; } if (parser.HasKey(_T("unified"))) bRet = !!CAppUtils::StartShowUnifiedDiff(nullptr, cmdLinePath, git_revnum_t(_T("HEAD")), cmdLinePath, git_revnum_t(GIT_REV_ZERO), bAlternativeTool); else bRet = !!diff.Diff(&cmdLinePath, &cmdLinePath, git_revnum_t(GIT_REV_ZERO), git_revnum_t(_T("HEAD")), false, parser.HasKey(_T("unified")) == TRUE, parser.GetLongVal(_T("line")), bAlternativeTool); } } } else { CGitDiff diff; if ( parser.HasKey(_T("startrev")) && parser.HasKey(_T("endrev")) && path2.Left(g_Git.m_CurrentDir.GetLength() + 1) == g_Git.m_CurrentDir + _T("\\")) { CTGitPath tgitPath2 = path2.Mid(g_Git.m_CurrentDir.GetLength() + 1); bRet = !!diff.Diff(&tgitPath2, &cmdLinePath, git_revnum_t(parser.GetVal(_T("startrev"))), git_revnum_t(parser.GetVal(_T("endrev"))), false, parser.HasKey(_T("unified")) == TRUE, parser.GetLongVal(_T("line")), bAlternativeTool); } else { bRet = CAppUtils::StartExtDiff( path2, orgCmdLinePath.GetWinPathString(), CString(), CString(), CString(), CString(), git_revnum_t(GIT_REV_ZERO), git_revnum_t(GIT_REV_ZERO), CAppUtils::DiffFlags().AlternativeTool(bAlternativeTool), parser.GetLongVal(_T("line"))); } } return bRet; }
int CGitLogList::RevertSelectedCommits(int parent) { CSysProgressDlg progress; int ret = -1; #if 0 if(!g_Git.CheckCleanWorkTree()) { CMessageBox::Show(NULL, IDS_PROC_NOCLEAN, IDS_APPNAME, MB_OK); } #endif if (this->GetSelectedCount() > 1) { progress.SetTitle(CString(MAKEINTRESOURCE(IDS_PROGS_TITLE_REVERTCOMMIT))); progress.SetAnimation(IDR_MOVEANI); progress.SetTime(true); progress.ShowModeless(this); } CBlockCacheForPath cacheBlock(g_Git.m_CurrentDir); POSITION pos = GetFirstSelectedItemPosition(); int i=0; while(pos) { int index = GetNextSelectedItem(pos); GitRev * r1 = reinterpret_cast<GitRev*>(m_arShownList.GetAt(index)); if (progress.IsVisible()) { progress.FormatNonPathLine(1, IDS_PROC_REVERTCOMMIT, r1->m_CommitHash.ToString()); progress.FormatNonPathLine(2, _T("%s"), (LPCTSTR)r1->GetSubject()); progress.SetProgress(i, this->GetSelectedCount()); } ++i; if(r1->m_CommitHash.IsEmpty()) continue; if (g_Git.GitRevert(parent, r1->m_CommitHash)) { CString str; str.LoadString(IDS_SVNACTION_FAILEDREVERT); str = g_Git.GetGitLastErr(str, CGit::GIT_CMD_REVERT); if( GetSelectedCount() == 1) CMessageBox::Show(NULL, str, _T("TortoiseGit"), MB_OK | MB_ICONERROR); else { if(CMessageBox::Show(NULL, str, _T("TortoiseGit"),2 , IDI_ERROR, CString(MAKEINTRESOURCE(IDS_SKIPBUTTON)), CString(MAKEINTRESOURCE(IDS_ABORTBUTTON))) == 2) { return ret; } } } else { ret =0; } if (progress.HasUserCancelled()) break; } return ret; }
//static function, Share with SyncDialog UINT CProgressDlg::RunCmdList(CWnd *pWnd,std::vector<CString> &cmdlist,bool bShowCommand,CString *pfilename,bool *bAbort,CGitByteArray *pdata, CGit *git) { UINT ret=0; PROCESS_INFORMATION pi; HANDLE hRead = 0; memset(&pi,0,sizeof(PROCESS_INFORMATION)); CBlockCacheForPath cacheBlock(git->m_CurrentDir); EnsurePostMessage(pWnd, MSG_PROGRESSDLG_UPDATE_UI, MSG_PROGRESSDLG_START, 0); if(pdata) pdata->clear(); for (size_t i = 0; i < cmdlist.size(); ++i) { if(cmdlist[i].IsEmpty()) continue; if (bShowCommand) { CStringA str = CUnicodeUtils::GetMulti(cmdlist[i].Trim() + _T("\r\n\r\n"), CP_UTF8); for (int j = 0; j < str.GetLength(); ++j) { if(pdata) { pdata->m_critSec.Lock(); pdata->push_back(str[j]); pdata->m_critSec.Unlock(); } else pWnd->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_RUN,str[j]); } if(pdata) pWnd->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_RUN,0); } git->RunAsync(cmdlist[i].Trim(),&pi, &hRead, NULL, pfilename); DWORD readnumber; char lastByte = '\0'; char byte; CString output; while(ReadFile(hRead,&byte,1,&readnumber,NULL)) { if(pdata) { if(byte == 0) byte = '\n'; pdata->m_critSec.Lock(); if (byte == '\n' && lastByte != '\r') pdata->push_back('\r'); pdata->push_back( byte); lastByte = byte; pdata->m_critSec.Unlock(); if(byte == '\r' || byte == '\n') pWnd->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_RUN,0); } else pWnd->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_RUN,byte); } if (pdata) { pdata->m_critSec.Lock(); bool post = !pdata->empty(); pdata->m_critSec.Unlock(); if (post) EnsurePostMessage(pWnd, MSG_PROGRESSDLG_UPDATE_UI, MSG_PROGRESSDLG_RUN, 0); } CloseHandle(pi.hThread); CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": waiting for process to finish (%s), aborted: %d\n"), cmdlist[i], *bAbort); WaitForSingleObject(pi.hProcess, INFINITE); DWORD status=0; if(!GetExitCodeProcess(pi.hProcess,&status) || *bAbort) { CloseHandle(pi.hProcess); CloseHandle(hRead); CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": process %s finished, status code could not be fetched, (error %d; %s), aborted: %d\n"), cmdlist[i], GetLastError(), (CString)CFormatMessageWrapper(), *bAbort); EnsurePostMessage(pWnd, MSG_PROGRESSDLG_UPDATE_UI, MSG_PROGRESSDLG_FAILED, status); return TGIT_GIT_ERROR_GET_EXIT_CODE; } CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": process %s finished with code %d\n"), cmdlist[i], status); ret |= status; } CloseHandle(pi.hProcess); CloseHandle(hRead); EnsurePostMessage(pWnd, MSG_PROGRESSDLG_UPDATE_UI, MSG_PROGRESSDLG_END, ret); return ret; }
void MeshUpdateQueue::addBlock(Map *map, v3s16 p, bool ack_block_to_server, bool urgent) { MutexAutoLock lock(m_mutex); cleanupCache(); /* Cache the block data (force-update the center block, don't update the neighbors but get them if they aren't already cached) */ std::vector<CachedMapBlockData*> cached_blocks; size_t cache_hit_counter = 0; cached_blocks.reserve(3*3*3); v3s16 dp; for (dp.X = -1; dp.X <= 1; dp.X++) for (dp.Y = -1; dp.Y <= 1; dp.Y++) for (dp.Z = -1; dp.Z <= 1; dp.Z++) { v3s16 p1 = p + dp; CachedMapBlockData *cached_block; if (dp == v3s16(0, 0, 0)) cached_block = cacheBlock(map, p1, FORCE_UPDATE); else cached_block = cacheBlock(map, p1, SKIP_UPDATE_IF_ALREADY_CACHED, &cache_hit_counter); cached_blocks.push_back(cached_block); } g_profiler->avg("MeshUpdateQueue MapBlock cache hit %", 100.0f * cache_hit_counter / cached_blocks.size()); /* Mark the block as urgent if requested */ if (urgent) m_urgents.insert(p); /* Find if block is already in queue. If it is, update the data and quit. */ for (QueuedMeshUpdate *q : m_queue) { if (q->p == p) { // NOTE: We are not adding a new position to the queue, thus // refcount_from_queue stays the same. if(ack_block_to_server) q->ack_block_to_server = true; q->crack_level = m_client->getCrackLevel(); q->crack_pos = m_client->getCrackPos(); return; } } /* Add the block */ QueuedMeshUpdate *q = new QueuedMeshUpdate; q->p = p; q->ack_block_to_server = ack_block_to_server; q->crack_level = m_client->getCrackLevel(); q->crack_pos = m_client->getCrackPos(); m_queue.push_back(q); // This queue entry is a new reference to the cached blocks for (CachedMapBlockData *cached_block : cached_blocks) { cached_block->refcount_from_queue++; } }
//static function, Share with SyncDialog UINT CProgressDlg::RunCmdList(CWnd *pWnd,std::vector<CString> &cmdlist,bool bShowCommand,CString *pfilename,bool *bAbort,CGitByteArray *pdata) { UINT ret=0; PROCESS_INFORMATION pi; HANDLE hRead = 0; memset(&pi,0,sizeof(PROCESS_INFORMATION)); CBlockCacheForPath cacheBlock(g_Git.m_CurrentDir); pWnd->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_START,0); if(pdata) pdata->clear(); for(int i=0;i<cmdlist.size();i++) { if(cmdlist[i].IsEmpty()) continue; if (bShowCommand) { CStringA str = CUnicodeUtils::GetMulti(cmdlist[i].Trim() + _T("\n\n"), CP_UTF8); for(int j=0;j<str.GetLength();j++) { if(pdata) { pdata->m_critSec.Lock(); pdata->push_back(str[j]); pdata->m_critSec.Unlock(); } else pWnd->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_RUN,str[j]); } if(pdata) pWnd->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_RUN,0); } g_Git.RunAsync(cmdlist[i].Trim(),&pi, &hRead, NULL, pfilename); DWORD readnumber; char byte; CString output; while(ReadFile(hRead,&byte,1,&readnumber,NULL)) { if(pdata) { if(byte == 0) byte = '\n'; pdata->m_critSec.Lock(); pdata->push_back( byte); pdata->m_critSec.Unlock(); if(byte == '\r' || byte == '\n') pWnd->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_RUN,0); } else pWnd->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_RUN,byte); } CloseHandle(pi.hThread); WaitForSingleObject(pi.hProcess, INFINITE); DWORD status=0; if(!GetExitCodeProcess(pi.hProcess,&status) || *bAbort) { CloseHandle(pi.hProcess); CloseHandle(hRead); pWnd->PostMessage(MSG_PROGRESSDLG_UPDATE_UI, MSG_PROGRESSDLG_FAILED, status); return TGIT_GIT_ERROR_GET_EXIT_CODE; } ret |= status; } CloseHandle(pi.hProcess); CloseHandle(hRead); pWnd->PostMessage(MSG_PROGRESSDLG_UPDATE_UI, MSG_PROGRESSDLG_END, ret); return ret; }
int CGitLogList::RevertSelectedCommits() { CSysProgressDlg progress; int ret = -1; #if 0 if(!g_Git.CheckCleanWorkTree()) { CMessageBox::Show(NULL,_T("Revert requires a clean working tree"),_T("TortoiseGit"),MB_OK); } #endif if (progress.IsValid() && (this->GetSelectedCount() > 1) ) { progress.SetTitle(_T("Revert Commit")); progress.SetAnimation(IDR_MOVEANI); progress.SetTime(true); progress.ShowModeless(this); } CBlockCacheForPath cacheBlock(g_Git.m_CurrentDir); POSITION pos = GetFirstSelectedItemPosition(); int i=0; while(pos) { int index = GetNextSelectedItem(pos); GitRev * r1 = reinterpret_cast<GitRev*>(m_arShownList.GetAt(index)); if (progress.IsValid() && (this->GetSelectedCount() > 1) ) { progress.FormatPathLine(1, _T("Revert %s"), r1->m_CommitHash.ToString()); progress.FormatPathLine(2, _T("%s"), r1->GetSubject()); progress.SetProgress(i, this->GetSelectedCount()); } i++; if(r1->m_CommitHash.IsEmpty()) continue; CString cmd, output; cmd.Format(_T("git.exe revert --no-edit --no-commit %s"), r1->m_CommitHash.ToString()); if(g_Git.Run(cmd, &output, CP_ACP)) { CString str; str=_T("Revert fail\n"); str+= cmd; str+= _T("\n")+output; if( GetSelectedCount() == 1) CMessageBox::Show(NULL,str, _T("TortoiseGit"),MB_OK|MB_ICONERROR); else { if(CMessageBox::Show(NULL, str, _T("TortoiseGit"),2 , IDI_ERROR, _T("&Skip"), _T("&Abort")) == 2) { return ret; } } } else { ret =0; } if ((progress.IsValid())&&(progress.HasUserCancelled())) break; } return ret; }