Пример #1
0
bool DropExportCommand::Execute()
{
	bool bRet = true;
#if 0
	CString droppath = parser.GetVal(_T("droptarget"));
	if (CTGitPath(droppath).IsAdminDir())
		return false;

	SVN svn;
	if ((pathList.GetCount() == 1)&&
		(pathList[0].IsEquivalentTo(CTSVNPath(droppath))))
	{
		// exporting to itself:
		// remove all svn admin dirs, effectively unversion the 'exported' folder.
		CString msg;
		msg.Format(IDS_PROC_EXPORTUNVERSION, (LPCTSTR)droppath);
		if (CMessageBox::Show(hwndExplorer, msg, _T("TortoiseSVN"), MB_ICONQUESTION|MB_YESNO) == IDYES)
		{
			CProgressDlg progress;
			progress.SetTitle(IDS_PROC_UNVERSION);
			progress.SetAnimation(IDR_MOVEANI);
			progress.FormatNonPathLine(1, IDS_SVNPROGRESS_EXPORTINGWAIT);
			progress.SetTime(true);
			progress.ShowModeless(hwndExplorer);
			std::vector<CTSVNPath> removeVector;

			CDirFileEnum lister(droppath);
			CString srcFile;
			bool bFolder = false;
			while (lister.NextFile(srcFile, &bFolder))
			{
				CTSVNPath item(srcFile);
				if ((bFolder)&&(g_SVNAdminDir.IsAdminDirName(item.GetFileOrDirectoryName())))
				{
					removeVector.push_back(item);
				}
			}
			DWORD count = 0;
			for (std::vector<CTSVNPath>::iterator it = removeVector.begin(); (it != removeVector.end()) && (!progress.HasUserCancelled()); ++it)
			{
				progress.FormatPathLine(1, IDS_SVNPROGRESS_UNVERSION, (LPCTSTR)it->GetWinPath());
				progress.SetProgress(count, removeVector.size());
				count++;
				it->Delete(false);
			}
			progress.Stop();
		}
		else
			return false;
	}
	else
	{
		for(int nPath = 0; nPath < pathList.GetCount(); nPath++)
		{
			CString dropper = droppath + _T("\\") + pathList[nPath].GetFileOrDirectoryName();
			if (PathFileExists(dropper))
			{
				CString sMsg;
				CString sBtn1(MAKEINTRESOURCE(IDS_PROC_OVERWRITEEXPORT_OVERWRITE));
				CString sBtn2(MAKEINTRESOURCE(IDS_PROC_OVERWRITEEXPORT_RENAME));
				CString sBtn3(MAKEINTRESOURCE(IDS_PROC_OVERWRITEEXPORT_CANCEL));
				sMsg.Format(IDS_PROC_OVERWRITEEXPORT, (LPCTSTR)dropper);
				UINT ret = CMessageBox::Show(hwndExplorer, sMsg, _T("TortoiseSVN"), MB_DEFBUTTON1, IDI_QUESTION, sBtn1, sBtn2, sBtn3);
				if (ret==2)
				{
					dropper.Format(IDS_PROC_EXPORTFOLDERNAME, (LPCTSTR)droppath, (LPCTSTR)pathList[nPath].GetFileOrDirectoryName());
					int exportcount = 1;
					while (PathFileExists(dropper))
					{
						dropper.Format(IDS_PROC_EXPORTFOLDERNAME2, (LPCTSTR)droppath, exportcount++, (LPCTSTR)pathList[nPath].GetFileOrDirectoryName());
					}
				}
				else if (ret == 3)
					return false;
			}
			if (!svn.Export(pathList[nPath], CTSVNPath(dropper), SVNRev::REV_WC ,SVNRev::REV_WC, FALSE, FALSE, svn_depth_infinity, hwndExplorer, parser.HasKey(_T("extended"))))
			{
				CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseSVN"), MB_OK | MB_ICONERROR);
				bRet = false;
			}
		}
	}
#endif
	return bRet;
}
bool DropCopyAddCommand::Execute()
{
	bool bRet = false;
	CString droppath = parser.GetVal(_T("droptarget"));
	if (CTGitPath(droppath).IsAdminDir())
		return FALSE;

	if(!CTGitPath(droppath).HasAdminDir(&g_Git.m_CurrentDir))
		return FALSE;

	int worktreePathLen = g_Git.m_CurrentDir.GetLength();
	orgPathList.RemoveAdminPaths();
	CTGitPathList copiedFiles;
	for(int nPath = 0; nPath < orgPathList.GetCount(); ++nPath)
	{
		if (orgPathList[nPath].IsEquivalentTo(CTGitPath(droppath)))
			continue;

		//copy the file to the new location
		CString name = orgPathList[nPath].GetFileOrDirectoryName();
		if (::PathFileExists(droppath + _T("\\") + name))
		{
			if (::PathIsDirectory(droppath + _T("\\") + name))
			{
				if (orgPathList[nPath].IsDirectory())
					continue;
			}

			CString strMessage;
			strMessage.Format(IDS_PROC_OVERWRITE_CONFIRM, (LPCTSTR)(droppath + _T("\\") + name));
			CString sBtn1(MAKEINTRESOURCE(IDS_PROC_OVERWRITEEXPORT_OVERWRITE));
			CString sBtn2(MAKEINTRESOURCE(IDS_PROC_OVERWRITEEXPORT_KEEP));
			CString sBtn3(MAKEINTRESOURCE(IDS_PROC_OVERWRITEEXPORT_CANCEL));
			UINT ret = CMessageBox::Show(hwndExplorer, strMessage, _T("TortoiseGit"), 2, IDI_QUESTION, sBtn1, sBtn2, sBtn3);

			if (ret == 3)
				return FALSE; //cancel the whole operation
			if (ret == 1)
			{
				if (!::CopyFile(orgPathList[nPath].GetWinPath(), droppath + _T("\\") + name, FALSE))
				{
					//the copy operation failed! Get out of here!
					ShowErrorMessage();
					return FALSE;
				}
			}
		}
		else
		{
			if (orgPathList[nPath].IsDirectory())
			{
				CString fromPath = orgPathList[nPath].GetWinPathString() + L"||";
				CString toPath = droppath + L"\\" + name + L"||";
				std::unique_ptr<TCHAR[]> fromBuf(new TCHAR[fromPath.GetLength() + 2]);
				std::unique_ptr<TCHAR[]> toBuf(new TCHAR[toPath.GetLength() + 2]);
				wcscpy_s(fromBuf.get(), fromPath.GetLength() + 2, fromPath);
				wcscpy_s(toBuf.get(), toPath.GetLength() + 2, toPath);
				CStringUtils::PipesToNulls(fromBuf.get(), fromPath.GetLength() + 2);
				CStringUtils::PipesToNulls(toBuf.get(), toPath.GetLength() + 2);

				SHFILEOPSTRUCT fileop = {0};
				fileop.wFunc = FO_COPY;
				fileop.pFrom = fromBuf.get();
				fileop.pTo = toBuf.get();
				fileop.fFlags = FOF_NO_CONNECTED_ELEMENTS | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NOCONFIRMMKDIR | FOF_NOCOPYSECURITYATTRIBS | FOF_SILENT;
				if (!SHFileOperation(&fileop))
				{
					// add all copied files WITH special handling for repos/submodules (folders which include a .git entry)
					CDirFileEnum finder(droppath + L"\\" + name);
					bool isDir = true;
					CString filepath;
					CString lastRepo;
					bool isRepo = false;
					while (finder.NextFile(filepath, &isDir, !isRepo)) // don't recurse into .git directories
					{
						if (!lastRepo.IsEmpty())
						{
							if (filepath.Find(lastRepo) == 0)
								continue;
							else
								lastRepo.Empty();
						}
						int pos = -1;
						if ((pos = filepath.Find(L"\\" + g_GitAdminDir.GetAdminDirName())) >= 0)
							isRepo = (pos == filepath.GetLength() - g_GitAdminDir.GetAdminDirName().GetLength() - 1);
						else
							isRepo = false;
						if (isRepo)
						{
							lastRepo = filepath.Mid(0, filepath.GetLength() - g_GitAdminDir.GetAdminDirName().GetLength());
							CString msg;
							if (!isDir)
								msg.Format(IDS_PROC_COPY_SUBMODULE, lastRepo);
							else
								msg.Format(IDS_PROC_COPY_REPOSITORY, lastRepo);
							int ret = CMessageBox::Show(hwndExplorer, msg, _T("TortoiseGit"), 1, IDI_QUESTION, CString(MAKEINTRESOURCE(IDS_DELETEBUTTON)), CString(MAKEINTRESOURCE(IDS_IGNOREBUTTON)), CString(MAKEINTRESOURCE(IDS_ABORTBUTTON)));
							if (ret == 3)
								return FALSE;
							if (ret == 1)
							{
								CTGitPath(filepath).Delete(false);
								lastRepo.Empty();
							}
							continue;
						}
						if (!isDir)
							copiedFiles.AddPath(CTGitPath(filepath.Mid(worktreePathLen + 1))); //add the new filepath
					}
				}
				continue; // do not add a directory to copiedFiles
			}
			else if (!CopyFile(orgPathList[nPath].GetWinPath(), droppath+_T("\\")+name, FALSE))
			{
				//the copy operation failed! Get out of here!
				ShowErrorMessage();
				return FALSE;
			}
		}
		CString destPath(droppath + _T("\\") + name);
		copiedFiles.AddPath(CTGitPath(destPath.Mid(worktreePathLen + 1))); //add the new filepath
	}
	//now add all the newly copied files to the working copy
	CGitProgressDlg progDlg;
	theApp.m_pMainWnd = &progDlg;
	AddProgressCommand addCommand;
	progDlg.SetCommand(&addCommand);
	addCommand.SetPathList(copiedFiles);
	progDlg.DoModal();
	bRet = !progDlg.DidErrorsOccur();

	return bRet;
}