CString GitPatch::CheckPatchPath(const CString& path) { // first check if the path already matches if (CountMatches(path) > (GetNumberOfFiles() / 3)) return path; CSysProgressDlg progress; CString tmp; progress.SetTitle(IDS_PATCH_SEARCHPATHTITLE); progress.SetShowProgressBar(false); tmp.LoadString(IDS_PATCH_SEARCHPATHLINE1); progress.SetLine(1, tmp); progress.ShowModeless(AfxGetMainWnd()); // now go up the tree and try again CString upperpath = path; while (upperpath.ReverseFind('\\')>0) { upperpath = upperpath.Left(upperpath.ReverseFind('\\')); progress.SetLine(2, upperpath, true); if (progress.HasUserCancelled()) return path; if (CountMatches(upperpath) > (GetNumberOfFiles()/3)) return upperpath; } // still no match found. So try sub folders bool isDir = false; CString subpath; CDirFileEnum filefinder(path); while (filefinder.NextFile(subpath, &isDir)) { if (progress.HasUserCancelled()) return path; if (!isDir) continue; if (GitAdminDir::IsAdminDirPath(subpath)) continue; progress.SetLine(2, subpath, true); if (CountMatches(subpath) > (GetNumberOfFiles()/3)) return subpath; } // if a patch file only contains newly added files // we can't really find the correct path. // But: we can compare paths strings without the filenames // and check if at least those match upperpath = path; while (upperpath.ReverseFind('\\')>0) { upperpath = upperpath.Left(upperpath.ReverseFind('\\')); progress.SetLine(2, upperpath, true); if (progress.HasUserCancelled()) return path; if (CountDirMatches(upperpath) > (GetNumberOfFiles()/3)) return upperpath; } return path; }
void CFilePatchesDlg::PatchSelected() { if (m_pCallBack) { CSysProgressDlg progDlg; progDlg.SetTitle(IDR_MAINFRAME); progDlg.SetShowProgressBar(true); progDlg.SetLine(1, CString(MAKEINTRESOURCE(IDS_PATCH_SELECTED))); progDlg.ShowModeless(m_hWnd); // The list cannot be sorted by user, so the order of the // items in the list is identical to the order in the array // m_arFileStates. int selCount = m_cFileList.GetSelectedCount(); int count = 1; POSITION pos = m_cFileList.GetFirstSelectedItemPosition(); int index; while (((index = m_cFileList.GetNextSelectedItem(pos)) >= 0) && (!progDlg.HasUserCancelled())) { if (m_arFileStates.GetAt(index) == FPDLG_FILESTATE_ERROR) MessageBox(m_pPatch->GetPatchRejects(index), NULL, MB_ICONERROR); else if (m_arFileStates.GetAt(index) != FPDLG_FILESTATE_PATCHED) { progDlg.SetLine(2, GetFullPath(index), true); m_pCallBack->PatchFile(m_pPatch->GetStrippedPath(index), m_pPatch->GetContentMods(index), m_pPatch->GetPropMods(index), _T(""), TRUE); m_ShownIndex = index; m_cFileList.Invalidate(); } progDlg.SetProgress64(count++, selCount); } progDlg.Stop(); } }
void CFilePatchesDlg::PatchAll() { if (m_pCallBack) { CSysProgressDlg progDlg; progDlg.SetTitle(IDR_MAINFRAME); progDlg.SetShowProgressBar(true); progDlg.SetLine(1, CString(MAKEINTRESOURCE(IDS_PATCH_ALL))); progDlg.ShowModeless(m_hWnd); for (int i=0; i<m_arFileStates.GetCount() && !progDlg.HasUserCancelled(); i++) { if (m_arFileStates.GetAt(i) == FPDLG_FILESTATE_ERROR) MessageBox(m_pPatch->GetPatchRejects(i), NULL, MB_ICONERROR); else if (m_arFileStates.GetAt(i) != FPDLG_FILESTATE_PATCHED) { progDlg.SetLine(2, GetFullPath(i), true); m_pCallBack->PatchFile(m_pPatch->GetStrippedPath(i), m_pPatch->GetContentMods(i), m_pPatch->GetPropMods(i), _T(""), TRUE); m_ShownIndex = i; m_cFileList.Invalidate(); } progDlg.SetProgress64(i, m_arFileStates.GetCount()); } progDlg.Stop(); } }
void CFilePatchesDlg::PatchSelected() { if (m_pCallBack) { CSysProgressDlg progDlg; progDlg.SetTitle(IDR_MAINFRAME); progDlg.SetShowProgressBar(true); progDlg.SetLine(1, CString(MAKEINTRESOURCE(IDS_PATCH_SELECTED))); progDlg.ShowModeless(m_hWnd); // The list cannot be sorted by user, so the order of the // items in the list is identical to the order in the array // m_arFileStates. int selCount = m_cFileList.GetSelectedCount(); int count = 1; POSITION pos = m_cFileList.GetFirstSelectedItemPosition(); int index; BOOL ret = TRUE; while (((index = m_cFileList.GetNextSelectedItem(pos)) >= 0) && (!progDlg.HasUserCancelled()) && ret == TRUE) { if (m_arFileStates.GetAt(index)!= FPDLG_FILESTATE_PATCHED) { progDlg.SetLine(2, m_pPatch->GetFullPath(m_sPath, index), true); ret = m_pCallBack->PatchFile(index, true, false); } progDlg.SetProgress64(count++, selCount); } progDlg.Stop(); } }
static bool GetFilesToCleanUp(CTGitPathList& delList, const CString& baseCmd, CGit *pGit, const CString& path, const boolean quotepath, CSysProgressDlg& sysProgressDlg) { CString cmd(baseCmd); if (!path.IsEmpty()) cmd += _T(" -- \"") + path + _T("\""); CString cmdout, cmdouterr; if (pGit->Run(cmd, &cmdout, &cmdouterr, CP_UTF8)) { MessageBox(nullptr, cmdouterr, _T("TortoiseGit"), MB_ICONERROR); return false; } if (sysProgressDlg.HasUserCancelled()) { CMessageBox::Show(nullptr, IDS_USERCANCELLED, IDS_APPNAME, MB_OK); return false; } int pos = 0; CString token = cmdout.Tokenize(_T("\n"), pos); while (!token.IsEmpty()) { if (token.Mid(0, 13) == _T("Would remove ")) { CString tempPath = token.Mid(13).TrimRight(); if (quotepath) tempPath = UnescapeQuotePath(tempPath.Trim(_T('"'))); delList.AddPath(pGit->CombinePath(tempPath)); } token = cmdout.Tokenize(_T("\n"), pos); } if (sysProgressDlg.HasUserCancelled()) { CMessageBox::Show(nullptr, IDS_USERCANCELLED, IDS_APPNAME, MB_OK); return false; } return true; }
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 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; }
void CFilePatchesDlg::PatchAll() { if (m_pCallBack) { CSysProgressDlg progDlg; progDlg.SetTitle(IDR_MAINFRAME); progDlg.SetShowProgressBar(true); progDlg.SetLine(1, CString(MAKEINTRESOURCE(IDS_PATCH_ALL))); progDlg.ShowModeless(m_hWnd); BOOL ret = TRUE; for (int i=0; i<m_arFileStates.GetCount() && !progDlg.HasUserCancelled() && ret == TRUE; i++) { if (m_arFileStates.GetAt(i)!= FPDLG_FILESTATE_PATCHED) { progDlg.SetLine(2, m_pPatch->GetFullPath(m_sPath, i), true); ret = m_pCallBack->PatchFile(i, true, false); } progDlg.SetProgress64(i, m_arFileStates.GetCount()); } progDlg.Stop(); } }
bool CleanupCommand::Execute() { bool bRet = false; CCleanTypeDlg dlg; if( dlg.DoModal() == IDOK) { bool quotepath = g_Git.GetConfigValueBool(_T("core.quotepath")); CString cmd; cmd.Format(_T("git clean")); if (dlg.m_bDryRun || !dlg.m_bNoRecycleBin) cmd += _T(" -n "); if(dlg.m_bDir) cmd += _T(" -d "); switch(dlg.m_CleanType) { case 0: cmd += _T(" -fx"); break; case 1: cmd += _T(" -f"); break; case 2: cmd += _T(" -fX"); break; } if (dlg.m_bDryRun || dlg.m_bNoRecycleBin) { CProgressDlg progress; for (int i = 0; i < this->pathList.GetCount(); ++i) { CString path; if (this->pathList[i].IsDirectory()) path = pathList[i].GetGitPathString(); else path = pathList[i].GetContainingDirectory().GetGitPathString(); progress.m_GitCmdList.push_back(cmd + _T(" \"") + path + _T("\"")); } if (progress.DoModal()==IDOK) return TRUE; } else { CSysProgressDlg sysProgressDlg; sysProgressDlg.SetAnimation(IDR_CLEANUPANI); sysProgressDlg.SetTitle(CString(MAKEINTRESOURCE(IDS_APPNAME))); sysProgressDlg.SetLine(1, CString(MAKEINTRESOURCE(IDS_PROC_CLEANUP_INFO1))); sysProgressDlg.SetLine(2, CString(MAKEINTRESOURCE(IDS_PROGRESSWAIT))); sysProgressDlg.SetShowProgressBar(false); sysProgressDlg.ShowModeless((HWND)NULL, true); CString cmdout, cmdouterr; if (g_Git.Run(cmd, &cmdout, &cmdouterr, CP_UTF8)) { MessageBox(NULL, cmdouterr, _T("TortoiseGit"), MB_ICONERROR); return FALSE; } if (sysProgressDlg.HasUserCancelled()) { CMessageBox::Show(NULL, IDS_SVN_USERCANCELLED, IDS_APPNAME, MB_OK); return FALSE; } int pos = 0; CString token = cmdout.Tokenize(_T("\n"), pos); CTGitPathList delList; while (!token.IsEmpty()) { if (token.Mid(0, 13) == _T("Would remove ")) { CString tempPath = token.Mid(13).TrimRight(); if (quotepath) { tempPath = UnescapeQuotePath(tempPath.Trim(_T('"'))); } delList.AddPath(CTGitPath(tempPath)); } token = cmdout.Tokenize(_T("\n"), pos); } if (sysProgressDlg.HasUserCancelled()) { CMessageBox::Show(NULL, IDS_SVN_USERCANCELLED, IDS_APPNAME, MB_OK); return FALSE; } delList.DeleteAllFiles(true, false); sysProgressDlg.Stop(); } } #if 0 CProgressDlg progress; progress.SetTitle(IDS_PROC_CLEANUP); progress.SetAnimation(IDR_CLEANUPANI); progress.SetShowProgressBar(false); progress.SetLine(1, CString(MAKEINTRESOURCE(IDS_PROC_CLEANUP_INFO1))); progress.SetLine(2, CString(MAKEINTRESOURCE(IDS_PROC_CLEANUP_INFO2))); progress.ShowModeless(hwndExplorer); CString strSuccessfullPaths, strFailedPaths; for (int i=0; i<pathList.GetCount(); ++i) { SVN svn; if (!svn.CleanUp(pathList[i])) { strFailedPaths += _T("- ") + pathList[i].GetWinPathString() + _T("\n"); strFailedPaths += svn.GetLastErrorMessage() + _T("\n\n"); } else { strSuccessfullPaths += _T("- ") + pathList[i].GetWinPathString() + _T("\n"); // after the cleanup has finished, crawl the path downwards and send a change // notification for every directory to the shell. This will update the // overlays in the left tree view of the explorer. CDirFileEnum crawler(pathList[i].GetWinPathString()); CString sPath; bool bDir = false; CTSVNPathList updateList; while (crawler.NextFile(sPath, &bDir)) { if ((bDir) && (!g_SVNAdminDir.IsAdminDirPath(sPath))) { updateList.AddPath(CTSVNPath(sPath)); } } updateList.AddPath(pathList[i]); CShellUpdater::Instance().AddPathsForUpdate(updateList); CShellUpdater::Instance().Flush(); updateList.SortByPathname(true); for (INT_PTR i=0; i<updateList.GetCount(); ++i) { SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATH, updateList[i].GetWinPath(), NULL); ATLTRACE(_T("notify change for path %s\n"), updateList[i].GetWinPath()); } } } progress.Stop(); CString strMessage; if ( !strSuccessfullPaths.IsEmpty() ) { CString tmp; tmp.Format(IDS_PROC_CLEANUPFINISHED, (LPCTSTR)strSuccessfullPaths); strMessage += tmp; bRet = true; } if ( !strFailedPaths.IsEmpty() ) { if (!strMessage.IsEmpty()) strMessage += _T("\n"); CString tmp; tmp.Format(IDS_PROC_CLEANUPFINISHED_FAILED, (LPCTSTR)strFailedPaths); strMessage += tmp; bRet = false; } CMessageBox::Show(hwndExplorer, strMessage, _T("TortoiseGit"), MB_OK | (strFailedPaths.IsEmpty()?MB_ICONINFORMATION:MB_ICONERROR)); #endif CShellUpdater::Instance().Flush(); return bRet; }
bool DropCopyCommand::Execute() { CString sDroppath = parser.GetVal(_T("droptarget")); if (CTGitPath(sDroppath).IsAdminDir()) { CMessageBox::Show(NULL,_T("Can't drop to .git repository directory\n"), _T("TortoiseGit"),MB_OK|MB_ICONERROR); return FALSE; } unsigned long count = 0; CString sNewName; pathList.RemoveAdminPaths(); if ((parser.HasKey(_T("rename")))&&(pathList.GetCount()==1)) { // ask for a new name of the source item do { CRenameDlg renDlg; renDlg.m_windowtitle.LoadString(IDS_PROC_COPYRENAME); renDlg.m_name = pathList[0].GetFileOrDirectoryName(); if (renDlg.DoModal() != IDOK) { return FALSE; } sNewName = renDlg.m_name; } while(sNewName.IsEmpty() || PathFileExists(sDroppath+_T("\\")+sNewName)); } CSysProgressDlg progress; progress.SetTitle(IDS_PROC_COPYING); progress.SetAnimation(IDR_MOVEANI); progress.SetTime(true); progress.ShowModeless(CWnd::FromHandle(hwndExplorer)); for(int nPath = 0; nPath < pathList.GetCount(); nPath++) { const CTGitPath& sourcePath = orgPathList[nPath]; CTGitPath fullDropPath(sDroppath); if (sNewName.IsEmpty()) fullDropPath.AppendPathString(sourcePath.GetFileOrDirectoryName()); else fullDropPath.AppendPathString(sNewName); // Check for a drop-on-to-ourselves if (sourcePath.IsEquivalentTo(fullDropPath)) { // Offer a rename progress.Stop(); CRenameDlg dlg; dlg.m_windowtitle.Format(IDS_PROC_NEWNAMECOPY, (LPCTSTR)sourcePath.GetUIFileOrDirectoryName()); if (dlg.DoModal() != IDOK) { return FALSE; } // rebuild the progress dialog progress.EnsureValid(); progress.SetTitle(IDS_PROC_COPYING); progress.SetAnimation(IDR_MOVEANI); progress.SetTime(true); progress.SetProgress(count, pathList.GetCount()); progress.ShowModeless(CWnd::FromHandle(hwndExplorer)); // Rebuild the destination path, with the new name fullDropPath.SetFromUnknown(sDroppath); fullDropPath.AppendPathString(dlg.m_name); } if( CopyFile( sourcePath.GetWinPath(), fullDropPath.GetWinPath(), true)) { CString ProjectTopDir; if(fullDropPath.HasAdminDir(&ProjectTopDir)) { g_Git.SetCurrentDir(ProjectTopDir); SetCurrentDirectory(ProjectTopDir); CString cmd; cmd = _T("git.exe add \""); CString path; path=fullDropPath.GetGitPathString().Mid(ProjectTopDir.GetLength()); if(path.GetLength()>0) if(path[0]==_T('\\') || path[0]==_T('/')) path=path.Mid(1); cmd += path; cmd +=_T('\"'); CString output; if (g_Git.Run(cmd, &output, CP_UTF8)) { CMessageBox::Show(NULL, output, _T("TortoiseGit"), MB_OK|MB_ICONERROR); } else CShellUpdater::Instance().AddPathForUpdate(fullDropPath); } } else { CString str; str+=_T("Copy file fail:"); str+=sourcePath.GetWinPath(); CMessageBox::Show(NULL, str, _T("TortoiseGit"), MB_OK|MB_ICONERROR); } count++; if (progress.IsValid()) { progress.FormatPathLine(1, IDS_PROC_COPYINGPROG, sourcePath.GetWinPath()); progress.FormatPathLine(2, IDS_PROC_CPYMVPROG2, fullDropPath.GetWinPath()); progress.SetProgress(count, pathList.GetCount()); } if ((progress.IsValid())&&(progress.HasUserCancelled())) { CMessageBox::Show(hwndExplorer, IDS_SVN_USERCANCELLED, IDS_APPNAME, MB_ICONINFORMATION); return false; } } return true; }
bool PasteCopyCommand::Execute() { CString sDroppath = parser.GetVal(_T("droptarget")); CTGitPath dropPath(sDroppath); ProjectProperties props; props.ReadProps(dropPath); if (dropPath.IsAdminDir()) return FALSE; if(!dropPath.HasAdminDir(&g_Git.m_CurrentDir)) return FALSE; //SVN svn; //SVNStatus status; unsigned long count = 0; CString sNewName; orgPathList.RemoveAdminPaths(); CSysProgressDlg progress; progress.SetTitle(IDS_PROC_COPYING); progress.SetAnimation(IDR_MOVEANI); progress.SetTime(true); progress.ShowModeless(CWnd::FromHandle(hwndExplorer)); for(int nPath = 0; nPath < orgPathList.GetCount(); nPath++) { const CTGitPath& sourcePath = orgPathList[nPath]; CTGitPath fullDropPath = dropPath; if (sNewName.IsEmpty()) fullDropPath.AppendPathString(sourcePath.GetFileOrDirectoryName()); else fullDropPath.AppendPathString(sNewName); // Check for a drop-on-to-ourselves if (sourcePath.IsEquivalentTo(fullDropPath)) { // Offer a rename progress.Stop(); CRenameDlg dlg; dlg.m_windowtitle.Format(IDS_PROC_NEWNAMECOPY, (LPCTSTR)sourcePath.GetUIFileOrDirectoryName()); if (dlg.DoModal() != IDOK) { return FALSE; } // rebuild the progress dialog progress.EnsureValid(); progress.SetTitle(IDS_PROC_COPYING); progress.SetAnimation(IDR_MOVEANI); progress.SetTime(true); progress.SetProgress(count, orgPathList.GetCount()); progress.ShowModeless(CWnd::FromHandle(hwndExplorer)); // Rebuild the destination path, with the new name fullDropPath.SetFromUnknown(sDroppath); fullDropPath.AppendPathString(dlg.m_name); } //svn_wc_status_kind s = status.GetAllStatus(sourcePath); //if ((s == svn_wc_status_none)||(s == svn_wc_status_unversioned)||(s == svn_wc_status_ignored)) { // source file is unversioned: move the file to the target, then add it CopyFile(sourcePath.GetWinPath(), fullDropPath.GetWinPath(), FALSE); CString cmd,output; cmd.Format(_T("git.exe add \"%s\""),fullDropPath.GetWinPath()); if( g_Git.Run(cmd,&output,CP_ACP)) { TRACE(_T("%s\n"), (LPCTSTR)output); CMessageBox::Show(hwndExplorer, output, _T("TortoiseGit"), MB_ICONERROR); return FALSE; //get out of here } else CShellUpdater::Instance().AddPathForUpdate(fullDropPath); } //else //{ // if (!svn.Copy(CTSVNPathList(sourcePath), fullDropPath, SVNRev::REV_WC, SVNRev())) // { // TRACE(_T("%s\n"), (LPCTSTR)svn.GetLastErrorMessage()); // CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseSVN"), MB_ICONERROR); // return FALSE; //get out of here // } // else // CShellUpdater::Instance().AddPathForUpdate(fullDropPath); //} count++; if (progress.IsValid()) { progress.FormatPathLine(1, IDS_PROC_COPYINGPROG, sourcePath.GetWinPath()); progress.FormatPathLine(2, IDS_PROC_CPYMVPROG2, fullDropPath.GetWinPath()); progress.SetProgress(count, orgPathList.GetCount()); } if ((progress.IsValid())&&(progress.HasUserCancelled())) { CMessageBox::Show(hwndExplorer, IDS_SVN_USERCANCELLED, IDS_APPNAME, MB_ICONINFORMATION); return false; } } return true; }
bool DropMoveCommand::Execute() { CString droppath = parser.GetVal(_T("droptarget")); CString ProjectTop; if (!CTGitPath(droppath).HasAdminDir(&ProjectTop)) return FALSE; if (ProjectTop != g_Git.m_CurrentDir ) { CMessageBox::Show(NULL,_T("Target and source must be the same git repository"),_T("TortoiseGit"),MB_OK); return FALSE; } droppath = droppath.Right(droppath.GetLength()-ProjectTop.GetLength()-1); unsigned long count = 0; pathList.RemoveAdminPaths(); CString sNewName; if ((parser.HasKey(_T("rename")))&&(pathList.GetCount()==1)) { // ask for a new name of the source item do { CRenameDlg renDlg; renDlg.m_windowtitle.LoadString(IDS_PROC_MOVERENAME); renDlg.m_name = pathList[0].GetFileOrDirectoryName(); if (renDlg.DoModal() != IDOK) { return FALSE; } sNewName = renDlg.m_name; } while(sNewName.IsEmpty() || PathFileExists(droppath+_T("\\")+sNewName)); } CSysProgressDlg progress; if (progress.IsValid()) { progress.SetTitle(IDS_PROC_MOVING); progress.SetAnimation(IDR_MOVEANI); progress.SetTime(true); progress.ShowModeless(CWnd::FromHandle(hwndExplorer)); } for(int nPath = 0; nPath < pathList.GetCount(); nPath++) { CTGitPath destPath; if (sNewName.IsEmpty()) destPath = CTGitPath(droppath+_T("\\")+pathList[nPath].GetFileOrDirectoryName()); else destPath = CTGitPath(droppath+_T("\\")+sNewName); if (destPath.Exists()) { CString name = pathList[nPath].GetFileOrDirectoryName(); if (!sNewName.IsEmpty()) name = sNewName; progress.Stop(); CRenameDlg dlg; dlg.m_name = name; dlg.m_windowtitle.Format(IDS_PROC_NEWNAMEMOVE, (LPCTSTR)name); if (dlg.DoModal() != IDOK) { return FALSE; } destPath.SetFromWin(droppath+_T("\\")+dlg.m_name); } CString cmd,out; cmd.Format(_T("git.exe mv -- \"%s\" \"%s\""),pathList[nPath].GetGitPathString(),destPath.GetGitPathString()); if(g_Git.Run(cmd,&out,CP_ACP)) { if (CMessageBox::Show(hwndExplorer, out, _T("TortoiseGit"), MB_YESNO)==IDYES) { #if 0 if (!svn.Move(CTSVNPathList(pathList[nPath]), destPath, TRUE)) { CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR); return FALSE; //get out of here } CShellUpdater::Instance().AddPathForUpdate(destPath); #endif } else { //TRACE(_T("%s\n"), (LPCTSTR)svn.GetLastErrorMessage()); CMessageBox::Show(hwndExplorer, _T("Cancel"), _T("TortoiseGit"), MB_ICONERROR); return FALSE; //get out of here } } else CShellUpdater::Instance().AddPathForUpdate(destPath); count++; if (progress.IsValid()) { progress.FormatPathLine(1, IDS_PROC_MOVINGPROG, pathList[nPath].GetWinPath()); progress.FormatPathLine(2, IDS_PROC_CPYMVPROG2, destPath.GetWinPath()); progress.SetProgress(count, pathList.GetCount()); } if ((progress.IsValid())&&(progress.HasUserCancelled())) { CMessageBox::Show(hwndExplorer, IDS_SVN_USERCANCELLED, IDS_APPNAME, MB_ICONINFORMATION); return FALSE; } } return true; }
bool PasteMoveCommand::Execute() { CString sDroppath = parser.GetVal(_T("droptarget")); CTGitPath dropPath(sDroppath); if (dropPath.IsAdminDir()) return FALSE; if(!dropPath.HasAdminDir(&g_Git.m_CurrentDir)) return FALSE; GitStatus status; unsigned long count = 0; orgPathList.RemoveAdminPaths(); CString sNewName; CSysProgressDlg progress; progress.SetTitle(IDS_PROC_MOVING); progress.SetAnimation(IDR_MOVEANI); progress.SetTime(true); progress.ShowModeless(CWnd::FromHandle(hwndExplorer)); for (int nPath = 0; nPath < orgPathList.GetCount(); ++nPath) { CTGitPath destPath; if (sNewName.IsEmpty()) destPath = CTGitPath(sDroppath+_T("\\")+orgPathList[nPath].GetFileOrDirectoryName()); else destPath = CTGitPath(sDroppath+_T("\\")+sNewName); if (destPath.Exists()) { CString name = orgPathList[nPath].GetFileOrDirectoryName(); if (!sNewName.IsEmpty()) name = sNewName; progress.Stop(); CRenameDlg dlg; dlg.m_name = name; dlg.m_windowtitle.Format(IDS_PROC_NEWNAMEMOVE, (LPCTSTR)name); if (dlg.DoModal() != IDOK) { return FALSE; } destPath.SetFromWin(sDroppath+_T("\\")+dlg.m_name); } CString top; top.Empty(); orgPathList[nPath].HasAdminDir(&top); git_wc_status_kind s = status.GetAllStatus(orgPathList[nPath]); if ((s == git_wc_status_none)||(s == git_wc_status_unversioned)||(s == git_wc_status_ignored)||top != g_Git.m_CurrentDir) { // source file is unversioned: move the file to the target, then add it MoveFile(orgPathList[nPath].GetWinPath(), destPath.GetWinPath()); CString cmd,output; cmd.Format(_T("git.exe add -- \"%s\""),destPath.GetWinPath()); if (g_Git.Run(cmd, &output, CP_UTF8)) //if (!Git.Add(CTGitorgPathList(destPath), &props, Git_depth_infinity, true, false, true)) { TRACE(_T("%s\n"), output); CMessageBox::Show(hwndExplorer, output, _T("TortoiseGit"), MB_ICONERROR); return FALSE; //get out of here } CShellUpdater::Instance().AddPathForUpdate(destPath); } else { CString cmd,output; cmd.Format(_T("git.exe mv \"%s\" \"%s\""),orgPathList[nPath].GetGitPathString(),destPath.GetGitPathString()); if (g_Git.Run(cmd, &output, CP_UTF8)) //if (!Git.Move(CTGitorgPathList(orgPathList[nPath]), destPath, FALSE)) { #if 0 if (Git.Err && (Git.Err->apr_err == Git_ERR_UNVERSIONED_RESOURCE || Git.Err->apr_err == Git_ERR_CLIENT_MODIFIED)) { // file/folder seems to have local modifications. Ask the user if // a force is requested. CString temp = Git.GetLastErrorMessage(); CString sQuestion(MAKEINTRESOURCE(IDS_PROC_FORCEMOVE)); temp += _T("\n") + sQuestion; if (CMessageBox::Show(hwndExplorer, temp, _T("TortoiseGit"), MB_YESNO)==IDYES) { if (!Git.Move(CTGitPathList(pathList[nPath]), destPath, TRUE)) { CMessageBox::Show(hwndExplorer, Git.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR); return FALSE; //get out of here } CShellUpdater::Instance().AddPathForUpdate(destPath); } } else #endif { TRACE(_T("%s\n"), (LPCTSTR)output); CMessageBox::Show(hwndExplorer, output, _T("TortoiseGit"), MB_ICONERROR); return FALSE; //get out of here } } else CShellUpdater::Instance().AddPathForUpdate(destPath); } ++count; if (progress.IsValid()) { progress.FormatPathLine(1, IDS_PROC_MOVINGPROG, orgPathList[nPath].GetWinPath()); progress.FormatPathLine(2, IDS_PROC_CPYMVPROG2, destPath.GetWinPath()); progress.SetProgress(count, orgPathList.GetCount()); } if ((progress.IsValid())&&(progress.HasUserCancelled())) { CMessageBox::Show(hwndExplorer, IDS_USERCANCELLED, IDS_APPNAME, MB_ICONINFORMATION); return FALSE; } } return true; }
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); } 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; }
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; }
void CFilePatchesDlg::OnNMRclickFilelist(NMHDR * /*pNMHDR*/, LRESULT *pResult) { *pResult = 0; if (m_sPath.IsEmpty()) return; CString temp; CMenu popup; POINT point; DWORD ptW = GetMessagePos(); point.x = GET_X_LPARAM(ptW); point.y = GET_Y_LPARAM(ptW); if (popup.CreatePopupMenu()) { UINT nFlags; nFlags = MF_STRING | (m_cFileList.GetSelectedCount()==1 ? MF_ENABLED : MF_DISABLED | MF_GRAYED); temp.LoadString(IDS_PATCH_REVIEW); popup.AppendMenu(nFlags, ID_PATCH_REVIEW, temp); popup.SetDefaultItem(ID_PATCH_REVIEW, FALSE); temp.LoadString(IDS_PATCH_PREVIEW); popup.AppendMenu(nFlags, ID_PATCHPREVIEW, temp); temp.LoadString(IDS_PATCH_ALL); popup.AppendMenu(MF_STRING | MF_ENABLED, ID_PATCHALL, temp); nFlags = MF_STRING | (m_cFileList.GetSelectedCount()>0 ? MF_ENABLED : MF_DISABLED | MF_GRAYED); temp.LoadString(IDS_PATCH_SELECTED); popup.AppendMenu(nFlags, ID_PATCHSELECTED, temp); // if the context menu is invoked through the keyboard, we have to use // a calculated position on where to anchor the menu on if ((point.x == -1) && (point.y == -1)) { CRect rect; GetWindowRect(&rect); point = rect.CenterPoint(); } bool bReview=false; int cmd = popup.TrackPopupMenu(TPM_RETURNCMD | TPM_LEFTALIGN | TPM_NONOTIFY, point.x, point.y, this, 0); switch (cmd) { case ID_PATCH_REVIEW: bReview = true; //go through case case ID_PATCHPREVIEW: { if (m_pCallBack) { int nIndex = m_cFileList.GetSelectionMark(); if ( m_arFileStates.GetAt(nIndex)!=FPDLG_FILESTATE_PATCHED) { m_pCallBack->PatchFile(GetFullPath(nIndex), m_pPatch->GetRevision(nIndex),false,bReview); } } } break; case ID_PATCHALL: { if (m_pCallBack) { CSysProgressDlg progDlg; progDlg.SetTitle(IDR_MAINFRAME); progDlg.SetShowProgressBar(true); progDlg.SetLine(1, CString(MAKEINTRESOURCE(IDS_PATCH_ALL))); progDlg.ShowModeless(m_hWnd); for (int i=0; i<m_arFileStates.GetCount() && !progDlg.HasUserCancelled(); i++) { if (m_arFileStates.GetAt(i)!= FPDLG_FILESTATE_PATCHED) { progDlg.SetLine(2, GetFullPath(i), true); m_pCallBack->PatchFile(GetFullPath(i), m_pPatch->GetRevision(i), TRUE); } progDlg.SetProgress64(i, m_arFileStates.GetCount()); } progDlg.Stop(); } } break; case ID_PATCHSELECTED: { if (m_pCallBack) { CSysProgressDlg progDlg; progDlg.SetTitle(IDR_MAINFRAME); progDlg.SetShowProgressBar(true); progDlg.SetLine(1, CString(MAKEINTRESOURCE(IDS_PATCH_SELECTED))); progDlg.ShowModeless(m_hWnd); // The list cannot be sorted by user, so the order of the // items in the list is identical to the order in the array // m_arFileStates. int selCount = m_cFileList.GetSelectedCount(); int count = 1; POSITION pos = m_cFileList.GetFirstSelectedItemPosition(); int index; while (((index = m_cFileList.GetNextSelectedItem(pos)) >= 0) && (!progDlg.HasUserCancelled())) { if (m_arFileStates.GetAt(index)!= FPDLG_FILESTATE_PATCHED) { progDlg.SetLine(2, GetFullPath(index), true); m_pCallBack->PatchFile(GetFullPath(index), m_pPatch->GetRevision(index), TRUE); } progDlg.SetProgress64(count++, selCount); } progDlg.Stop(); } } break; default: break; } } }
bool CleanupCommand::Execute() { bool bRet = false; CCleanTypeDlg dlg; if( dlg.DoModal() == IDOK) { bool quotepath = g_Git.GetConfigValueBool(_T("core.quotepath")); CString cmd; cmd.Format(_T("git.exe clean")); if (dlg.m_bDryRun || !dlg.m_bNoRecycleBin) cmd += _T(" -n "); if(dlg.m_bDir) cmd += _T(" -d "); switch(dlg.m_CleanType) { case 0: cmd += _T(" -fx"); break; case 1: cmd += _T(" -f"); break; case 2: cmd += _T(" -fX"); break; } STRING_VECTOR submoduleList; SubmodulePayload payload(submoduleList); if (dlg.m_bSubmodules) { payload.basePath = CTGitPath(g_Git.m_CurrentDir).GetGitPathString(); if (pathList.GetCount() != 1 || pathList.GetCount() == 1 && !pathList[0].IsEmpty()) { for (int i = 0; i < pathList.GetCount(); ++i) { CString path; if (pathList[i].IsDirectory()) payload.prefixList.push_back(pathList[i].GetGitPathString()); else payload.prefixList.push_back(pathList[i].GetContainingDirectory().GetGitPathString()); } } if (!GetSubmodulePathList(payload)) return FALSE; std::sort(submoduleList.begin(), submoduleList.end()); } if (dlg.m_bDryRun || dlg.m_bNoRecycleBin) { while (true) { CProgressDlg progress; for (int i = 0; i < this->pathList.GetCount(); ++i) { CString path; if (this->pathList[i].IsDirectory()) path = pathList[i].GetGitPathString(); else path = pathList[i].GetContainingDirectory().GetGitPathString(); progress.m_GitDirList.push_back(g_Git.m_CurrentDir); progress.m_GitCmdList.push_back(cmd + _T(" \"") + path + _T("\"")); } if (dlg.m_bSubmodules) { for (CString dir : submoduleList) { progress.m_GitDirList.push_back(CTGitPath(dir).GetWinPathString()); progress.m_GitCmdList.push_back(cmd); } } INT_PTR idRetry = -1; if (!dlg.m_bDryRun) idRetry = progress.m_PostFailCmdList.Add(CString(MAKEINTRESOURCE(IDS_MSGBOX_RETRY))); INT_PTR result = progress.DoModal(); if (result == IDOK) return TRUE; if (progress.m_GitStatus && result == IDC_PROGRESS_BUTTON1 + idRetry) continue; break; } } else { CSysProgressDlg sysProgressDlg; sysProgressDlg.SetAnimation(IDR_CLEANUPANI); sysProgressDlg.SetTitle(CString(MAKEINTRESOURCE(IDS_APPNAME))); sysProgressDlg.SetLine(1, CString(MAKEINTRESOURCE(IDS_PROC_CLEANUP_INFO1))); sysProgressDlg.SetLine(2, CString(MAKEINTRESOURCE(IDS_PROGRESSWAIT))); sysProgressDlg.SetShowProgressBar(false); sysProgressDlg.ShowModeless((HWND)NULL, true); CTGitPathList delList; for (size_t i = 0; i <= submoduleList.size(); ++i) { CGit git; CGit *pGit; if (i == 0) pGit = &g_Git; else { git.m_CurrentDir = submoduleList[i - 1]; pGit = &git; } CString cmdout, cmdouterr; if (pGit->Run(cmd, &cmdout, &cmdouterr, CP_UTF8)) { MessageBox(nullptr, cmdouterr, _T("TortoiseGit"), MB_ICONERROR); return FALSE; } if (sysProgressDlg.HasUserCancelled()) { CMessageBox::Show(nullptr, IDS_SVN_USERCANCELLED, IDS_APPNAME, MB_OK); return FALSE; } int pos = 0; CString token = cmdout.Tokenize(_T("\n"), pos); while (!token.IsEmpty()) { if (token.Mid(0, 13) == _T("Would remove ")) { CString tempPath = token.Mid(13).TrimRight(); if (quotepath) { tempPath = UnescapeQuotePath(tempPath.Trim(_T('"'))); } if (i == 0) delList.AddPath(CTGitPath(tempPath)); else delList.AddPath(CTGitPath(submoduleList[i - 1] + "/" + tempPath)); } token = cmdout.Tokenize(_T("\n"), pos); } if (sysProgressDlg.HasUserCancelled()) { CMessageBox::Show(nullptr, IDS_SVN_USERCANCELLED, IDS_APPNAME, MB_OK); return FALSE; } } delList.DeleteAllFiles(true, false); sysProgressDlg.Stop(); } } #if 0 CProgressDlg progress; progress.SetTitle(IDS_PROC_CLEANUP); progress.SetAnimation(IDR_CLEANUPANI); progress.SetShowProgressBar(false); progress.SetLine(1, CString(MAKEINTRESOURCE(IDS_PROC_CLEANUP_INFO1))); progress.SetLine(2, CString(MAKEINTRESOURCE(IDS_PROC_CLEANUP_INFO2))); progress.ShowModeless(hwndExplorer); CString strSuccessfullPaths, strFailedPaths; for (int i=0; i<pathList.GetCount(); ++i) { SVN svn; if (!svn.CleanUp(pathList[i])) { strFailedPaths += _T("- ") + pathList[i].GetWinPathString() + _T("\n"); strFailedPaths += svn.GetLastErrorMessage() + _T("\n\n"); } else { strSuccessfullPaths += _T("- ") + pathList[i].GetWinPathString() + _T("\n"); // after the cleanup has finished, crawl the path downwards and send a change // notification for every directory to the shell. This will update the // overlays in the left tree view of the explorer. CDirFileEnum crawler(pathList[i].GetWinPathString()); CString sPath; bool bDir = false; CTSVNPathList updateList; while (crawler.NextFile(sPath, &bDir)) { if ((bDir) && (!g_SVNAdminDir.IsAdminDirPath(sPath))) { updateList.AddPath(CTSVNPath(sPath)); } } updateList.AddPath(pathList[i]); CShellUpdater::Instance().AddPathsForUpdate(updateList); CShellUpdater::Instance().Flush(); updateList.SortByPathname(true); for (INT_PTR i=0; i<updateList.GetCount(); ++i) { SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATH, updateList[i].GetWinPath(), NULL); CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": notify change for path %s\n"), updateList[i].GetWinPath()); } } } progress.Stop(); CString strMessage; if ( !strSuccessfullPaths.IsEmpty() ) { CString tmp; tmp.Format(IDS_PROC_CLEANUPFINISHED, (LPCTSTR)strSuccessfullPaths); strMessage += tmp; bRet = true; } if ( !strFailedPaths.IsEmpty() ) { if (!strMessage.IsEmpty()) strMessage += _T("\n"); CString tmp; tmp.Format(IDS_PROC_CLEANUPFINISHED_FAILED, (LPCTSTR)strFailedPaths); strMessage += tmp; bRet = false; } CMessageBox::Show(hwndExplorer, strMessage, _T("TortoiseGit"), MB_OK | (strFailedPaths.IsEmpty()?MB_ICONINFORMATION:MB_ICONERROR)); #endif CShellUpdater::Instance().Flush(); return bRet; }