Пример #1
0
bool RemoveCommand::Execute()
{
	bool bRet = false;
	// removing items from a working copy is done item-by-item so we
	// have a chance to show a progress bar
	//
	// removing items from an URL in the repository requires that we
	// ask the user for a log message.
#if 0
	BOOL bForce = FALSE;
	SVN svn;
	if ((!pathList.IsEmpty())&&(SVN::PathIsURL(pathList[0])))
	{
		// Delete using URL's, not wc paths
		svn.SetPromptApp(&theApp);
		CInputLogDlg dlg;
		CString sUUID;
		svn.GetRepositoryRootAndUUID(pathList[0], sUUID);
		dlg.SetUUID(sUUID);
		CString sHint;
		if (pathList.GetCount() == 1)
			sHint.Format(IDS_INPUT_REMOVEONE, (LPCTSTR)pathList[0].GetSVNPathString());
		else
			sHint.Format(IDS_INPUT_REMOVEMORE, pathList.GetCount());
		dlg.SetActionText(sHint);
		if (dlg.DoModal()==IDOK)
		{
			if (!svn.Remove(pathList, TRUE, parser.HasKey(_T("keep")), dlg.GetLogMessage()))
			{
				CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);
				return FALSE;
			}
			return true;
		}
		return FALSE;
	}
	else
	{
		for (int nPath = 0; nPath < pathList.GetCount(); ++nPath)
		{
			CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": remove file %s\n"), (LPCTSTR)pathList[nPath].GetUIPathString());
			// even though SVN::Remove takes a list of paths to delete at once
			// we delete each item individually so we can prompt the user
			// if something goes wrong or unversioned/modified items are
			// to be deleted
			CTSVNPathList removePathList(pathList[nPath]);
			if (bForce)
			{
				CTSVNPath delPath = removePathList[0];
				delPath.Delete(true);
			}
			if (!svn.Remove(removePathList, bForce, parser.HasKey(_T("keep"))))
			{
				if ((svn.Err->apr_err == SVN_ERR_UNVERSIONED_RESOURCE) ||
					(svn.Err->apr_err == SVN_ERR_CLIENT_MODIFIED))
				{
					CString msg, yes, no, yestoall;
					if (pathList[nPath].IsDirectory())
					{
						msg.Format(IDS_PROC_REMOVEFORCEFOLDER, pathList[nPath].GetWinPath());
					}
					else
					{
						msg.Format(IDS_PROC_REMOVEFORCE, (LPCTSTR)svn.GetLastErrorMessage());
					}
					yes.LoadString(IDS_MSGBOX_YES);
					no.LoadString(IDS_MSGBOX_NO);
					yestoall.LoadString(IDS_PROC_YESTOALL);
					UINT ret = CMessageBox::Show(hwndExplorer, msg, _T("TortoiseGit"), 2, IDI_ERROR, yes, no, yestoall);
					if (ret == 3)
						bForce = TRUE;
					if ((ret == 1)||(ret==3))
					{
						CTSVNPath delPath = removePathList[0];
						delPath.Delete(true);
						if (!svn.Remove(removePathList, TRUE, parser.HasKey(_T("keep"))))
						{
							CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);
						}
						else
							bRet = true;
					}
				}
				else
					CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);
			}
		}
	}
	if (bRet)
		CShellUpdater::Instance().AddPathsForUpdate(pathList);
#endif

	//we don't ask user about if keep local copy.
	//because there are command "Delete(keep local copy)" at explore context menu
	//int key=CMessageBox::Show(hwndExplorer, _T("File will removed from version control\r\n Do you want to keep local copy"), _T("TortoiseGit"), MB_ICONINFORMATION|MB_YESNOCANCEL);
	//if(key == IDCANCEL)

	CString format;
	BOOL keepLocal = parser.HasKey(_T("keep"));
	if (pathList.GetCount() > 1)
		format.Format(keepLocal ? IDS_WARN_DELETE_MANY_FROM_INDEX : IDS_WARN_DELETE_MANY, pathList.GetCount());
	else
		format.Format(keepLocal ? IDS_WARN_DELETE_ONE_FROM_INDEX : IDS_WARN_REMOVE, pathList[0].GetGitPathString());
	if (CMessageBox::Show(hwndExplorer, format, _T("TortoiseGit"), 2, IDI_QUESTION, CString(MAKEINTRESOURCE(IDS_REMOVEBUTTON)), CString(MAKEINTRESOURCE(IDS_MSGBOX_ABORT))) == 2)
		return false;

	if (keepLocal)
	{
		format= _T("git.exe rm -r -f --cached -- \"%s\"");
	}
	else
	{
		format=_T("git.exe rm -r -f -- \"%s\"");
	}

	CString output;
	CString cmd;
	int nPath;
	for (nPath = 0; nPath < pathList.GetCount(); ++nPath)
	{
		cmd.Format(format, (LPCTSTR)pathList[nPath].GetGitPathString());
		if (g_Git.Run(cmd, &output, CP_UTF8))
		{
			if (CMessageBox::Show(hwndExplorer, output, _T("TortoiseGit"), 2, IDI_ERROR, CString(MAKEINTRESOURCE(IDS_IGNOREBUTTON)), CString(MAKEINTRESOURCE(IDS_ABORTBUTTON))) == 2)
				return FALSE;
		}
	}

	output.Format(IDS_PROC_FILESREMOVED, nPath);

	CShellUpdater::Instance().AddPathsForUpdate(pathList);

	CMessageBox::Show(hwndExplorer, output, _T("TortoiseGit"), MB_ICONINFORMATION|MB_OK);

	CShellUpdater::Instance().Flush();
	return bRet;
}
Пример #2
0
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;
}
Пример #3
0
bool RemoveCommand::Execute()
{
    bool bRet = false;
    // removing items from a working copy is done item-by-item so we
    // have a chance to show a progress bar
    //
    // removing items from an URL in the repository requires that we
    // ask the user for a log message.
    SVN svn;
    if ((pathList.GetCount())&&(SVN::PathIsURL(pathList[0])))
    {
        // Delete using URL's, not wc paths
        svn.SetPromptApp(&theApp);
        CInputLogDlg dlg;
        CString sUUID;
        svn.GetRepositoryRootAndUUID(pathList[0], true, sUUID);
        dlg.SetUUID(sUUID);
        CString sHint;
        if (pathList.GetCount() == 1)
            sHint.Format(IDS_INPUT_REMOVEONE, (LPCTSTR)pathList[0].GetSVNPathString());
        else
            sHint.Format(IDS_INPUT_REMOVEMORE, pathList.GetCount());
        dlg.SetActionText(sHint);
        if (dlg.DoModal()==IDOK)
        {
            if (!svn.Remove(pathList, true, !!parser.HasKey(L"keep"), dlg.GetLogMessage()))
            {
                svn.ShowErrorDialog(GetExplorerHWND(), pathList.GetCommonDirectory());
                return false;
            }
            return true;
        }
        return false;
    }
    else
    {
        bool bForce = false;
        for(int nPath = 0; nPath < pathList.GetCount(); nPath++)
        {
            CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": remove file %s\n", (LPCTSTR)pathList[nPath].GetUIPathString());
            // even though SVN::Remove takes a list of paths to delete at once
            // we delete each item individually so we can prompt the user
            // if something goes wrong or unversioned/modified items are
            // to be deleted
            CTSVNPathList removePathList(pathList[nPath]);
            if ((bForce)&&(!parser.HasKey(L"keep")))
            {
                CTSVNPath delPath = removePathList[0];
                if (!delPath.IsDirectory())
                    delPath.Delete(true);
                // note: we don't move folders to the trash bin, so they can't
                // get restored anymore - svn removes *all* files in a removed
                // folder, even modified and unversioned ones
                // We could move the folders here to the trash bin too, but then
                // the folder would be gone and will require a recursive commit.
                // Of course: a solution would be to first create a copy of the folder,
                // move the original folder to the trash, then rename the copied folder
                // to the original name, then let svn delete the folder - but
                // that would just take too much time for bigger folders...
            }
            if (!svn.Remove(removePathList, bForce, !!parser.HasKey(L"keep")))
            {
                if ((svn.GetSVNError()->apr_err == SVN_ERR_UNVERSIONED_RESOURCE) ||
                    (svn.GetSVNError()->apr_err == SVN_ERR_CLIENT_MODIFIED))
                {
                    UINT ret = 0;
                    CString msg;
                    if (pathList[nPath].IsDirectory())
                        msg.Format(IDS_PROC_REMOVEFORCE_TASK1_2, (LPCTSTR)svn.GetLastErrorMessage(0), (LPCTSTR)pathList[nPath].GetFileOrDirectoryName());
                    else
                        msg.Format(IDS_PROC_REMOVEFORCE_TASK1, (LPCTSTR)svn.GetLastErrorMessage(0), (LPCTSTR)pathList[nPath].GetFileOrDirectoryName());
                    CTaskDialog taskdlg(msg,
                                        CString(MAKEINTRESOURCE(IDS_PROC_REMOVEFORCE_TASK2)),
                                        L"TortoiseSVN",
                                        0,
                                        TDF_ENABLE_HYPERLINKS | TDF_USE_COMMAND_LINKS | TDF_ALLOW_DIALOG_CANCELLATION | TDF_POSITION_RELATIVE_TO_WINDOW);
                    taskdlg.AddCommandControl(IDYES, CString(MAKEINTRESOURCE(IDS_PROC_REMOVEFORCE_TASK3)));
                    taskdlg.AddCommandControl(IDNO, CString(MAKEINTRESOURCE(IDS_PROC_REMOVEFORCE_TASK4)));
                    taskdlg.SetCommonButtons(TDCBF_CANCEL_BUTTON);
                    taskdlg.SetVerificationCheckboxText(CString(MAKEINTRESOURCE(IDS_PROC_REMOVEFORCE_TASK5)));
                    taskdlg.SetDefaultCommandControl(IDNO);
                    taskdlg.SetMainIcon(TD_WARNING_ICON);
                    ret = (UINT)taskdlg.DoModal(GetExplorerHWND());
                    if (taskdlg.GetVerificationCheckboxState())
                        bForce = true;
                    if (ret == IDYESTOALL)
                        bForce = true;
                    if ((ret == IDYES)||(ret==IDYESTOALL))
                    {
                        if (!parser.HasKey(L"keep"))
                        {
                            CTSVNPath delPath = removePathList[0];
                            if (!delPath.IsDirectory())
                                delPath.Delete(true);
                            // note: see comment for the delPath.Delete() above
                        }
                        if (!svn.Remove(removePathList, true, !!parser.HasKey(L"keep")))
                        {
                            svn.ShowErrorDialog(GetExplorerHWND(), removePathList.GetCommonDirectory());
                        }
                        else
                            bRet = true;
                    }
                }
                else
                    svn.ShowErrorDialog(GetExplorerHWND(), removePathList.GetCommonDirectory());
            }
        }
    }
    if (bRet)
        CShellUpdater::Instance().AddPathsForUpdate(pathList);
    return bRet;
}
Пример #4
0
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;
}
Пример #5
0
bool RemoveCommand::Execute()
{
	bool bRet = false;
	// removing items from a working copy is done item-by-item so we
	// have a chance to show a progress bar
	//
	// removing items from an URL in the repository requires that we
	// ask the user for a log message.
	bool bForce = false;
	SVN svn;
	if ((pathList.GetCount())&&(SVN::PathIsURL(pathList[0])))
	{
		// Delete using URL's, not wc paths
		svn.SetPromptApp(&theApp);
		CInputLogDlg dlg;
		CString sUUID;
		svn.GetRepositoryRootAndUUID(pathList[0], true, sUUID);
		dlg.SetUUID(sUUID);
		CString sHint;
		if (pathList.GetCount() == 1)
			sHint.Format(IDS_INPUT_REMOVEONE, (LPCTSTR)pathList[0].GetSVNPathString());
		else
			sHint.Format(IDS_INPUT_REMOVEMORE, pathList.GetCount());
		dlg.SetActionText(sHint);
		if (dlg.DoModal()==IDOK)
		{
			if (!svn.Remove(pathList, true, !!parser.HasKey(_T("keep")), dlg.GetLogMessage()))
			{
				CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseSVN"), MB_ICONERROR);
				return false;
			}
			return true;
		}
		return false;
	}
	else
	{
		for(int nPath = 0; nPath < pathList.GetCount(); nPath++)
		{
			TRACE(_T("remove file %s\n"), (LPCTSTR)pathList[nPath].GetUIPathString());
			// even though SVN::Remove takes a list of paths to delete at once
			// we delete each item individually so we can prompt the user
			// if something goes wrong or unversioned/modified items are
			// to be deleted
			CTSVNPathList removePathList(pathList[nPath]);
			if ((bForce)&&(!parser.HasKey(_T("keep"))))
			{
				CTSVNPath delPath = removePathList[0];
				if (!delPath.IsDirectory())
					delPath.Delete(true);
				// note: we don't move folders to the trash bin, so they can't
				// get restored anymore - svn removes *all* files in a removed
				// folder, even modified and unversioned ones
				// We could move the folders here to the trash bin too, but then
				// the folder would be gone and will require a recursive commit.
				// Of course: a solution would be to first create a copy of the folder,
				// move the original folder to the trash, then rename the copied folder
				// to the original name, then let svn delete the folder - but
				// that would just take too much time for bigger folders...
			}
			if (!svn.Remove(removePathList, bForce, !!parser.HasKey(_T("keep"))))
			{
				if ((svn.Err->apr_err == SVN_ERR_UNVERSIONED_RESOURCE) ||
					(svn.Err->apr_err == SVN_ERR_CLIENT_MODIFIED))
				{
					CString msg, yes, no, yestoall;
					if (pathList[nPath].IsDirectory())
					{
						msg.Format(IDS_PROC_REMOVEFORCEFOLDER, pathList[nPath].GetWinPath());
					}
					else
					{
						msg.Format(IDS_PROC_REMOVEFORCE, (LPCTSTR)svn.GetLastErrorMessage());
					}
					yes.LoadString(IDS_MSGBOX_YES);
					no.LoadString(IDS_MSGBOX_NO);
					yestoall.LoadString(IDS_PROC_YESTOALL);
					UINT ret = CMessageBox::Show(hwndExplorer, msg, _T("TortoiseSVN"), 2, IDI_ERROR, yes, no, yestoall);
					if (ret == 3)
						bForce = true;
					if ((ret == 1)||(ret==3))
					{
						if (!parser.HasKey(_T("keep")))
						{
							CTSVNPath delPath = removePathList[0];
							if (!delPath.IsDirectory())
								delPath.Delete(true);
							// note: see comment for the delPath.Delete() above
						}
						if (!svn.Remove(removePathList, true, !!parser.HasKey(_T("keep"))))
						{
							CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseSVN"), MB_ICONERROR);
						}
						else
							bRet = true;
					}
				}
				else
					CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseSVN"), MB_ICONERROR);
			}
		}
	}
	if (bRet)
		CShellUpdater::Instance().AddPathsForUpdate(pathList);
	return bRet;
}