bool CopyCommand::Execute() { bool bRet = false; CString msg; if (parser.HasKey(_T("logmsg"))) { msg = parser.GetVal(_T("logmsg")); } if (parser.HasKey(_T("logmsgfile"))) { CString logmsgfile = parser.GetVal(_T("logmsgfile")); CStringUtils::ReadStringFromTextFile(logmsgfile, msg); } BOOL repeat = FALSE; CCopyDlg dlg; dlg.m_sLogMessage = msg; dlg.m_path = cmdLinePath; CString url = parser.GetVal(_T("url")); CString logmessage; SVNRev copyRev = SVNRev::REV_HEAD; BOOL doSwitch = FALSE; do { repeat = FALSE; dlg.m_URL = url; dlg.m_sLogMessage = logmessage; dlg.m_CopyRev = copyRev; dlg.m_bDoSwitch = doSwitch; if (dlg.DoModal() == IDOK) { theApp.m_pMainWnd = NULL; TRACE(_T("copy %s to %s\n"), (LPCTSTR)cmdLinePath.GetWinPathString(), (LPCTSTR)dlg.m_URL); CSVNProgressDlg progDlg; progDlg.SetCommand(CSVNProgressDlg::SVNProgress_Copy); if (parser.HasVal(_T("closeonend"))) progDlg.SetAutoClose(parser.GetLongVal(_T("closeonend"))); progDlg.SetOptions(dlg.m_bDoSwitch ? ProgOptSwitchAfterCopy : ProgOptNone); progDlg.SetPathList(pathList); progDlg.SetUrl(dlg.m_URL); progDlg.SetCommitMessage(dlg.m_sLogMessage); progDlg.SetRevision(dlg.m_CopyRev); url = dlg.m_URL; logmessage = dlg.m_sLogMessage; copyRev = dlg.m_CopyRev; doSwitch = dlg.m_bDoSwitch; progDlg.DoModal(); CRegDWORD err = CRegDWORD(_T("Software\\TortoiseGit\\ErrorOccurred"), FALSE); err = (DWORD)progDlg.DidErrorsOccur(); bRet = !progDlg.DidErrorsOccur(); repeat = progDlg.DidErrorsOccur(); CRegDWORD bFailRepeat = CRegDWORD(_T("Software\\TortoiseGit\\CommitReopen"), FALSE); if (DWORD(bFailRepeat) == FALSE) repeat = false; // do not repeat if the user chose not to in the settings. } } while(repeat); return bRet; }
bool ImportCommand::Execute() { bool bRet = false; CString msg; if (parser.HasKey(_T("logmsg"))) { msg = parser.GetVal(_T("logmsg")); } if (parser.HasKey(_T("logmsgfile"))) { CString logmsgfile = parser.GetVal(_T("logmsgfile")); CStringUtils::ReadStringFromTextFile(logmsgfile, msg); } CImportDlg dlg; dlg.m_path = cmdLinePath; dlg.m_sMessage = msg; if (parser.HasVal(_T("url"))) dlg.m_url = parser.GetVal(_T("url")); if (dlg.DoModal() == IDOK) { CSVNProgressDlg progDlg; theApp.m_pMainWnd = &progDlg; progDlg.SetCommand(CSVNProgressDlg::SVNProgress_Import); progDlg.SetAutoClose (parser); DWORD dwOpts = dlg.m_bIncludeIgnored ? ProgOptIncludeIgnored : ProgOptNone; if (dlg.m_UseAutoprops) dwOpts |= ProgOptUseAutoprops; progDlg.SetOptions(dwOpts); progDlg.SetPathList(pathList); progDlg.SetUrl(dlg.m_url); progDlg.SetCommitMessage(dlg.m_sMessage); ProjectProperties props; props.ReadPropsPathList(pathList); progDlg.SetProjectProperties(props); progDlg.DoModal(); bRet = !progDlg.DidErrorsOccur(); } return bRet; }
bool RenameCommand::Execute() { bool bRet = false; CString filename = cmdLinePath.GetFileOrDirectoryName(); CString basePath = cmdLinePath.GetContainingDirectory().GetGitPathString(); //::SetCurrentDirectory(basePath); // show the rename dialog until the user either cancels or enters a new // name (one that's different to the original name CString sNewName; do { CRenameDlg dlg; dlg.m_name = filename; if (dlg.DoModal() != IDOK) return FALSE; sNewName = dlg.m_name; } while(PathIsRelative(sNewName) && !PathIsURL(sNewName) && (sNewName.IsEmpty() || (sNewName.Compare(filename)==0))); if(!basePath.IsEmpty()) sNewName=basePath+"/"+sNewName; CString cmd; CString output; cmd.Format(_T("git.exe mv -- \"%s\" \"%s\""), cmdLinePath.GetGitPathString(), sNewName); if(g_Git.Run(cmd,&output,CP_ACP)) { CMessageBox::Show(hwndExplorer, output, _T("TortoiseGit"), MB_OK); } CTGitPath newpath; newpath.SetFromGit(sNewName); CShellUpdater::Instance().AddPathForUpdate(newpath); #if 0 TRACE(_T("rename file %s to %s\n"), (LPCTSTR)cmdLinePath.GetWinPathString(), (LPCTSTR)sNewName); CTSVNPath destinationPath(basePath); if (PathIsRelative(sNewName) && !PathIsURL(sNewName)) destinationPath.AppendPathString(sNewName); else destinationPath.SetFromWin(sNewName); // check if a rename just with case is requested: that's not possible on windows file systems // and we have to show an error. if (cmdLinePath.GetWinPathString().CompareNoCase(destinationPath.GetWinPathString())==0) { //rename to the same file! CString sHelpPath = theApp.m_pszHelpFilePath; sHelpPath += _T("::/tsvn-dug-rename.html#tsvn-dug-renameincase"); CMessageBox::Show(hwndExplorer, IDS_PROC_CASERENAME, IDS_APPNAME, MB_OK|MB_HELP, sHelpPath); } else { CString sMsg; if (SVN::PathIsURL(cmdLinePath)) { // rename an URL. // Ask for a commit message, then rename directly in // the repository CInputLogDlg input; CString sUUID; SVN svn; svn.GetRepositoryRootAndUUID(cmdLinePath, sUUID); input.SetUUID(sUUID); CString sHint; sHint.Format(IDS_INPUT_MOVE, (LPCTSTR)cmdLinePath.GetSVNPathString(), (LPCTSTR)destinationPath.GetSVNPathString()); input.SetActionText(sHint); if (input.DoModal() == IDOK) { sMsg = input.GetLogMessage(); } else { return FALSE; } } if ((cmdLinePath.IsDirectory())||(pathList.GetCount() > 1)) { // renaming a directory can take a while: use the // progress dialog to show the progress of the renaming // operation. CSVNProgressDlg progDlg; progDlg.SetCommand(CSVNProgressDlg::SVNProgress_Rename); if (parser.HasVal(_T("closeonend"))) progDlg.SetAutoClose(parser.GetLongVal(_T("closeonend"))); progDlg.SetPathList(pathList); progDlg.SetUrl(destinationPath.GetWinPathString()); progDlg.SetCommitMessage(sMsg); progDlg.SetRevision(SVNRev::REV_WC); progDlg.DoModal(); bRet = !progDlg.DidErrorsOccur(); } else { SVN svn; CString sFilemask = cmdLinePath.GetFilename(); if (sFilemask.ReverseFind('.')>=0) { sFilemask = sFilemask.Left(sFilemask.ReverseFind('.')); } else sFilemask.Empty(); CString sNewMask = sNewName; if (sNewMask.ReverseFind('.'>=0)) { sNewMask = sNewMask.Left(sNewMask.ReverseFind('.')); } else sNewMask.Empty(); if (((!sFilemask.IsEmpty()) && (parser.HasKey(_T("noquestion")))) || (cmdLinePath.GetFileExtension().Compare(destinationPath.GetFileExtension())!=0)) { if (!svn.Move(CTSVNPathList(cmdLinePath), destinationPath, TRUE, sMsg)) { TRACE(_T("%s\n"), (LPCTSTR)svn.GetLastErrorMessage()); CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR); } else bRet = true; } else { // when refactoring, multiple files have to be renamed // at once because those files belong together. // e.g. file.aspx, file.aspx.cs, file.aspx.resx CTSVNPathList renlist; CSimpleFileFind filefind(cmdLinePath.GetDirectory().GetWinPathString(), sFilemask+_T(".*")); while (filefind.FindNextFileNoDots()) { if (!filefind.IsDirectory()) renlist.AddPath(CTSVNPath(filefind.GetFilePath())); } if (renlist.GetCount()<=1) { // we couldn't find any other matching files // just do the default... if (!svn.Move(CTSVNPathList(cmdLinePath), destinationPath, TRUE, sMsg)) { TRACE(_T("%s\n"), (LPCTSTR)svn.GetLastErrorMessage()); CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR); } else { bRet = true; CShellUpdater::Instance().AddPathForUpdate(destinationPath); } } else { std::map<CString, CString> renmap; CString sTemp; CString sRenList; for (int i=0; i<renlist.GetCount(); ++i) { CString sFilename = renlist[i].GetFilename(); CString sNewFilename = sNewMask + sFilename.Mid(sFilemask.GetLength()); sTemp.Format(_T("\n%s -> %s"), (LPCTSTR)sFilename, (LPCTSTR)sNewFilename); if (!renlist[i].IsEquivalentTo(cmdLinePath)) sRenList += sTemp; renmap[renlist[i].GetWinPathString()] = renlist[i].GetContainingDirectory().GetWinPathString()+_T("\\")+sNewFilename; } CString sRenameMultipleQuestion; sRenameMultipleQuestion.Format(IDS_PROC_MULTIRENAME, (LPCTSTR)sRenList); UINT idret = CMessageBox::Show(hwndExplorer, sRenameMultipleQuestion, _T("TortoiseGit"), MB_ICONQUESTION|MB_YESNOCANCEL); if (idret == IDYES) { CProgressDlg progress; progress.SetTitle(IDS_PROC_MOVING); progress.SetAnimation(IDR_MOVEANI); progress.SetTime(true); progress.ShowModeless(CWnd::FromHandle(hwndExplorer)); DWORD count = 1; for (std::map<CString, CString>::iterator it=renmap.begin(); it != renmap.end(); ++it) { progress.FormatPathLine(1, IDS_PROC_MOVINGPROG, (LPCTSTR)it->first); progress.FormatPathLine(2, IDS_PROC_CPYMVPROG2, (LPCTSTR)it->second); progress.SetProgress(count, renmap.size()); if (!svn.Move(CTSVNPathList(CTSVNPath(it->first)), CTSVNPath(it->second), TRUE, sMsg)) { if (svn.Err->apr_err == SVN_ERR_ENTRY_NOT_FOUND) { bRet = !!MoveFile(it->first, it->second); } else { TRACE(_T("%s\n"), (LPCTSTR)svn.GetLastErrorMessage()); CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR); bRet = false; } } else { bRet = true; CShellUpdater::Instance().AddPathForUpdate(CTSVNPath(it->second)); } } progress.Stop(); } else if (idret == IDNO) { // no, user wants to just rename the file he selected if (!svn.Move(CTSVNPathList(cmdLinePath), destinationPath, TRUE, sMsg)) { TRACE(_T("%s\n"), (LPCTSTR)svn.GetLastErrorMessage()); CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR); } else { bRet = true; CShellUpdater::Instance().AddPathForUpdate(destinationPath); } } else if (idret == IDCANCEL) { // nothing } } } } } #endif CShellUpdater::Instance().Flush(); return bRet; }
bool RenameCommand::Execute() { bool bRet = false; CString filename = cmdLinePath.GetFileOrDirectoryName(); CString basePath = cmdLinePath.GetContainingDirectory().GetWinPathString(); ::SetCurrentDirectory(basePath); // show the rename dialog until the user either cancels or enters a new // name (one that's different to the original name CString sNewName; do { CRenameDlg dlg; dlg.m_name = filename; if (!SVN::PathIsURL(cmdLinePath)) dlg.SetFileSystemAutoComplete(); if (dlg.DoModal() != IDOK) return FALSE; sNewName = dlg.m_name; } while(PathIsRelative(sNewName) && !PathIsURL(sNewName) && (sNewName.IsEmpty() || (sNewName.Compare(filename)==0))); CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": rename file %s to %s\n", (LPCTSTR)cmdLinePath.GetWinPathString(), (LPCTSTR)sNewName); CTSVNPath destinationPath(basePath); if (PathIsRelative(sNewName) && !PathIsURL(sNewName)) destinationPath.AppendPathString(sNewName); else destinationPath.SetFromWin(sNewName); CString sMsg; if (SVN::PathIsURL(cmdLinePath)) { // rename an URL. // Ask for a commit message, then rename directly in // the repository CInputLogDlg input; CString sUUID; SVN svn; svn.GetRepositoryRootAndUUID(cmdLinePath, true, sUUID); input.SetUUID(sUUID); CString sHint; sHint.FormatMessage(IDS_INPUT_MOVE, (LPCTSTR)cmdLinePath.GetSVNPathString(), (LPCTSTR)destinationPath.GetSVNPathString()); input.SetActionText(sHint); if (input.DoModal() == IDOK) { sMsg = input.GetLogMessage(); } else { return FALSE; } } if ((cmdLinePath.IsDirectory())||(pathList.GetCount() > 1)) { // renaming a directory can take a while: use the // progress dialog to show the progress of the renaming // operation. CSVNProgressDlg progDlg; progDlg.SetCommand(CSVNProgressDlg::SVNProgress_Rename); progDlg.SetAutoClose (parser); progDlg.SetPathList(pathList); progDlg.SetUrl(destinationPath.GetWinPathString()); progDlg.SetCommitMessage(sMsg); progDlg.DoModal(); bRet = !progDlg.DidErrorsOccur(); } else { CString sFilemask = cmdLinePath.GetFilename(); int slashpos = 0; // find out up to which char sFilemask and sNewName are identical int minlen = min(sFilemask.GetLength(), sNewName.GetLength()); for (; slashpos < minlen; ++slashpos) { if (sFilemask[slashpos] != sNewName[slashpos]) break; } if (sFilemask.ReverseFind('.') >= slashpos) { while (sFilemask.ReverseFind('.') >= slashpos) sFilemask = sFilemask.Left(sFilemask.ReverseFind('.')); } else sFilemask.Empty(); CString sNewMask = sNewName; if (sNewMask.ReverseFind('.') >= slashpos) { while (sNewMask.ReverseFind('.') >= slashpos) sNewMask = sNewMask.Left(sNewMask.ReverseFind('.')); } else sNewMask.Empty(); CString sRightPartNew = sNewName.Mid(sNewMask.GetLength()); CString sRightPartOld = cmdLinePath.GetFilename().Mid(sFilemask.GetLength()); // if the file extension changed, or the old and new right parts are not the // same then we can not correctly guess the new names of similar files, so // just do the plain rename of the selected file and don't offer to rename similar ones. if (((!sFilemask.IsEmpty()) && (parser.HasKey(L"noquestion"))) || (cmdLinePath.GetFileExtension().Compare(destinationPath.GetFileExtension())!=0) || (sRightPartOld.CompareNoCase(sRightPartNew))) { if (RenameWithReplace(GetExplorerHWND(), CTSVNPathList(cmdLinePath), destinationPath, sMsg)) bRet = true; } else { // when refactoring, multiple files have to be renamed // at once because those files belong together. // e.g. file.aspx, file.aspx.cs, file.aspx.resx CTSVNPathList renlist; CSimpleFileFind filefind(cmdLinePath.GetDirectory().GetWinPathString(), sFilemask+L".*"); while (filefind.FindNextFileNoDots()) { if (!filefind.IsDirectory()) renlist.AddPath(CTSVNPath(filefind.GetFilePath())); } if ((renlist.GetCount() <= 1) || (renlist.GetCount() > 10)) // arbitrary value of ten { // Either no matching files to rename, or way too many of them: // just do the default... if (RenameWithReplace(GetExplorerHWND(), CTSVNPathList(cmdLinePath), destinationPath, sMsg)) { bRet = true; CShellUpdater::Instance().AddPathForUpdate(destinationPath); } } else { std::map<CString, CString> renmap; CString sTemp; CString sRenList; for (int i=0; i<renlist.GetCount(); ++i) { CString sFilename = renlist[i].GetFilename(); CString sNewFilename = sNewMask + sFilename.Mid(sFilemask.GetLength()); sTemp.Format(L"\n%s -> %s", (LPCTSTR)sFilename, (LPCTSTR)sNewFilename); if (!renlist[i].IsEquivalentTo(cmdLinePath)) sRenList += sTemp; renmap[renlist[i].GetWinPathString()] = renlist[i].GetContainingDirectory().GetWinPathString()+L"\\"+sNewFilename; } CString sRenameMultipleQuestion; sRenameMultipleQuestion.Format(IDS_PROC_MULTIRENAME, (LPCTSTR)sRenList); UINT idret = ::MessageBox(GetExplorerHWND(), sRenameMultipleQuestion, L"TortoiseSVN", MB_ICONQUESTION|MB_YESNOCANCEL); if (idret == IDYES) { CProgressDlg progress; progress.SetTitle(IDS_PROC_MOVING); progress.SetTime(true); progress.ShowModeless(CWnd::FromHandle(GetExplorerHWND())); DWORD count = 1; for (std::map<CString, CString>::iterator it=renmap.begin(); it != renmap.end(); ++it) { progress.FormatPathLine(1, IDS_PROC_MOVINGPROG, (LPCTSTR)it->first); progress.FormatPathLine(2, IDS_PROC_CPYMVPROG2, (LPCTSTR)it->second); progress.SetProgress64(count, renmap.size()); if (RenameWithReplace(GetExplorerHWND(), CTSVNPathList(CTSVNPath(it->first)), CTSVNPath(it->second), sMsg)) { bRet = true; CShellUpdater::Instance().AddPathForUpdate(CTSVNPath(it->second)); } } progress.Stop(); } else if (idret == IDNO) { // no, user wants to just rename the file he selected if (RenameWithReplace(GetExplorerHWND(), CTSVNPathList(cmdLinePath), destinationPath, sMsg)) { bRet = true; CShellUpdater::Instance().AddPathForUpdate(destinationPath); } } else if (idret == IDCANCEL) { // nothing } } } } return bRet; }